Einlesen von Zeichenfolgen in den OLE DB-Anbieter
Die CCustomRowset::Execute
Funktion öffnet eine Datei und liest Zeichenfolgen. Der Consumer übergibt den Dateinamen an den Anbieter, indem "ICommandText::SetCommandText" aufgerufen wird. Der Anbieter empfängt den Dateinamen und speichert ihn in der Membervariable m_strCommandText
. Execute
liest den Dateinamen von m_strCommandText
. Wenn der Dateiname ungültig ist oder die Datei nicht verfügbar ist, Execute
wird ein Fehler zurückgegeben. Andernfalls wird die Datei geöffnet und aufruft fgets
, um die Zeichenfolgen abzurufen. Erstellt für jeden gelesenen Satz von Zeichenfolgen Execute
eine Instanz des Benutzerdatensatzes (geändert CCustomWindowsFile
vom Speichern von Zeichenfolgen im OLE DB-Anbieter) und platziert ihn in einem Array.
Wenn die Datei nicht geöffnet werden kann, Execute
muss DB_E_NOTABLE zurückgegeben werden. Wenn sie stattdessen E_FAIL zurückgibt, funktioniert der Anbieter nicht mit vielen Verbrauchern und besteht nicht die OLE DB-Konformitätstests.
Beispiel
/////////////////////////////////////////////////////////////////////////
// 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;
}
};
Wenn dies geschehen ist, sollte Ihr Anbieter bereit sein, kompilieren und ausführen zu können. Um den Anbieter zu testen, benötigen Sie einen Consumer mit übereinstimmenden Funktionen. Die Implementierung eines einfachen Verbrauchers zeigt, wie ein solcher Testanwender erstellt wird. Führen Sie den Testanwender mit dem Anbieter aus, und stellen Sie sicher, dass der Testanwender die richtigen Zeichenfolgen vom Anbieter abruft.
Wenn Sie Ihren Anbieter erfolgreich getestet haben, sollten Sie die Funktionalität verbessern, indem Sie zusätzliche Schnittstellen implementieren. Ein Beispiel ist in der Verbesserung des einfachen schreibgeschützten Anbieters dargestellt.