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.

488 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: dbcmdop.cxx
  7. //
  8. // Contents: Wrapper classes for DBCOMMANDTREE structure
  9. //
  10. // Classes: CDbSelectNode
  11. // CDbProjectNode
  12. // CDbProjectListAnchor
  13. // CDbSortNode
  14. // CDbSortListAnchor
  15. // CDbNestingNode
  16. //
  17. // History: 6-15-95 srikants Created
  18. //
  19. //----------------------------------------------------------------------------
  20. #include <pch.cxx>
  21. #pragma hdrstop
  22. //+---------------------------------------------------------------------------
  23. //
  24. // Method: CDbSelectNode::CDbSelectNode
  25. //
  26. // Synopsis: Construct a select node.
  27. //
  28. // Arguments: -NONE-
  29. //
  30. // History: 6-15-95 srikants Created
  31. //
  32. // Notes: Only the normal select can be created. For OFS,
  33. // order-preserving functions identially with normal select.
  34. //
  35. //----------------------------------------------------------------------------
  36. CDbSelectNode::CDbSelectNode( )
  37. : CDbCmdTreeNode( DBOP_select )
  38. {
  39. CDbTableId * pTableId = new CDbTableId( DBTABLEID_NAME );
  40. if ( 0 != pTableId )
  41. {
  42. if ( pTableId->IsValid() )
  43. {
  44. InsertChild( pTableId );
  45. }
  46. else
  47. {
  48. delete pTableId;
  49. }
  50. }
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Method: CDbSelectNode::SetRestriction
  55. //
  56. // Synopsis: Set the restriction expression
  57. //
  58. // Arguments: [pRestr] - restriction expression to be set.
  59. //
  60. // History: 6-15-95 srikants Created
  61. //
  62. // Notes:
  63. //
  64. //----------------------------------------------------------------------------
  65. BOOL CDbSelectNode::SetRestriction( CDbCmdTreeNode * pRestr )
  66. {
  67. if ( IsValid() &&
  68. GetFirstChild() &&
  69. GetFirstChild()->GetNextSibling() != 0 )
  70. {
  71. //
  72. // Restriction expression already set on node. Remove and
  73. // replace it.
  74. //
  75. CDbCmdTreeNode * pTableNode = RemoveFirstChild();
  76. CDbCmdTreeNode * pOldRst = RemoveFirstChild();
  77. Win4Assert( 0 == GetFirstChild() ); // don't expect any more children
  78. delete pOldRst;
  79. InsertChild(pTableNode);
  80. }
  81. return AddRestriction(pRestr);
  82. }
  83. //+---------------------------------------------------------------------------
  84. //
  85. // Member: CDbListAnchor::_AppendListElement
  86. //
  87. // Synopsis: Helper function to add a list-element node and the given
  88. // column node to the anchor.
  89. //
  90. // Arguments: [eleType] - The type of the element node.
  91. // [pColumn] - The column specification node. This will be made
  92. // the child of the newly created list element.
  93. //
  94. // Returns: TRUE if successful; FALSE otherwise.
  95. //
  96. // History: 11-16-95 srikants Created
  97. //
  98. // Notes:
  99. //
  100. //----------------------------------------------------------------------------
  101. BOOL CDbListAnchor::_AppendListElement( DBCOMMANDOP eleType, CDbColumnNode * pColumn )
  102. {
  103. Win4Assert( _IsValidListElement( eleType ) );
  104. Win4Assert( 0 != pColumn );
  105. CDbCmdTreeNode * pLE = new CDbCmdTreeNode( eleType );
  106. if ( 0 != pLE )
  107. {
  108. pLE->InsertChild( pColumn );
  109. AppendChild( pLE );
  110. }
  111. return (0 != pLE);
  112. }
  113. //+---------------------------------------------------------------------------
  114. //
  115. // Method: CDbListAnchor::AppendList, protected
  116. //
  117. // Synopsis: Appends a list of elements to a list anchor
  118. //
  119. // Arguments: [pListElement] - pointer to head list element
  120. //
  121. // Returns: BOOL - TRUE if successful, FALSE otherwise
  122. //
  123. // History: 17 Aug 1995 AlanW Created
  124. //
  125. // Notes:
  126. //
  127. //----------------------------------------------------------------------------
  128. BOOL CDbListAnchor::AppendList( CDbCmdTreeNode * pListElement )
  129. {
  130. Win4Assert( _IsValidListElement( pListElement->GetCommandType() ));
  131. Win4Assert( pListElement->GetFirstChild() != 0 );
  132. AppendChild( pListElement );
  133. return TRUE;
  134. }
  135. //+---------------------------------------------------------------------------
  136. //
  137. // Method: CDbListAnchor::AppendListElement, protected
  138. //
  139. // Synopsis: Appends a single element to a list anchor
  140. //
  141. // Arguments: [pListElement] - pointer to list element
  142. //
  143. // Returns: BOOL - TRUE if successful, FALSE otherwise
  144. //
  145. // History: 17 Aug 1995 AlanW Created
  146. //
  147. // Notes:
  148. //
  149. //----------------------------------------------------------------------------
  150. BOOL CDbListAnchor::AppendListElement( CDbCmdTreeNode * pListElement )
  151. {
  152. Win4Assert( _IsValidListElement( pListElement->GetCommandType() ) &&
  153. pListElement->GetNextSibling() == 0 );
  154. Win4Assert( pListElement->GetFirstChild() != 0 );
  155. AppendChild( pListElement );
  156. return TRUE;
  157. }
  158. //+---------------------------------------------------------------------------
  159. //
  160. // Method: CDbListAnchor::AppendListElement, protected
  161. //
  162. // Synopsis:
  163. //
  164. // Arguments: [eleType] - list element type
  165. // [PropSpec] - Full property spec of column to add
  166. //
  167. // Returns: BOOL - TRUE if successful, FALSE otherwise
  168. //
  169. // History: 6-15-95 srikants Created
  170. //
  171. // Notes:
  172. //
  173. //----------------------------------------------------------------------------
  174. BOOL CDbListAnchor::AppendListElement( DBCOMMANDOP eleType,
  175. const DBID & PropSpec)
  176. {
  177. XPtr<CDbColumnNode> pColumn( new CDbColumnNode( PropSpec, TRUE ) );
  178. if ( 0 == pColumn.GetPointer() || !pColumn->IsValid() )
  179. return FALSE;
  180. if ( _AppendListElement( eleType, pColumn.GetPointer() ) )
  181. {
  182. pColumn.Acquire();
  183. return TRUE;
  184. }
  185. else
  186. {
  187. return FALSE;
  188. }
  189. }
  190. //+---------------------------------------------------------------------------
  191. //
  192. // Method: CDbProjectListAnchor::AppendListElement, public
  193. //
  194. // Synopsis: Add a project_list_element node to the end of the list
  195. //
  196. // Arguments: [propSpec] - column to be added to the list
  197. // [pwszName] - name of column
  198. //
  199. // Returns: BOOL - TRUE if successful, FALSE otherwise
  200. //
  201. // History: 6-15-95 srikants Created
  202. //
  203. // Notes:
  204. //
  205. //----------------------------------------------------------------------------
  206. BOOL CDbProjectListAnchor::AppendListElement( const DBID & propSpec, LPWSTR pwszName )
  207. {
  208. BOOL fSuccess = FALSE;
  209. XPtr<CDbProjectListElement> pListElem( new CDbProjectListElement( ) );
  210. if ( 0 == pListElem.GetPointer() )
  211. return FALSE;
  212. if ( !pListElem->SetName(pwszName) )
  213. return FALSE;
  214. XPtr<CDbColumnNode> pColumn( new CDbColumnNode( propSpec, TRUE ) );
  215. if ( 0 == pColumn.GetPointer() || !pColumn->IsValid() )
  216. return FALSE;
  217. if ( pListElem->SetColumn( pColumn.GetPointer() ) )
  218. pColumn.Acquire();
  219. else
  220. return FALSE;
  221. AppendChild( pListElem.GetPointer() );
  222. pListElem.Acquire();
  223. return TRUE;
  224. }
  225. //+---------------------------------------------------------------------------
  226. //
  227. // Method: CDbProjectNode::_FindOrAddAnchor, private
  228. //
  229. // Synopsis: Return the project list anchor node. Add one if there
  230. // isn't one.
  231. //
  232. // Returns: CDbProjectListAnchor* - pointer to the anchor node, or NULL
  233. // if there was an allocation failure.
  234. //
  235. // History: 6-15-95 srikants Created
  236. //
  237. // Notes:
  238. //
  239. //----------------------------------------------------------------------------
  240. CDbProjectListAnchor * CDbProjectNode::_FindOrAddAnchor()
  241. {
  242. CDbCmdTreeNode * pChild = GetFirstChild();
  243. while ( 0 != pChild )
  244. {
  245. if (pChild->IsListAnchor())
  246. {
  247. Win4Assert( DBOP_project_list_anchor == pChild->GetCommandType() );
  248. return (CDbProjectListAnchor *)pChild;
  249. }
  250. pChild = pChild->GetNextSibling();
  251. }
  252. CDbProjectListAnchor * pAnchor = new CDbProjectListAnchor();
  253. if ( 0 != pAnchor )
  254. {
  255. AppendChild( pAnchor );
  256. }
  257. return pAnchor;
  258. }
  259. //+---------------------------------------------------------------------------
  260. //
  261. // Method: CDbSortNode::_FindOrAddAnchor, private
  262. //
  263. // Synopsis: Return the sort list anchor node. Add one if there
  264. // isn't one.
  265. //
  266. // Returns: CDbSortListAnchor* - pointer to the anchor node, or NULL
  267. // if there was an allocation failure.
  268. //
  269. // History: 6-15-95 srikants Created
  270. //
  271. // Notes: We should probably implement this in a base class
  272. // with the method taking the list anchor type.
  273. //
  274. //----------------------------------------------------------------------------
  275. CDbSortListAnchor * CDbSortNode::_FindOrAddAnchor()
  276. {
  277. CDbCmdTreeNode * pChild = GetFirstChild();
  278. while ( 0 != pChild )
  279. {
  280. if (pChild->IsListAnchor())
  281. {
  282. Win4Assert( DBOP_sort_list_anchor == pChild->GetCommandType() );
  283. return (CDbSortListAnchor *)pChild;
  284. }
  285. pChild = pChild->GetNextSibling();
  286. }
  287. CDbSortListAnchor * pAnchor = new CDbSortListAnchor();
  288. if ( 0 != pAnchor )
  289. {
  290. AppendChild( pAnchor );
  291. }
  292. return pAnchor;
  293. }
  294. //+---------------------------------------------------------------------------
  295. //
  296. // Method: CDbSortNode::AddSortColumn, public
  297. //
  298. // Synopsis: Add a sort column to the sort list.
  299. //
  300. // Returns: TRUE if successful, FALSE otherwise (allocation failure).
  301. //
  302. // History: 17 Aug 1995 AlanW Created
  303. //
  304. // Notes: Sort lists consist of a sort list anchor, with a chain
  305. // of sort list elements as children. Each sort list element
  306. // has information pertaining to the sort (direction and locale)
  307. // and one child which is a column specification.
  308. //
  309. //----------------------------------------------------------------------------
  310. BOOL CDbSortNode::AddSortColumn(DBID const & propSpec,
  311. BOOL fDirection,
  312. LCID locale)
  313. {
  314. CDbSortListAnchor * pAnchor = _FindOrAddAnchor();
  315. XPtr<CDbColumnNode> pCol( new CDbColumnNode( propSpec, TRUE ) );
  316. if ( 0 == pCol.GetPointer() || 0 == pAnchor || !pCol->IsValid() )
  317. return FALSE;
  318. CDbSortListElement * pSortInfo = new CDbSortListElement( fDirection,
  319. locale );
  320. if ( 0 != pSortInfo )
  321. {
  322. if ( pSortInfo->IsValid() )
  323. {
  324. pSortInfo->AddColumn( pCol.Acquire() );
  325. if ( pAnchor->AppendListElement( pSortInfo ) )
  326. return TRUE;
  327. }
  328. delete pSortInfo;
  329. }
  330. return FALSE;
  331. } //AddSortColumn
  332. //+---------------------------------------------------------------------------
  333. //
  334. // Method: CDbNestingNode::AddTable, public
  335. //
  336. // Synopsis: Add a table node to a nesting. Remove an existing
  337. // table node if there is one there.
  338. //
  339. // Arguments: [pTable] - node to be added to tree. Ownership passes
  340. // to the command tree.
  341. //
  342. // Returns: BOOL - TRUE if operation worked
  343. //
  344. // History: 08 Aug 1995 AlanW Created
  345. //
  346. // Notes: Nesting nodes are expected to have 0, 1, 4 or 5 child
  347. // nodes depending upon whether AddTable and _FindGroupListAnchor
  348. // have been called.
  349. //
  350. //----------------------------------------------------------------------------
  351. BOOL CDbNestingNode::AddTable( CDbCmdTreeNode * pTable )
  352. {
  353. Win4Assert (! pTable->IsListAnchor());
  354. CDbCmdTreeNode * pChild = GetFirstChild();
  355. if ( 0 != pChild && ! pChild->IsListAnchor())
  356. {
  357. // Found a table??? Assert on this; we could be nice to the
  358. // caller and replace it.
  359. Win4Assert ( ! pChild->IsListAnchor() );
  360. return FALSE;
  361. }
  362. InsertChild( pTable );
  363. return TRUE;
  364. }
  365. //+---------------------------------------------------------------------------
  366. //
  367. // Method: CDbNestingNode::_FindGroupListAnchor, private
  368. //
  369. // Synopsis: Return the group list anchor node. If there is none,
  370. // add it and the parent list node, the child list node and
  371. // the grouping column node.
  372. //
  373. // Returns: CDbProjectListAnchor* - pointer to the anchor node, or NULL
  374. // if there was an allocation failure.
  375. //
  376. // History: 08 Aug 1995 AlanW Created
  377. //
  378. // Notes: Nesting nodes are expected to have 0, 1, 4 or 5 child
  379. // nodes depending upon whether AddTable and _FindGroupListAnchor
  380. // have been called.
  381. //
  382. //----------------------------------------------------------------------------
  383. CDbProjectListAnchor * CDbNestingNode::_FindGroupListAnchor()
  384. {
  385. CDbCmdTreeNode * pChild = GetFirstChild();
  386. if ( 0 != pChild )
  387. {
  388. if (! pChild->IsListAnchor())
  389. {
  390. pChild = pChild->GetNextSibling();
  391. }
  392. if ( 0 != pChild )
  393. {
  394. Win4Assert( DBOP_project_list_anchor == pChild->GetCommandType() );
  395. return (CDbProjectListAnchor *)pChild;
  396. }
  397. }
  398. XPtr<CDbProjectListAnchor> pGroupList = new CDbProjectListAnchor();
  399. XPtr<CDbProjectListAnchor> pParentList = new CDbProjectListAnchor();
  400. XPtr<CDbProjectListAnchor> pChildList = new CDbProjectListAnchor();
  401. XPtr<CDbColumnNode> pGroupColumn = new CDbColumnNode(
  402. //, PROPID_CHAPTER
  403. );
  404. if ( ! pGroupList.IsNull() &&
  405. ! pParentList.IsNull() &&
  406. ! pChildList.IsNull() &&
  407. ! pGroupColumn.IsNull() )
  408. {
  409. pGroupList->AppendSibling(pGroupColumn.Acquire());
  410. pGroupList->InsertSibling(pChildList.Acquire());
  411. pGroupList->InsertSibling(pParentList.Acquire());
  412. AppendChild(pGroupList.GetPointer());
  413. return pGroupList.Acquire();
  414. }
  415. return 0;
  416. }