📄 xoledatabase.cpp
字号:
// OleDatabase.cpp: implementation of the OleDatabase class
///////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XOleDatabase.h"
/*******************************************/
/* * * * 几个字符转换宏 * * * */
/*******************************************/
#ifdef _UNICODE
#define T(x) L ## x
#define XScanf swscanf
#define XSprintf swprintf
#define TStrToWStr(s, d, n) lstrcpynW(d, s, n)
#define WStrToTStr(s, d, n) lstrcpynW(d, s, n)
#define StrToTStr(s, d, n) MultiByteToWideChar(CP_ACP, 0, s, -1, d, n)
#define TStrToStr(s, d, n) WideCharToMultiByte(CP_ACP, 0, s, -1, d, n, NULL, NULL)
#else
#define T(x) x
#define XScanf sscanf
#define XSprintf sprintf
#define TStrToStr(s, d, n) lstrcpynA(d, s, n)
#define StrToTStr(s, d, n) lstrcpynA(d, s, n)
#define TStrToWStr(s, d, n) MultiByteToWideChar(CP_ACP, 0, s, -1, d, n)
#define WStrToTStr(s, d, n) WideCharToMultiByte(CP_ACP, 0, s, -1, d, n, NULL, NULL)
#endif
// 几个有用的转换函数
LPCSTR XTrimStr(LPSTR lpBuffer, long nMaxSize);
LPCWSTR XTrimWStr(LPWSTR lpBuffer, long nMaxSize);
void XScanOleVariant(WORD wdType, LPCTSTR lpBuffer, LPVOID lpDest, DWORD dwSize);
void XFormatOleVariant(WORD wdType, LPVOID lpSrc, LPTSTR lpBuffer, DWORD dwSize);
// 二进制和文本字符串的相互转换
void BinaryToTStr(LPVOID lpSrc, LPTSTR lpDest, DWORD dwSize);
void TStrToBinary(LPCTSTR lpSrc, LPVOID lpDest, DWORD dwSize);
/*******************************************/
/* * * * 自定义COM指针 * * * */
/*******************************************/
template <class T_CLASS>
class XComPtr
{
public:
T_CLASS * m_lpPtr;
public:
XComPtr()
{
m_lpPtr = NULL;
}
XComPtr(T_CLASS* lpPtr)
{
if(lpPtr != NULL) lpPtr->AddRef();
m_lpPtr = lpPtr;
}
XComPtr(const XComPtr<T_CLASS>& rfp)
{
m_lpPtr = rfp.m_lpPtr;
if(m_lpPtr != NULL) m_lpPtr->AddRef();
}
~XComPtr()
{
if(m_lpPtr != NULL)
m_lpPtr->Release();
}
operator T_CLASS*() const
{
return (T_CLASS *)m_lpPtr;
}
T_CLASS** operator&()
{
return &m_lpPtr;
}
T_CLASS* operator=(T_CLASS* lpPtr)
{
if(lpPtr != NULL) lpPtr->AddRef();
if(m_lpPtr != NULL) m_lpPtr->Release();
m_lpPtr = lpPtr;
return lpPtr;
}
T_CLASS* operator=(const XComPtr<T_CLASS>& rfp)
{
if(m_lpPtr != NULL)
m_lpPtr->Release();
m_lpPtr = rfp.m_lpPtr;
if(m_lpPtr != NULL) m_lpPtr->AddRef();
return m_lpPtr;
}
T_CLASS* operator->()
{
return m_lpPtr;
}
void AddRef()
{
IUnknown *lpTemp = m_lpPtr;
if(lpTemp != NULL) lpTemp->AddRef();
}
void Release()
{
IUnknown *lpTemp = m_lpPtr;
if(lpTemp != NULL)
{
m_lpPtr = NULL;
lpTemp->Release();
}
}
void Attach(T_CLASS *lpPtr)
{
if(m_lpPtr != NULL)
m_lpPtr->Release();
m_lpPtr = lpPtr;
}
T_CLASS* Detach()
{
T_CLASS* lpPtr = m_lpPtr;
m_lpPtr = NULL;
return lpPtr;
}
template <class Q_CLASS>
HRESULT QueryInterface(REFIID rfd, Q_CLASS** pp) const
{
return m_lpPtr->QueryInterface(rfd, (void **)pp);
}
template <class Q_CLASS>
HRESULT QueryInterface(Q_CLASS** pp) const
{
return m_lpPtr->QueryInterface(__uuidof(Q_CLASS), (void **)pp);
}
};
/********************************************/
/* * * * 大对象字段对象 * * * */
/********************************************/
class XOleStream : public ISequentialStream
{
public:
XOleStream(HANDLE hFile);
XOleStream(void * lpBuffer, DWORD dwSize);
virtual ~XOleStream();
private:
DWORD m_rfCount;
DWORD m_dwIndex;
DWORD m_dwBuffer;
// 文件方式吗
BOOL m_bFileMode;
// 文件或缓冲区方式
union {
HANDLE m_hFile;
LPBYTE m_lpBuffer;
};
public:
virtual DWORD GetLength();
virtual BOOL Seek(DWORD dwPos);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
STDMETHODIMP Read(
/* [out] */ void __RPC_FAR * pv,
/* [in] */ ULONG cb,
/* [out] */ ULONG __RPC_FAR *pcbRead);
STDMETHODIMP Write(
/* [in] */ const void __RPC_FAR *pv,
/* [in] */ ULONG cb,
/* [out]*/ ULONG __RPC_FAR *pcbWritten);
};
XOleStream::XOleStream(HANDLE hFile)
{
m_rfCount = 0;
m_dwIndex = 0;
// 文件方式读写
m_hFile = hFile;
m_bFileMode = TRUE;
m_dwBuffer = GetFileSize(hFile, NULL);
}
XOleStream::XOleStream(void * lpBuffer, DWORD dwSize)
{
m_rfCount = 0;
m_dwIndex = 0;
// 文件方式读写
m_dwBuffer = dwSize;
m_bFileMode = FALSE;
m_lpBuffer = (LPBYTE)lpBuffer;
}
XOleStream::~XOleStream()
{
}
ULONG XOleStream::AddRef(void)
{
m_rfCount ++;
return m_rfCount;
}
ULONG XOleStream::Release(void)
{
m_rfCount --;
if(m_rfCount > 0)
return m_rfCount;
delete this;
return 0;
}
HRESULT XOleStream::QueryInterface(REFIID riid, void** ppv)
{
*ppv = NULL;
if( riid == IID_IUnknown ||
riid == IID_ISequentialStream )
{
((IUnknown *)this)->AddRef();
*ppv = this; return S_OK;
}
return E_NOINTERFACE;
}
BOOL XOleStream::Seek(DWORD dwPos)
{
if( m_bFileMode )
{
SetFilePointer(m_hFile, dwPos, NULL, FILE_BEGIN);
m_dwIndex = dwPos;
}
else
{
if(dwPos > m_dwBuffer)
return FALSE;
m_dwIndex = dwPos;
}
return TRUE;
}
DWORD XOleStream::GetLength()
{
return m_dwBuffer;
}
HRESULT XOleStream::Read(void *pv, ULONG cb, ULONG* pcbRead)
{
if(pcbRead != NULL)
*pcbRead = 0;
if(pv == NULL)
return STG_E_INVALIDPOINTER;
if(cb == 0) return S_OK;
// 实际读出的大小
DWORD dwByteLeft = m_dwBuffer - m_dwIndex;
if(cb > dwByteLeft) cb = dwByteLeft;
if(cb == 0) return S_FALSE;
if( m_bFileMode )
{
DWORD dwByte = 0;
ReadFile(m_hFile, pv, cb, &dwByte, NULL);
m_dwIndex += cb;
}
else
{
// Copy User buffer the bytes
memcpy(pv, m_lpBuffer + m_dwIndex, cb);
m_dwIndex += cb;
}
if(pcbRead != NULL) *pcbRead = cb;
return S_OK;
}
HRESULT XOleStream::Write(const void *pv, ULONG cb, ULONG* pcbWritten)
{
if(pv == NULL)
return STG_E_INVALIDPOINTER;
if(pcbWritten != NULL)
*pcbWritten = 0;
if(cb == 0) return S_OK;
if( m_bFileMode )
{
DWORD dwByte = 0;
WriteFile(m_hFile, pv, cb, &dwByte, NULL);
m_dwIndex += cb;
// 文件可能变大了
if(m_dwIndex + cb > m_dwBuffer)
m_dwBuffer = m_dwIndex + cb;
}
else
{
// 实际写入的大小
DWORD dwByteLeft = m_dwBuffer - m_dwIndex;
if(cb > dwByteLeft) cb = dwByteLeft;
if(cb == 0) return S_FALSE;
// Copy User buffer the bytes
memcpy(m_lpBuffer + m_dwIndex, pv, cb);
m_dwIndex += cb;
}
if(pcbWritten != NULL)
*pcbWritten = cb;
return S_OK;
}
/********************************************/
/* * * * 基本数据库对象 * * * */
/********************************************/
XOleDatabase::XOleDatabase()
{
m_lpInit = NULL;
m_lpTrans = NULL;
m_lpSession = NULL;
m_lpCommand = NULL;
}
XOleDatabase::~XOleDatabase()
{
// Close Database
CloseConnect();
}
void XOleDatabase::CloseConnect()
{
if(m_lpTrans != NULL)
{
m_lpTrans->Release();
m_lpTrans = NULL;
}
if(m_lpCommand != NULL)
{
m_lpCommand->Release();
m_lpCommand = NULL;
}
if(m_lpSession != NULL)
{
m_lpSession->Release();
m_lpSession = NULL;
}
if(m_lpInit != NULL)
{
m_lpInit->Release();
m_lpInit = NULL;
}
}
HRESULT XOleDatabase::Connect(LPCTSTR lpConnect)
{
HRESULT hr;
WCHAR lpBuffer[4096];
XComPtr<IDataInitialize> dbDataInit;
// 确认已经断开
CloseConnect();
// 连接数据源实例
TStrToWStr(lpConnect, lpBuffer, 4096);
hr = CoCreateInstance(
CLSID_MSDAINITIALIZE,
NULL, CLSCTX_INPROC_SERVER,
IID_IDataInitialize,
(void **) &dbDataInit
);
if(hr != S_OK) return hr;
// 获取数据源指针
hr = dbDataInit->GetDataSource( NULL,
CLSCTX_INPROC_SERVER, lpBuffer,
IID_IDBInitialize, (IUnknown **)&m_lpInit );
if(hr != S_OK) return hr;
// 初始化数据源
hr = m_lpInit->Initialize();
if(hr != S_OK) return hr;
// 创建会话对象
hr = m_lpInit->QueryInterface(
IID_IDBCreateSession,
(void **) &m_lpSession
);
if(hr != S_OK) return hr;
// 创建命令对象
return m_lpSession->CreateSession( NULL,
IID_IDBCreateCommand, (IUnknown **) &m_lpCommand);
}
HRESULT XOleDatabase::Connect(
REFCLSID rcDriver,
LPCTSTR lpSource,
LPCTSTR lpDBName,
LPCTSTR lpUserID,
LPCTSTR lpUserKey
)
{
HRESULT hr;
DBPROP lpProp[5];
WCHAR lpBuffer[256];
XComPtr<IDBProperties> dbPropert;
// 确认已经断开
CloseConnect();
// 获取IDBInitialize
hr = CoCreateInstance(
rcDriver, NULL,
CLSCTX_INPROC_SERVER,
IID_IDBInitialize,
(void **) &m_lpInit
);
if(hr != S_OK) return hr;
// 初始化所有属性
for(int i = 0; i < 5; i ++)
{
lpProp[i].colid = DB_NULLID;
lpProp[i].dwStatus = 0x00000000;
lpProp[i].dwOptions = DBPROPOPTIONS_REQUIRED;
}
// Prompt information
lpProp[0].vValue.vt = VT_I2;
lpProp[0].vValue.iVal = DBPROMPT_NOPROMPT;
lpProp[0].dwPropertyID = DBPROP_INIT_PROMPT;
// DataSource name
lpProp[1].vValue.vt = VT_BSTR;
TStrToWStr(lpSource, lpBuffer, 256);
lpProp[1].dwPropertyID = DBPROP_INIT_DATASOURCE;
lpProp[1].vValue.bstrVal = SysAllocString(lpBuffer);
// Database name
lpProp[2].vValue.vt = VT_BSTR;
TStrToWStr(lpDBName, lpBuffer, 256);
lpProp[2].dwPropertyID = DBPROP_INIT_CATALOG;
lpProp[2].vValue.bstrVal = SysAllocString(lpBuffer);
// User Name
lpProp[3].vValue.vt = VT_BSTR;
TStrToWStr(lpUserID, lpBuffer, 256);
lpProp[3].dwPropertyID = DBPROP_AUTH_USERID;
lpProp[3].vValue.bstrVal = SysAllocString(lpBuffer);
// User Password
lpProp[4].vValue.vt = VT_BSTR;
TStrToWStr(lpUserKey, lpBuffer, 256);
lpProp[4].dwPropertyID = DBPROP_AUTH_PASSWORD;
lpProp[4].vValue.bstrVal = SysAllocString(lpBuffer);
// 设置属性集
DBPROPSET dbPropSet;
dbPropSet.cProperties = 5;
dbPropSet.rgProperties = lpProp;
dbPropSet.guidPropertySet = DBPROPSET_DBINIT;
hr = m_lpInit->QueryInterface(
IID_IDBProperties, (void **) &dbPropert);
if(hr != S_OK) return hr;
// 设置属性 --- 可能有些没有成功
hr = dbPropert->SetProperties(1, &dbPropSet);
// 初始化数据源
hr = m_lpInit->Initialize();
if(hr != S_OK) return hr;
// 创建会话对象
hr = m_lpInit->QueryInterface(
IID_IDBCreateSession,
(void **) &m_lpSession
);
if(hr != S_OK) return hr;
// 创建命令对象
return m_lpSession->CreateSession( NULL,
IID_IDBCreateCommand, (IUnknown **) &m_lpCommand);
}
HRESULT XOleDatabase::Connect(
LPCTSTR lpDriver,
LPCTSTR lpSource,
LPCTSTR lpDBName,
LPCTSTR lpUserID,
LPCTSTR lpUserKey
)
{
HRESULT hr;
CLSID rcDriver;
WCHAR lpBuffer[256];
TStrToWStr(lpDriver, lpBuffer, 256);
hr = CLSIDFromProgID(lpBuffer, &rcDriver);
if(hr != S_OK) return hr;
return Connect(rcDriver, lpSource,
lpDBName, lpUserID, lpUserKey);
}
HRESULT XOleDatabase::ExecuteCommand(LPCTSTR lpQuery)
{
HRESULT hr;
WCHAR lpBuffer[4096];
XComPtr<ICommand> dbCommand;
XComPtr<ICommandText> dbCmdText;
// Create command
hr = m_lpCommand->CreateCommand( NULL,
IID_ICommand, (IUnknown **) &dbCommand );
if(hr != S_OK) return hr;
// Create command text
hr = dbCommand.QueryInterface(IID_ICommandText, &dbCmdText);
if(hr != S_OK) return hr;
TStrToWStr(lpQuery, lpBuffer, 4096);
hr = dbCmdText->SetCommandText(DBGUID_DBSQL, lpBuffer);
if(hr != S_OK) return hr;
// Execute command
return dbCommand->Execute(NULL, IID_NULL, NULL, NULL, NULL);
}
// 判断满足SQL语句的记录是否存在
HRESULT XOleDatabase::IsQueryExist(LPCTSTR lpQuery)
{
HRESULT hr;
WCHAR lpBuffer[4096];
XComPtr<IRowset> dbRowset;
XComPtr<ICommand> dbCommand;
XComPtr<ICommandText> dbCmdText;
// Create command
hr = m_lpCommand->CreateCommand( NULL,
IID_ICommand, (IUnknown **) &dbCommand );
if(hr != S_OK) return hr;
// Create command text
hr = dbCommand.QueryInterface(IID_ICommandText, &dbCmdText);
if(hr != S_OK) return hr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -