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

📄 xoledatabase.cpp

📁 通过oledb
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 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 + -