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

📄 xoledatabase.cpp

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