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.

411 lines
11 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. QueryResultsBuilder.cpp
  5. Abstract:
  6. The classes implementated in this file facilitate the generation of the result set from a DB query.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 12/05/2000
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. ////////////////////////////////////////////////////////////////////////////////
  13. Taxonomy::QueryResultEntry::QueryResultEntry()
  14. {
  15. m_ID_node = -1; // long m_ID_node;
  16. m_ID_topic = -1; // long m_ID_topic;
  17. m_ID_parent = -1; // long m_ID_parent;
  18. m_ID_owner = -1; // long m_ID_owner;
  19. m_lOriginalPos = -1; // long m_lOriginalPos;
  20. //
  21. // CPCHQueryResult::Payload m_data;
  22. }
  23. ////////////////////////////////////////
  24. bool Taxonomy::QueryResults::Compare::operator()( /*[in]*/ const QueryResultEntry* left, /*[in]*/ const QueryResultEntry* right ) const
  25. {
  26. return left->m_data.m_lPos < right->m_data.m_lPos;
  27. }
  28. ////////////////////////////////////////
  29. Taxonomy::QueryResults::QueryResults( /*[in]*/ Taxonomy::Updater& updater ) : m_updater( updater )
  30. {
  31. // Taxonomy::Updater& m_updater;
  32. // ResultVec m_vec;
  33. }
  34. Taxonomy::QueryResults::~QueryResults()
  35. {
  36. Clean();
  37. }
  38. void Taxonomy::QueryResults::Clean()
  39. {
  40. MPC::CallDestructorForAll( m_vec );
  41. }
  42. HRESULT Taxonomy::QueryResults::AllocateNew( /*[in ]*/ LPCWSTR szCategory ,
  43. /*[out]*/ QueryResultEntry*& qre )
  44. {
  45. __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::AllocateNew" );
  46. HRESULT hr;
  47. __MPC_EXIT_IF_ALLOC_FAILS(hr, qre, new QueryResultEntry);
  48. qre->m_data.m_bstrCategory = szCategory;
  49. m_vec.push_back( qre );
  50. hr = S_OK;
  51. __HCP_FUNC_CLEANUP;
  52. __HCP_FUNC_EXIT(hr);
  53. }
  54. HRESULT Taxonomy::QueryResults::Sort()
  55. {
  56. Compare cmp;
  57. std::sort< ResultIter >( m_vec.begin(), m_vec.end(), cmp );
  58. return S_OK;
  59. }
  60. ////////////////////
  61. HRESULT Taxonomy::QueryResults::Append( /*[in]*/ Taxonomy::RS_Data_Taxonomy* rs ,
  62. /*[in]*/ LPCWSTR szCategory )
  63. {
  64. __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::Append" );
  65. HRESULT hr;
  66. QueryResultEntry* qre;
  67. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strDescriptionURI ));
  68. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strIconURI ));
  69. __MPC_EXIT_IF_METHOD_FAILS(hr, AllocateNew( szCategory, qre ));
  70. qre->m_ID_node = rs->m_ID_node ;
  71. qre->m_ID_topic = -1 ;
  72. qre->m_ID_parent = rs->m_ID_parent ;
  73. qre->m_ID_owner = rs->m_ID_owner ;
  74. qre->m_lOriginalPos = rs->m_lPos ;
  75. qre->m_data.m_bstrEntry = rs->m_strEntry .c_str();
  76. qre->m_data.m_bstrTitle = rs->m_strTitle .c_str();
  77. qre->m_data.m_bstrTopicURL = rs->m_strDescriptionURI.c_str();
  78. qre->m_data.m_bstrIconURL = rs->m_strIconURI .c_str();
  79. qre->m_data.m_bstrDescription = rs->m_strDescription .c_str();
  80. ////qre->m_data.m_lType
  81. qre->m_data.m_lPos = rs->m_lPos ;
  82. qre->m_data.m_fVisible = rs->m_fVisible ;
  83. qre->m_data.m_fSubsite = rs->m_fSubsite ;
  84. qre->m_data.m_lNavModel = rs->m_lNavModel ;
  85. hr = S_OK;
  86. __HCP_FUNC_CLEANUP;
  87. __HCP_FUNC_EXIT(hr);
  88. }
  89. HRESULT Taxonomy::QueryResults::Append( /*[in]*/ Taxonomy::RS_Data_Topics* rs ,
  90. /*[in]*/ LPCWSTR szCategory )
  91. {
  92. __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::Append" );
  93. HRESULT hr;
  94. QueryResultEntry* qre;
  95. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strURI ));
  96. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strIconURI ));
  97. __MPC_EXIT_IF_METHOD_FAILS(hr, AllocateNew( szCategory, qre ));
  98. qre->m_ID_node = -1 ;
  99. qre->m_ID_topic = rs->m_ID_topic ;
  100. qre->m_ID_parent = rs->m_ID_node ;
  101. qre->m_ID_owner = rs->m_ID_owner ;
  102. qre->m_lOriginalPos = rs->m_lPos ;
  103. ////qre->m_data.m_bstrEntry
  104. qre->m_data.m_bstrTitle = rs->m_strTitle .c_str();
  105. qre->m_data.m_bstrTopicURL = rs->m_strURI .c_str();
  106. qre->m_data.m_bstrIconURL = rs->m_strIconURI .c_str();
  107. qre->m_data.m_bstrDescription = rs->m_strDescription.c_str();
  108. qre->m_data.m_lType = rs->m_lType ;
  109. qre->m_data.m_lPos = rs->m_lPos ;
  110. qre->m_data.m_fVisible = rs->m_fVisible ;
  111. ////qre->m_data.m_fSubsite
  112. ////qre->m_data.m_lNavModel
  113. hr = S_OK;
  114. __HCP_FUNC_CLEANUP;
  115. __HCP_FUNC_EXIT(hr);
  116. }
  117. ////////////////////
  118. HRESULT Taxonomy::QueryResults::LookupNodes( /*[in]*/ LPCWSTR szCategory ,
  119. /*[in]*/ long ID_node ,
  120. /*[in]*/ bool fVisibleOnly )
  121. {
  122. __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::LookupNodes" );
  123. HRESULT hr;
  124. Taxonomy::RS_Taxonomy* rsTaxonomy;
  125. bool fFound;
  126. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTaxonomy( &rsTaxonomy ));
  127. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Seek_Children( ID_node, &fFound ));
  128. while(fFound)
  129. {
  130. if(fVisibleOnly == false || rsTaxonomy->m_fVisible)
  131. {
  132. __MPC_EXIT_IF_METHOD_FAILS(hr, Append( rsTaxonomy, szCategory ));
  133. }
  134. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Move( 0, 1, &fFound ));
  135. }
  136. hr = S_OK;
  137. __HCP_FUNC_CLEANUP;
  138. __HCP_FUNC_EXIT(hr);
  139. }
  140. HRESULT Taxonomy::QueryResults::LookupTopics( /*[in]*/ LPCWSTR szCategory ,
  141. /*[in]*/ long ID_node ,
  142. /*[in]*/ bool fVisibleOnly )
  143. {
  144. __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::LookupTopics" );
  145. HRESULT hr;
  146. Taxonomy::RS_Topics* rsTopics;
  147. bool fFound;
  148. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTopics( &rsTopics ));
  149. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Seek_TopicsUnderNode( ID_node, &fFound ));
  150. while(fFound)
  151. {
  152. if(fVisibleOnly == false || rsTopics->m_fVisible)
  153. {
  154. __MPC_EXIT_IF_METHOD_FAILS(hr, Append( rsTopics, szCategory ));
  155. }
  156. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Move( 0, 1, &fFound ));
  157. }
  158. hr = S_OK;
  159. __HCP_FUNC_CLEANUP;
  160. __HCP_FUNC_EXIT(hr);
  161. }
  162. ////////////////////
  163. struct InsertionMode
  164. {
  165. LPCWSTR szMode;
  166. int iDir;
  167. bool fNodes;
  168. bool fTopics;
  169. };
  170. static const struct InsertionMode s_lookup[] =
  171. {
  172. { L"" , 1, false, false }, // Synonym of END
  173. { L"TOP" , -1, false, false },
  174. { L"BEFORE_NODE" , -1, true , false }, // (INSERTLOCATION = <Entry>)
  175. { L"BEFORE_TOPIC", -1, false, true }, // (INSERTLOCATION = <URI>)
  176. { L"AFTER_NODE" , 1, true , false }, // (INSERTLOCATION = <Entry>)
  177. { L"AFTER_TOPIC" , 1, false, true }, // (INSERTLOCATION = <URI>)
  178. { L"END" , 1, false, false },
  179. };
  180. HRESULT Taxonomy::QueryResults::MakeRoomForInsert( /*[in ]*/ LPCWSTR szMode ,
  181. /*[in ]*/ LPCWSTR szID ,
  182. /*[in ]*/ long ID_node ,
  183. /*[out]*/ long& lPosRet )
  184. {
  185. __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::MakeRoomForInsert" );
  186. HRESULT hr;
  187. Taxonomy::RS_Taxonomy* rsTaxonomy;
  188. Taxonomy::RS_Topics* rsTopics;
  189. ResultIterConst it;
  190. const InsertionMode* ptr;
  191. long lPos;
  192. for(lPos = 0, ptr = s_lookup; lPos < ARRAYSIZE(s_lookup); lPos++, ptr++)
  193. {
  194. if(!MPC::StrICmp( ptr->szMode, szMode )) break;
  195. }
  196. if(lPos == ARRAYSIZE(s_lookup))
  197. {
  198. __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  199. }
  200. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTaxonomy( &rsTaxonomy ));
  201. __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTopics ( &rsTopics ));
  202. Clean();
  203. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupNodes ( NULL, ID_node, /*fVisibleOnly*/false ));
  204. __MPC_EXIT_IF_METHOD_FAILS(hr, LookupTopics( NULL, ID_node, /*fVisibleOnly*/false ));
  205. __MPC_EXIT_IF_METHOD_FAILS(hr, Sort());
  206. //
  207. // First Pass, reorder the set.
  208. //
  209. for(lPos = 1, it = m_vec.begin(); it != m_vec.end(); it++)
  210. {
  211. QueryResultEntry* qre = *it;
  212. qre->m_data.m_lPos = lPos++;
  213. }
  214. //
  215. // Second Pass, find the right position.
  216. //
  217. lPosRet = -1;
  218. if(ptr->fNodes || ptr->fTopics)
  219. {
  220. for(it = m_vec.begin(); it != m_vec.end(); it++)
  221. {
  222. QueryResultEntry* qre = *it;
  223. if((ptr->fNodes && qre->m_ID_node != -1 && !MPC::StrICmp( szID, qre->m_data.m_bstrEntry )) ||
  224. (ptr->fTopics && qre->m_ID_topic != -1 && !MPC::StrICmp( szID, qre->m_data.m_bstrTopicURL )) )
  225. {
  226. lPosRet = (*it)->m_data.m_lPos;
  227. if(ptr->iDir > 0) lPosRet++; // Add after the selected element.
  228. break;
  229. }
  230. }
  231. }
  232. //
  233. // Stop not found? Add at the beginning or end.
  234. //
  235. if(lPosRet == -1)
  236. {
  237. if(ptr->iDir < 0)
  238. {
  239. lPosRet = 1;
  240. }
  241. else
  242. {
  243. lPosRet = m_vec.size() + 1;
  244. }
  245. }
  246. //
  247. // Third Pass, move down the elements after the inserted one and reorganize.
  248. //
  249. for(it = m_vec.begin(); it != m_vec.end(); it++)
  250. {
  251. QueryResultEntry* qre = *it;
  252. if(qre->m_data.m_lPos >= lPosRet)
  253. {
  254. qre->m_data.m_lPos++;
  255. }
  256. if(qre->m_data.m_lPos != qre->m_lOriginalPos)
  257. {
  258. if(qre->m_ID_node != -1)
  259. {
  260. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Seek_Node( qre->m_ID_node ));
  261. rsTaxonomy->m_lPos = qre->m_data.m_lPos;
  262. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Update());
  263. }
  264. if(qre->m_ID_topic != -1)
  265. {
  266. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Seek_SingleTopic( qre->m_ID_topic ));
  267. rsTopics->m_lPos = qre->m_data.m_lPos;
  268. __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Update());
  269. }
  270. qre->m_lOriginalPos = qre->m_data.m_lPos;
  271. }
  272. }
  273. hr = S_OK;
  274. __HCP_FUNC_CLEANUP;
  275. __HCP_FUNC_EXIT(hr);
  276. }
  277. HRESULT Taxonomy::QueryResults::PopulateCollection( /*[in]*/ CPCHQueryResultCollection* pColl )
  278. {
  279. __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::PopulateCollection" );
  280. HRESULT hr;
  281. __MPC_EXIT_IF_METHOD_FAILS(hr, Sort());
  282. for(ResultIterConst it = m_vec.begin(); it != m_vec.end(); it++)
  283. {
  284. CComPtr<CPCHQueryResult> item;
  285. QueryResultEntry* qre = *it;
  286. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->CreateItem( &item ));
  287. item->Initialize( qre->m_data );
  288. }
  289. hr = S_OK;
  290. __HCP_FUNC_CLEANUP;
  291. __HCP_FUNC_EXIT(hr);
  292. }