⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctable.cpp

📁 用测试OLE DB提供者的一个程序。能够测试出OEL DB提供者到底实现了哪些接口?很灵的。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			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 + -