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

📄 xoledatabase.cpp

📁 通过oledb
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	TStrToWStr(lpQuery, lpBuffer, 4096);
	hr = dbCmdText->SetCommandText(DBGUID_DBSQL, lpBuffer);
	if(hr != S_OK)  return hr;

	// Execute command
	hr = dbCommand->Execute( NULL, IID_IRowset, 
				NULL, NULL, (IUnknown **) &dbRowset );
	if(hr != S_OK)  return hr;

	// Whether is existing
	hr = dbRowset->RestartPosition(NULL);
	if(hr != S_OK)  return hr;

	// Now determind 
	DWORD  dwCount;
	HROW   hTempRow, * lpRow = &hTempRow;
	hr = dbRowset->GetNextRows(NULL, 0, 1, &dwCount, &lpRow);
	if(hr != S_OK)  return hr;

	// Release row and return
	dbRowset->ReleaseRows(1, lpRow, NULL, NULL, NULL);
	if(dwCount == 1)   return S_OK;	
	return S_FALSE;
}

HRESULT XOleDatabase::StartTransaction()
{
	// 获取事务接口
	HRESULT  hr = m_lpCommand->QueryInterface(
		 IID_ITransactionLocal, (void **) &m_lpTrans);
	if(hr != S_OK)  return hr;

	// 启动当前事务
	hr = ((ITransactionLocal *)m_lpTrans)->StartTransaction(
			ISOLATIONLEVEL_READCOMMITTED, 0, NULL, NULL);

	// 如果事务启动失败
	if(hr != S_OK)
	{
		m_lpTrans->Release();
		m_lpTrans = NULL;
	}

	// 事务启动成功
	return S_OK;
}

HRESULT XOleDatabase::AbortTransaction()
{
	if(m_lpTrans == NULL)
		return E_NOINTERFACE;

	// 取消事务,释放接口
	HRESULT  hr = m_lpTrans->Abort(NULL, 0, 0);
	m_lpTrans->Release();  m_lpTrans = NULL;
	return  hr;
}

HRESULT XOleDatabase::CommitTransaction()
{
	if(m_lpTrans == NULL)
		return E_NOINTERFACE;

	// 取消事务,释放接口
	HRESULT  hr = m_lpTrans->Commit(0, XACTTC_SYNC, 0);
	m_lpTrans->Release();  m_lpTrans = NULL;
	return  hr;
}

HRESULT XOleDatabase::GetSchemaRowset(
			LPCTSTR strType, XOleRowset * lpRowset)
{
	HRESULT    hr;
	WCHAR      lpBuffer[256];
	VARIANT    lpRestrict[4];

	IRowset  * pIRowset;
	XComPtr<IOpenRowset>  dbOpenSet;
	XComPtr<IDBSchemaRowset>  dbSchema;

	// Release rowset
	lpRowset->CloseRowset();

	// Create IOpenRowset interface
	hr = m_lpSession->CreateSession( NULL, 
		  IID_IOpenRowset, (IUnknown **) &dbOpenSet );
	if(hr != S_OK)   return hr;

	// Create ISchemaRowset interface
	hr = dbOpenSet.QueryInterface(IID_IDBSchemaRowset, &dbSchema);
	if(hr != S_OK)   return hr;

	// Search schema rowset
	VariantInit(lpRestrict);
	VariantInit(lpRestrict + 1);
	VariantInit(lpRestrict + 2);

	lpRestrict[3].vt = VT_BSTR;
	TStrToWStr(strType, lpBuffer, 256);
	lpRestrict[3].bstrVal = SysAllocString(lpBuffer);

	hr = dbSchema->GetRowset( NULL, DBSCHEMA_TABLES, 
							4, lpRestrict, IID_IRowset, 0, 
							NULL, (IUnknown **) &pIRowset );
	if(hr != S_OK)  return hr;

	hr = lpRowset->Attach(pIRowset);
	pIRowset->Release();
	return hr;
}

// 获取表的字段信息
int  XOleDatabase::GetTableColumnInfo(LPCTSTR strTable, XColumnInfo * lpDesc)
{
	HRESULT    hr;
	DBPROP     lpProp[4];
	DBPROPSET  dbPropSet;
	WCHAR      lpBuffer[256];
	
	IRowset   * pIRowset;
	XComPtr<IOpenRowset>  dbOpenSet;

	// Create open rowset
	hr = m_lpSession->CreateSession( NULL, 
		IID_IOpenRowset, (IUnknown **) &dbOpenSet );
	if(hr != S_OK)   return -1;

	// Can scroll back
	lpProp[0].colid = DB_NULLID;
	lpProp[0].vValue.vt = VT_BOOL;
	lpProp[0].vValue.boolVal = VARIANT_TRUE;
	lpProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
	lpProp[0].dwPropertyID = DBPROP_CANSCROLLBACKWARDS;

	dbPropSet.cProperties = 1;
	dbPropSet.rgProperties = lpProp;
	dbPropSet.guidPropertySet = DBPROPSET_ROWSET;

	// Table name
	TStrToWStr(strTable, lpBuffer, 256);

	// Open the rowset
	DBID  xmTable;
	xmTable.eKind = DBKIND_NAME;
	xmTable.uName.pwszName = lpBuffer;
	hr = dbOpenSet->OpenRowset( NULL, &xmTable, NULL, 
						  IID_IRowset, 1, &dbPropSet, 
						  (IUnknown **) &pIRowset  );
	if(hr != S_OK)   return -1;

	// 开始获取字段信息
	LPOLESTR  lpOleStr;
	DBCOLUMNINFO  * lpInfo;

	DWORD  i, dwColumn, dwSize;
	XComPtr<IColumnsInfo>  dbColumn;

	// Get Column infomation
	hr = pIRowset->QueryInterface(
		IID_IColumnsInfo, (void **) &dbColumn);
	if(hr != S_OK)  return -1;

	hr = dbColumn->GetColumnInfo(
		&dwColumn, &lpInfo, &lpOleStr);
	if(hr != S_OK)  return -1;

	for(i = 0; i < dwColumn; i ++)
	{
		// Column Name
		if(lpInfo[i].pwszName == NULL)
			lpDesc[i].lpName[0] = 0x00;
		else 
			WStrToTStr( lpInfo[i].pwszName, 
				lpDesc[i].lpName, 20 );

		// ColumnInfo Size
		lpDesc[i].wdType = lpInfo[i].wType;
		lpDesc[i].wdPrec = lpInfo[i].bScale;
		lpDesc[i].dwProp = lpInfo[i].dwFlags;
		lpDesc[i].dwSize = lpInfo[i].ulColumnSize;

		// String Null Space
		if(lpInfo[i].wType == DBTYPE_WSTR)
		{
			dwSize = lpInfo[i].ulColumnSize;
			lpDesc[i].dwSize += dwSize;
		}
	}

	CoTaskMemFree(lpOleStr);
	CoTaskMemFree(lpDesc);
	return  dwColumn;
}

// 单独打开一个表
HRESULT XOleDatabase::OpenRowset(
						 LPCTSTR      strTable, 
						 XOleRowset * lpRowset, 
						 BOOL       bCanModify, // FALSE
						 void    * lpRowBuffer, // NULL
						 long     nColumnCount, // 0
						 const WORD   * lpType, // NULL
						 const int    * lpSize  // NULL
					   )
{
	HRESULT    hr;
	DWORD      nCount;
	DBPROP     lpProp[4];
	DBPROPSET  dbPropSet;
	WCHAR      lpBuffer[256];
	
	IRowset   * pIRowset;
	XComPtr<IOpenRowset>  dbOpenSet;

	// Release rowset
	lpRowset->CloseRowset();

	// Create open rowset
	hr = m_lpSession->CreateSession( NULL, 
		IID_IOpenRowset, (IUnknown **) &dbOpenSet );
	if(hr != S_OK)   return hr;

	// Can scroll back
	lpProp[0].colid = DB_NULLID;
	lpProp[0].vValue.vt = VT_BOOL;
	lpProp[0].vValue.boolVal = VARIANT_TRUE;
	lpProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
	lpProp[0].dwPropertyID = DBPROP_CANSCROLLBACKWARDS;

	// If can be modified
	nCount = 1;
	if( bCanModify )
	{
		nCount = 3;

		// Change information
		lpProp[1].colid = DB_NULLID;
		lpProp[1].vValue.vt = VT_BOOL;
		lpProp[1].vValue.boolVal = VARIANT_TRUE;
		lpProp[1].dwOptions = DBPROPOPTIONS_REQUIRED;
		lpProp[1].dwPropertyID = DBPROP_IRowsetChange;

		// Update information
		lpProp[2].colid = DB_NULLID;
		lpProp[2].vValue.vt = VT_I4;
		lpProp[2].vValue.lVal = DBPROPVAL_UP_INSERT | 
								DBPROPVAL_UP_CHANGE | 
								DBPROPVAL_UP_DELETE; 
		lpProp[2].dwOptions = DBPROPOPTIONS_REQUIRED;
		lpProp[2].dwPropertyID = DBPROP_UPDATABILITY;
	}

	dbPropSet.cProperties = nCount;
	dbPropSet.rgProperties = lpProp;
	dbPropSet.guidPropertySet = DBPROPSET_ROWSET;

	// Table name
	TStrToWStr(strTable, lpBuffer, 256);

	// Open the rowset
	DBID  xmTable;
	xmTable.eKind = DBKIND_NAME;
	xmTable.uName.pwszName = lpBuffer;
	hr = dbOpenSet->OpenRowset( NULL, &xmTable, NULL, 
						  IID_IRowset, 1, &dbPropSet, 
						  (IUnknown **) &pIRowset  );
	if(hr != S_OK)   return hr;

	// Create rowset
	if(lpRowBuffer == NULL)
	{
		hr = lpRowset->Attach(pIRowset);
		pIRowset->Release();
	}
	else 
	{
		hr = lpRowset->Attach(pIRowset, lpRowBuffer, 
				 nColumnCount, lpType, lpSize);
		pIRowset->Release();
	}

	// 如果能够修改
	if(hr == S_OK && bCanModify)
		hr = lpRowset->InitializeChange();

	return hr;
}

// 查询数据库记录
HRESULT XOleDatabase::QueryRowset( 
						 LPCTSTR      strQuery, 
						 XOleRowset * lpRowset, 
						 BOOL       bCanModify, // FALSE
						 void    * lpRowBuffer, // NULL
						 long     nColumnCount, // 0
						 const WORD   * lpType, // NULL
						 const int    * lpSize  // NULL
					   )
{
	HRESULT    hr;
	DWORD      nCount;
	DBPROP     lpProp[4];
	DBPROPSET  dbPropSet;
	WCHAR      lpBuffer[4096];

	IRowset   * pIRowset;
	XComPtr<ICommand>  dbCommand;
	XComPtr<ICommandText>  dbCmdText;
	XComPtr<ICommandProperties>  dbCmdPropt;

	// Release rowset
	lpRowset->CloseRowset();

	// Create command
	hr = m_lpCommand->CreateCommand( NULL, 
		  IID_ICommand, (IUnknown **) &dbCommand );
	if(hr != S_OK)   return hr;

	// Set Rowset property
	hr = dbCommand.QueryInterface( 
			IID_ICommandProperties, &dbCmdPropt );
	if(hr != S_OK)   return hr;

	// Can scroll back
	lpProp[0].colid = DB_NULLID;
	lpProp[0].vValue.vt = VT_BOOL;
	lpProp[0].dwStatus = DBPROPSTATUS_OK;
	lpProp[0].vValue.boolVal = VARIANT_TRUE;
	lpProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
	lpProp[0].dwPropertyID = DBPROP_CANSCROLLBACKWARDS;

	// If can be modified
	nCount = 1;
	if( bCanModify )
	{
		nCount = 3;

		// Change information
		lpProp[1].colid = DB_NULLID;
		lpProp[1].vValue.vt = VT_BOOL;
		lpProp[1].dwStatus = DBPROPSTATUS_OK;
		lpProp[1].vValue.boolVal = VARIANT_TRUE;
		lpProp[1].dwOptions = DBPROPOPTIONS_REQUIRED;
		lpProp[1].dwPropertyID = DBPROP_IRowsetChange;

		// Update information
		lpProp[2].colid = DB_NULLID;
		lpProp[2].vValue.vt = VT_I4;
		lpProp[2].dwStatus = DBPROPSTATUS_OK;
		lpProp[2].vValue.lVal = DBPROPVAL_UP_INSERT | 
								DBPROPVAL_UP_CHANGE | 
								DBPROPVAL_UP_DELETE; 
		lpProp[2].dwOptions = DBPROPOPTIONS_REQUIRED;
		lpProp[2].dwPropertyID = DBPROP_UPDATABILITY;
	}

	dbPropSet.cProperties = nCount;
	dbPropSet.rgProperties = lpProp;
	dbPropSet.guidPropertySet = DBPROPSET_ROWSET;

	// Set properties
	hr = dbCmdPropt->SetProperties(1, &dbPropSet);
	if(hr != S_OK)   return hr;

	// Create command text
	hr = dbCommand.QueryInterface(IID_ICommandText, &dbCmdText);
	if(hr != S_OK)   return hr;

	TStrToWStr(strQuery, lpBuffer, 4096);
	hr = dbCmdText->SetCommandText(DBGUID_DBSQL, lpBuffer);
	if(hr != S_OK)   return hr;

	// Execute command
	hr = dbCommand->Execute( NULL, IID_IRowset, 
			NULL, NULL, (IUnknown **) &pIRowset );
	if(hr != S_OK)   return hr;

	// Create rowset
	if(lpRowBuffer == NULL)
	{
		hr = lpRowset->Attach(pIRowset);
		pIRowset->Release();
	}
	else 
	{
		hr = lpRowset->Attach(pIRowset, lpRowBuffer, 
				 nColumnCount, lpType, lpSize);
		pIRowset->Release();
	}

	// 如果能够修改
	if(hr == S_OK && bCanModify)
		hr = lpRowset->InitializeChange();

	return hr;
}


/*******************************************/
/* * * *        XOleRowset对象       * * * */
/*******************************************/

XOleRowset::XOleRowset()
{
	// 字段的总个数
	m_nColumnCount = 0;

	// 记录数据缓冲区
	m_dwBuffer = 0;
	m_lpBuffer = NULL;
	m_lpMalloc = NULL;

	// 当前记录的信息
	m_hCurrent = NULL;
	m_hAccessor = NULL;

	// 记录集基本信息
	m_lpRowset = NULL;
	m_lpChange = NULL;
}

XOleRowset::~XOleRowset()
{
	// 退出前释放
	CloseRowset();
}

void XOleRowset::CloseRowset()
{
	// 释放当前的记录
	ReleaseCurrent();

	// 以词释放所有对象
	if(m_lpChange != NULL)
	{
		m_lpChange->Release();
		m_lpChange = NULL;
	}

	if(m_lpRowset != NULL)
	{
		m_lpRowset->Release();
		m_lpRowset = NULL;
	}

	if(m_lpMalloc != NULL)
	{
		delete m_lpMalloc;
		m_lpMalloc = NULL;
	}

	// 字段的总个数
	m_nColumnCount = 0;

	// 记录数据缓冲区
	m_dwBuffer = 0;
	m_lpBuffer = NULL;

	// 当前记录的信息
	m_hCurrent = NULL;
	m_hAccessor = NULL;
}

// 载入当前数据
HRESULT XOleRowset::LoadData(void * lpNewBuffer)
{
	if(m_lpRowset == NULL || m_hCurrent == NULL)
		return E_NOINTERFACE;

	// 释放当前的缓冲区
	if(lpNewBuffer != NULL)
	{
		if(m_lpMalloc != NULL)
		{
			delete m_lpMalloc;
			m_lpMalloc = NULL;
		}

		m_lpBuffer = (LPBYTE)lpNewBuffer;
		m_dwBuffer = 0x00000000;
	}

	// 直接读取记录数据
	ZeroDataBuffer();
	HRESULT  hr = m_lpRowset->GetData( 
		m_hCurrent, m_hAccessor, m_lpBuffer);
	if(hr == S_OK)  HandleDataBuffer();
	return hr;
}

// 载入当前记录
HRESULT XOleRowset::LoadCurrent()
{
	HRESULT  hr = S_OK;
	DWORD    dwRowCount = 0;

	if(m_lpRowset == NULL)
		return E_NOINTERFACE;

	if(m_hCurrent == NULL)
	{
		// 获取当前记录句柄
		HROW  * lpCurrent = &m_hCurrent;
		hr = m_lpRowset->GetNextRows(NULL, 
				-1, 1, &dwRowCount, &lpCurrent);
		if(hr != S_OK)  return hr;

		// 读取当前记录的值
		ZeroDataBuffer();
		hr = m_lpRowset->GetData(m_hCurrent, 
			   m_hAccessor, m_lpBuffer);
		if(hr == S_OK)  HandleDataBuffer();
	}

	return  hr;
}

HRESULT XOleRowset::ReleaseCurrent()
{
	HRESULT  hr = S_OK;

	if(m_hCurrent != NULL)
	{
		hr = m_lpRowset->ReleaseRows( 1, 
			  &m_hCurrent, NULL, NULL, NULL);
		m_hCurrent = NULL;
	}

	return hr;
}

BOOL XOleRowset::IsRowExist()
{
	if(m_hCurrent == NULL)
		return FALSE;
	return TRUE;
}

int  XOleRowset::GetRowCount()
{
	int    nCount = 0;
	HRESULT  hr = MoveFirst(FALSE);
	while(hr == S_OK)
	{
		nCount ++;
		hr = MoveNext(FALSE);
	}

	return  nCount;
}

// 装载数据前,清空数据
void XOleRowset::ZeroDataBuffer()
{
	DWORD  nIdx = 0;

	for(int i = 0; i < m_nColumnCount; i ++)
	{
		nIdx = m_lpColumnInfo[i].dwOffset;

		switch( m_lpColumnInfo[i].wdType )
		{
		case DBTYPE_STR: 
			m_lpBuffer[nIdx] = 0x00;
			break;
		case DBTYPE_WSTR: 
		case DBTYPE_BSTR: 
			m_lpBuffer[nIdx] = 0x00;
			m_lpBuffer[nIdx + 1] = 0x00;
			break;
		}
	}
}

// 装载数据后,进行处理预处理
void XOleRowset::HandleDataBuffer()
{
	DWORD  nIdx = 0;

	for(int i = 0; i < m_nColumnCount; i ++)
	{
		nIdx = m_lpColumnInfo[i].dwOffset;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -