📄 ctable.cpp
字号:
case DBTYPE_BYTES:
rgBindings[cBindings].cbMaxLen = min(m_rgColumnInfo[i].ulColumnSize, MAX_COL_SIZE);
break;
//Strings are kind of a pain. Although we get the luxury of
//Having the provider coerce the type, we need to allocate a buffer
//large enough for the provider to store the type in string format
case DBTYPE_STR:
case DBTYPE_WSTR:
//Account for TYPE -> String
//(make sure enough room in buffer)
switch(m_rgColumnInfo[i].wType)
{
case DBTYPE_NULL:
case DBTYPE_EMPTY:
//Don't need much room for these...
break;
case DBTYPE_I1:
case DBTYPE_I2:
case DBTYPE_I4:
case DBTYPE_UI1:
case DBTYPE_UI2:
case DBTYPE_UI4:
case DBTYPE_R4:
//All of the above fit well into 15 characters of display size
rgBindings[cBindings].cbMaxLen = 15;
break;
case DBTYPE_I8:
case DBTYPE_UI8:
case DBTYPE_R8:
case DBTYPE_CY:
case DBTYPE_ERROR:
case DBTYPE_BOOL:
//All of the above fit well into 25 characters of display size
rgBindings[cBindings].cbMaxLen = 25;
break;
case DBTYPE_DECIMAL:
case DBTYPE_NUMERIC:
case DBTYPE_DATE:
case DBTYPE_DBDATE:
case DBTYPE_DBTIMESTAMP:
case DBTYPE_GUID:
//All of the above fit well into 50 characters of display size
rgBindings[cBindings].cbMaxLen = 50;//030902
break;
case DBTYPE_BYTES:
//Bytes -> String, 1 byte = 2 Ascii chars. (0xFF == "FF")
rgBindings[cBindings].cbMaxLen = min(m_rgColumnInfo[i].ulColumnSize, MAX_COL_SIZE) * 2;
break;
case DBTYPE_STR:
case DBTYPE_WSTR:
case DBTYPE_BSTR:
//String -> String
//cbMaxLen already contains the length, and below we will
//account for the NULL terminator as well...
rgBindings[cBindings].cbMaxLen = min(m_rgColumnInfo[i].ulColumnSize, MAX_COL_SIZE);
break;
default:
//For everything else, VARIANT, IUNKNOWN, UDT, etc
//Just default to our largest buffer size
rgBindings[cBindings].cbMaxLen = MAX_COL_SIZE;
break;
};
break;
//Currently we only handle binding to STR, WSTR, VARIANT
default:
ASSERT(!"Unhandled Binding Type!");
break;
};
//BLOB or IUnknown Bindings
if(m_rgColumnInfo[i].wType == DBTYPE_IUNKNOWN ||
(m_rgColumnInfo[i].dwFlags & DBCOLUMNFLAGS_ISLONG && (dwRowsetOpts & (ROWSET_BLOB_ISEQSTREAM|ROWSET_BLOB_ILOCKBYTES|ROWSET_BLOB_ISTORAGE|ROWSET_BLOB_ISTREAM))))
{
//For ColumnsRowset
rgBindings[cBindings].cbMaxLen = MAX_COL_SIZE;
rgBindings[cBindings].wType = DBTYPE_IUNKNOWN;
//Create pObject
SAFE_ALLOC(rgBindings[cBindings].pObject, DBOBJECT, 1);
rgBindings[cBindings].pObject->dwFlags = STGM_READ;
rgBindings[cBindings].pObject->iid = IID_ISequentialStream;
//Setup pObject->iid
if(dwRowsetOpts & ROWSET_BLOB_ISTORAGE)
rgBindings[cBindings].pObject->iid = IID_IStorage;
else if(dwRowsetOpts & ROWSET_BLOB_ISTREAM)
rgBindings[cBindings].pObject->iid = IID_IStream;
else if(dwRowsetOpts & ROWSET_BLOB_ILOCKBYTES)
rgBindings[cBindings].pObject->iid = IID_ILockBytes;
else
rgBindings[cBindings].pObject->iid = IID_ISequentialStream;
}
//ulColumnSize - is count of Chars for Strings
if(rgBindings[cBindings].wType == DBTYPE_WSTR)
rgBindings[cBindings].cbMaxLen *= 2;
//Account for the NULL terminator
if(rgBindings[cBindings].wType == DBTYPE_STR)
rgBindings[cBindings].cbMaxLen += sizeof(CHAR);
if(rgBindings[cBindings].wType == DBTYPE_WSTR)//030902
rgBindings[cBindings].cbMaxLen += sizeof(WCHAR);//030902
//MAX_LENGTH
rgBindings[cBindings].cbMaxLen = min(rgBindings[cBindings].cbMaxLen, MAX_COL_SIZE);
dwOffset = rgBindings[cBindings].cbMaxLen + rgBindings[cBindings].obValue;
dwOffset = ROUNDUP( dwOffset );
switch(eBindCols)
{
case BIND_ALLCOLS:
cBindings++;
break;
case BIND_ALLCOLSEXPECTBOOKMARK:
if(rgBindings[cBindings].iOrdinal != 0)
cBindings++;
break;
case BIND_UPDATEABLECOLS:
if(m_rgColumnInfo[i].dwFlags & DBCOLUMNFLAGS_WRITE || m_rgColumnInfo[i].dwFlags & DBCOLUMNFLAGS_WRITEUNKNOWN)
cBindings++;
break;
case BIND_BOOKMARKONLY:
rgBindings[cBindings].iOrdinal = 0;
cBindings++;
i = m_cColumns;
break;
default:
ASSERT(!"Unhandled Type!");
break;
}
}
//Size for pData
if(pcRowSize)
*pcRowSize = dwOffset;
CLEANUP:
//Accessors
if(pcBindings)
*pcBindings = cBindings;
if(prgBindings)
*prgBindings = rgBindings;
else
SAFE_FREE(rgBindings);
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CRowset::CreateAccessor
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::CreateAccessor(DBACCESSORFLAGS dwAccessorFlags, ULONG cBindings, DBBINDING* rgBindings, ULONG cRowSize, HACCESSOR* phAccessor)
{
ASSERT(phAccessor);
ASSERT(m_pIAccessor);
HRESULT hr = S_OK;
HWND hWnd = m_pCMDIChild->m_hWnd;
CListBox* pCListBox = m_pCMDIChild->m_pCListBox;
DBBINDSTATUS* rgStatus = NULL;
//Alloc the space to hold the status
SAFE_ALLOC(rgStatus, DBBINDSTATUS, cBindings);
//Create the accessor
*phAccessor = NULL;
TESTC(pCListBox->OutputPreMethod("IAccessor::CreateAccessor(%d, %d, 0x%08x, %d, &0x%08x, 0x%08x)", dwAccessorFlags, cBindings, rgBindings, cRowSize, *phAccessor, rgStatus));
XTEST(hWnd, hr = m_pIAccessor->CreateAccessor(dwAccessorFlags, cBindings, rgBindings, cRowSize, phAccessor, rgStatus));
if(hr == DB_S_ERRORSOCCURRED || hr == DB_E_ERRORSOCCURRED)
DisplayAccessorErrors(NULL, cBindings, rgBindings, rgStatus);
TESTC(pCListBox->OutputPostMethod(hr, "IAccessor::CreateAccessor(%d, %d, 0x%08x, %d, &0x%08x, 0x%08x)", dwAccessorFlags, cBindings, rgBindings, cRowSize, *phAccessor, rgStatus));
CLEANUP:
SAFE_FREE(rgStatus);
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CRowset::ReleaseAccessor
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::ReleaseAccessor(HACCESSOR* phAccessor)
{
ASSERT(phAccessor);
HRESULT hr = S_OK;
HWND hWnd = m_pCMDIChild->m_hWnd;
CListBox* pCListBox = m_pCMDIChild->m_pCListBox;
ULONG ulRefCount = 0;
if(m_pIAccessor && *phAccessor)
{
TESTC(hr = pCListBox->OutputPreMethod("IAccessor::ReleaseAccessor(0x%08x, &%d)", *phAccessor, ulRefCount));
XTEST(hWnd, hr = m_pIAccessor->ReleaseAccessor(*phAccessor, &ulRefCount));
TESTC(hr = pCListBox->OutputPostMethod(hr, "IAccessor::ReleaseAccessor(0x%08x, &%d)", *phAccessor, ulRefCount));
}
CLEANUP:
//Only NULL the handle if the RefCount is 0
if(ulRefCount == 0)
*phAccessor = NULL;
return hr;
}
/////////////////////////////////////////////////////////////////
// HRESULT CRowset::CreateRowset
//
/////////////////////////////////////////////////////////////////
HRESULT CRowset::CreateRowset(ROWSETSOURCE eRowsetSource, ULONG cPropSets, DBPROPSET* rgPropSets, LONG* pcRowsAffected, DBID* pTableID, DBID* pIndexID, REFIID riid, const GUID* pGuidSchema, ULONG cRestrictions, VARIANT* rgRestrictions)
{
HRESULT hr = S_OK; // HRESULT
HRESULT hrOptional = S_OK; // HRESULT
ULONG cOptColumns = 0;
DBID* rgOptColumns = NULL;
IUnknown* pIUnknown = NULL;
IMultipleResults* pIMultipleResults = NULL;
ULONG ulValue = 0;
BOOL bValue = FALSE;
HWND hWnd = m_pCMDIChild->m_hWnd;
CListBox* pCListBox = m_pCMDIChild->m_pCListBox;
COptionsDlg* pCOptionsDlg = GetOptionsObj();
if(pcRowsAffected)
*pcRowsAffected = DB_COUNTUNAVAILABLE;
//Schema Rowset
if(eRowsetSource == ROWSET_FROMSCHEMA)
{
WCHAR wszBuffer[MAX_NAME_LEN+1];
CHAR szBuffer[MAX_NAME_LEN+1];
GUID guidSchema = pGuidSchema ? *pGuidSchema : GUID_NULL;
CHAR* pszSchemaName = GetSchemaName(guidSchema);
//Try to find the String Resprentation of the guidSchema
if(pszSchemaName == NULL)
{
StringFromGUID2(guidSchema, wszBuffer, MAX_NAME_LEN);
ConvertToMBCS(wszBuffer, szBuffer, MAX_NAME_LEN);
pszSchemaName = szBuffer;
}
//GetSchema Rowset
ASSERT(m_pCSession->m_pIDBSchemaRowset);
TESTC(pCListBox->OutputPreMethod("IDBSchemaRowset::GetRowset(NULL, %s, %d, 0x%08x, %s, %d, 0x%08x, &0x%08x)", pszSchemaName, cRestrictions, rgRestrictions, GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
XTEST_(hWnd, hr = m_pCSession->m_pIDBSchemaRowset->GetRowset(
NULL, // punkOuter
guidSchema, // schema IID
cRestrictions, // # of restrictions
rgRestrictions, // array of restrictions
riid, // rowset interface
cPropSets, // # of properties
rgPropSets, // properties
&pIUnknown),S_OK); // rowset pointer
TESTC(pCListBox->OutputPostMethod(hr, "IDBSchemaRowset::GetRowset(NULL, %s, %d, 0x%08x, %s, %d, 0x%08x, &0x%08x)", pszSchemaName, cRestrictions, rgRestrictions, GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
}
//Rowset from ColumnsRowset
else if(eRowsetSource == ROWSET_FROMCOMMANDCOLUMNSROWSET || eRowsetSource == ROWSET_FROMROWSETCOLUMNSROWSET)
{
//Which ColumnsRowset interface, Command or Rowset?
IColumnsRowset* pIColumnsRowset = (eRowsetSource == ROWSET_FROMCOMMANDCOLUMNSROWSET ? m_pCCommand->m_pIColumnsRowset : m_pIColumnsRowset);
ASSERT(pIColumnsRowset);
//GetAvailableColumns
//We just use cRestrictions passed in as the flag
//to indicate weither to use Optional Columns
if(cRestrictions)
{
TESTC(pCListBox->OutputPreMethod("IColumnsRowset::GetAvailableColumns(&%d, &0x%08x)", cOptColumns, rgOptColumns));
XTEST(hWnd, hr = pIColumnsRowset->GetAvailableColumns(&cOptColumns, &rgOptColumns));
TESTC(pCListBox->OutputPostMethod(hr, "IColumnsRowset::GetAvailableColumns(&%d, &0x%08x)", cOptColumns, rgOptColumns));
}
//GetColumnsRowset
TESTC(pCListBox->OutputPreMethod("IColumnsRowset::GetColumnsRowset(NULL, %d, 0x%08x, %s, %d, 0x%08x, &0x%08x)", cOptColumns, rgOptColumns, GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
XTEST_(hWnd, hr = pIColumnsRowset->GetColumnsRowset(
NULL, // punkOuter
cOptColumns, // cOptionalColumns
rgOptColumns, // rgOptionalColumns
riid, // rowset interface
cPropSets, // # of properties
rgPropSets, // properties
&pIUnknown),S_OK); // rowset pointer
TESTC(pCListBox->OutputPostMethod(hr, "IColumnsRowset::GetColumnsRowset(NULL, %d, 0x%08x, %s, %d, 0x%08x, &0x%08x)", cOptColumns, rgOptColumns, GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
}
//Rowset from Enumerator
else if(eRowsetSource == ROWSET_FROMENUM)
{
//GetSourcesRowset
ASSERT(m_pCDataSource->m_pISourcesRowset);
TESTC(pCListBox->OutputPreMethod("ISourcesRowset::GetSourcesRowset(NULL, %s, %d, 0x%08x, &0x%08x)", GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
XTEST_(hWnd, hr = m_pCDataSource->m_pISourcesRowset->GetSourcesRowset(
NULL, // punkOuter
riid, // rowset interface
cPropSets, // # of properties
rgPropSets, // properties
&pIUnknown),S_OK); // rowset pointer
TESTC(pCListBox->OutputPostMethod(hr, "ISourcesRowset::GetSourcesRowset(NULL, %s, %d, 0x%08x, &0x%08x)", GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
}
//Rowset from Command
else if(eRowsetSource == ROWSET_FROMCOMMAND || eRowsetSource == ROWSET_FROMCOMMANDWITHPARAMETERS)
{
DBPARAMS* pDispParams = NULL;
if(eRowsetSource == ROWSET_FROMCOMMANDWITHPARAMETERS)
pDispParams = &m_pCCommand->m_ParamInfo;
//Clear previous rowset (if requested)
if(pCOptionsDlg->m_dwCommandOpts & COMMAND_RELEASEROWSET)
ReleaseRowset();
//SetCommandText (unless requested not to...)
if(!(pCOptionsDlg->m_dwCommandOpts & COMMAND_NOCOMMANDTEXT))
{
ASSERT(pTableID);
TESTC(hr = m_pCCommand->SetCommandText(pTableID->uName.pwszName));
}
//Execute
TESTC(pCListBox->OutputPreMethod("ICommand::Execute(NULL, %s, NULL, &%d, &0x%08x)", GetInterfaceName(riid), pcRowsAffected ? *pcRowsAffected : 0, pIUnknown));
XTEST_(hWnd, hr = m_pCCommand->m_pICommand->Execute(
NULL, // pUnkOuter
riid, // refiid
pDispParams, // disp parms
pcRowsAffected, // rows affected
&pIUnknown),S_OK); // IRowset pointer
TESTC(pCListBox->OutputPostMethod(hr, "ICommand::Execute(NULL, %s, NULL, &%d, &0x%08x)", GetInterfaceName(riid), pcRowsAffected ? *pcRowsAffected : 0, pIUnknown));
}
//IOpenRowset
else if(eRowsetSource == ROWSET_FROMOPENROWSET)
{
ASSERT(m_pCSession->m_pIOpenRowset);
WCHAR wszTableName[MAX_NAME_LEN+1];
WCHAR wszIndexName[MAX_NAME_LEN+1];
// From IOpenRowset, get a rowset object
DBIDToString(pTableID, wszTableName, MAX_NAME_LEN);
DBIDToString(pIndexID, wszIndexName, MAX_NAME_LEN);
TESTC(pCListBox->OutputPreMethod("IOpenRowset::OpenRowset(NULL, %S, %S, %s, %d, 0x%08x, &0x%08x)", wszTableName, wszIndexName, GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
XTEST_(hWnd, hr = m_pCSession->m_pIOpenRowset->OpenRowset(
NULL, // pUnkOuter
pTableID, // pTableID
pIndexID, // pIndexID
riid, // refiid
cPropSets, // cProperties
rgPropSets, // rgProperties
&pIUnknown),S_OK); // IRowset pointer
TESTC(pCListBox->OutputPostMethod(hr, "IOpenRowset::OpenRowset(NULL, %S, %S, %s, %d, 0x%08x, &0x%08x)", wszTableName, wszIndexName, GetInterfaceName(riid), cPropSets, rgPropSets, pIUnknown));
}
// Override the IRowset interface ptr with IMDDataset
else if(eRowsetSource == ROWSET_FROMCOMMANDDATASET)
{
// Clear previous rowset
ReleaseRowset();
m_pCDataset->RestartPosition();
TESTC(hr = m_pCDataset->GetIMDDataset(riid, &pIUnknown));
}
// Use the axis rowset to obtain IRowset interface ptr
else if (eRowsetSource == ROWSET_FROMAXISDATASET)
{
// Clear previous rowset
ReleaseRowset();
XTESTC(hWnd, hr = m_pCDataset->GetAxisRowset(riid, &pIUnknown));
}
else
{
ASSERT(!"Unhandled Source");
hr = E_FAIL;
goto CLEANUP;
}
//Special Handling for IMultipleResults
if(pIUnknown && (riid == IID_IMultipleResults || SUCCEEDED(pCListBox->OutputQI(pIUnknown, IID_IMultipleResults, (IUnknown**)&pIMultipleResults))))
{
//Obtain IMultipleResults
TESTC(hr = m_pCMultipleResults->CreateObject(pIUnknown));
pCListBox->OutputRelease(&pIUnknown);
//Get the First Rowset...
TESTC(hr = m_pCMultipleResults->GetResult(IID_IUnknown, pcRowsAffected, &pIUnknown));
}
//Display Errors (if occurred)
if(hr == DB_S_ERRORSOCCURRED || hr == DB_E_ERRORSOCCURRED)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -