423 lines
12 KiB
C++
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;
|
|
}
|
|
|
|
|