Leaked source code of windows server 2003
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.

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