2025-11-28 00:35:46 +09:00

423 lines
12 KiB
C++

//-----------------------------------------------------------------------------
// Microsoft OLE DB RowsetViewer
// Copyright (C) 1994 - 1999 By Microsoft Corporation.
//
// @doc
//
// @module CSESSION.CPP
//
//-----------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////
// Includes
//
/////////////////////////////////////////////////////////////////
#include "Headers.h"
/////////////////////////////////////////////////////////////////
// CSession::CSession
//
/////////////////////////////////////////////////////////////////
CSession::CSession(CMainWindow* pCMainWindow, CMDIChild* pCMDIChild)
: CAsynchBase(eCSession, pCMainWindow, pCMDIChild)
{
//OLE DB Interfaces
m_pIGetDataSource = NULL; //Session interface
m_pIOpenRowset = NULL; //Session interface
m_pISessionProperties = NULL; //Session interface
m_pIDBCreateCommand = NULL; //Session interface
m_pIDBSchemaRowset = NULL; //Session interface
m_pIIndexDefinition = NULL; //Session interface
m_pIAlterIndex = NULL; //Session interface
m_pIAlterTable = NULL; //Session interface
m_pITableDefinition = NULL; //Session interface
m_pITableDefinitionWithConstraints = NULL; //Session interface
m_pITransaction = NULL; //Session interface
m_pITransactionLocal = NULL; //Session interface
m_pITransactionJoin = NULL; //Session interface
m_pITransactionObject = NULL; //Session interface
m_pIBindResource = NULL; //Session interface
m_pICreateRow = NULL; //Session interface
m_cProvTypes = 0; // for native type names
m_rgProvTypes = NULL;
}
/////////////////////////////////////////////////////////////////
// CSession::~CSession
//
/////////////////////////////////////////////////////////////////
CSession::~CSession()
{
ReleaseObject(0);
//Objects
m_listCPropSets.RemoveAll();
}
/////////////////////////////////////////////////////////////////
// IUnknown** CSession::GetInterfaceAddress
//
/////////////////////////////////////////////////////////////////
IUnknown** CSession::GetInterfaceAddress(REFIID riid)
{
HANDLE_GETINTERFACE(IGetDataSource);
HANDLE_GETINTERFACE(IOpenRowset);
HANDLE_GETINTERFACE(ISessionProperties);
HANDLE_GETINTERFACE(IDBCreateCommand);
HANDLE_GETINTERFACE(IDBSchemaRowset);
HANDLE_GETINTERFACE(IIndexDefinition);
HANDLE_GETINTERFACE(IAlterIndex);
HANDLE_GETINTERFACE(IAlterTable);
HANDLE_GETINTERFACE(ITableDefinition);
HANDLE_GETINTERFACE(ITableDefinitionWithConstraints);
HANDLE_GETINTERFACE(ITransaction);
HANDLE_GETINTERFACE(ITransactionLocal);
HANDLE_GETINTERFACE(ITransactionJoin);
HANDLE_GETINTERFACE(ITransactionObject);
HANDLE_GETINTERFACE(IBindResource);
HANDLE_GETINTERFACE(ICreateRow);
//Otherwise delegate
return CAsynchBase::GetInterfaceAddress(riid);
}
/////////////////////////////////////////////////////////////////
// HRESULT CSession::AutoRelease
//
/////////////////////////////////////////////////////////////////
HRESULT CSession::AutoRelease()
{
//Session
RELEASE_INTERFACE(IGetDataSource);
RELEASE_INTERFACE(IOpenRowset);
RELEASE_INTERFACE(ISessionProperties);
RELEASE_INTERFACE(IDBCreateCommand);
RELEASE_INTERFACE(IDBSchemaRowset);
RELEASE_INTERFACE(IIndexDefinition);
RELEASE_INTERFACE(IAlterIndex);
RELEASE_INTERFACE(IAlterTable);
RELEASE_INTERFACE(ITableDefinition);
RELEASE_INTERFACE(ITableDefinitionWithConstraints);
RELEASE_INTERFACE(ITransaction);
RELEASE_INTERFACE(ITransactionLocal);
RELEASE_INTERFACE(ITransactionObject);
RELEASE_INTERFACE(ITransactionJoin);
RELEASE_INTERFACE(IBindResource);
RELEASE_INTERFACE(ICreateRow);
//Delegate
return CAsynchBase::AutoRelease();
}
/////////////////////////////////////////////////////////////////
// HRESULT CSession::AutoQI
//
/////////////////////////////////////////////////////////////////
HRESULT CSession::AutoQI(DWORD dwCreateOpts)
{
//Delegate First so we have base interfaces
CAsynchBase::AutoQI(dwCreateOpts);
//[MANDATORY]
if(dwCreateOpts & CREATE_QI_MANDATORY)
{
OBTAIN_INTERFACE(IOpenRowset);
OBTAIN_INTERFACE(IGetDataSource);
OBTAIN_INTERFACE(ISessionProperties);
}
//AutoQI
if(dwCreateOpts & CREATE_QI_OPTIONAL)
{
//[OPTIONAL]
OBTAIN_INTERFACE(IDBCreateCommand);
OBTAIN_INTERFACE(IDBSchemaRowset);
OBTAIN_INTERFACE(IIndexDefinition);
OBTAIN_INTERFACE(IAlterIndex);
OBTAIN_INTERFACE(IAlterTable);
OBTAIN_INTERFACE(ITableDefinition);
OBTAIN_INTERFACE(ITableDefinitionWithConstraints);
OBTAIN_INTERFACE(ITransaction);
OBTAIN_INTERFACE(ITransactionLocal);
OBTAIN_INTERFACE(ITransactionObject);
OBTAIN_INTERFACE(ITransactionJoin);
OBTAIN_INTERFACE(IBindResource);
OBTAIN_INTERFACE(ICreateRow);
}
return S_OK;
}
/////////////////////////////////////////////////////////////////
// HRESULT CSession::CreateCommand
//
/////////////////////////////////////////////////////////////////
HRESULT CSession::CreateCommand(CAggregate* pCAggregate, REFIID riid, IUnknown** ppIUnknown)
{
HRESULT hr = S_OK;
//Obtain the IDBCreateCommand Interface
IDBCreateCommand* pIDBCreateCommand = SOURCE_GETINTERFACE(this, IDBCreateCommand);
if(pIDBCreateCommand)
{
//CreateCommand
XTEST(hr = pIDBCreateCommand->CreateCommand(pCAggregate, riid, ppIUnknown));
TESTC(TRACE_METHOD(hr, L"IDBCreateCommand::CreateCommand(0x%p, %s, &0x%p)", pCAggregate, GetInterfaceName(riid), ppIUnknown ? *ppIUnknown : NULL));
//Handle Aggregation
if(pCAggregate)
TESTC(hr = pCAggregate->HandleAggregation(riid, ppIUnknown));
}
CLEANUP:
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CSession::GetDataSource
//
/////////////////////////////////////////////////////////////////
HRESULT CSession::GetDataSource(REFIID riid, IUnknown** ppIUnknown)
{
HRESULT hr = S_OK;
//This interface is required to continue...
if(m_pIGetDataSource)
{
//IGetDataSource::GetDataSource
XTEST(hr = m_pIGetDataSource->GetDataSource(riid, ppIUnknown));
TESTC(TRACE_METHOD(hr, L"IGetDataSource::GetDataSource(%s, &0x%p)", GetInterfaceName(riid), ppIUnknown ? *ppIUnknown : NULL));
}
CLEANUP:
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CSession::OpenRowset
//
/////////////////////////////////////////////////////////////////
HRESULT CSession::OpenRowset(CAggregate* pCAggregate, DBID* pTableID, DBID* pIndexID, REFIID riid, ULONG cPropSets, DBPROPSET* rgPropSets, IUnknown** ppIUnknown)
{
HRESULT hr = E_FAIL; // HRESULT
if(!m_pIOpenRowset)
return E_FAIL;
WCHAR wszTableName[MAX_QUERY_LEN+1];
WCHAR wszIndexName[MAX_QUERY_LEN+1];
// From IOpenRowset, get a rowset object
DBIDToString(pTableID, wszTableName, MAX_QUERY_LEN);
DBIDToString(pIndexID, wszIndexName, MAX_QUERY_LEN);
XTEST_(hr = m_pIOpenRowset->OpenRowset(
pCAggregate, // pUnkOuter
pTableID, // pTableID
pIndexID, // pIndexID
riid, // refiid
cPropSets, // cProperties
rgPropSets, // rgProperties
ppIUnknown),S_OK); // IRowset pointer
TRACE_METHOD(hr, L"IOpenRowset::OpenRowset(0x%p, %s, %s, %s, %d, 0x%p, &0x%p)", pCAggregate, wszTableName, wszIndexName, GetInterfaceName(riid), cPropSets, rgPropSets, ppIUnknown ? *ppIUnknown : NULL);
//Display Errors (if occurred)
TESTC(hr = DisplayPropErrors(hr, cPropSets, rgPropSets));
//Handle Aggregation
if(pCAggregate)
TESTC(hr = pCAggregate->HandleAggregation(riid, ppIUnknown));
CLEANUP:
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CSession::GetSchemaRowset
//
/////////////////////////////////////////////////////////////////
HRESULT CSession::GetSchemaRowset(CAggregate* pCAggregate, REFGUID guidSchema, ULONG cRestrictions, VARIANT* rgRestrictions, REFIID riid, ULONG cPropSets, DBPROPSET* rgPropSets, IUnknown** ppIUnknown)
{
HRESULT hr = S_OK;
if(!m_pIDBSchemaRowset)
return E_FAIL;
//Schema Rowset
WCHAR wszBuffer[MAX_NAME_LEN+1];
WCHAR* pwszSchemaName = GetSchemaName(guidSchema);
//Try to find the String Resprentation of the guidSchema
if(pwszSchemaName == NULL)
{
StringFromGUID2(guidSchema, wszBuffer, MAX_NAME_LEN);
pwszSchemaName = wszBuffer;
}
//GetSchema Rowset
XTEST_(hr = m_pIDBSchemaRowset->GetRowset(
pCAggregate, // punkOuter
guidSchema, // schema IID
cRestrictions, // # of restrictions
rgRestrictions, // array of restrictions
riid, // rowset interface
cPropSets, // # of properties
rgPropSets, // properties
ppIUnknown),S_OK); // rowset pointer
TRACE_METHOD(hr, L"IDBSchemaRowset::GetRowset(0x%p, %s, %d, 0x%p, %s, %d, 0x%p, &0x%p)", pCAggregate, pwszSchemaName, cRestrictions, rgRestrictions, GetInterfaceName(riid), cPropSets, rgPropSets, ppIUnknown ? *ppIUnknown : NULL);
//Display Errors (if occurred)
TESTC(hr = DisplayPropErrors(hr, cPropSets, rgPropSets));
//Handle Aggregation
if(pCAggregate)
TESTC(hr = pCAggregate->HandleAggregation(riid, ppIUnknown));
CLEANUP:
return hr;
}
////////////////////////////////////////////////////////////////
// HRESULT CSession::GetProviderTypes
//
////////////////////////////////////////////////////////////////
HRESULT CSession::GetProviderTypes()
{
HRESULT hr = S_OK;
HROW rghRows[MAX_BLOCK_SIZE];
HROW* phRows = rghRows;
DBCOUNTITEM cRowsObtained = 0;
CComPtr<IUnknown> spUnknown;
CRowset cRowset(m_pCMainWindow);
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
//Setup the Bindings
const static DBCOUNTITEM cBindings = 4;
const static DBBINDING rgBindings[cBindings] =
{
1,
offsetof(PROVTYPEINFO, wszTypeName),
0,
0,
NULL,
NULL,
NULL,
DBPART_VALUE,
DBMEMOWNER_CLIENTOWNED,
DBPARAMIO_NOTPARAM,
MAX_NAME_LEN,
0,
DBTYPE_WSTR,
0,
0,
2,
offsetof(PROVTYPEINFO, wType),
0,
0,
NULL,
NULL,
NULL,
DBPART_VALUE,
DBMEMOWNER_CLIENTOWNED,
DBPARAMIO_NOTPARAM,
sizeof(DBTYPE),
0,
DBTYPE_UI2,
0,
0,
3,
offsetof(PROVTYPEINFO, ulColumnSize),
0,
0,
NULL,
NULL,
NULL,
DBPART_VALUE,
DBMEMOWNER_CLIENTOWNED,
DBPARAMIO_NOTPARAM,
sizeof(DBLENGTH), //TODO64: So is this schema going to be updated to allow for more than 4gig size?
0,
DBTYPE_UI4, //TODO64: Sure would be nice to have defined type that toggels for the OS?
0,
0,
15,
offsetof(PROVTYPEINFO, iMaxScale),
0,
0,
NULL,
NULL,
NULL,
DBPART_VALUE,
DBMEMOWNER_CLIENTOWNED,
DBPARAMIO_NOTPARAM,
sizeof(SHORT),
0,
DBTYPE_I2,
0,
0,
};
//IDBSchemaRowset is optional
//Only need to obtain this info once, so if already done, just exit
if(m_pIDBSchemaRowset == NULL || m_cProvTypes != 0)
goto CLEANUP;
//PROVIDER_TYPES Rowset (is required if Schemas are supported)
TESTC(hr = GetSchemaRowset(NULL, DBSCHEMA_PROVIDER_TYPES, 0, NULL, IID_IUnknown, 0, NULL, &spUnknown));
TESTC(hr = cRowset.CreateObject(this, IID_IUnknown, spUnknown));
//IAccessor::CreateAccessor
TESTC(hr = cRowset.CreateAccessor(DBACCESSOR_ROWDATA, cBindings, (DBBINDING*)rgBindings, 0, &hAccessor));
//Loop through the entire returned rowset
while(TRUE)
{
TESTC(hr = cRowset.GetNextRows(0, MAX_BLOCK_SIZE, &cRowsObtained, &phRows));
//ENDOFROWSET
if(cRowsObtained==0)
break;
//Alloc room for ProviderInfo (in chunks)
SAFE_REALLOC(m_rgProvTypes, PROVTYPEINFO, m_cProvTypes + cRowsObtained);
memset(&m_rgProvTypes[m_cProvTypes], 0, sizeof(PROVTYPEINFO) * (size_t)cRowsObtained);
//Loop over rows obtained and get ProviderInfo
for(ULONG i=0; i<cRowsObtained; i++)
{
//Get the Data
TESTC(hr = cRowset.GetData(rghRows[i], hAccessor, (void*)&m_rgProvTypes[m_cProvTypes]));
m_cProvTypes++;
}
//Release all the rows
TESTC(hr = cRowset.ReleaseRows(cRowsObtained, rghRows));
}
CLEANUP:
cRowset.ReleaseAccessor(&hAccessor);
return hr;
}