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

📄 atldbcli.h

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 H
📖 第 1 页 / 共 5 页
字号:
	}
	void Close()
	{
		if (m_pColumnInfo != NULL)
		{
			CoTaskMemFree(m_pColumnInfo);
			m_pColumnInfo = NULL;
		}

		// Free the memory for the string buffer returned by IColumnsInfo::GetColumnInfo,
		// if necessary
		if (m_pStringsBuffer != NULL)
		{
			CoTaskMemFree(m_pStringsBuffer);
			m_pStringsBuffer = NULL;
		}

		delete [] m_pBuffer;
		m_pBuffer = NULL;
		m_nColumns = 0;

		CAccessorBase::Close();
	}
	bool GetColumnType(ULONG nColumn, DBTYPE* pType) const
	{
		if (TranslateColumnNo(nColumn))
		{
			*pType = m_pColumnInfo[nColumn].wType;
			return true;
		}
		else
			return false;
	}
	bool GetColumnFlags(ULONG nColumn, DBCOLUMNFLAGS* pFlags) const
	{
		if (TranslateColumnNo(nColumn))
		{
			*pFlags = m_pColumnInfo[nColumn].dwFlags;
			return true;
		}
		else
			return false;
	}
	bool GetOrdinal(TCHAR* pColumnName, ULONG* pOrdinal) const
	{
		ATLASSERT(pColumnName != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
		{
			*pOrdinal = m_pColumnInfo[nColumn].iOrdinal;
			return true;
		}
		else
			return false;
	}

	void* GetValue(ULONG nColumn) const
	{
		if (TranslateColumnNo(nColumn))
			return _GetDataPtr(nColumn);
		else
			return NULL;
	}

	void* GetValue(TCHAR* pColumnName) const
	{
		ATLASSERT(pColumnName != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
			return _GetDataPtr(nColumn);
		else
			return NULL;    // Not Found
	}

	template <class ctype>
	void _GetValue(ULONG nColumn, ctype* pData) const
	{
		ATLASSERT(pData != NULL);
		ATLASSERT(m_pColumnInfo[nColumn].ulColumnSize == sizeof(ctype));
		ctype* pBuffer = (ctype*)_GetDataPtr(nColumn);
		*pData = *pBuffer;
	}
	template <class ctype>
	void _SetValue(ULONG nColumn, const ctype& data)
	{
		ATLASSERT(m_pColumnInfo[nColumn].ulColumnSize == sizeof(ctype));
		ctype* pBuffer = (ctype*)_GetDataPtr(nColumn);
		*pBuffer = (ctype)data;
	}
	template <class ctype>
	bool GetValue(ULONG nColumn, ctype* pData) const
	{
		if (TranslateColumnNo(nColumn))
		{
			_GetValue(nColumn, pData);
			return true;
		}
		return false;
	}
	template <class ctype>
	bool SetValue(ULONG nColumn, const ctype& data)
	{
		if (TranslateColumnNo(nColumn))
		{
			_SetValue(nColumn, data);
			return true;
		}
		return false;
	}
	template <class ctype>
	bool GetValue(TCHAR *pColumnName, ctype* pData) const
	{
		ATLASSERT(pColumnName != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
		{
			_GetValue(nColumn, pData);
			return true;
		}
		return false;
	}
	template <class ctype>
	bool SetValue(TCHAR *pColumnName, const ctype& data)
	{
		ATLASSERT(pColumnName != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
		{
			_SetValue(nColumn, data);
			return true;
		}
		return false;
	}
	bool GetLength(ULONG nColumn, ULONG* pLength) const
	{
		ATLASSERT(pLength != NULL);
		if (TranslateColumnNo(nColumn))
		{
			*pLength = *(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize));
			return true;
		}
		else
			return false;
	}
	bool SetLength(ULONG nColumn, ULONG nLength)
	{
		if (TranslateColumnNo(nColumn))
		{
			*(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize)) = nLength;
			return true;
		}
		else
			return false;
	}
	bool GetLength(TCHAR* pColumnName, ULONG* pLength) const
	{
		ATLASSERT(pColumnName != NULL);
		ATLASSERT(pLength != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
		{
			*pLength = *(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize));
			return true;
		}
		else
			return false;
	}
	bool SetLength(TCHAR* pColumnName, ULONG nLength)
	{
		ATLASSERT(pColumnName != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
		{
			*(ULONG*)(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize)) = nLength;
			return true;
		}
		else
			return false;
	}
	bool GetStatus(ULONG nColumn, DBSTATUS* pStatus) const
	{
		ATLASSERT(pStatus != NULL);
		if (TranslateColumnNo(nColumn))
		{
			*pStatus = *(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize), sizeof(ULONG)));
			return true;
		}
		else
			return false;
	}
	bool SetStatus(ULONG nColumn, DBSTATUS status)
	{
		if (TranslateColumnNo(nColumn))
		{
			*(ULONG*)(AddOffset(AddOffset((ULONG)_GetDataPtr(nColumn), m_pColumnInfo[nColumn].ulColumnSize), sizeof(ULONG))) = status;
			return true;
		}
		else
			return false;
	}
	bool GetStatus(TCHAR* pColumnName, DBSTATUS* pStatus) const
	{
		ATLASSERT(pColumnName != NULL);
		ATLASSERT(pStatus != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
		{
			*pStatus = *(ULONG*)((BYTE*)_GetDataPtr(nColumn) + m_pColumnInfo[nColumn].ulColumnSize + sizeof(ULONG));
			return true;
		}
		else
			return false;
	}
	bool SetStatus(TCHAR* pColumnName, DBSTATUS status)
	{
		ATLASSERT(pColumnName != NULL);
		ULONG nColumn;
		if (GetInternalColumnNo(pColumnName, &nColumn))
		{
			*(ULONG*)((BYTE*)_GetDataPtr(nColumn) + m_pColumnInfo[nColumn].ulColumnSize + sizeof(ULONG)) = status;
			return true;
		}
		else
			return false;
	}

	// Returns true if a bookmark is available
	HRESULT GetBookmark(CBookmark<>* pBookmark) const
	{
		HRESULT hr;
		if (m_pColumnInfo->iOrdinal == 0)
			hr = pBookmark->SetBookmark(m_pColumnInfo->ulColumnSize, (BYTE*)_GetDataPtr(0));
		else
			hr = E_FAIL;
		return hr;
	}

	ULONG GetColumnCount() const
	{
		return m_nColumns;
	}

	LPOLESTR GetColumnName(ULONG nColumn) const
	{
		if (TranslateColumnNo(nColumn))
			return m_pColumnInfo[nColumn].pwszName;
		else
			return NULL;
	}

	HRESULT GetColumnInfo(IRowset* pRowset, ULONG* pColumns, DBCOLUMNINFO** ppColumnInfo)
	{
		CComPtr<IColumnsInfo> spColumnsInfo;
		HRESULT hr = pRowset->QueryInterface(&spColumnsInfo);
		if (SUCCEEDED(hr))
			hr = spColumnsInfo->GetColumnInfo(pColumns, ppColumnInfo, &m_pStringsBuffer);

		return hr;
	}

	HRESULT AddBindEntry(const DBCOLUMNINFO& info)
	{
		m_pColumnInfo = (DBCOLUMNINFO*)CoTaskMemRealloc(m_pColumnInfo, (m_nColumns + 1) * sizeof(DBCOLUMNINFO));
		if (m_pColumnInfo == NULL)
			return E_OUTOFMEMORY;

		m_pColumnInfo[m_nColumns] = info;
		m_nColumns++;

		return S_OK;
	}

// Implementation
	// Free's any columns in the current record that need to be freed.
	// E.g. Calls SysFreeString on any BSTR's and Release on any interfaces.
	void FreeRecordMemory(IRowset* pRowset)
	{
		ULONG i;

		for (i = 0; i < m_nColumns; i++)
			CAccessorBase::FreeType(m_pColumnInfo[i].wType, (BYTE*)_GetDataPtr(i), pRowset);
	}
	void* _GetDataPtr(ULONG nColumn) const
	{
		return m_pBuffer + (ULONG)m_pColumnInfo[nColumn].pTypeInfo;
	}
	bool GetInternalColumnNo(TCHAR* pColumnName, ULONG* pColumn) const
	{
		ATLASSERT(pColumnName != NULL);
		ATLASSERT(pColumn != NULL);
		USES_CONVERSION;
		ULONG       i;
		ULONG       nSize = (lstrlen(pColumnName) + 1) * sizeof(OLECHAR);
		OLECHAR*    pOleColumnName = T2OLE(pColumnName);

		// Search through the columns trying to find a match
		for (i = 0; i < m_nColumns; i++)
		{
			if (m_pColumnInfo[i].pwszName != NULL &&
				memcmp(m_pColumnInfo[i].pwszName, pOleColumnName, nSize) == 0)
				break;
		}
		if (i < m_nColumns)
		{
			*pColumn = i;
			return true;
		}
		else
			return false;   // Not Found
	}
	HRESULT BindColumns(IUnknown* pUnk)
	{
		ATLASSERT(pUnk != NULL);
		CComPtr<IAccessor> spAccessor;
		HRESULT hr = pUnk->QueryInterface(&spAccessor);
		if (FAILED(hr))
			return hr;

		ULONG   i;
		ULONG   nOffset = 0, nLengthOffset, nStatusOffset;

		// If the user hasn't specifed the column information to bind by calling AddBindEntry then
		// we get it ourselves
		if (m_pColumnInfo == NULL)
		{
			CComPtr<IColumnsInfo> spColumnsInfo;
			hr = pUnk->QueryInterface(&spColumnsInfo);
			if (FAILED(hr))
				return hr;

			hr = spColumnsInfo->GetColumnInfo(&m_nColumns, &m_pColumnInfo, &m_pStringsBuffer);
			if (FAILED(hr))
				return hr;

			m_bOverride = false;
		}
		else
			m_bOverride = true;

		DBBINDING* pBinding = NULL;
		ATLTRY(pBinding= new DBBINDING[m_nColumns]);
		if (pBinding == NULL)
			return E_OUTOFMEMORY;

		DBBINDING* pCurrent = pBinding;
		DBOBJECT*  pObject;
		for (i = 0; i < m_nColumns; i++)
		{
			// If it's a BLOB or the column size is large enough for us to treat it as
			// a BLOB then we also need to set up the DBOBJECT structure.
			if (m_pColumnInfo[i].ulColumnSize > 1024 || m_pColumnInfo[i].wType == DBTYPE_IUNKNOWN)
			{
				pObject = NULL;
				ATLTRY(pObject = new DBOBJECT);
				if (pObject == NULL)
					return E_OUTOFMEMORY;
				pObject->dwFlags = STGM_READ;
				pObject->iid     = IID_ISequentialStream;
				m_pColumnInfo[i].wType      = DBTYPE_IUNKNOWN;
				m_pColumnInfo[i].ulColumnSize   = sizeof(IUnknown*);
			}
			else
				pObject = NULL;

			// If column is of type STR or WSTR increase length by 1
			// to accommodate the NULL terminator.
			if (m_pColumnInfo[i].wType == DBTYPE_STR ||
				m_pColumnInfo[i].wType == DBTYPE_WSTR)
					m_pColumnInfo[i].ulColumnSize += 1;

			nLengthOffset = AddOffset(nOffset, m_pColumnInfo[i].ulColumnSize);
			nStatusOffset = AddOffset(nLengthOffset, sizeof(ULONG));
			Bind(pCurrent, m_pColumnInfo[i].iOrdinal, m_pColumnInfo[i].wType,
				m_pColumnInfo[i].ulColumnSize, m_pColumnInfo[i].bPrecision, m_pColumnInfo[i].bScale,
				DBPARAMIO_NOTPARAM, nOffset,
				nLengthOffset, nStatusOffset, pObject);
			pCurrent++;

			// Note that, as we're not using this for anything else, we're using the
			// pTypeInfo element to store the offset to our data.
			m_pColumnInfo[i].pTypeInfo = (ITypeInfo*)nOffset;

			nOffset = AddOffset(nStatusOffset, sizeof(DBSTATUS));
		}
		// Allocate the accessor memory if we haven't done so yet
		if (m_pAccessorInfo == NULL)
		{
			hr = AllocateAccessorMemory(1); // We only have one accessor
			if (FAILED(hr))
			{
				delete [] pBinding;
				return hr;
			}
			m_pAccessorInfo->bAutoAccessor = TRUE;
		}

		// Allocate enough memory for the data buffer and tell the rowset
		// Note that the rowset will free the memory in its destructor.
		m_pBuffer = NULL;
		ATLTRY(m_pBuffer = new BYTE[nOffset]);
		if (m_pBuffer == NULL)
		{
			delete [] pBinding;
			return E_OUTOFMEMORY;
		}
		hr = BindEntries(pBinding, m_nColumns, &m_pAccessorInfo->hAccessor,
				nOffset, spAccessor);
		delete [] pBinding;

		return hr;
	}

	static ULONG AddOffset(ULONG nCurrent, ULONG nAdd)
	{
		struct foobar
		{
			char    foo;
			long    bar;
		};
		ULONG nAlign = offsetof(foobar, bar);

		return nCurrent + nAdd + (nAdd % nAlign);;
	}

	// Translate the column number to the index into the column info array
	bool TranslateColumnNo(ULONG& nColumn) const
	{
		ATLASSERT(m_pColumnInfo != NULL);
		// If the user has overriden the binding then we need to search
		// through the column info for the ordinal number
		if (m_bOverride)
		{
			for (ULONG i = 0; i < m_nColumns; i++)
			{
				if (m_pColumnInfo[i].iOrdinal == nColumn)
				{
					nColumn = i;
					return true;
				}
			}
			return false;
		}
		else
		{
			// Note that m_pColumnInfo->iOrdinal will be zero if have bound
			// a bookmark as the first entry, otherwise it will be 1.
			// If the column is out of range then return false
			if (nColumn > (m_nColumns - 1 + m_pColumnInfo->iOrdinal))
				return false;

			// otherwise translate the column to an index into our internal
			// binding entries array
			nColumn -= m_pColumnInfo->iOrdinal;
			return true;
		}
	}
	typedef CDynamicAccessor _OutputColumnsClass;
	static bool HasOutputColumns() { return true; }

	ULONG               m_nColumns;
	DBCOLUMNINFO*       m_pColumnInfo;
	OLECHAR*            m_pStringsBuffer;
	bool                m_bOverride;
};


///////////////////////////////////////////////////////////////////////////
// class CDynamicParameterAccessor

class CDynamicParameterAccessor : public CDynamicAccessor
{
// Constructors and Destructors
public:
	typedef CDynamicParameterAccessor _ParamClass;
	CDynamicParameterAccessor()
	{
		m_pParameterEntry       = NULL;
		m_pParameterBuffer      = NULL;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -