Чтение строк в поставщике OLE DB
Функция CCustomRowset::Execute
открывает файл и считывает строки. Потребитель передает имя файла поставщику путем вызова ICommandText::SetCommandText. Поставщик получает имя файла и сохраняет его в переменной-члене m_strCommandText
. Execute
считывает имя файла из m_strCommandText
. Если имя файла недопустимо или файл недоступен, Execute
возвращает ошибку. В противном случае он открывает файл и вызовы fgets
для получения строк. Для каждого набора строк, которые он считывает, Execute
создает экземпляр записи пользователя (измененной CCustomWindowsFile
из хранимых строк в поставщике OLE DB) и помещает его в массив.
Если файл не удается открыть, 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;
}
};
После этого поставщик должен быть готов к компиляции и выполнению. Для тестирования поставщика требуется потребитель с соответствующими функциями. Реализация простого потребителя показывает, как создать такого тестового потребителя. Запустите тестовый потребитель с поставщиком и убедитесь, что тестовый потребитель получает правильные строки от поставщика.
При успешном тестировании поставщика может потребоваться улучшить ее функциональность, реализуя дополнительные интерфейсы. Пример показан в разделе "Повышение простого поставщика только для чтения".
См. также
Реализация простого поставщика, предназначенного только для чтения