//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 2000. // // File: dbcmdop.cxx // // Contents: Wrapper classes for DBCOMMANDTREE structure // // Classes: CDbSelectNode // CDbProjectNode // CDbProjectListAnchor // CDbSortNode // CDbSortListAnchor // CDbNestingNode // // History: 6-15-95 srikants Created // //---------------------------------------------------------------------------- #include #pragma hdrstop //+--------------------------------------------------------------------------- // // Method: CDbSelectNode::CDbSelectNode // // Synopsis: Construct a select node. // // Arguments: -NONE- // // History: 6-15-95 srikants Created // // Notes: Only the normal select can be created. For OFS, // order-preserving functions identially with normal select. // //---------------------------------------------------------------------------- CDbSelectNode::CDbSelectNode( ) : CDbCmdTreeNode( DBOP_select ) { CDbTableId * pTableId = new CDbTableId( DBTABLEID_NAME ); if ( 0 != pTableId ) { if ( pTableId->IsValid() ) { InsertChild( pTableId ); } else { delete pTableId; } } } //+--------------------------------------------------------------------------- // // Method: CDbSelectNode::SetRestriction // // Synopsis: Set the restriction expression // // Arguments: [pRestr] - restriction expression to be set. // // History: 6-15-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- BOOL CDbSelectNode::SetRestriction( CDbCmdTreeNode * pRestr ) { if ( IsValid() && GetFirstChild() && GetFirstChild()->GetNextSibling() != 0 ) { // // Restriction expression already set on node. Remove and // replace it. // CDbCmdTreeNode * pTableNode = RemoveFirstChild(); CDbCmdTreeNode * pOldRst = RemoveFirstChild(); Win4Assert( 0 == GetFirstChild() ); // don't expect any more children delete pOldRst; InsertChild(pTableNode); } return AddRestriction(pRestr); } //+--------------------------------------------------------------------------- // // Member: CDbListAnchor::_AppendListElement // // Synopsis: Helper function to add a list-element node and the given // column node to the anchor. // // Arguments: [eleType] - The type of the element node. // [pColumn] - The column specification node. This will be made // the child of the newly created list element. // // Returns: TRUE if successful; FALSE otherwise. // // History: 11-16-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- BOOL CDbListAnchor::_AppendListElement( DBCOMMANDOP eleType, CDbColumnNode * pColumn ) { Win4Assert( _IsValidListElement( eleType ) ); Win4Assert( 0 != pColumn ); CDbCmdTreeNode * pLE = new CDbCmdTreeNode( eleType ); if ( 0 != pLE ) { pLE->InsertChild( pColumn ); AppendChild( pLE ); } return (0 != pLE); } //+--------------------------------------------------------------------------- // // Method: CDbListAnchor::AppendList, protected // // Synopsis: Appends a list of elements to a list anchor // // Arguments: [pListElement] - pointer to head list element // // Returns: BOOL - TRUE if successful, FALSE otherwise // // History: 17 Aug 1995 AlanW Created // // Notes: // //---------------------------------------------------------------------------- BOOL CDbListAnchor::AppendList( CDbCmdTreeNode * pListElement ) { Win4Assert( _IsValidListElement( pListElement->GetCommandType() )); Win4Assert( pListElement->GetFirstChild() != 0 ); AppendChild( pListElement ); return TRUE; } //+--------------------------------------------------------------------------- // // Method: CDbListAnchor::AppendListElement, protected // // Synopsis: Appends a single element to a list anchor // // Arguments: [pListElement] - pointer to list element // // Returns: BOOL - TRUE if successful, FALSE otherwise // // History: 17 Aug 1995 AlanW Created // // Notes: // //---------------------------------------------------------------------------- BOOL CDbListAnchor::AppendListElement( CDbCmdTreeNode * pListElement ) { Win4Assert( _IsValidListElement( pListElement->GetCommandType() ) && pListElement->GetNextSibling() == 0 ); Win4Assert( pListElement->GetFirstChild() != 0 ); AppendChild( pListElement ); return TRUE; } //+--------------------------------------------------------------------------- // // Method: CDbListAnchor::AppendListElement, protected // // Synopsis: // // Arguments: [eleType] - list element type // [PropSpec] - Full property spec of column to add // // Returns: BOOL - TRUE if successful, FALSE otherwise // // History: 6-15-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- BOOL CDbListAnchor::AppendListElement( DBCOMMANDOP eleType, const DBID & PropSpec) { XPtr pColumn( new CDbColumnNode( PropSpec, TRUE ) ); if ( 0 == pColumn.GetPointer() || !pColumn->IsValid() ) return FALSE; if ( _AppendListElement( eleType, pColumn.GetPointer() ) ) { pColumn.Acquire(); return TRUE; } else { return FALSE; } } //+--------------------------------------------------------------------------- // // Method: CDbProjectListAnchor::AppendListElement, public // // Synopsis: Add a project_list_element node to the end of the list // // Arguments: [propSpec] - column to be added to the list // [pwszName] - name of column // // Returns: BOOL - TRUE if successful, FALSE otherwise // // History: 6-15-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- BOOL CDbProjectListAnchor::AppendListElement( const DBID & propSpec, LPWSTR pwszName ) { BOOL fSuccess = FALSE; XPtr pListElem( new CDbProjectListElement( ) ); if ( 0 == pListElem.GetPointer() ) return FALSE; if ( !pListElem->SetName(pwszName) ) return FALSE; XPtr pColumn( new CDbColumnNode( propSpec, TRUE ) ); if ( 0 == pColumn.GetPointer() || !pColumn->IsValid() ) return FALSE; if ( pListElem->SetColumn( pColumn.GetPointer() ) ) pColumn.Acquire(); else return FALSE; AppendChild( pListElem.GetPointer() ); pListElem.Acquire(); return TRUE; } //+--------------------------------------------------------------------------- // // Method: CDbProjectNode::_FindOrAddAnchor, private // // Synopsis: Return the project list anchor node. Add one if there // isn't one. // // Returns: CDbProjectListAnchor* - pointer to the anchor node, or NULL // if there was an allocation failure. // // History: 6-15-95 srikants Created // // Notes: // //---------------------------------------------------------------------------- CDbProjectListAnchor * CDbProjectNode::_FindOrAddAnchor() { CDbCmdTreeNode * pChild = GetFirstChild(); while ( 0 != pChild ) { if (pChild->IsListAnchor()) { Win4Assert( DBOP_project_list_anchor == pChild->GetCommandType() ); return (CDbProjectListAnchor *)pChild; } pChild = pChild->GetNextSibling(); } CDbProjectListAnchor * pAnchor = new CDbProjectListAnchor(); if ( 0 != pAnchor ) { AppendChild( pAnchor ); } return pAnchor; } //+--------------------------------------------------------------------------- // // Method: CDbSortNode::_FindOrAddAnchor, private // // Synopsis: Return the sort list anchor node. Add one if there // isn't one. // // Returns: CDbSortListAnchor* - pointer to the anchor node, or NULL // if there was an allocation failure. // // History: 6-15-95 srikants Created // // Notes: We should probably implement this in a base class // with the method taking the list anchor type. // //---------------------------------------------------------------------------- CDbSortListAnchor * CDbSortNode::_FindOrAddAnchor() { CDbCmdTreeNode * pChild = GetFirstChild(); while ( 0 != pChild ) { if (pChild->IsListAnchor()) { Win4Assert( DBOP_sort_list_anchor == pChild->GetCommandType() ); return (CDbSortListAnchor *)pChild; } pChild = pChild->GetNextSibling(); } CDbSortListAnchor * pAnchor = new CDbSortListAnchor(); if ( 0 != pAnchor ) { AppendChild( pAnchor ); } return pAnchor; } //+--------------------------------------------------------------------------- // // Method: CDbSortNode::AddSortColumn, public // // Synopsis: Add a sort column to the sort list. // // Returns: TRUE if successful, FALSE otherwise (allocation failure). // // History: 17 Aug 1995 AlanW Created // // Notes: Sort lists consist of a sort list anchor, with a chain // of sort list elements as children. Each sort list element // has information pertaining to the sort (direction and locale) // and one child which is a column specification. // //---------------------------------------------------------------------------- BOOL CDbSortNode::AddSortColumn(DBID const & propSpec, BOOL fDirection, LCID locale) { CDbSortListAnchor * pAnchor = _FindOrAddAnchor(); XPtr pCol( new CDbColumnNode( propSpec, TRUE ) ); if ( 0 == pCol.GetPointer() || 0 == pAnchor || !pCol->IsValid() ) return FALSE; CDbSortListElement * pSortInfo = new CDbSortListElement( fDirection, locale ); if ( 0 != pSortInfo ) { if ( pSortInfo->IsValid() ) { pSortInfo->AddColumn( pCol.Acquire() ); if ( pAnchor->AppendListElement( pSortInfo ) ) return TRUE; } delete pSortInfo; } return FALSE; } //AddSortColumn //+--------------------------------------------------------------------------- // // Method: CDbNestingNode::AddTable, public // // Synopsis: Add a table node to a nesting. Remove an existing // table node if there is one there. // // Arguments: [pTable] - node to be added to tree. Ownership passes // to the command tree. // // Returns: BOOL - TRUE if operation worked // // History: 08 Aug 1995 AlanW Created // // Notes: Nesting nodes are expected to have 0, 1, 4 or 5 child // nodes depending upon whether AddTable and _FindGroupListAnchor // have been called. // //---------------------------------------------------------------------------- BOOL CDbNestingNode::AddTable( CDbCmdTreeNode * pTable ) { Win4Assert (! pTable->IsListAnchor()); CDbCmdTreeNode * pChild = GetFirstChild(); if ( 0 != pChild && ! pChild->IsListAnchor()) { // Found a table??? Assert on this; we could be nice to the // caller and replace it. Win4Assert ( ! pChild->IsListAnchor() ); return FALSE; } InsertChild( pTable ); return TRUE; } //+--------------------------------------------------------------------------- // // Method: CDbNestingNode::_FindGroupListAnchor, private // // Synopsis: Return the group list anchor node. If there is none, // add it and the parent list node, the child list node and // the grouping column node. // // Returns: CDbProjectListAnchor* - pointer to the anchor node, or NULL // if there was an allocation failure. // // History: 08 Aug 1995 AlanW Created // // Notes: Nesting nodes are expected to have 0, 1, 4 or 5 child // nodes depending upon whether AddTable and _FindGroupListAnchor // have been called. // //---------------------------------------------------------------------------- CDbProjectListAnchor * CDbNestingNode::_FindGroupListAnchor() { CDbCmdTreeNode * pChild = GetFirstChild(); if ( 0 != pChild ) { if (! pChild->IsListAnchor()) { pChild = pChild->GetNextSibling(); } if ( 0 != pChild ) { Win4Assert( DBOP_project_list_anchor == pChild->GetCommandType() ); return (CDbProjectListAnchor *)pChild; } } XPtr pGroupList = new CDbProjectListAnchor(); XPtr pParentList = new CDbProjectListAnchor(); XPtr pChildList = new CDbProjectListAnchor(); XPtr pGroupColumn = new CDbColumnNode( //, PROPID_CHAPTER ); if ( ! pGroupList.IsNull() && ! pParentList.IsNull() && ! pChildList.IsNull() && ! pGroupColumn.IsNull() ) { pGroupList->AppendSibling(pGroupColumn.Acquire()); pGroupList->InsertSibling(pChildList.Acquire()); pGroupList->InsertSibling(pParentList.Acquire()); AppendChild(pGroupList.GetPointer()); return pGroupList.Acquire(); } return 0; }