windows-nt/Source/XPSP1/NT/admin/pchealth/helpctr/service/database/queryresultsbuilder.cpp
2020-09-26 16:20:57 +08:00

412 lines
11 KiB
C++

/******************************************************************************
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 = <Entry>)
{ L"BEFORE_TOPIC", -1, false, true }, // (INSERTLOCATION = <URI>)
{ L"AFTER_NODE" , 1, true , false }, // (INSERTLOCATION = <Entry>)
{ L"AFTER_TOPIC" , 1, false, true }, // (INSERTLOCATION = <URI>)
{ 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<CPCHQueryResult> 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);
}