📄 xoledatabase.cpp
字号:
switch( m_lpColumnInfo[i].wdType )
{
case DBTYPE_STR:
XTrimStr( (LPSTR)(m_lpBuffer + nIdx),
m_lpColumnInfo[i].dwSize);
break;
case DBTYPE_WSTR:
case DBTYPE_BSTR:
XTrimWStr( (LPWSTR)(m_lpBuffer + nIdx),
m_lpColumnInfo[i].dwSize);
break;
case DBTYPE_BLOB:
{
XBLOBCOLUMN * lpColumn =
(XBLOBCOLUMN *)(m_lpBuffer + nIdx);
// 记录是否存在
if(lpColumn->lpTemp[1] == DBSTATUS_S_OK)
{
ISequentialStream * lpStream =
(ISequentialStream *)(lpColumn->lpTemp[0]);
DWORD dwRealByte = 0;
lpStream->Read(lpColumn->lpBuffer,
lpColumn->dwMaxSize, &dwRealByte);
lpColumn->dwMaxSize = dwRealByte;
// 释放Stream对象
lpStream->Release();
}
}
break;
case DBTYPE_FILE:
{
XBLOBCOLUMN * lpColumn =
(XBLOBCOLUMN *)(m_lpBuffer + nIdx);
// 记录是否存在
if(lpColumn->lpTemp[1] == DBSTATUS_S_OK)
{
ISequentialStream * lpStream =
(ISequentialStream *)lpColumn;
// 一个缓冲区
HRESULT hr;
char lpBuffer[4096];
DWORD dwByte, dwRealByte;
lpColumn->dwMaxSize = 0;
// 逐个的读出信息
do
{
hr = lpStream->Read(lpBuffer,
4096, &dwRealByte);
WriteFile(lpColumn->hFile, lpBuffer,
dwRealByte, &dwByte, NULL);
lpColumn->dwMaxSize += dwRealByte;
} while(hr >= 0 && dwRealByte >= 4096);
// 释放Stream对象
lpStream->Release();
}
}
break;
}
}
}
HRESULT XOleRowset::InitializeChange()
{
if(m_lpRowset == NULL)
return E_NOINTERFACE;
// Query change interface
if(m_lpChange != NULL)
return S_OK;
return m_lpRowset->QueryInterface(
IID_IRowsetChange, (void **) &m_lpChange);
}
// 关联记录集
HRESULT XOleRowset::Attach(IRowset * lpRowset)
{
HRESULT hr;
LPOLESTR lpOleStr;
DBCOLUMNINFO * lpDesc;
static DBBINDING lpBind[256];
DWORD i, dwCount;
DWORD dwSize, dwOffset = 0;
XComPtr<IAccessor> dbAccessor;
XComPtr<IColumnsInfo> dbColumn;
if(lpRowset == NULL)
return E_POINTER;
// Attach lpRowset
CloseRowset();
lpRowset->AddRef();
m_lpRowset = lpRowset;
// Get Column infomation
hr = m_lpRowset->QueryInterface(
IID_IColumnsInfo, (void **) &dbColumn);
if(hr != S_OK) return hr;
hr = dbColumn->GetColumnInfo(
&dwCount, &lpDesc, &lpOleStr);
if(hr != S_OK) return hr;
dwOffset = 0;
m_nColumnCount = dwCount;
for(i = 0; i < dwCount; i ++)
{
// Column Name
if(lpDesc[i].pwszName == NULL)
m_lpColumnInfo[i].lpName[0] = 0x00;
else
WStrToTStr( lpDesc[i].pwszName,
m_lpColumnInfo[i].lpName, 20 );
// ColumnInfo Size
m_lpColumnInfo[i].dwOffset = dwOffset;
m_lpColumnInfo[i].wdType = lpDesc[i].wType;
m_lpColumnInfo[i].wdPrec = lpDesc[i].bScale;
m_lpColumnInfo[i].dwSize = lpDesc[i].ulColumnSize;
// String Null Space
if(lpDesc[i].wType == DBTYPE_STR)
m_lpColumnInfo[i].dwSize += 1;
else if(lpDesc[i].wType == DBTYPE_WSTR)
{
dwSize = lpDesc[i].ulColumnSize;
m_lpColumnInfo[i].dwSize += (dwSize + 2);
}
// Bind information
memset(lpBind + i, 0, sizeof(DBBINDING));
lpBind[i].obValue = dwOffset;
lpBind[i].dwPart = DBPART_VALUE;
lpBind[i].wType = lpDesc[i].wType;
lpBind[i].bScale = lpDesc[i].bScale;
lpBind[i].eParamIO = DBPARAMIO_NOTPARAM;
lpBind[i].iOrdinal = lpDesc[i].iOrdinal;
lpBind[i].bPrecision = lpDesc[i].bPrecision;
lpBind[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
lpBind[i].cbMaxLen = m_lpColumnInfo[i].dwSize;
// 偏移量自增加
dwOffset += m_lpColumnInfo[i].dwSize;
}
CoTaskMemFree( lpDesc );
CoTaskMemFree( lpOleStr );
// Create Accessor interface
hr = m_lpRowset->QueryInterface(
IID_IAccessor, (void **) &dbAccessor);
if(hr != S_OK) return hr;
// Create hAccessor
hr = dbAccessor->CreateAccessor(DBACCESSOR_ROWDATA,
dwCount, lpBind, dwOffset, &m_hAccessor, NULL);
// Okey return
m_lpMalloc = new BYTE[dwOffset];
m_lpBuffer = m_lpMalloc;
m_dwBuffer = dwOffset;
return hr;
}
// 关联记录集
HRESULT XOleRowset::Attach(
IRowset * lpRowset,
void * lpBuffer,
int nColumnCount,
const WORD * lpType,
const int * lpSize
)
{
HRESULT hr;
int nOffset = 0;
XBLOBCOLUMN * lpColumn;
static DBBINDING lpBind[256];
XComPtr<IAccessor> dbAccessor;
if(lpRowset == NULL)
return E_POINTER;
// Attach lpRowset
CloseRowset();
lpRowset->AddRef();
m_lpRowset = lpRowset;
m_nColumnCount = nColumnCount;
// Set binding info
for(int i = 0; i < nColumnCount; i ++)
{
// Field info
m_lpColumnInfo[i].wdPrec = 10;
m_lpColumnInfo[i].lpName[0] = 0x00;
m_lpColumnInfo[i].wdType = lpType[i];
m_lpColumnInfo[i].dwSize = lpSize[i];
m_lpColumnInfo[i].dwOffset = nOffset;
if(lpType[i] == DBTYPE_BLOB || lpType[i] == DBTYPE_FILE)
{
lpColumn = (XBLOBCOLUMN *)(
(LPBYTE)lpBuffer + nOffset);
memset(lpBind + i, 0, sizeof(DBBINDING));
lpBind[i].iOrdinal = i + 1; // Ordinal
lpBind[i].obValue = nOffset; // nOffset
lpBind[i].obStatus = nOffset + 4;
lpBind[i].obLength = nOffset + 8;
lpBind[i].wType = DBTYPE_IUNKNOWN;
lpBind[i].pObject = &lpColumn->dbObject;
lpBind[i].eParamIO = DBPARAMIO_NOTPARAM;
lpBind[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
lpBind[i].dwPart = DBPART_VALUE | DBPART_STATUS |
DBPART_LENGTH;
lpColumn->lpTemp[0] = 0x0000;
lpColumn->lpTemp[2] = 0x00000000;
lpColumn->lpTemp[1] = DBSTATUS_S_OK;
lpBind[i].pObject->dwFlags = STGM_READ;
lpBind[i].pObject->iid = IID_ISequentialStream;
}
else
{
// Bind info
memset(lpBind + i, 0, sizeof(DBBINDING));
lpBind[i].iOrdinal = i + 1; // Ordinal
lpBind[i].obValue = nOffset; // nOffset
lpBind[i].wType = lpType[i]; // DB_TYPE
lpBind[i].cbMaxLen = lpSize[i]; // nMaxLen
lpBind[i].dwPart = DBPART_VALUE;// PartVal
lpBind[i].eParamIO = DBPARAMIO_NOTPARAM;
lpBind[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
// 精度与小数位数
if(lpType[i] == DBTYPE_NUMERIC)
{
lpBind[i].bScale = (BYTE) m_lpColumnInfo[i].wdPrec;
lpBind[i].bPrecision = (BYTE) (38 - lpBind[i].bScale);
}
}
// 调整偏移量
nOffset += lpSize[i];
}
// Create Accessor interface
hr = m_lpRowset->QueryInterface(
IID_IAccessor, (void **) &dbAccessor);
if(hr != S_OK) return hr;
// Create hAccessor
hr = dbAccessor->CreateAccessor(
DBACCESSOR_ROWDATA, nColumnCount,
lpBind, nOffset, &m_hAccessor, NULL );
if(hr != S_OK) return hr;
// Create buffer
m_dwBuffer = nOffset;
m_lpBuffer = (LPBYTE)lpBuffer;
if(m_lpBuffer == NULL)
{
m_lpMalloc = new BYTE[nOffset];
m_lpBuffer = m_lpMalloc;
}
return S_OK;
}
HRESULT XOleRowset::MoveFirst(BOOL bLoadData)
{
HRESULT hr;
DWORD dwRowCount = 0;
HROW * lpCurrent = &m_hCurrent;
ReleaseCurrent();
if(m_lpRowset == NULL)
return E_NOINTERFACE;
hr = m_lpRowset->RestartPosition(NULL);
if(hr != S_OK) return hr;
hr = m_lpRowset->GetNextRows(NULL, 0,
1, &dwRowCount, &lpCurrent);
if( bLoadData )
{
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::MoveNext(BOOL bLoadData)
{
HRESULT hr;
DWORD dwRowCount = 0;
HROW * lpCurrent = &m_hCurrent;
ReleaseCurrent();
if(m_lpRowset == NULL)
return E_NOINTERFACE;
hr = m_lpRowset->GetNextRows(NULL, 0,
1, &dwRowCount, &lpCurrent);
if( bLoadData )
{
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::MovePrev(BOOL bLoadData)
{
HRESULT hr;
DWORD dwRowCount;
HROW * lpCurrent = &m_hCurrent;
ReleaseCurrent();
if(m_lpRowset == NULL)
return E_NOINTERFACE;
hr = m_lpRowset->GetNextRows(NULL, -2,
1, &dwRowCount, &lpCurrent);
if( bLoadData )
{
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::MoveLast(BOOL bLoadData)
{
HRESULT hr;
DWORD dwRowCount = 0;
HROW * lpCurrent = &m_hCurrent;
ReleaseCurrent();
if(m_lpRowset == NULL)
return E_NOINTERFACE;
hr = m_lpRowset->RestartPosition(NULL);
if(hr != S_OK) return hr;
hr = m_lpRowset->GetNextRows(NULL, -1,
1, &dwRowCount, &lpCurrent);
if( bLoadData )
{
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::MoveOffset(int nOffset, BOOL bLoadData)
{
HRESULT hr;
DWORD dwRowCount = 0;
HROW * lpCurrent = &m_hCurrent;
ReleaseCurrent();
if(m_lpRowset == NULL)
return E_NOINTERFACE;
hr = m_lpRowset->GetNextRows(NULL, nOffset,
1, &dwRowCount, &lpCurrent);
if( bLoadData )
{
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::GetRowInfo(DWORD * lpState)
{
if(m_lpRowset == NULL || m_hCurrent == NULL)
return E_NOINTERFACE;
// 重新构建访问器
HRESULT hr;
DWORD dwOffset = 0;
HACCESSOR hAccessor;
static DBBINDING lpBind[256];
XComPtr<IAccessor> dbAccessor;
// Create Accessor interface
hr = m_lpRowset->QueryInterface(
IID_IAccessor, (void **) &dbAccessor);
if(hr != S_OK) return hr;
// Set binding info
for(int i = 0; i < m_nColumnCount; i ++)
{
memset(lpBind + i, 0, sizeof(DBBINDING));
lpBind[i].iOrdinal = i + 1; // Ordinal
lpBind[i].obLength = dwOffset; // obLength
lpBind[i].obStatus = dwOffset + 4; // obStatus
lpBind[i].eParamIO = DBPARAMIO_NOTPARAM;
lpBind[i].wType = m_lpColumnInfo[i].wdType;
lpBind[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
lpBind[i].cbMaxLen = m_lpColumnInfo[i].dwSize;
lpBind[i].dwPart = DBPART_LENGTH | DBPART_STATUS;
dwOffset += 8; // Length and Status Size
}
// Create hAccessor
hr = dbAccessor->CreateAccessor(
DBACCESSOR_ROWDATA, m_nColumnCount,
lpBind, dwOffset, &hAccessor, NULL );
if(hr != S_OK) return hr;
// 获取Length和Status
memset(lpState, 0x00, dwOffset);
hr = m_lpRowset->GetData(m_hCurrent,
hAccessor, lpState);
return hr;
}
HRESULT XOleRowset::InsertRow()
{
if(m_lpChange == NULL)
return E_NOINTERFACE;
// 将指针设在末尾处
MoveLast(FALSE);
ReleaseCurrent();
// 设置大对象流对象
DWORD nIdx = 0;
HRESULT hr = S_OK;
XOleStream * lpStream;
for(int i = 0; i < m_nColumnCount; i ++)
{
if(m_lpColumnInfo[i].wdType == DBTYPE_BLOB)
{
nIdx = m_lpColumnInfo[i].dwOffset;
XBLOBCOLUMN * lpColumn =
(XBLOBCOLUMN *)(m_lpBuffer + nIdx);
// 会自动释放的
lpStream = new XOleStream(lpColumn->lpBuffer,
lpColumn->dwMaxSize);
lpStream->AddRef();
lpColumn->lpTemp[0] = (DWORD)lpStream;
lpColumn->lpTemp[1] = DBSTATUS_S_OK;
lpColumn->lpTemp[2] = lpColumn->dwMaxSize;
}
else if(m_lpColumnInfo[i].wdType == DBTYPE_FILE)
{
nIdx = m_lpColumnInfo[i].dwOffset;
XBLOBCOLUMN * lpColumn =
(XBLOBCOLUMN *)(m_lpBuffer + nIdx);
// 会自动释放的
lpStream = new XOleStream(lpColumn->hFile);
lpStream->AddRef();
lpColumn->lpTemp[0] = (DWORD)lpStream;
lpColumn->lpTemp[1] = DBSTATUS_S_OK;
lpColumn->lpTemp[2] = lpColumn->dwMaxSize;
}
}
// 新增记录数据
return m_lpChange->InsertRow(NULL,
m_hAccessor, m_lpBuffer, &m_hCurrent);
}
HRESULT XOleRowset::DeleteRow()
{
if(m_hCurrent == NULL || m_lpChange == NULL)
return E_NOINTERFACE;
return m_lpChange->DeleteRows(NULL,
1, &m_hCurrent, NULL);
}
HRESULT XOleRowset::ModifyRow()
{
if(m_hCurrent == NULL || m_lpChange == NULL)
return E_NOINTERFACE;
// 设置大对象流对象
DWORD nIdx = 0;
HRESULT hr = S_OK;
XOleStream * lpStream;
for(int i = 0; i < m_nColumnCount; i ++)
{
if(m_lpColumnInfo[i].wdType == DBTYPE_BLOB)
{
nIdx = m_lpColumnInfo[i].dwOffset;
XBLOBCOLUMN * lpColumn =
(XBLOBCOLUMN *)(m_lpBuffer + nIdx);
// 会自动释放的
lpStream = new XOleStream(lpColumn->lpBuffer,
lpColumn->dwMaxSize);
lpStream->AddRef();
lpColumn->lpTemp[0] = (DWORD)lpStream;
lpColumn->lpTemp[1] = DBSTATUS_S_OK;
lpColumn->lpTemp[2] = lpStream->GetLength();
}
else if(m_lpColumnInfo[i].wdType == DBTYPE_FILE)
{
nIdx = m_lpColumnInfo[i].dwOffset;
XBLOBCOLUMN * lpColumn =
(XBLOBCOLUMN *)(m_lpBuffer + nIdx);
// 会自动释放的
lpStream = new XOleStream(lpColumn->hFile);
lpStream->AddRef();
lpColumn->lpTemp[0] = (DWORD)lpStream;
lpColumn->lpTemp[1] = DBSTATUS_S_OK;
lpColumn->lpTemp[2] = lpStream->GetLength();
}
}
// 设置数据
return m_lpChange->SetData(m_hCurrent,
m_hAccessor, m_lpBuffer);
}
int XOleRowset::GetColumnIndex(LPCTSTR strName)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -