📄 xoledatabase.cpp
字号:
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 + -