Compartir a través de


Leer cadenas desde el proveedor OLE DB

La función CCustomRowset::Execute abre un archivo y lee cadenas. El consumidor pasa el nombre de archivo al proveedor llamando a ICommandText::SetCommandText. El proveedor recibe el nombre de archivo y lo almacena en la variable miembro m_strCommandText. Execute lee el nombre de archivo desde m_strCommandText. Si el nombre de archivo no es válido o el archivo no está disponible, Execute devuelve un error. De lo contrario, abre el archivo y llama a fgets para recuperar las cadenas. Para cada conjunto de cadenas que lee, Execute crea una instancia del registro de usuario (CCustomWindowsFile modificada a partir del almacenamiento de cadenas en el proveedor OLE DB) y la coloca en una matriz.

Si no se puede abrir el archivo, Execute debe devolver DB_E_NOTABLE. Si devuelve E_FAIL en su lugar, el proveedor no funcionará con muchos consumidores y no superará las pruebas de conformidad de OLE DB.

Ejemplo

/////////////////////////////////////////////////////////////////////////
// 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;
    }
};

Una vez hecho esto, el proveedor debe estar listo para compilarse y ejecutarse. Para probar el proveedor, necesita un consumidor con funcionalidad coincidente. Implementar un consumidor sencillo muestra cómo crear un consumidor de prueba de este tipo. Ejecute el consumidor de prueba con el proveedor y compruebe que el consumidor de prueba recupera las cadenas adecuadas del proveedor.

Cuando haya probado correctamente el proveedor, es posible que quiera mejorar su funcionalidad mediante la implementación de interfaces adicionales. Se muestra un ejemplo en Mejorar un proveedor sencillo de solo lectura.

Consulte también

Implementar un proveedor sencillo de solo lectura