OLE DB プロバイダーへの文字列の読み込み
CCustomRowset::Execute
関数は、ファイルを開き、文字列を読み取ります。 コンシューマーは、ICommandText::SetCommandText を呼び出すことによって、ファイル名をプロバイダーに渡します。 プロバイダーはファイル名を受け取り、それをメンバー変数 m_strCommandText
に格納します。 Execute
は m_strCommandText
からファイル名を読み取ります。 ファイル名が無効な場合または使用できない場合、Execute
はエラーを返します。 それ以外の場合は、ファイルを開き、fgets
を呼び出して文字列を取得します。 それが読み取る文字列のセットごとに、Execute
はユーザー レコードのインスタンスを作成して (「OLE DB プロバイダーへの文字列の格納」の変更された CCustomWindowsFile
)、配列に格納します。
ファイルを開くことができない場合、Execute
は DB_E_NOTABLE を返す必要があります。 代わりに E_FAIL を返した場合、プロバイダーは多くのコンシューマーで動作せず、OLE DB 準拠テストに合格しません。
例
/////////////////////////////////////////////////////////////////////////
// CustomRS.h
class CCustomRowset : public CRowsetImpl< CCustomRowset, CCustomWindowsFile, CCustomCommand>
{
public:
HRESULT Execute(DBPARAMS * pParams, LONG* pcRowsAffected)
{
enum {
sizeOfBuffer = 256,
sizeOfFile = MAX_PATH
};
USES_CONVERSION;
FILE* pFile = NULL;
TCHAR szString[sizeOfBuffer];
TCHAR szFile[sizeOfFile];
size_t nLength;
ObjectLock lock(this);
// From a filename, passed in as a command text, scan the file
// placing data in the data array.
if (!m_strCommandText)
{
ATLTRACE("No filename specified");
return E_FAIL;
}
// Open the file
_tcscpy_s(szFile, sizeOfFile, m_strCommandText);
if (szFile[0] == _T('\0') ||
(fopen_s(&pFile, (char*)&szFile[0], "r") == 0))
{
ATLTRACE("Could not open file");
return DB_E_NOTABLE;
}
// Scan and parse the file.
// The file should contain two strings per record
LONG cFiles = 0;
while (fgets((char*)szString, sizeOfBuffer, pFile) != NULL)
{
nLength = strnlen((char*)szString, sizeOfBuffer);
szString[nLength-1] = '\0'; // Strip off trailing CR/LF
CCustomWindowsFile am;
_tcscpy_s(am.szCommand, am.iSize, szString);
_tcscpy_s(am.szCommand2, am.iSize, szString);
if (fgets((char*)szString, sizeOfBuffer, pFile) != NULL)
{
nLength = strnlen((char*)szString, sizeOfBuffer);
szString[nLength-1] = '\0'; // Strip off trailing CR/LF
_tcscpy_s(am.szText, am.iSize, szString);
_tcscpy_s(am.szText2, am.iSize, szString);
}
am.dwBookmark = ++cFiles;
if (!m_rgRowData.Add(am))
{
ATLTRACE("Couldn't add data to array");
fclose(pFile);
return E_FAIL;
}
}
if (pcRowsAffected != NULL)
*pcRowsAffected = cFiles;
return S_OK;
}
};
これが完了したら、プロバイダーはコンパイルして実行できる状態になる必要があります。 プロバイダーをテストするには、対応する機能を備えたコンシューマーが必要です。 「単純なコンシューマーの実装」では、このようなテスト コンシューマーを作成する方法が示されています。 プロバイダーを使ってテスト コンシューマーを実行し、テスト コンシューマーがプロバイダーから適切な文字列を取得することを確認します。
プロバイダーのテストが正常に完了したら、追加のインターフェイスを実装して機能を拡張することができます。 例については、「単純な読み取り専用プロバイダーの機能の拡張」をご覧ください。