Случилось страшное!!! Провайдер для ТП и параметризованные запросы оказались несовместимыми! При умолчальном значении OLEDB_SERVICES для ключа HKEY_CLASSES_ROOT\CLSID\{50BAEED9-ED25-11D2-B97B-000000000000} параметризованные запросы не работают. При нулевом значении такие запросы работают, но подыхает провайдер
Похоже, при этом отваливается возможность получения IRowsetLocate. Ладно, переделал под использование IRowset и оно заработало. (
Но, блин, YAHOOею от этих приколов )
Итак:
- параметризованные запросы в 1С++ восстановлены.
- в OLEDBCommand вставлено свойство "РазмерПорцииСтрок": по сколько строк за раз забирать из выборки данных OLE DB. Насколько оно влияет на скорость не проверял.
Описание изменений в 1С++.Основные изменения внесены в класс COLEDBCommand. Суть изменений: метод funcExecuteStatement вынесен в отдельный класс - OleDb::CResult, обрабатывающий результат запроса (в виде IRowset) и предоставляющий методы для получения информации о колонках и методы для получения значений строк в объекты CValue. В результате заполнение ТЗ в funcExecuteStatement свелось к этому простому коду:
CValue Value;
ULONG nRow = 0;
while (Result.GetNextRow ()) {
pVT->NewRow(nRow);
for (ULONG nCol = 0; nCol < cCols; ++nCol) {
Result.GetFieldValue(nCol, Value);
pVT->SetValue(Value, nCol, nRow);
}
++nRow;
}
Краткое описание OleDb::CResult.
Обязанности класса: подготовка к парсингу полученного результата (инициализация служебных данных), пребразование данных результата в объекты CValue, получение информации о составе колонок. Навигацию по результату сам класс не производит - это обязанность производных классов.
Класс является абстрактным базовым классов для классов CResultSequentialAccess и CResultDirectAccess.
Класс принимает в конструкторе интерфейс IRowset.
В класс перенесены из COLEDBCommand методы Binding, CreateAccessor, GetType1C, FindKindCol, AddOffset, GetErrorDescription.
Код преобразования данных OLE DB в CValue вынесен в метод GetFieldValue. Этот код был очень огромным (очень сложно было его понимать), поэтому он разделен на несколько простых функций: ReadLongField, ReadNumericField, ReadBoolField, ReadDateField, ReadTimestampField, ReadWideStringField, Read1SField.
Открытый интерфейс OleDb::CResult:
CResult (IRowset *pRowset) - конструктор
bool IsEmpty () const - проверка на пустой результат
ULONG GetNumFields () const - получить количество полей
CString const &GetFieldName (ULONG Field) const - получить имя поля
CType const &GetFieldType (ULONG Field) const - получить тип значения поля
bool GetFieldValue (ULONG Field, CValue &Value) - получить значение поля текущей строки
Класс OleDb::CResultSequentialAccess - производный от OleDb::CResult. Работает с результатом при помощи последовательного доступа. Открытый интерфейс:
CResultSequentialAccess (IRowset *pRowset, UINT RowsChunk = DEFAULT_ROWS_CHUNK) - конструктор, принимает результат запроса и размер порции строк.
bool GetNextRow () - получение следующей строки.
Класс OleDb::CResultDirectAccess - производный от OleDb::CResult. Позволяет работать с результатом запроса при помощи произвольного доступа - т.е. позволяет получить строку по индексу. Открытый интерфейс:
CResultDirectAccess (IRowset *pRowset) - конструктор
bool GetRow (ULONG Row) - получить строку по индексу.
Изменения, обеспечивающие взаимодействие с другими ВКCOLEDBCommand::CreateCommand объявлена как DLLEXPORT. Это позволяет сторонней ВК создать команду, имея контекст "OLEDBData".
Добавлен класс OleDb::CCommandProxy. Объявление этого класса должно быть одинаково как для 1С++, так и для другой ВК. CCommandProxy по сути является простой оберткой над смартпойнтером для COLEDBCommand (он реализует так называемую идиому pimpl). Класс содержит ряд методов идентичным методам COLEDBCommand. Эти методы просто переадресуют вызов в COLEDBCommand. CCommandProxy объявлен как DLLEXPORT. Класс позволяет вызывать методы COLEDBCommand, не зная структуры COLEDBCommand. Поэтому допустима модификация этого класса без необходимости перекомпиляции сторонних ВК.
Добавлены классы OleDb::CResultProxy, OleDb::CResultSequentialAccessProxy и OleDb::CResultDirectAccessProxy. Это DLLEXPORT-обертки, реализующие идиому pimpl для классов OleDb::CResult, OleDb::CResultSequentialAccess и OleDb::CResultDirectAccess.
В COLEDBCommand добавлены методы ExecuteStatementExternalSequential и ExecuteStatementExternalDirect. Методы выполняют запрос и возвращают объект класса OleDb::CResultSequentialAccessProxy или OleDb::CResultDirectAccessProxy - в зависимости от того типа доступа, который требуется.