Поделиться через


Чтение строк в поставщике 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;
    }
};

После этого поставщик должен быть готов к компиляции и выполнению. Для тестирования поставщика требуется потребитель с соответствующими функциями. Реализация простого потребителя показывает, как создать такого тестового потребителя. Запустите тестовый потребитель с поставщиком и убедитесь, что тестовый потребитель получает правильные строки от поставщика.

При успешном тестировании поставщика может потребоваться улучшить ее функциональность, реализуя дополнительные интерфейсы. Пример показан в разделе "Повышение простого поставщика только для чтения".

См. также

Реализация простого поставщика, предназначенного только для чтения