/****************************************************************************** Copyright (c) 2000 Microsoft Corporation Module Name: QueryResultsBuilder.cpp Abstract: The classes implementated in this file facilitate the generation of the result set from a DB query. Revision History: Davide Massarenti (Dmassare) 12/05/2000 created ******************************************************************************/ #include "stdafx.h" //////////////////////////////////////////////////////////////////////////////// Taxonomy::QueryResultEntry::QueryResultEntry() { m_ID_node = -1; // long m_ID_node; m_ID_topic = -1; // long m_ID_topic; m_ID_parent = -1; // long m_ID_parent; m_ID_owner = -1; // long m_ID_owner; m_lOriginalPos = -1; // long m_lOriginalPos; // // CPCHQueryResult::Payload m_data; } //////////////////////////////////////// bool Taxonomy::QueryResults::Compare::operator()( /*[in]*/ const QueryResultEntry* left, /*[in]*/ const QueryResultEntry* right ) const { return left->m_data.m_lPos < right->m_data.m_lPos; } //////////////////////////////////////// Taxonomy::QueryResults::QueryResults( /*[in]*/ Taxonomy::Updater& updater ) : m_updater( updater ) { // Taxonomy::Updater& m_updater; // ResultVec m_vec; } Taxonomy::QueryResults::~QueryResults() { Clean(); } void Taxonomy::QueryResults::Clean() { MPC::CallDestructorForAll( m_vec ); } HRESULT Taxonomy::QueryResults::AllocateNew( /*[in ]*/ LPCWSTR szCategory , /*[out]*/ QueryResultEntry*& qre ) { __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::AllocateNew" ); HRESULT hr; __MPC_EXIT_IF_ALLOC_FAILS(hr, qre, new QueryResultEntry); qre->m_data.m_bstrCategory = szCategory; m_vec.push_back( qre ); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT Taxonomy::QueryResults::Sort() { Compare cmp; std::sort< ResultIter >( m_vec.begin(), m_vec.end(), cmp ); return S_OK; } //////////////////// HRESULT Taxonomy::QueryResults::Append( /*[in]*/ Taxonomy::RS_Data_Taxonomy* rs , /*[in]*/ LPCWSTR szCategory ) { __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::Append" ); HRESULT hr; QueryResultEntry* qre; __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strDescriptionURI )); __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strIconURI )); __MPC_EXIT_IF_METHOD_FAILS(hr, AllocateNew( szCategory, qre )); qre->m_ID_node = rs->m_ID_node ; qre->m_ID_topic = -1 ; qre->m_ID_parent = rs->m_ID_parent ; qre->m_ID_owner = rs->m_ID_owner ; qre->m_lOriginalPos = rs->m_lPos ; qre->m_data.m_bstrEntry = rs->m_strEntry .c_str(); qre->m_data.m_bstrTitle = rs->m_strTitle .c_str(); qre->m_data.m_bstrTopicURL = rs->m_strDescriptionURI.c_str(); qre->m_data.m_bstrIconURL = rs->m_strIconURI .c_str(); qre->m_data.m_bstrDescription = rs->m_strDescription .c_str(); ////qre->m_data.m_lType qre->m_data.m_lPos = rs->m_lPos ; qre->m_data.m_fVisible = rs->m_fVisible ; qre->m_data.m_fSubsite = rs->m_fSubsite ; qre->m_data.m_lNavModel = rs->m_lNavModel ; hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT Taxonomy::QueryResults::Append( /*[in]*/ Taxonomy::RS_Data_Topics* rs , /*[in]*/ LPCWSTR szCategory ) { __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::Append" ); HRESULT hr; QueryResultEntry* qre; __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strURI )); __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.ExpandURL( rs->m_strIconURI )); __MPC_EXIT_IF_METHOD_FAILS(hr, AllocateNew( szCategory, qre )); qre->m_ID_node = -1 ; qre->m_ID_topic = rs->m_ID_topic ; qre->m_ID_parent = rs->m_ID_node ; qre->m_ID_owner = rs->m_ID_owner ; qre->m_lOriginalPos = rs->m_lPos ; ////qre->m_data.m_bstrEntry qre->m_data.m_bstrTitle = rs->m_strTitle .c_str(); qre->m_data.m_bstrTopicURL = rs->m_strURI .c_str(); qre->m_data.m_bstrIconURL = rs->m_strIconURI .c_str(); qre->m_data.m_bstrDescription = rs->m_strDescription.c_str(); qre->m_data.m_lType = rs->m_lType ; qre->m_data.m_lPos = rs->m_lPos ; qre->m_data.m_fVisible = rs->m_fVisible ; ////qre->m_data.m_fSubsite ////qre->m_data.m_lNavModel hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////// HRESULT Taxonomy::QueryResults::LookupNodes( /*[in]*/ LPCWSTR szCategory , /*[in]*/ long ID_node , /*[in]*/ bool fVisibleOnly ) { __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::LookupNodes" ); HRESULT hr; Taxonomy::RS_Taxonomy* rsTaxonomy; bool fFound; __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTaxonomy( &rsTaxonomy )); __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Seek_Children( ID_node, &fFound )); while(fFound) { if(fVisibleOnly == false || rsTaxonomy->m_fVisible) { __MPC_EXIT_IF_METHOD_FAILS(hr, Append( rsTaxonomy, szCategory )); } __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Move( 0, 1, &fFound )); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT Taxonomy::QueryResults::LookupTopics( /*[in]*/ LPCWSTR szCategory , /*[in]*/ long ID_node , /*[in]*/ bool fVisibleOnly ) { __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::LookupTopics" ); HRESULT hr; Taxonomy::RS_Topics* rsTopics; bool fFound; __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTopics( &rsTopics )); __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Seek_TopicsUnderNode( ID_node, &fFound )); while(fFound) { if(fVisibleOnly == false || rsTopics->m_fVisible) { __MPC_EXIT_IF_METHOD_FAILS(hr, Append( rsTopics, szCategory )); } __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Move( 0, 1, &fFound )); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////// struct InsertionMode { LPCWSTR szMode; int iDir; bool fNodes; bool fTopics; }; static const struct InsertionMode s_lookup[] = { { L"" , 1, false, false }, // Synonym of END { L"TOP" , -1, false, false }, { L"BEFORE_NODE" , -1, true , false }, // (INSERTLOCATION = ) { L"BEFORE_TOPIC", -1, false, true }, // (INSERTLOCATION = ) { L"AFTER_NODE" , 1, true , false }, // (INSERTLOCATION = ) { L"AFTER_TOPIC" , 1, false, true }, // (INSERTLOCATION = ) { L"END" , 1, false, false }, }; HRESULT Taxonomy::QueryResults::MakeRoomForInsert( /*[in ]*/ LPCWSTR szMode , /*[in ]*/ LPCWSTR szID , /*[in ]*/ long ID_node , /*[out]*/ long& lPosRet ) { __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::MakeRoomForInsert" ); HRESULT hr; Taxonomy::RS_Taxonomy* rsTaxonomy; Taxonomy::RS_Topics* rsTopics; ResultIterConst it; const InsertionMode* ptr; long lPos; for(lPos = 0, ptr = s_lookup; lPos < ARRAYSIZE(s_lookup); lPos++, ptr++) { if(!MPC::StrICmp( ptr->szMode, szMode )) break; } if(lPos == ARRAYSIZE(s_lookup)) { __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); } __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTaxonomy( &rsTaxonomy )); __MPC_EXIT_IF_METHOD_FAILS(hr, m_updater.GetTopics ( &rsTopics )); Clean(); __MPC_EXIT_IF_METHOD_FAILS(hr, LookupNodes ( NULL, ID_node, /*fVisibleOnly*/false )); __MPC_EXIT_IF_METHOD_FAILS(hr, LookupTopics( NULL, ID_node, /*fVisibleOnly*/false )); __MPC_EXIT_IF_METHOD_FAILS(hr, Sort()); // // First Pass, reorder the set. // for(lPos = 1, it = m_vec.begin(); it != m_vec.end(); it++) { QueryResultEntry* qre = *it; qre->m_data.m_lPos = lPos++; } // // Second Pass, find the right position. // lPosRet = -1; if(ptr->fNodes || ptr->fTopics) { for(it = m_vec.begin(); it != m_vec.end(); it++) { QueryResultEntry* qre = *it; if((ptr->fNodes && qre->m_ID_node != -1 && !MPC::StrICmp( szID, qre->m_data.m_bstrEntry )) || (ptr->fTopics && qre->m_ID_topic != -1 && !MPC::StrICmp( szID, qre->m_data.m_bstrTopicURL )) ) { lPosRet = (*it)->m_data.m_lPos; if(ptr->iDir > 0) lPosRet++; // Add after the selected element. break; } } } // // Stop not found? Add at the beginning or end. // if(lPosRet == -1) { if(ptr->iDir < 0) { lPosRet = 1; } else { lPosRet = m_vec.size() + 1; } } // // Third Pass, move down the elements after the inserted one and reorganize. // for(it = m_vec.begin(); it != m_vec.end(); it++) { QueryResultEntry* qre = *it; if(qre->m_data.m_lPos >= lPosRet) { qre->m_data.m_lPos++; } if(qre->m_data.m_lPos != qre->m_lOriginalPos) { if(qre->m_ID_node != -1) { __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Seek_Node( qre->m_ID_node )); rsTaxonomy->m_lPos = qre->m_data.m_lPos; __MPC_EXIT_IF_METHOD_FAILS(hr, rsTaxonomy->Update()); } if(qre->m_ID_topic != -1) { __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Seek_SingleTopic( qre->m_ID_topic )); rsTopics->m_lPos = qre->m_data.m_lPos; __MPC_EXIT_IF_METHOD_FAILS(hr, rsTopics->Update()); } qre->m_lOriginalPos = qre->m_data.m_lPos; } } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT Taxonomy::QueryResults::PopulateCollection( /*[in]*/ CPCHQueryResultCollection* pColl ) { __HCP_FUNC_ENTRY( "Taxonomy::QueryResults::PopulateCollection" ); HRESULT hr; __MPC_EXIT_IF_METHOD_FAILS(hr, Sort()); for(ResultIterConst it = m_vec.begin(); it != m_vec.end(); it++) { CComPtr item; QueryResultEntry* qre = *it; __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->CreateItem( &item )); item->Initialize( qre->m_data ); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); }