Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2228 lines
58 KiB

  1. VERSION 1.0 CLASS
  2. BEGIN
  3. MultiUse = -1 'True
  4. Persistable = 0 'NotPersistable
  5. DataBindingBehavior = 0 'vbNone
  6. DataSourceBehavior = 0 'vbNone
  7. MTSTransactionMode = 0 'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "Taxonomy"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = False
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = True
  14. Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes"
  15. Attribute VB_Ext_KEY = "Top_Level" ,"No"
  16. Option Explicit
  17. Public Event ReportStatus(ByVal strStatus As String, ByRef blnCancel As Boolean)
  18. Public Sub GetURIs( _
  19. ByVal o_dict As Scripting.Dictionary _
  20. )
  21. Dim rs As ADODB.Recordset
  22. Dim strQuery As String
  23. Dim strURI As String
  24. CheckDatabaseVersion
  25. Set rs = New ADODB.Recordset
  26. strQuery = "" & _
  27. "SELECT DISTINCT ContentURI " & _
  28. "FROM Taxonomy "
  29. rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  30. Do While (Not rs.EOF)
  31. strURI = Trim$(rs("ContentURI") & "")
  32. If (strURI <> "") Then
  33. If (Not o_dict.Exists(strURI)) Then
  34. o_dict.Add strURI, True
  35. End If
  36. End If
  37. rs.MoveNext
  38. Loop
  39. End Sub
  40. Public Sub GetTitlesForKeyword( _
  41. ByVal i_intKID As Long, _
  42. ByVal o_rs As ADODB.Recordset _
  43. )
  44. Dim strQuery As String
  45. CheckDatabaseVersion
  46. CloseRecordSet o_rs
  47. ' ADO uses % as a wildcard character in SQL statements whereas Access uses *.
  48. strQuery = "" & _
  49. "SELECT * " & _
  50. "FROM Taxonomy " & _
  51. "WHERE (Keywords Like ""% " & i_intKID & " %"")"
  52. o_rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  53. End Sub
  54. Public Sub GetNodeDetails( _
  55. ByVal i_intTID As Long, _
  56. ByVal o_rs As ADODB.Recordset _
  57. )
  58. Dim strQuery As String
  59. CheckDatabaseVersion
  60. CloseRecordSet o_rs
  61. strQuery = "" & _
  62. "SELECT * " & _
  63. "FROM Taxonomy " & _
  64. "WHERE (TID=" & i_intTID & ")"
  65. o_rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  66. End Sub
  67. Public Sub GetNodeChildren( _
  68. ByVal i_intTID As Long, _
  69. ByVal o_rs As ADODB.Recordset _
  70. )
  71. Dim strQuery As String
  72. CheckDatabaseVersion
  73. CloseRecordSet o_rs
  74. strQuery = "" & _
  75. "SELECT * " & _
  76. "FROM Taxonomy " & _
  77. "WHERE ((ParentTID=" & i_intTID & ") " & _
  78. "AND (TID<>" & ROOT_TID_C & ")) " & _
  79. "ORDER BY TID"
  80. o_rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  81. End Sub
  82. Public Function GetTypes( _
  83. ) As Variant()
  84. Dim strQuery As String
  85. Dim rs As ADODB.Recordset
  86. Dim arrTypes() As Variant
  87. Dim intIndex As Long
  88. Dim intTypeID As Long
  89. Dim strDescription As String
  90. CheckDatabaseVersion
  91. Set rs = New ADODB.Recordset
  92. strQuery = "" & _
  93. "SELECT * " & _
  94. "FROM Types " & _
  95. "ORDER BY Description"
  96. rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  97. ReDim arrTypes(rs.RecordCount - 1)
  98. intIndex = 0
  99. Do While (Not rs.EOF)
  100. intTypeID = rs("TypeID")
  101. strDescription = rs("Description") & ""
  102. arrTypes(intIndex) = Array(intTypeID, strDescription)
  103. intIndex = intIndex + 1
  104. rs.MoveNext
  105. Loop
  106. GetTypes = arrTypes
  107. End Function
  108. Private Function p_CreateTaxonomyElement( _
  109. ByVal i_DOMDoc As MSXML2.DOMDocument, _
  110. ByVal i_rs As ADODB.Recordset _
  111. ) As MSXML2.IXMLDOMElement
  112. Dim Element As MSXML2.IXMLDOMElement
  113. Set Element = i_DOMDoc.createElement(HHT_TAXONOMY_ENTRY_C)
  114. With Element
  115. .setAttribute HHT_TITLE_C, i_rs("ENUTitle") & ""
  116. .setAttribute HHT_URI_C, i_rs("ContentURI") & ""
  117. .setAttribute HHT_ICONURI_C, i_rs("IconURI") & ""
  118. .setAttribute HHT_DESCRIPTION_C, i_rs("ENUDescription") & ""
  119. .setAttribute HHT_TYPE_C, IIf(IsNull(i_rs("Type")), 0, i_rs("Type"))
  120. .setAttribute HHT_VISIBLE_C, IIf(i_rs("Visible"), "True", "False")
  121. .setAttribute HHT_SUBSITE_C, IIf(i_rs("SubSite"), "True", "False")
  122. .setAttribute HHT_tid_C, i_rs("TID")
  123. .setAttribute HHT_comments_C, i_rs("Comments") & ""
  124. .setAttribute HHT_locinclude_C, i_rs("LocInclude") & ""
  125. .setAttribute HHT_skus_C, i_rs("SKUs")
  126. .setAttribute HHT_modifiedtime_C, i_rs("ModifiedTime")
  127. .setAttribute HHT_username_C, i_rs("Username")
  128. .setAttribute HHT_leaf_C, IIf(i_rs("Leaf"), "True", "False")
  129. .setAttribute HHT_parenttid_C, i_rs("ParentTID")
  130. .setAttribute HHT_basefile_C, i_rs("BaseFile") & ""
  131. .setAttribute HHT_keywords_C, i_rs("Keywords") & ""
  132. .setAttribute HHT_orderunderparent_C, i_rs("OrderUnderParent")
  133. .setAttribute HHT_authoringgroup_C, i_rs("AuthoringGroup")
  134. .setAttribute HHT_ENTRY_C, i_rs("Entry") & ""
  135. .setAttribute HHT_NAVIGATIONMODEL_C, NavModelString(i_rs("NavigationModel") & "")
  136. End With
  137. Set p_CreateTaxonomyElement = Element
  138. End Function
  139. Public Sub FixOrderingNumbers()
  140. Dim rsLock As ADODB.Recordset
  141. Dim rs As ADODB.Recordset
  142. Dim strQuery As String
  143. Dim intParentTID As Long
  144. Dim intLastParentTID As Long
  145. Dim intOrderUnderParent As Long
  146. CheckDatabaseVersion
  147. LockTable LOCK_TABLE_TAXONOMY, rsLock
  148. Set rs = New ADODB.Recordset
  149. strQuery = "" & _
  150. "SELECT * " & _
  151. "FROM Taxonomy " & _
  152. "ORDER BY ParentTID, OrderUnderParent"
  153. rs.Open strQuery, g_cnn, adOpenForwardOnly, adLockPessimistic
  154. intLastParentTID = INVALID_ID_C
  155. Do While (Not rs.EOF)
  156. intParentTID = rs("ParentTID")
  157. If (intParentTID <> intLastParentTID) Then
  158. intLastParentTID = intParentTID
  159. intOrderUnderParent = 0
  160. End If
  161. If (rs("TID") <> ROOT_TID_C) Then
  162. intOrderUnderParent = intOrderUnderParent + PREFERRED_ORDER_DELTA_C
  163. rs("OrderUnderParent") = intOrderUnderParent
  164. rs.Update
  165. End If
  166. rs.MoveNext
  167. Loop
  168. End Sub
  169. Public Function GetCategory( _
  170. ByRef i_DOMNode As MSXML2.IXMLDOMNode _
  171. ) As String
  172. Dim DOMNode As MSXML2.IXMLDOMNode
  173. Dim DOMNodeParent As MSXML2.IXMLDOMNode
  174. Dim intTID As Long
  175. Dim strParentCategory As String
  176. Dim strParentEntry As String
  177. If (i_DOMNode.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  178. Exit Function
  179. End If
  180. intTID = XMLGetAttribute(i_DOMNode, HHT_tid_C)
  181. If (intTID = ROOT_TID_C) Then
  182. Exit Function
  183. End If
  184. Set DOMNodeParent = i_DOMNode.parentNode
  185. If (DOMNodeParent Is Nothing) Then
  186. Exit Function
  187. End If
  188. strParentCategory = GetCategory(DOMNodeParent)
  189. strParentEntry = XMLGetAttribute(DOMNodeParent, HHT_ENTRY_C)
  190. If (XMLGetAttribute(DOMNodeParent, HHT_tid_C) = ROOT_TID_C) Then
  191. strParentEntry = ""
  192. End If
  193. If (strParentCategory = "") Then
  194. GetCategory = strParentEntry
  195. Else
  196. GetCategory = strParentCategory & "/" & strParentEntry
  197. End If
  198. End Function
  199. Private Sub p_CreateKeywordElements( _
  200. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  201. ByRef i_colKeywords As Collection _
  202. )
  203. Dim strKeywords As String
  204. Dim strKeyword As String
  205. Dim arrKeywords() As String
  206. Dim strKID As String
  207. Dim intIndex As Long
  208. Dim DOMDoc As MSXML2.DOMDocument
  209. Dim Element As MSXML2.IXMLDOMElement
  210. strKeywords = XMLGetAttribute(u_DOMNode, HHT_keywords_C)
  211. arrKeywords = Split(strKeywords, " ")
  212. Set DOMDoc = u_DOMNode.ownerDocument
  213. For intIndex = LBound(arrKeywords) To UBound(arrKeywords)
  214. strKID = arrKeywords(intIndex)
  215. If (strKID = "") Then
  216. GoTo LForEnd
  217. End If
  218. If (Not CollectionContainsKey(i_colKeywords, strKID)) Then
  219. GoTo LForEnd
  220. End If
  221. strKeyword = i_colKeywords(strKID)
  222. Set Element = DOMDoc.createElement(HHT_KEYWORD_C)
  223. Element.Text = XMLEscape(strKeyword)
  224. u_DOMNode.appendChild Element
  225. LForEnd:
  226. Next
  227. End Sub
  228. Private Sub p_SetRealSKUs( _
  229. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  230. ByVal i_enumAllowedSKUs As SKU_E _
  231. )
  232. Dim enumSKUs As SKU_E
  233. Dim DOMNode As MSXML2.IXMLDOMNode
  234. DoEvents
  235. If (u_DOMNode.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  236. Exit Sub
  237. End If
  238. enumSKUs = XMLGetAttribute(u_DOMNode, HHT_skus_C)
  239. enumSKUs = enumSKUs And i_enumAllowedSKUs
  240. XMLSetAttribute u_DOMNode, HHT_skus_C, enumSKUs
  241. For Each DOMNode In u_DOMNode.childNodes
  242. p_SetRealSKUs DOMNode, enumSKUs
  243. Next
  244. End Sub
  245. Private Sub p_SetAttributes( _
  246. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  247. ByRef i_colKeywords As Collection, _
  248. ByRef i_strCategory As String _
  249. )
  250. Dim DOMNode As MSXML2.IXMLDOMNode
  251. Dim strEntry As String
  252. Dim strCategory As String
  253. Dim intTID As Long
  254. Dim blnLeaf As Boolean
  255. DoEvents
  256. If (u_DOMNode.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  257. Exit Sub
  258. End If
  259. p_RaiseEventAndLookForCancel "Setting keywords and category of " & _
  260. XMLGetAttribute(u_DOMNode, HHT_TITLE_C)
  261. p_CreateKeywordElements u_DOMNode, i_colKeywords
  262. XMLSetAttribute u_DOMNode, HHT_ACTION_C, HHTVAL_ADD_C
  263. XMLSetAttribute u_DOMNode, HHT_CATEGORY_C, i_strCategory
  264. blnLeaf = XMLGetAttribute(u_DOMNode, HHT_leaf_C)
  265. If (blnLeaf) Then
  266. Exit Sub
  267. End If
  268. strEntry = XMLGetAttribute(u_DOMNode, HHT_ENTRY_C)
  269. If (i_strCategory = "") Then
  270. strCategory = strEntry
  271. Else
  272. strCategory = i_strCategory & "/" & strEntry
  273. End If
  274. intTID = XMLGetAttribute(u_DOMNode, HHT_tid_C)
  275. If (intTID = ROOT_TID_C) Then
  276. strCategory = ""
  277. End If
  278. For Each DOMNode In u_DOMNode.childNodes
  279. p_SetAttributes DOMNode, i_colKeywords, strCategory
  280. Next
  281. End Sub
  282. Public Sub SetCategory2AndEntry( _
  283. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  284. ByRef i_strCategory As String _
  285. )
  286. Dim DOMNode As MSXML2.IXMLDOMNode
  287. Dim strEntry As String
  288. Dim strCategory As String
  289. Dim intTID As Long
  290. Dim blnLeaf As Boolean
  291. DoEvents
  292. If (u_DOMNode.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  293. Exit Sub
  294. End If
  295. blnLeaf = XMLGetAttribute(u_DOMNode, HHT_leaf_C)
  296. If (blnLeaf) Then
  297. Exit Sub
  298. End If
  299. strEntry = XMLGetAttribute(u_DOMNode, HHT_ENTRY_C)
  300. If (i_strCategory = "") Then
  301. strCategory = strEntry
  302. Else
  303. strCategory = i_strCategory & "/" & strEntry
  304. End If
  305. intTID = XMLGetAttribute(u_DOMNode, HHT_tid_C)
  306. If (intTID = ROOT_TID_C) Then
  307. strCategory = ""
  308. End If
  309. XMLSetAttribute u_DOMNode, HHT_category2_C, strCategory
  310. For Each DOMNode In u_DOMNode.childNodes
  311. SetCategory2AndEntry DOMNode, strCategory
  312. Next
  313. End Sub
  314. Private Sub p_SetOrderingInfo( _
  315. ByRef u_DOMNode As MSXML2.IXMLDOMNode _
  316. )
  317. Dim DOMNodeSibling As MSXML2.IXMLDOMNode
  318. Dim DOMNode As MSXML2.IXMLDOMNode
  319. Dim strEntry As String
  320. Dim strURI As String
  321. DoEvents
  322. If (u_DOMNode.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  323. Exit Sub
  324. End If
  325. Set DOMNodeSibling = u_DOMNode.previousSibling
  326. If (DOMNodeSibling Is Nothing) Then
  327. XMLSetAttribute u_DOMNode, HHT_INSERTMODE_C, HHTVAL_TOP_C
  328. Else
  329. strEntry = XMLGetAttribute(DOMNodeSibling, HHT_ENTRY_C)
  330. strURI = XMLGetAttribute(DOMNodeSibling, HHT_URI_C)
  331. If (strEntry <> "") Then
  332. XMLSetAttribute u_DOMNode, HHT_INSERTMODE_C, HHTVAL_AFTER_NODE_C
  333. XMLSetAttribute u_DOMNode, HHT_INSERTLOCATION_C, strEntry
  334. ElseIf (strURI <> "") Then
  335. XMLSetAttribute u_DOMNode, HHT_INSERTMODE_C, HHTVAL_AFTER_TOPIC_C
  336. XMLSetAttribute u_DOMNode, HHT_INSERTLOCATION_C, strURI
  337. End If
  338. End If
  339. For Each DOMNode In u_DOMNode.childNodes
  340. p_SetOrderingInfo DOMNode
  341. Next
  342. End Sub
  343. Private Sub p_RemoveNodesWithOtherSKUs( _
  344. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  345. ByVal i_enumRequiredSKUs As SKU_E _
  346. )
  347. Dim enumSKUs As SKU_E
  348. Dim DOMNode As MSXML2.IXMLDOMNode
  349. DoEvents
  350. If (u_DOMNode.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  351. Exit Sub
  352. End If
  353. enumSKUs = XMLGetAttribute(u_DOMNode, HHT_skus_C)
  354. If ((enumSKUs And i_enumRequiredSKUs) = 0) Then
  355. u_DOMNode.parentNode.removeChild u_DOMNode
  356. Exit Sub
  357. End If
  358. For Each DOMNode In u_DOMNode.childNodes
  359. p_RemoveNodesWithOtherSKUs DOMNode, i_enumRequiredSKUs
  360. Next
  361. End Sub
  362. Private Sub p_FlattenHHT( _
  363. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  364. ByRef u_DOMNodeEntries As MSXML2.IXMLDOMNode _
  365. )
  366. Dim DOMNode As MSXML2.IXMLDOMNode
  367. Dim intTID As Long
  368. DoEvents
  369. If (u_DOMNode.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  370. Exit Sub
  371. End If
  372. u_DOMNode.parentNode.removeChild u_DOMNode
  373. intTID = XMLGetAttribute(u_DOMNode, HHT_tid_C)
  374. If (intTID <> ROOT_TID_C) Then
  375. u_DOMNodeEntries.appendChild u_DOMNode
  376. End If
  377. For Each DOMNode In u_DOMNode.childNodes
  378. p_FlattenHHT DOMNode, u_DOMNodeEntries
  379. Next
  380. End Sub
  381. Private Sub p_RemoveAttributes( _
  382. ByRef u_DOMElement As MSXML2.IXMLDOMElement, _
  383. ByVal i_blnWinMe As Boolean, _
  384. ByVal i_blnAuthoringGroupHHT As Boolean _
  385. )
  386. Dim Attr As MSXML2.IXMLDOMAttribute
  387. Dim DOMNode As MSXML2.IXMLDOMNode
  388. Dim blnLeaf As Boolean
  389. DoEvents
  390. If (u_DOMElement.nodeName <> HHT_TAXONOMY_ENTRY_C) Then
  391. If (u_DOMElement.nodeName <> HHT_TAXONOMY_ENTRIES_C) Then
  392. Exit Sub
  393. End If
  394. End If
  395. For Each Attr In u_DOMElement.Attributes
  396. Select Case Attr.Name
  397. Case HHT_tid_C, HHT_locinclude_C, HHT_modifiedtime_C, HHT_comments_C, _
  398. HHT_parenttid_C, HHT_basefile_C, HHT_keywords_C, HHT_orderunderparent_C, _
  399. HHT_allowedskus_C, HHT_username_C
  400. u_DOMElement.removeAttribute Attr.Name
  401. Case HHT_skus_C, HHT_authoringgroup_C
  402. If (Not i_blnAuthoringGroupHHT) Then
  403. u_DOMElement.removeAttribute Attr.Name
  404. End If
  405. Case HHT_leaf_C
  406. blnLeaf = Attr.Value
  407. u_DOMElement.removeAttribute Attr.Name
  408. If (blnLeaf) Then
  409. u_DOMElement.removeAttribute HHT_ENTRY_C
  410. End If
  411. Case HHT_VISIBLE_C
  412. If (i_blnWinMe) Then
  413. u_DOMElement.removeAttribute HHT_VISIBLE_C
  414. End If
  415. End Select
  416. Next
  417. For Each DOMNode In u_DOMElement.childNodes
  418. p_RemoveAttributes DOMNode, i_blnWinMe, i_blnAuthoringGroupHHT
  419. Next
  420. End Sub
  421. Public Sub TransformHHTTov10( _
  422. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  423. ByRef i_colKeywords As Collection, _
  424. ByRef i_strCategory As String, _
  425. ByVal i_intAllowedSKUs As Long, _
  426. ByRef u_DOMNodeEntries As MSXML2.IXMLDOMNode, _
  427. ByVal i_intRequiredSKUs As Long, _
  428. ByVal i_blnAuthoringGroupHHT As Boolean _
  429. )
  430. p_RaiseEventAndLookForCancel "Transforming HHT"
  431. p_SetRealSKUs u_DOMNode, i_intAllowedSKUs
  432. p_SetAttributes u_DOMNode, i_colKeywords, i_strCategory
  433. If (i_intRequiredSKUs <> ALL_SKUS_C) Then
  434. p_RaiseEventAndLookForCancel "Removing Nodes/Topics from other SKUs"
  435. p_RemoveNodesWithOtherSKUs u_DOMNode, i_intRequiredSKUs
  436. End If
  437. If (i_blnAuthoringGroupHHT) Then
  438. p_RaiseEventAndLookForCancel "Setting ordering info"
  439. p_SetOrderingInfo u_DOMNode
  440. End If
  441. p_RaiseEventAndLookForCancel "Transforming HHT"
  442. p_FlattenHHT u_DOMNode, u_DOMNodeEntries
  443. p_RemoveAttributes u_DOMNodeEntries, _
  444. IIf((i_intRequiredSKUs = SKU_WINDOWS_MILLENNIUM_E), True, False), _
  445. i_blnAuthoringGroupHHT
  446. End Sub
  447. Private Sub p_AddChild( _
  448. ByRef u_DOMNodeParent As MSXML2.IXMLDOMElement, _
  449. ByRef i_DOMNode As MSXML2.IXMLDOMNode _
  450. )
  451. Dim DOMNodeList As MSXML2.IXMLDOMNodeList
  452. Dim DOMDocument As MSXML2.DOMDocument
  453. Dim strQuery As String
  454. Dim intOrderUnderParent As Long
  455. intOrderUnderParent = XMLGetAttribute(i_DOMNode, HHT_orderunderparent_C)
  456. strQuery = "child::TAXONOMY_ENTRY[" & _
  457. "attribute::" & HHT_orderunderparent_C & _
  458. " > " & intOrderUnderParent & "]"
  459. Set DOMDocument = u_DOMNodeParent.ownerDocument
  460. DOMDocument.setProperty "SelectionLanguage", "XPath"
  461. Set DOMNodeList = u_DOMNodeParent.selectNodes(strQuery)
  462. If (DOMNodeList.length <> 0) Then
  463. u_DOMNodeParent.insertBefore i_DOMNode, DOMNodeList(0)
  464. Else
  465. u_DOMNodeParent.appendChild i_DOMNode
  466. End If
  467. End Sub
  468. Public Function GetTaxonomyInXml() As MSXML2.IXMLDOMNode
  469. Dim rs As ADODB.Recordset
  470. Dim strQuery As String
  471. Dim DOMDoc As MSXML2.DOMDocument
  472. Dim DOMNode As MSXML2.IXMLDOMNode
  473. Dim Element As MSXML2.IXMLDOMElement
  474. Dim dictTaxonomy As Scripting.Dictionary
  475. Dim intTID As Long
  476. Dim intParentTID As Long
  477. Dim vntKey As Variant
  478. CheckDatabaseVersion
  479. Set DOMDoc = New MSXML2.DOMDocument
  480. Set DOMNode = HhtPreamble(DOMDoc, True)
  481. Set dictTaxonomy = New Scripting.Dictionary
  482. Set rs = New ADODB.Recordset
  483. strQuery = "" & _
  484. "SELECT * " & _
  485. "FROM Taxonomy " & _
  486. "ORDER BY ParentTID, OrderUnderParent"
  487. rs.Open strQuery, g_cnn, adOpenForwardOnly, adLockPessimistic
  488. Do While (Not rs.EOF)
  489. Set Element = p_CreateTaxonomyElement(DOMDoc, rs)
  490. dictTaxonomy.Add rs("TID").Value, Array(rs("ParentTID").Value, Element)
  491. p_RaiseEventAndLookForCancel "Reading title: " & rs("ENUTitle")
  492. rs.MoveNext
  493. Loop
  494. For Each vntKey In dictTaxonomy.Keys
  495. intParentTID = dictTaxonomy(vntKey)(0)
  496. If (vntKey = ROOT_TID_C) Then
  497. GoTo LForEnd
  498. End If
  499. If (Not dictTaxonomy.Exists(intParentTID)) Then
  500. GoTo LForEnd
  501. End If
  502. Set Element = dictTaxonomy(intParentTID)(1)
  503. Element.appendChild dictTaxonomy(vntKey)(1)
  504. LForEnd:
  505. Next
  506. If (dictTaxonomy.Exists(ROOT_TID_C)) Then
  507. DOMNode.appendChild dictTaxonomy(ROOT_TID_C)(1)
  508. End If
  509. Set GetTaxonomyInXml = DOMDoc
  510. End Function
  511. Public Sub Move( _
  512. ByVal i_intTID As Long, _
  513. ByVal i_intRefTID As Long, _
  514. ByVal i_blnAbove As Boolean, _
  515. ByVal i_dtmReadTime As Date, _
  516. ByRef o_intOrderUnderParent As Long, _
  517. Optional ByVal i_intAuthoringGroup As Long = INVALID_ID_C _
  518. )
  519. On Error GoTo LErrorHandler
  520. g_cnn.BeginTrans
  521. Dim rsLock As ADODB.Recordset
  522. Dim rs As ADODB.Recordset
  523. Dim intOrderUnderParent As Long
  524. Dim intParentTID As Long
  525. Dim intAuthoringGroup As Long
  526. CheckDatabaseVersion
  527. LockTable LOCK_TABLE_TAXONOMY, rsLock
  528. Set rs = New ADODB.Recordset
  529. GetNodeDetails i_intTID, rs
  530. If (rs.EOF) Then
  531. GoTo LEnd
  532. End If
  533. CheckForSameAuthoringGroup rs("AuthoringGroup"), i_intAuthoringGroup
  534. If (i_dtmReadTime <> 0) Then
  535. If (i_dtmReadTime <> rs("ModifiedTime")) Then
  536. ' Someone else has modified this Node since caller last read it.
  537. Err.Raise errNodeOrTopicAlreadyModified
  538. End If
  539. End If
  540. If (p_RefNodeIsADescendent(i_intTID, i_intRefTID)) Then
  541. Err.Raise errRefNodeCannotBeDescendent
  542. End If
  543. p_GetNewOrderAndParentTID i_intTID, i_intRefTID, i_blnAbove, intOrderUnderParent, _
  544. intParentTID
  545. If ((intParentTID = rs("ParentTID")) And _
  546. (intOrderUnderParent = rs("OrderUnderParent"))) Then
  547. ' Nothing has changed
  548. GoTo LEnd
  549. End If
  550. If (i_intAuthoringGroup = INVALID_ID_C) Then
  551. intAuthoringGroup = g_clsParameters.AuthoringGroup
  552. Else
  553. intAuthoringGroup = i_intAuthoringGroup
  554. End If
  555. rs("ModifiedTime") = Now
  556. rs("Username") = g_strUserName
  557. rs("ParentTID") = intParentTID
  558. rs("OrderUnderParent") = intOrderUnderParent
  559. rs("AuthoringGroup") = intAuthoringGroup
  560. rs.Update
  561. o_intOrderUnderParent = intOrderUnderParent
  562. LEnd:
  563. g_cnn.CommitTrans
  564. Exit Sub
  565. LErrorHandler:
  566. g_cnn.RollbackTrans
  567. Err.Raise Err.Number, Err.Source, Err.Description
  568. End Sub
  569. Public Sub MoveInto( _
  570. ByVal i_intTID As Long, _
  571. ByVal i_intParentTID As Long, _
  572. ByVal i_dtmReadTime As Date, _
  573. ByRef o_intOrderUnderParent As Long _
  574. )
  575. On Error GoTo LErrorHandler
  576. g_cnn.BeginTrans
  577. Dim rsLock As ADODB.Recordset
  578. Dim rs As ADODB.Recordset
  579. Dim rsParent As ADODB.Recordset
  580. Dim intOrderUnderParent As Long
  581. CheckDatabaseVersion
  582. LockTable LOCK_TABLE_TAXONOMY, rsLock
  583. Set rs = New ADODB.Recordset
  584. GetNodeDetails i_intTID, rs
  585. If (rs.EOF) Then
  586. GoTo LEnd
  587. End If
  588. CheckForSameAuthoringGroup rs("AuthoringGroup")
  589. If (i_dtmReadTime <> 0) Then
  590. If (i_dtmReadTime <> rs("ModifiedTime")) Then
  591. ' Someone else has modified this Node since caller last read it.
  592. Err.Raise errNodeOrTopicAlreadyModified
  593. End If
  594. End If
  595. If (i_intParentTID = rs("ParentTID")) Then
  596. ' Nothing has changed
  597. GoTo LEnd
  598. End If
  599. If (p_RefNodeIsADescendent(i_intTID, i_intParentTID)) Then
  600. Err.Raise errRefNodeCannotBeDescendent
  601. End If
  602. Set rsParent = New ADODB.Recordset
  603. GetNodeDetails i_intParentTID, rsParent
  604. If (rsParent("Leaf")) Then
  605. Err.Raise errParentCannotBeLeaf
  606. End If
  607. intOrderUnderParent = p_GetNewOrderForLastChild(i_intParentTID)
  608. rs("ModifiedTime") = Now
  609. rs("Username") = g_strUserName
  610. rs("ParentTID") = i_intParentTID
  611. rs("OrderUnderParent") = intOrderUnderParent
  612. rs("AuthoringGroup") = g_clsParameters.AuthoringGroup
  613. rs.Update
  614. o_intOrderUnderParent = intOrderUnderParent
  615. LEnd:
  616. g_cnn.CommitTrans
  617. Exit Sub
  618. LErrorHandler:
  619. g_cnn.RollbackTrans
  620. Err.Raise Err.Number, Err.Source, Err.Description
  621. End Sub
  622. Public Sub CreateTaxonomyEntries( _
  623. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  624. ByVal i_intParentTID As Long, _
  625. ByVal i_blnFast As Boolean _
  626. )
  627. Dim rsLock As ADODB.Recordset
  628. LockTable LOCK_TABLE_TAXONOMY, rsLock
  629. p_CreateTaxonomyEntries u_DOMNode, i_intParentTID, i_blnFast
  630. End Sub
  631. Private Sub p_CreateTaxonomyEntries( _
  632. ByRef u_DOMNode As MSXML2.IXMLDOMNode, _
  633. ByVal i_intParentTID As Long, _
  634. ByVal i_blnFast As Boolean _
  635. )
  636. Dim rsLock As ADODB.Recordset
  637. Dim strTitle As String
  638. Dim strDescription As String
  639. Dim intType As Long
  640. Dim intNavModel As Long
  641. Dim strURI As String
  642. Dim strIconURI As String
  643. Dim intSKUs As Long
  644. Dim blnLeaf As Boolean
  645. Dim strLocInclude As String
  646. Dim blnVisible As Boolean
  647. Dim blnSubSite As Boolean
  648. Dim strKeywords As String
  649. Dim strBaseFile As String
  650. Dim strEntry As String
  651. Dim DOMNode As MSXML2.IXMLDOMNode
  652. Dim ModifiedDOMNodes As MSXML2.IXMLDOMNode
  653. Dim DOMNodeChild As MSXML2.IXMLDOMNode
  654. Dim intTID As Long
  655. strTitle = XMLGetAttribute(u_DOMNode, HHT_TITLE_C)
  656. strDescription = XMLGetAttribute(u_DOMNode, HHT_DESCRIPTION_C)
  657. intType = XMLGetAttribute(u_DOMNode, HHT_TYPE_C)
  658. intNavModel = NavModelNumber(XMLGetAttribute(u_DOMNode, HHT_NAVIGATIONMODEL_C))
  659. strURI = XMLGetAttribute(u_DOMNode, HHT_URI_C)
  660. strIconURI = XMLGetAttribute(u_DOMNode, HHT_ICONURI_C)
  661. intSKUs = XMLGetAttribute(u_DOMNode, HHT_skus_C)
  662. blnLeaf = XMLGetAttribute(u_DOMNode, HHT_leaf_C)
  663. strLocInclude = XMLGetAttribute(u_DOMNode, HHT_locinclude_C)
  664. blnVisible = XMLGetAttribute(u_DOMNode, HHT_VISIBLE_C)
  665. blnSubSite = XMLGetAttribute(u_DOMNode, HHT_SUBSITE_C)
  666. strKeywords = XMLGetAttribute(u_DOMNode, HHT_keywords_C)
  667. strBaseFile = XMLGetAttribute(u_DOMNode, HHT_basefile_C)
  668. strEntry = XMLGetAttribute(u_DOMNode, HHT_ENTRY_C)
  669. p_RaiseEventAndLookForCancel "Creating Title: " & strTitle
  670. DoEvents
  671. If (i_blnFast) Then
  672. p_CreateFast False, strTitle, strDescription, intType, intNavModel, strURI, strIconURI, _
  673. intSKUs, blnLeaf, i_intParentTID, strLocInclude, blnVisible, blnSubSite, _
  674. strKeywords, strBaseFile, "", strEntry, u_DOMNode.ownerDocument, DOMNode, _
  675. INVALID_ID_C
  676. Else
  677. p_Create False, strTitle, strDescription, intType, intNavModel, strURI, strIconURI, _
  678. intSKUs, blnLeaf, i_intParentTID, strLocInclude, blnVisible, blnSubSite, _
  679. strKeywords, strBaseFile, "", strEntry, u_DOMNode.ownerDocument, DOMNode, _
  680. ModifiedDOMNodes
  681. End If
  682. XMLCopyAttributes DOMNode, u_DOMNode
  683. intTID = XMLGetAttribute(DOMNode, HHT_tid_C)
  684. If (Not u_DOMNode.firstChild Is Nothing) Then
  685. For Each DOMNodeChild In u_DOMNode.childNodes
  686. p_CreateTaxonomyEntries DOMNodeChild, intTID, i_blnFast
  687. Next
  688. End If
  689. End Sub
  690. Private Sub p_CreateURIKeywordsTable()
  691. Dim oc As ADOX.Catalog
  692. Dim strTable As String
  693. Dim tbl As ADOX.Table
  694. Dim col As ADOX.Column
  695. Dim idx As ADOX.Index
  696. Set oc = New ADOX.Catalog
  697. Set oc.ActiveConnection = g_cnn
  698. strTable = "URIKeywords"
  699. If (Not TableExists(oc, strTable)) Then
  700. Set tbl = New ADOX.Table
  701. With tbl
  702. .Name = strTable
  703. Set .ParentCatalog = oc
  704. .Columns.Append "URI", adVarWChar
  705. Set col = New ADOX.Column
  706. With col
  707. Set .ParentCatalog = oc
  708. .Name = "MergedKeywords"
  709. .Type = adLongVarWChar ' Memo field
  710. .Properties("Jet OLEDB:Allow Zero Length").Value = True
  711. End With
  712. .Columns.Append col
  713. Set idx = New ADOX.Index
  714. With idx
  715. .Name = "URI"
  716. .Columns.Append "URI"
  717. .PrimaryKey = True
  718. End With
  719. .Indexes.Append idx
  720. End With
  721. oc.Tables.Append tbl
  722. Set oc = Nothing
  723. End If
  724. End Sub
  725. Public Sub PropagateKeywords()
  726. On Error GoTo LErrorHandler
  727. g_cnn.BeginTrans
  728. Dim rsLock As ADODB.Recordset
  729. Dim oc As ADOX.Catalog
  730. Dim rs As ADODB.Recordset
  731. Dim strQuery As String
  732. Dim strURI As String
  733. Dim strKeywords As String
  734. Dim dictURIs As Scripting.Dictionary
  735. Dim vntKey As Variant
  736. CheckDatabaseVersion
  737. LockTable LOCK_TABLE_TAXONOMY, rsLock
  738. Set rs = New ADODB.Recordset
  739. strQuery = "" & _
  740. "SELECT * " & _
  741. "FROM Taxonomy " & _
  742. "WHERE (ContentURI <> """")" & _
  743. "ORDER BY TID "
  744. rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  745. Set dictURIs = New Scripting.Dictionary
  746. Do While (Not rs.EOF)
  747. DoEvents
  748. strURI = Trim$(LCase$(rs("ContentURI") & ""))
  749. strKeywords = rs("Keywords") & ""
  750. If (dictURIs.Exists(strURI)) Then
  751. strKeywords = p_MergeKeywords(dictURIs(strURI), strKeywords)
  752. dictURIs.Remove strURI
  753. End If
  754. dictURIs.Add strURI, strKeywords
  755. rs.MoveNext
  756. Loop
  757. p_CreateURIKeywordsTable
  758. rs.Close
  759. rs.Open "DELETE * FROM URIKeywords", g_cnn, adOpenStatic, adLockOptimistic
  760. rs.Open "SELECT * FROM URIKeywords", g_cnn, adOpenStatic, adLockOptimistic
  761. ' Create a table that shows what the Keywords should be for each URI
  762. For Each vntKey In dictURIs.Keys
  763. rs.AddNew
  764. rs("URI") = vntKey
  765. rs("MergedKeywords") = dictURIs.Item(vntKey)
  766. rs.Update
  767. Next
  768. rs.Close
  769. ' Create a table that shows the TID, Keywords pair for each row that needs to change.
  770. strQuery = "" & _
  771. "SELECT Taxonomy.TID, URIKeywords.MergedKeywords INTO TIDKeywords " & _
  772. "FROM " & _
  773. " Taxonomy INNER JOIN URIKeywords " & _
  774. " ON Taxonomy.ContentURI = URIKeywords.URI " & _
  775. "WHERE ((Taxonomy.ContentURI <> """") " & _
  776. "AND (Taxonomy.Keywords <> URIKeywords.MergedKeywords)) "
  777. rs.Open strQuery, g_cnn, adOpenStatic, adLockOptimistic
  778. ' Change the rows that need to change.
  779. strQuery = "" & _
  780. "UPDATE " & _
  781. "Taxonomy INNER JOIN TIDKeywords ON Taxonomy.TID = TIDKeywords.TID " & _
  782. "SET " & _
  783. " Taxonomy.Keywords = TIDKeywords.MergedKeywords, " & _
  784. " Taxonomy.ModifiedTime = #" & Now & "#, " & _
  785. " Taxonomy.Username = """ & g_strUserName & """"
  786. rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  787. LEnd:
  788. g_cnn.CommitTrans
  789. Set oc = New ADOX.Catalog
  790. Set oc.ActiveConnection = g_cnn
  791. DeleteTable oc, "URIKeywords"
  792. DeleteTable oc, "TIDKeywords"
  793. Exit Sub
  794. LErrorHandler:
  795. g_cnn.RollbackTrans
  796. Err.Raise Err.Number, Err.Source, Err.Description
  797. End Sub
  798. Public Sub CreateFast( _
  799. ByVal i_strTitle As String, _
  800. ByVal i_strDescription As String, _
  801. ByVal i_intType As Long, _
  802. ByVal i_intNavModel As Long, _
  803. ByVal i_strURI As String, _
  804. ByVal i_strIconURI As String, _
  805. ByVal i_intSelectedSKUs As Long, _
  806. ByVal i_blnLeaf As Boolean, _
  807. ByVal i_intParentTID As Long, _
  808. ByVal i_strLocInclude As String, _
  809. ByVal i_blnVisible As Boolean, _
  810. ByVal i_blnSubSite As Boolean, _
  811. ByVal i_strKeywords As String, _
  812. ByVal i_strBaseFile As String, _
  813. ByVal i_strComments As String, _
  814. ByVal i_strEntry As String, _
  815. ByRef i_DOMDoc As MSXML2.DOMDocument, _
  816. ByRef o_DOMNode As MSXML2.IXMLDOMNode, _
  817. Optional ByVal i_intAuthoringGroup As Long = INVALID_ID_C _
  818. )
  819. p_CreateFast True, i_strTitle, i_strDescription, i_intType, i_intNavModel, i_strURI, _
  820. i_strIconURI, i_intSelectedSKUs, i_blnLeaf, i_intParentTID, i_strLocInclude, _
  821. i_blnVisible, i_blnSubSite, i_strKeywords, i_strBaseFile, _
  822. i_strComments, i_strEntry, i_DOMDoc, o_DOMNode, i_intAuthoringGroup
  823. End Sub
  824. Private Sub p_CreateFast( _
  825. ByVal i_blnLock As Boolean, _
  826. ByVal i_strTitle As String, _
  827. ByVal i_strDescription As String, _
  828. ByVal i_intType As Long, _
  829. ByVal i_intNavModel As Long, _
  830. ByVal i_strURI As String, _
  831. ByVal i_strIconURI As String, _
  832. ByVal i_intSelectedSKUs As Long, _
  833. ByVal i_blnLeaf As Boolean, _
  834. ByVal i_intParentTID As Long, _
  835. ByVal i_strLocInclude As String, _
  836. ByVal i_blnVisible As Boolean, _
  837. ByVal i_blnSubSite As Boolean, _
  838. ByVal i_strKeywords As String, _
  839. ByVal i_strBaseFile As String, _
  840. ByVal i_strComments As String, _
  841. ByVal i_strEntry As String, _
  842. ByRef i_DOMDoc As MSXML2.DOMDocument, _
  843. ByRef o_DOMNode As MSXML2.IXMLDOMNode, _
  844. ByVal i_intAuthoringGroup As Long _
  845. )
  846. ' Same as Create, except that we skip the following:
  847. ' p_ValidateTitle
  848. ' p_ValidateDescription
  849. ' FormatKeywordsForTaxonomy
  850. ' p_GetMergedKeywords
  851. ' p_PropagateKeywords
  852. Dim rsLock As ADODB.Recordset
  853. Dim rs As ADODB.Recordset
  854. Dim strQuery As String
  855. Dim intOrderUnderParent As Long
  856. Dim intAuthoringGroup As Long
  857. Dim strEntry As String
  858. CheckDatabaseVersion
  859. If (i_blnLock) Then
  860. LockTable LOCK_TABLE_TAXONOMY, rsLock
  861. End If
  862. Set rs = New ADODB.Recordset
  863. strQuery = "" & _
  864. "SELECT * " & _
  865. "FROM Taxonomy "
  866. rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  867. If (rs.RecordCount > 0) Then
  868. rs.MoveLast
  869. End If
  870. intOrderUnderParent = p_GetNewOrderForLastChild(i_intParentTID)
  871. If (i_intAuthoringGroup = INVALID_ID_C) Then
  872. intAuthoringGroup = g_clsParameters.AuthoringGroup
  873. Else
  874. intAuthoringGroup = i_intAuthoringGroup
  875. End If
  876. If (Not i_blnLeaf) Then
  877. strEntry = p_Mangle(i_strEntry & "")
  878. If (strEntry = "") Then
  879. strEntry = p_Mangle(i_strTitle)
  880. End If
  881. End If
  882. If (Len(i_strDescription) > 255) Then
  883. WriteLog "Truncating Description"
  884. WriteLog "URI: " & i_strURI
  885. WriteLog "Description: " & i_strDescription
  886. WriteLog ""
  887. i_strDescription = Mid$(i_strDescription, 1, 255)
  888. End If
  889. rs.AddNew
  890. rs("ModifiedTime") = Now
  891. rs("Username") = g_strUserName
  892. ' As a fix for a weird "multiple-step OLE DB operation" error, I have appended & "" to
  893. ' all strings.
  894. rs("Comments") = i_strComments & ""
  895. rs("ENUTitle") = i_strTitle & ""
  896. rs("ENUDescription") = i_strDescription & ""
  897. rs("Type") = i_intType
  898. If (Not i_blnLeaf) Then
  899. rs("NavigationModel") = i_intNavModel
  900. End If
  901. rs("ContentURI") = i_strURI & ""
  902. rs("IconURI") = i_strIconURI & ""
  903. rs("SKUs") = i_intSelectedSKUs
  904. rs("ParentTID") = i_intParentTID
  905. rs("Leaf") = i_blnLeaf
  906. rs("BaseFile") = i_strBaseFile & ""
  907. rs("LocInclude") = i_strLocInclude & ""
  908. rs("Visible") = i_blnVisible
  909. rs("SubSite") = i_blnSubSite
  910. rs("Keywords") = i_strKeywords & ""
  911. rs("OrderUnderParent") = intOrderUnderParent
  912. rs("AuthoringGroup") = intAuthoringGroup
  913. rs("Entry") = strEntry
  914. rs.Update
  915. Set o_DOMNode = p_CreateTaxonomyElement(i_DOMDoc, rs)
  916. End Sub
  917. Private Function p_GetMidOrder( _
  918. ByVal i_intOrder1 As Long, _
  919. ByVal i_intOrder2 As Long _
  920. ) As Long
  921. ' Never return i_intOrder1 or i_intOrder2.
  922. If (i_intOrder2 <= i_intOrder1 + 1) Then
  923. Err.Raise errOutOfOrderingNumbers
  924. End If
  925. ' i_intOrder1 i_intOrder2 p_GetMidOrder
  926. ' 5 7 6
  927. ' 5 8 7
  928. p_GetMidOrder = i_intOrder1 + (i_intOrder2 - i_intOrder1 + 1) \ 2
  929. End Function
  930. Private Function p_GetNextOrder( _
  931. ByVal i_intOrder As Long _
  932. ) As Long
  933. ' Never return i_intOrder itself.
  934. Dim intOrder1 As Long
  935. Dim intOrder2 As Long
  936. If (i_intOrder = 0) Then
  937. p_GetNextOrder = PREFERRED_ORDER_DELTA_C
  938. Exit Function
  939. End If
  940. If (i_intOrder = MAX_ORDER_C) Then
  941. Err.Raise errOutOfOrderingNumbers
  942. End If
  943. intOrder1 = i_intOrder + PREFERRED_ORDER_DELTA_C
  944. ' i_intOrder MAX_ORDER_C intOrder2
  945. ' 5 6 6
  946. ' 5 7 6
  947. ' 5 8 7
  948. intOrder2 = i_intOrder + (MAX_ORDER_C - i_intOrder + 1) \ 2
  949. If (intOrder1 <= intOrder2) Then
  950. p_GetNextOrder = intOrder1
  951. Else
  952. p_GetNextOrder = intOrder2
  953. End If
  954. End Function
  955. Private Sub p_GetNewOrderAndParentTID( _
  956. ByRef i_intTID As Long, _
  957. ByRef i_intRefTID As Long, _
  958. ByVal i_blnAbove As Boolean, _
  959. ByRef o_intOrderUnderParent As Long, _
  960. ByRef o_intParentTID As Long _
  961. )
  962. Dim strQuery As String
  963. Dim rs As ADODB.Recordset
  964. Dim strSign As String
  965. Dim strOrdering As String
  966. Dim intRefOrderUnderParent As Long
  967. Set rs = New ADODB.Recordset
  968. strQuery = "" & _
  969. "SELECT * " & _
  970. "FROM Taxonomy " & _
  971. "WHERE (TID = " & i_intRefTID & ")"
  972. rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  973. If (rs.EOF) Then
  974. Err.Raise errDoesNotExist
  975. End If
  976. o_intParentTID = rs("ParentTID")
  977. If (i_blnAbove) Then
  978. strSign = "<"
  979. strOrdering = "DESC"
  980. Else
  981. strSign = ">"
  982. End If
  983. intRefOrderUnderParent = rs("OrderUnderParent")
  984. strQuery = "" & _
  985. "SELECT * " & _
  986. "FROM Taxonomy " & _
  987. "WHERE ((ParentTID = " & rs("ParentTID") & ") " & _
  988. "AND (OrderUnderParent " & strSign & intRefOrderUnderParent & "))" & _
  989. "ORDER BY OrderUnderParent " & strOrdering
  990. rs.Close
  991. rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  992. If (rs.EOF) Then
  993. If (i_blnAbove) Then
  994. o_intOrderUnderParent = p_GetMidOrder(0, intRefOrderUnderParent)
  995. Else
  996. o_intOrderUnderParent = p_GetNextOrder(intRefOrderUnderParent)
  997. End If
  998. Exit Sub
  999. End If
  1000. If (rs("TID") = i_intTID) Then
  1001. o_intOrderUnderParent = rs("OrderUnderParent")
  1002. Exit Sub
  1003. End If
  1004. If (i_blnAbove) Then
  1005. o_intOrderUnderParent = p_GetMidOrder(rs("OrderUnderParent"), intRefOrderUnderParent)
  1006. Else
  1007. o_intOrderUnderParent = p_GetMidOrder(intRefOrderUnderParent, rs("OrderUnderParent"))
  1008. End If
  1009. End Sub
  1010. Private Function p_GetNewOrderForLastChild( _
  1011. ByRef i_intTID As Long _
  1012. ) As Long
  1013. Dim strQuery As String
  1014. Dim rs As ADODB.Recordset
  1015. Dim intOrderOfLastChild As Long
  1016. Set rs = New ADODB.Recordset
  1017. strQuery = "" & _
  1018. "SELECT Max(OrderUnderParent) as MaxOrderUnderParent " & _
  1019. "FROM Taxonomy " & _
  1020. "WHERE (ParentTID=" & i_intTID & ")"
  1021. rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  1022. If (Not rs.EOF) Then
  1023. If (Not IsNull(rs("MaxOrderUnderParent"))) Then
  1024. intOrderOfLastChild = rs("MaxOrderUnderParent")
  1025. End If
  1026. End If
  1027. p_GetNewOrderForLastChild = p_GetNextOrder(intOrderOfLastChild)
  1028. End Function
  1029. Public Sub Create( _
  1030. ByVal i_strTitle As String, _
  1031. ByVal i_strDescription As String, _
  1032. ByVal i_intType As Long, _
  1033. ByVal i_intNavModel As Long, _
  1034. ByVal i_strURI As String, _
  1035. ByVal i_strIconURI As String, _
  1036. ByVal i_intSelectedSKUs As Long, _
  1037. ByVal i_blnLeaf As Boolean, _
  1038. ByVal i_intParentTID As Long, _
  1039. ByVal i_strLocInclude As String, _
  1040. ByVal i_blnVisible As Boolean, _
  1041. ByVal i_blnSubSite As Boolean, _
  1042. ByVal i_strKeywords As String, _
  1043. ByVal i_strBaseFile As String, _
  1044. ByVal i_strComments As String, _
  1045. ByVal i_strEntry As String, _
  1046. ByRef i_DOMDoc As MSXML2.DOMDocument, _
  1047. ByRef o_DOMNode As MSXML2.IXMLDOMNode, _
  1048. ByRef o_ModifiedDOMNodes As MSXML2.IXMLDOMNode _
  1049. )
  1050. p_Create True, i_strTitle, i_strDescription, i_intType, i_intNavModel, i_strURI, _
  1051. i_strIconURI, i_intSelectedSKUs, i_blnLeaf, i_intParentTID, i_strLocInclude, _
  1052. i_blnVisible, i_blnSubSite, i_strKeywords, i_strBaseFile, _
  1053. i_strComments, i_strEntry, i_DOMDoc, o_DOMNode, o_ModifiedDOMNodes
  1054. End Sub
  1055. Private Sub p_Create( _
  1056. ByVal i_blnLock As Boolean, _
  1057. ByVal i_strTitle As String, _
  1058. ByVal i_strDescription As String, _
  1059. ByVal i_intType As Long, _
  1060. ByVal i_intNavModel As Long, _
  1061. ByVal i_strURI As String, _
  1062. ByVal i_strIconURI As String, _
  1063. ByVal i_intSelectedSKUs As Long, _
  1064. ByVal i_blnLeaf As Boolean, _
  1065. ByVal i_intParentTID As Long, _
  1066. ByVal i_strLocInclude As String, _
  1067. ByVal i_blnVisible As Boolean, _
  1068. ByVal i_blnSubSite As Boolean, _
  1069. ByVal i_strKeywords As String, _
  1070. ByVal i_strBaseFile As String, _
  1071. ByVal i_strComments As String, _
  1072. ByVal i_strEntry As String, _
  1073. ByRef i_DOMDoc As MSXML2.DOMDocument, _
  1074. ByRef o_DOMNode As MSXML2.IXMLDOMNode, _
  1075. ByRef o_ModifiedDOMNodes As MSXML2.IXMLDOMNode _
  1076. )
  1077. Dim rsLock As ADODB.Recordset
  1078. Dim rs As ADODB.Recordset
  1079. Dim strQuery As String
  1080. Dim intTID As Long
  1081. Dim strKeywords As String
  1082. Dim intOrderUnderParent As Long
  1083. Dim strEntry As String
  1084. CheckDatabaseVersion
  1085. If (i_blnLock) Then
  1086. LockTable LOCK_TABLE_TAXONOMY, rsLock
  1087. End If
  1088. ' Do some validation to see if the Title is acceptable.
  1089. p_ValidateTitle i_strTitle
  1090. ' Do some validation to see if the Description is acceptable.
  1091. p_ValidateDescription i_strDescription
  1092. ' Convert i_strKeywords into canonical format
  1093. strKeywords = FormatKeywordsForTaxonomy(i_strKeywords)
  1094. strKeywords = p_GetMergedKeywords(i_strURI, i_strKeywords, "")
  1095. ' Create a new record in the database
  1096. intOrderUnderParent = p_GetNewOrderForLastChild(i_intParentTID)
  1097. Set rs = New ADODB.Recordset
  1098. strQuery = "" & _
  1099. "SELECT * " & _
  1100. "FROM Taxonomy "
  1101. rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  1102. If (rs.RecordCount > 0) Then
  1103. rs.MoveLast
  1104. End If
  1105. If (Not i_blnLeaf) Then
  1106. strEntry = p_Mangle(i_strEntry & "")
  1107. If (strEntry = "") Then
  1108. strEntry = p_Mangle(i_strTitle)
  1109. End If
  1110. End If
  1111. rs.AddNew
  1112. rs("ModifiedTime") = Now
  1113. rs("Username") = g_strUserName
  1114. ' & "" is a workaround for a weird OLEDB error when setting Comments to an empty string
  1115. rs("Comments") = i_strComments & ""
  1116. rs("ENUTitle") = i_strTitle
  1117. rs("ENUDescription") = i_strDescription
  1118. rs("Type") = i_intType
  1119. If (Not i_blnLeaf) Then
  1120. rs("NavigationModel") = i_intNavModel
  1121. End If
  1122. rs("ContentURI") = i_strURI
  1123. rs("IconURI") = i_strIconURI
  1124. rs("SKUs") = i_intSelectedSKUs
  1125. rs("ParentTID") = i_intParentTID
  1126. rs("Leaf") = i_blnLeaf
  1127. rs("BaseFile") = i_strBaseFile
  1128. rs("LocInclude") = i_strLocInclude
  1129. rs("Visible") = i_blnVisible
  1130. rs("SubSite") = i_blnSubSite
  1131. rs("Keywords") = strKeywords
  1132. rs("OrderUnderParent") = intOrderUnderParent
  1133. rs("AuthoringGroup") = g_clsParameters.AuthoringGroup
  1134. rs("Entry") = strEntry
  1135. rs.Update
  1136. Set o_DOMNode = p_CreateTaxonomyElement(i_DOMDoc, rs)
  1137. p_PropagateKeywords i_strURI, strKeywords, o_ModifiedDOMNodes
  1138. End Sub
  1139. Public Sub SetKeywords( _
  1140. ByVal i_intTID As Long, _
  1141. ByVal i_strURI As String, _
  1142. ByVal i_strKeywords As String, _
  1143. ByVal i_dtmReadTime As Date, _
  1144. ByRef i_DOMDoc As MSXML2.DOMDocument, _
  1145. ByRef o_DOMNode As MSXML2.IXMLDOMNode, _
  1146. ByRef o_ModifiedDOMNodes As MSXML2.IXMLDOMNode _
  1147. )
  1148. On Error GoTo LErrorHandler
  1149. g_cnn.BeginTrans
  1150. Dim rsLock As ADODB.Recordset
  1151. Dim rs As ADODB.Recordset
  1152. CheckDatabaseVersion
  1153. LockTable LOCK_TABLE_TAXONOMY, rsLock
  1154. ' Does the record exist?
  1155. Set rs = New ADODB.Recordset
  1156. GetNodeDetails i_intTID, rs
  1157. If (rs.EOF) Then
  1158. GoTo LEnd
  1159. End If
  1160. CheckForSameAuthoringGroup rs("AuthoringGroup")
  1161. If (i_dtmReadTime <> 0) Then
  1162. If (i_dtmReadTime <> rs("ModifiedTime")) Then
  1163. ' Someone else has modified this Node since caller last read it.
  1164. Err.Raise errNodeOrTopicAlreadyModified
  1165. End If
  1166. End If
  1167. rs("ModifiedTime") = Now
  1168. rs("Username") = g_strUserName
  1169. rs("Keywords") = i_strKeywords
  1170. rs.Update
  1171. Set o_DOMNode = p_CreateTaxonomyElement(i_DOMDoc, rs)
  1172. p_PropagateKeywords i_strURI, i_strKeywords, o_ModifiedDOMNodes
  1173. LEnd:
  1174. g_cnn.CommitTrans
  1175. Exit Sub
  1176. LErrorHandler:
  1177. g_cnn.RollbackTrans
  1178. Err.Raise Err.Number, Err.Source, Err.Description
  1179. End Sub
  1180. Public Sub Update( _
  1181. ByVal i_intTID As Long, _
  1182. ByVal i_strTitle As String, _
  1183. ByVal i_strDescription As String, _
  1184. ByVal i_intType As Long, _
  1185. ByVal i_intNavModel As Long, _
  1186. ByVal i_strURI As String, _
  1187. ByVal i_strIconURI As String, _
  1188. ByVal i_intSelectedSKUs As Long, _
  1189. ByVal i_strLocInclude As String, _
  1190. ByVal i_blnVisible As Boolean, _
  1191. ByVal i_blnSubSite As Boolean, _
  1192. ByVal i_strKeywords As String, _
  1193. ByVal i_strDeletedKeywords As String, _
  1194. ByVal i_strComments As String, _
  1195. ByVal i_strEntry As String, _
  1196. ByVal i_dtmReadTime As Date, _
  1197. ByRef i_DOMDoc As MSXML2.DOMDocument, _
  1198. ByRef o_DOMNode As MSXML2.IXMLDOMNode, _
  1199. ByRef o_ModifiedDOMNodes As MSXML2.IXMLDOMNode _
  1200. )
  1201. On Error GoTo LErrorHandler
  1202. g_cnn.BeginTrans
  1203. Dim rsLock As ADODB.Recordset
  1204. Dim rs As ADODB.Recordset
  1205. Dim strKeywords As String
  1206. Dim strEntry As String
  1207. CheckDatabaseVersion
  1208. LockTable LOCK_TABLE_TAXONOMY, rsLock
  1209. ' Do some validation to see if the Title is acceptable.
  1210. p_ValidateTitle i_strTitle
  1211. ' Do some validation to see if the Description is acceptable.
  1212. p_ValidateDescription i_strDescription
  1213. ' Convert i_strKeywords into canonical format
  1214. strKeywords = FormatKeywordsForTaxonomy(i_strKeywords)
  1215. strKeywords = p_GetMergedKeywords(i_strURI, i_strKeywords, i_strDeletedKeywords)
  1216. ' Does the record exist?
  1217. Set rs = New ADODB.Recordset
  1218. GetNodeDetails i_intTID, rs
  1219. If (rs.EOF) Then
  1220. GoTo LEnd
  1221. End If
  1222. CheckForSameAuthoringGroup rs("AuthoringGroup")
  1223. If (i_dtmReadTime <> 0) Then
  1224. If (i_dtmReadTime <> rs("ModifiedTime")) Then
  1225. ' Someone else has modified this Node since caller last read it.
  1226. Err.Raise errNodeOrTopicAlreadyModified
  1227. End If
  1228. End If
  1229. If (Not rs("Leaf")) Then
  1230. strEntry = p_Mangle(i_strEntry & "")
  1231. If (strEntry = "") Then
  1232. strEntry = p_Mangle(i_strTitle)
  1233. End If
  1234. End If
  1235. rs("ModifiedTime") = Now
  1236. rs("Username") = g_strUserName
  1237. rs("ENUTitle") = i_strTitle
  1238. rs("ENUDescription") = i_strDescription
  1239. rs("Type") = i_intType
  1240. If (Not rs("Leaf")) Then
  1241. rs("NavigationModel") = i_intNavModel
  1242. End If
  1243. rs("ContentURI") = i_strURI
  1244. rs("IconURI") = i_strIconURI
  1245. ' & "" is a workaround for a weird OLEDB error when setting Comments to an empty string
  1246. rs("Comments") = i_strComments & ""
  1247. rs("SKUs") = i_intSelectedSKUs
  1248. rs("LocInclude") = i_strLocInclude
  1249. rs("Visible") = i_blnVisible
  1250. rs("SubSite") = i_blnSubSite
  1251. rs("Keywords") = strKeywords
  1252. rs("AuthoringGroup") = g_clsParameters.AuthoringGroup
  1253. rs("Entry") = strEntry
  1254. rs.Update
  1255. Set o_DOMNode = p_CreateTaxonomyElement(i_DOMDoc, rs)
  1256. p_PropagateKeywords i_strURI, strKeywords, o_ModifiedDOMNodes
  1257. LEnd:
  1258. g_cnn.CommitTrans
  1259. Exit Sub
  1260. LErrorHandler:
  1261. g_cnn.RollbackTrans
  1262. Err.Raise Err.Number, Err.Source, Err.Description
  1263. End Sub
  1264. Private Sub p_DeleteDescendents( _
  1265. ByVal i_intTID As Long _
  1266. )
  1267. On Error Resume Next
  1268. Dim rs As ADODB.Recordset
  1269. Dim strQuery As String
  1270. Dim intTID As Long
  1271. Set rs = New ADODB.Recordset
  1272. If (intTID <> ROOT_TID_C) Then
  1273. p_RaiseEventAndLookForCancel "Deleting TID " & i_intTID
  1274. strQuery = "DELETE * FROM Taxonomy WHERE (TID = " & i_intTID & ")"
  1275. rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  1276. End If
  1277. strQuery = "" & _
  1278. "SELECT * " & _
  1279. "FROM Taxonomy " & _
  1280. "WHERE (ParentTID=" & i_intTID & ")"
  1281. rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  1282. Do While (Not rs.EOF)
  1283. intTID = rs("TID")
  1284. If (intTID <> ROOT_TID_C) Then
  1285. p_DeleteDescendents intTID
  1286. End If
  1287. ' I keep on getting errors on MoveNext saying that the record has been deleted.
  1288. ' If I continue, things work. Hence the On Error Resume Next above.
  1289. rs.MoveNext
  1290. Loop
  1291. End Sub
  1292. Public Sub Delete( _
  1293. ByVal i_intTID As Long, _
  1294. ByVal i_dtmReadTime As Date _
  1295. )
  1296. On Error GoTo LErrorHandler
  1297. g_cnn.BeginTrans
  1298. Dim rsLock As ADODB.Recordset
  1299. Dim rs As ADODB.Recordset
  1300. CheckDatabaseVersion
  1301. LockTable LOCK_TABLE_TAXONOMY, rsLock
  1302. Set rs = New ADODB.Recordset
  1303. GetNodeDetails i_intTID, rs
  1304. ' Does an entry exist?
  1305. If (rs.EOF) Then
  1306. GoTo LEnd
  1307. End If
  1308. CheckForSameAuthoringGroup rs("AuthoringGroup")
  1309. If (i_dtmReadTime <> 0) Then
  1310. If (i_dtmReadTime <> rs("ModifiedTime")) Then
  1311. ' Someone else has modified this Node since caller last read it.
  1312. Err.Raise errNodeOrTopicAlreadyModified
  1313. End If
  1314. End If
  1315. p_DeleteDescendents i_intTID
  1316. LEnd:
  1317. g_cnn.CommitTrans
  1318. Exit Sub
  1319. LErrorHandler:
  1320. g_cnn.RollbackTrans
  1321. Err.Raise Err.Number, Err.Source, Err.Description
  1322. End Sub
  1323. Private Function p_GetMergedKeywords( _
  1324. ByRef i_strURI As String, _
  1325. ByRef i_strKeywords As String, _
  1326. ByRef i_strDeletedKeywords As String _
  1327. ) As String
  1328. Dim strURI As String
  1329. Dim strQuery As String
  1330. Dim rs As ADODB.Recordset
  1331. p_GetMergedKeywords = i_strKeywords
  1332. strURI = Trim$(i_strURI)
  1333. If (strURI = "") Then
  1334. Exit Function
  1335. End If
  1336. Set rs = New ADODB.Recordset
  1337. strQuery = "" & _
  1338. "SELECT * " & _
  1339. "FROM Taxonomy " & _
  1340. "WHERE (ContentURI = """ & strURI & """)"
  1341. rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  1342. Do While (Not rs.EOF)
  1343. p_GetMergedKeywords = p_GetMergedKeywords & rs("Keywords")
  1344. rs.MoveNext
  1345. Loop
  1346. p_GetMergedKeywords = p_GetKeywordString(p_GetMergedKeywords, i_strDeletedKeywords)
  1347. End Function
  1348. Private Sub p_PropagateKeywords( _
  1349. ByRef i_strURI As String, _
  1350. ByRef i_strKeywords As String, _
  1351. ByRef o_ModifiedDOMNodes As MSXML2.IXMLDOMNode _
  1352. )
  1353. Dim strURI As String
  1354. Dim strQuery As String
  1355. Dim rs As ADODB.Recordset
  1356. Dim intTID As Long
  1357. Dim DOMDoc As MSXML2.DOMDocument
  1358. Dim Node As MSXML2.IXMLDOMNode
  1359. Dim Element As MSXML2.IXMLDOMElement
  1360. Dim colTaxonomy As Collection
  1361. Set DOMDoc = New MSXML2.DOMDocument
  1362. Set o_ModifiedDOMNodes = HhtPreamble(DOMDoc, True)
  1363. Set colTaxonomy = New Collection
  1364. strURI = Trim$(i_strURI)
  1365. If (strURI = "") Then
  1366. Exit Sub
  1367. End If
  1368. Set rs = New ADODB.Recordset
  1369. strQuery = "" & _
  1370. "SELECT * " & _
  1371. "FROM Taxonomy " & _
  1372. "WHERE (ContentURI = """ & strURI & """)"
  1373. rs.Open strQuery, g_cnn, adOpenStatic, adLockReadOnly
  1374. ' Doing this without the CollectionContainsKey check causes a weird bug.
  1375. ' This bug doesn't manifest itself if I slow things down with a Debug.Print
  1376. ' right here. Otherwise, it adds the new Records created by p_SetKeywords to
  1377. ' rs, even though rs is Static.
  1378. Do While (Not rs.EOF)
  1379. intTID = rs("TID")
  1380. If (Not CollectionContainsKey(colTaxonomy, intTID)) Then
  1381. colTaxonomy.Add True, CStr(intTID)
  1382. If (rs("Keywords") <> i_strKeywords) Then
  1383. p_SetKeywords intTID, i_strKeywords
  1384. Set Element = p_CreateTaxonomyElement(DOMDoc, rs)
  1385. XMLSetAttribute Element, HHT_keywords_C, i_strKeywords
  1386. XMLSetAttribute Element, HHT_modifiedtime_C, Now
  1387. XMLSetAttribute Element, HHT_username_C, g_strUserName
  1388. o_ModifiedDOMNodes.appendChild Element
  1389. End If
  1390. End If
  1391. rs.MoveNext
  1392. Loop
  1393. End Sub
  1394. Private Sub p_SetKeywords( _
  1395. ByVal i_intTID As Long, _
  1396. ByRef i_strKeywords As String _
  1397. )
  1398. On Error GoTo LErrorHandler
  1399. g_cnn.BeginTrans
  1400. Dim rs As ADODB.Recordset
  1401. Set rs = New ADODB.Recordset
  1402. GetNodeDetails i_intTID, rs
  1403. If (rs.EOF) Then
  1404. GoTo LEnd
  1405. End If
  1406. rs("ModifiedTime") = Now
  1407. rs("Username") = g_strUserName
  1408. rs("Keywords") = i_strKeywords
  1409. rs("AuthoringGroup") = g_clsParameters.AuthoringGroup
  1410. rs.Update
  1411. LEnd:
  1412. g_cnn.CommitTrans
  1413. Exit Sub
  1414. LErrorHandler:
  1415. g_cnn.RollbackTrans
  1416. Err.Raise Err.Number, Err.Source, Err.Description
  1417. End Sub
  1418. Private Function p_MergeKeywords( _
  1419. ByRef i_strKeywords1 As String, _
  1420. ByRef i_strKeywords2 As String _
  1421. ) As String
  1422. ' Assumption: KIDs in i_strKeywords1 and i_strKeywords2 are sorted.
  1423. Dim arrKIDs1() As String
  1424. Dim arrKIDs2() As String
  1425. Dim intIndex1 As Long
  1426. Dim intIndex2 As Long
  1427. Dim intKID1 As Long
  1428. Dim intKID2 As Long
  1429. Dim strKeywords As String
  1430. arrKIDs1 = Split(i_strKeywords1, " ")
  1431. arrKIDs2 = Split(i_strKeywords2, " ")
  1432. strKeywords = " "
  1433. intIndex2 = LBound(arrKIDs2)
  1434. For intIndex1 = LBound(arrKIDs1) To UBound(arrKIDs1)
  1435. If (arrKIDs1(intIndex1) = "") Then
  1436. GoTo LForEnd
  1437. End If
  1438. intKID1 = arrKIDs1(intIndex1)
  1439. Do While (intIndex2 <= UBound(arrKIDs2))
  1440. If (arrKIDs2(intIndex2) = "") Then
  1441. GoTo LWhileEnd1
  1442. End If
  1443. intKID2 = arrKIDs2(intIndex2)
  1444. If (intKID1 < intKID2) Then
  1445. Exit Do
  1446. ElseIf (intKID1 = intKID2) Then
  1447. GoTo LWhileEnd1
  1448. Else
  1449. strKeywords = strKeywords & intKID2 & " "
  1450. End If
  1451. LWhileEnd1:
  1452. intIndex2 = intIndex2 + 1
  1453. Loop
  1454. strKeywords = strKeywords & intKID1 & " "
  1455. LForEnd:
  1456. Next
  1457. Do While (intIndex2 <= UBound(arrKIDs2))
  1458. If (arrKIDs2(intIndex2) = "") Then
  1459. GoTo LWhileEnd2
  1460. End If
  1461. intKID2 = arrKIDs2(intIndex2)
  1462. strKeywords = strKeywords & intKID2 & " "
  1463. LWhileEnd2:
  1464. intIndex2 = intIndex2 + 1
  1465. Loop
  1466. If (strKeywords = " ") Then
  1467. p_MergeKeywords = ""
  1468. Else
  1469. p_MergeKeywords = strKeywords
  1470. End If
  1471. End Function
  1472. Private Function p_GetKeywordString( _
  1473. ByVal i_strKeywords As String, _
  1474. ByVal i_strExcludedKeywords As String _
  1475. ) As String
  1476. ' Assumption: KIDs in i_strExcludedKeywords are sorted.
  1477. ' Keywords in i_strKeywords are not sorted and may contain duplicates.
  1478. Dim arrKIDs1() As String
  1479. Dim arrKIDs2() As String
  1480. Dim intIndex1 As Long
  1481. Dim intIndex2 As Long
  1482. Dim intKID1 As Long
  1483. Dim intKID2 As Long
  1484. Dim strKeywords As String
  1485. strKeywords = FormatKeywordsForTaxonomy(i_strKeywords)
  1486. If (strKeywords = "") Then
  1487. p_GetKeywordString = ""
  1488. Exit Function
  1489. End If
  1490. arrKIDs1 = Split(strKeywords, " ")
  1491. arrKIDs2 = Split(i_strExcludedKeywords, " ")
  1492. strKeywords = " "
  1493. For intIndex1 = LBound(arrKIDs1) To UBound(arrKIDs1)
  1494. If (arrKIDs1(intIndex1) = "") Then
  1495. GoTo LForEnd
  1496. End If
  1497. intKID1 = arrKIDs1(intIndex1)
  1498. Do While (intIndex2 <= UBound(arrKIDs2))
  1499. If (arrKIDs2(intIndex2) = "") Then
  1500. GoTo LWhileEnd
  1501. End If
  1502. intKID2 = arrKIDs2(intIndex2)
  1503. If (intKID1 < intKID2) Then
  1504. Exit Do
  1505. ElseIf (intKID1 = intKID2) Then
  1506. ' This keyword needs to be skipped.
  1507. GoTo LForEnd
  1508. End If
  1509. LWhileEnd:
  1510. intIndex2 = intIndex2 + 1
  1511. Loop
  1512. strKeywords = strKeywords & intKID1 & " "
  1513. LForEnd:
  1514. Next
  1515. If (strKeywords = " ") Then
  1516. p_GetKeywordString = ""
  1517. Else
  1518. p_GetKeywordString = strKeywords
  1519. End If
  1520. End Function
  1521. Public Sub KeywordifyTitles( _
  1522. ByVal i_intTID As Long _
  1523. )
  1524. On Error GoTo LErrorHandler
  1525. g_cnn.BeginTrans
  1526. Dim rsLock As ADODB.Recordset
  1527. Dim clsKeywordifier As Keywordifier
  1528. Dim intAG As Long
  1529. CheckDatabaseVersion
  1530. LockTable LOCK_TABLE_TAXONOMY, rsLock
  1531. Set clsKeywordifier = New Keywordifier
  1532. intAG = g_clsParameters.AuthoringGroup
  1533. p_KeywordifyTitles i_intTID, intAG, clsKeywordifier
  1534. LEnd:
  1535. g_cnn.CommitTrans
  1536. Exit Sub
  1537. LErrorHandler:
  1538. g_cnn.RollbackTrans
  1539. Err.Raise Err.Number, Err.Source, Err.Description
  1540. End Sub
  1541. Private Sub p_KeywordifyTitles( _
  1542. ByVal i_intTID As Long, _
  1543. ByVal i_intAG As Long, _
  1544. ByRef i_clsKeywordifier As Keywordifier _
  1545. )
  1546. Dim rs As ADODB.Recordset
  1547. Dim strQuery As String
  1548. Dim strTitle As String
  1549. Dim strOldKeywords As String
  1550. Dim strAddlKeywords As String
  1551. Dim strNewKeywords As String
  1552. Dim intTID As Long
  1553. ' Does the record exist?
  1554. Set rs = New ADODB.Recordset
  1555. GetNodeDetails i_intTID, rs
  1556. If (rs.EOF) Then
  1557. Exit Sub
  1558. End If
  1559. If (rs("ContentURI") <> "") And (i_intAG = rs("AuthoringGroup")) Then
  1560. strOldKeywords = rs("Keywords")
  1561. strTitle = rs("ENUTitle")
  1562. p_RaiseEventAndLookForCancel "Creating keywords from " & strTitle
  1563. strAddlKeywords = i_clsKeywordifier.CreateKeywordsFromTitle(strTitle)
  1564. strNewKeywords = p_MergeKeywords(strOldKeywords, strAddlKeywords)
  1565. If (strNewKeywords <> strOldKeywords) Then
  1566. rs("Keywords") = strNewKeywords
  1567. rs("ModifiedTime") = Now
  1568. rs("Username") = g_strUserName
  1569. rs.Update
  1570. End If
  1571. End If
  1572. rs.Close
  1573. strQuery = "" & _
  1574. "SELECT * " & _
  1575. "FROM Taxonomy " & _
  1576. "WHERE (ParentTID=" & i_intTID & ")"
  1577. rs.Open strQuery, g_cnn, adOpenStatic, adLockPessimistic
  1578. Do While (Not rs.EOF)
  1579. intTID = rs("TID")
  1580. If (intTID <> ROOT_TID_C) Then
  1581. p_KeywordifyTitles intTID, i_intAG, i_clsKeywordifier
  1582. End If
  1583. rs.MoveNext
  1584. Loop
  1585. End Sub
  1586. Private Function p_IsSpecialChar( _
  1587. ByVal i_chr As String _
  1588. ) As Boolean
  1589. Select Case i_chr
  1590. Case "A" To "Z", "a" To "z", "0" To "9"
  1591. p_IsSpecialChar = False
  1592. Case Else
  1593. p_IsSpecialChar = True
  1594. End Select
  1595. End Function
  1596. Private Function p_Mangle( _
  1597. ByVal i_strName _
  1598. ) As String
  1599. Dim intIndex As Long
  1600. Dim chr As String
  1601. p_Mangle = ""
  1602. For intIndex = 1 To Len(i_strName)
  1603. chr = Mid$(i_strName, intIndex, 1)
  1604. p_Mangle = p_Mangle & IIf(p_IsSpecialChar(chr), "_", chr)
  1605. Next
  1606. End Function
  1607. Private Function p_RefNodeIsADescendent( _
  1608. ByVal i_intTID As Long, _
  1609. ByVal i_intRefTID As Long _
  1610. ) As Boolean
  1611. Dim intTID As Long
  1612. Dim rs As ADODB.Recordset
  1613. Dim strQuery As String
  1614. CheckDatabaseVersion
  1615. Set rs = New ADODB.Recordset
  1616. If (i_intTID = i_intRefTID) Then
  1617. p_RefNodeIsADescendent = True
  1618. Exit Function
  1619. End If
  1620. p_RefNodeIsADescendent = False
  1621. intTID = i_intRefTID
  1622. Do While (intTID <> ROOT_TID_C)
  1623. strQuery = "" & _
  1624. "SELECT * " & _
  1625. "FROM Taxonomy " & _
  1626. "WHERE (TID=" & intTID & ")"
  1627. rs.Open strQuery, g_cnn, adOpenForwardOnly, adLockReadOnly
  1628. If (rs.EOF) Then
  1629. Exit Function
  1630. End If
  1631. If (rs("ParentTID") = i_intTID) Then
  1632. p_RefNodeIsADescendent = True
  1633. Exit Function
  1634. End If
  1635. intTID = rs("ParentTID")
  1636. rs.Close
  1637. Loop
  1638. End Function
  1639. Private Sub p_ValidateTitle( _
  1640. ByVal i_strTitle As String _
  1641. )
  1642. If (ContainsGarbage(i_strTitle)) Then
  1643. Err.Raise errContainsGarbageChar
  1644. ElseIf (Len(i_strTitle) > MAX_TITLE_LENGTH_C) Then
  1645. Err.Raise errTooLong
  1646. End If
  1647. End Sub
  1648. Private Sub p_ValidateDescription( _
  1649. ByVal i_strDescription As String _
  1650. )
  1651. If (ContainsGarbage(i_strDescription)) Then
  1652. Err.Raise errContainsGarbageChar
  1653. End If
  1654. End Sub
  1655. Private Sub p_RaiseEventAndLookForCancel( _
  1656. ByVal strStatus As String _
  1657. )
  1658. Dim blnCancel As Boolean
  1659. blnCancel = False
  1660. RaiseEvent ReportStatus(strStatus, blnCancel)
  1661. If (blnCancel) Then
  1662. Err.Raise errCancel
  1663. End If
  1664. End Sub