神通数据库 OLE DB枚举器

神通数据库 OLE DB提供一个枚举器组件,用户可以使用它得到网络中所有可用神通数据库 OLE DB连接上的数据源列表。枚举器组件由GUID CLSID_OSCAROLEDB_ENUMERATOR = {}来标识。

下面举例说明。枚举SHENTONG OLE DB 数据源的步骤如下:

通过调用 ISourceRowset::GetSourcesRowset 检索源行集。

通过调用 GetColumnInfo::IcolumnInfo 查找对枚举符行集的描述。

根据列信息创建绑定结构。

通过调用 IAccessor::CreateAccessor 创建行集存取程序。

通过调用 IRowset::GetNextRows 提取行。

通过调用 IRowset::GetData 从行集的行复本中检索数据并对数据进行处理。

//How to use the enumerator object to list

//the data sources available.

#define UNICODE

#define _UNICODE

#define DBINITCONSTANTS

#define INITGUID

#include <windows.h>

#include <stddef.h>

#include <oledb.h>

#include <oledberr.h>

#include <SQLOLEDB.h>

#include <stdio.h>

#define NUMROWS_CHUNK 5

//AdjustLen supports binding on four-byte boundaries.

_inline ULONG AdjustLen(ULONG cb)

{

return ((cb + 3) & ~3);

}

// Get the characteristics of the rowset (the IColumnsInfo interface).

HRESULT GetColumnInfo

(

IRowset* pIRowset,

UINT* pnCols,

DBCOLUMNINFO** ppColumnsInfo,

OLECHAR** ppColumnStrings

)

{

IColumnsInfo* pIColumnsInfo;

HRESULT hr;

*pnCols = 0;

if (FAILED(pIRowset->QueryInterface(IID_IColumnsInfo,

(void**) &pIColumnsInfo)))

{

return (E_FAIL);

}

hr = pIColumnsInfo->GetColumnInfo((ULONG*) pnCols,

ppColumnsInfo,

ppColumnStrings);

if (FAILED(hr))

{

//Process error.

}

pIColumnsInfo->Release();

return (hr);

}

// Create binding structures from column information. Binding structures

// will be used to create an accessor that allows row value retrieval.

void CreateDBBindings

(

UINT nCols,

DBCOLUMNINFO* pColumnsInfo,

DBBINDING** ppDBBindings,

BYTE** ppRowValues

)

{

ULONG nCol;

ULONG cbRow = 0;

ULONG cbCol;

DBBINDING* pDBBindings;

BYTE* pRowValues;

pDBBindings = new DBBINDING[nCols];

for (nCol = 0; nCol < nCols; nCol++)

{

pDBBindings[nCol].iOrdinal = nCol+1;

pDBBindings[nCol].pTypeInfo = NULL;

pDBBindings[nCol].pObject = NULL;

pDBBindings[nCol].pBindExt = NULL;

pDBBindings[nCol].dwPart = DBPART_VALUE;

pDBBindings[nCol].dwMemOwner =

DBMEMOWNER_CLIENTOWNED;

pDBBindings[nCol].eParamIO = DBPARAMIO_NOTPARAM;

pDBBindings[nCol].dwFlags = 0;

pDBBindings[nCol].wType = pColumnsInfo[nCol].wType;

pDBBindings[nCol].bPrecision = pColumnsInfo[nCol].bPrecision;

pDBBindings[nCol].bScale = pColumnsInfo[nCol].bScale;

cbCol = pColumnsInfo[nCol].ulColumnSize;

switch (pColumnsInfo[nCol].wType)

{

case DBTYPE_STR:

{

cbCol += 1;

break;

}

case DBTYPE_WSTR:

{

cbCol = (cbCol + 1) * sizeof(WCHAR);

break;

}

default:

break;

}

pDBBindings[nCol].obValue = cbRow;

pDBBindings[nCol].cbMaxLen = cbCol;

cbRow += AdjustLen(cbCol);

}

pRowValues = new BYTE[cbRow];

*ppDBBindings = pDBBindings;

*ppRowValues = pRowValues;

return;

}

int main()

{

ISourcesRowset* pISourceRowset = NULL;

IRowset* pIRowset = NULL;

IAccessor* pIAccessor = NULL;

DBBINDING* pDBBindings = NULL;

HROW* pRows = new HROW[500];

BYTE* pData = NULL;

HACCESSOR hAccessorRetrieve = NULL;

ULONG cRows = 0;

ULONG DSSeqNumber = 0;

HRESULT hr;

UINT nCols;

DBCOLUMNINFO* pColumnsInfo = NULL;

OLECHAR* pColumnStrings = NULL;

DBBINDSTATUS* pDBBindStatus = NULL;

BYTE* pRowValues = NULL;

ULONG cRowsObtained;

ULONG iRow;

char* pMultiByte = NULL;

short* psSourceType = NULL;

BYTE* pDatasource = NULL;

//Initialize COM library.

CoInitialize(NULL);

//Initialize the enumerator.

if(FAILED(CoCreateInstance(CLSID_OSCAROLEDB_ENUMERATOR,

NULL,

CLSCTX_INPROC_SERVER,

IID_ISourcesRowset,

(void**)&pISourceRowset)))

{

//Process error.

return TRUE;

}

//Retrieve the source rowset.

hr = pISourceRowset->GetSourcesRowset(NULL,

IID_IRowset,

0,

NULL,

(IUnknown**)&pIRowset);

pISourceRowset->Release();

if(FAILED(hr))

{

//Process error.

return TRUE;

}

//Get the description of the enumerator's rowset.

if(FAILED(hr = GetColumnInfo(pIRowset,

&nCols,

&pColumnsInfo,

&pColumnStrings)))

{

//Process error.

goto SAFE_EXIT;

}

//Create the binding structures.

CreateDBBindings(nCols,

pColumnsInfo,

&pDBBindings,

&pRowValues);

pDBBindStatus = new DBBINDSTATUS[nCols];

if (sizeof(TCHAR) != sizeof(WCHAR))

{

pMultiByte = new char[pDBBindings[0].cbMaxLen];

}

if(FAILED(pIRowset->QueryInterface(IID_IAccessor,

(void**)&pIAccessor)))

{

//Process error.

goto SAFE_EXIT;

}

//Create the rowset accessor.

if(FAILED(hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,

nCols,

pDBBindings,

0,

&hAccessorRetrieve,

pDBBindStatus)))

{

//Process error.

goto SAFE_EXIT;

}

//Process all the rows, NUMROWS_CHUNK rows at a time.

while (SUCCEEDED(hr))

{

hr=pIRowset->GetNextRows(NULL,

0,

NUMROWS_CHUNK,

&cRowsObtained,

&pRows);

if(FAILED(hr))

{

//process error

}

if(cRowsObtained == 0 || FAILED(hr))

break;

for(iRow = 0; iRow < cRowsObtained; iRow++)

{

//Get the rowset data.

if(SUCCEEDED(hr = pIRowset->GetData(pRows[iRow],

hAccessorRetrieve,

pRowValues)))

{

psSourceType = (short *)(pRowValues +

pDBBindings[3].obValue);

if (*psSourceType == DBSOURCETYPE_DATASOURCE)

{

DSSeqNumber = DSSeqNumber + 1;

//Data source counter.

pDatasource = (pRowValues +

pDBBindings[0].obValue);

if(sizeof(TCHAR) != sizeof(WCHAR))

{

WideCharToMultiByte(CP_ACP, 0,

(WCHAR*)pDatasource, -1, pMultiByte,

pDBBindings[0].cbMaxLen, NULL, NULL);

printf( "DataSource# %d\tName: %S\n",

DSSeqNumber, (WCHAR *) MultiByte );

}

else

{

printf( "DataSource# %d\tName: %S\n",

DSSeqNumber, (WCHAR *) pDatasource );

} //if

} //if

} //if

} //for

pIRowset->ReleaseRows(cRowsObtained, pRows, NULL,

NULL, NULL);

} //while

//Release COM library.

CoUninitialize();

return(0);

SAFE_EXIT:

//Do the clean-up.

return TRUE;

};