Библиотека Интернет Индустрии I2R.ru |
|||
|
Эффективное преобразование типов при работе с OLE DBВ статье речь пойдёт о применении стандартных средств OLEDB к задачам безопасных и эффективных преобразований типов. Важность задач этого типа является следствием широкого распространения подхода, при котором в ряде крупных коммерческих продуктов в качестве библиотеки для работы с СУБД используется OLE DB. Краткое введение Ряд крупных проектов современности (в том числе и тот, в котором работаю я) используеют в качестве библиотеки для работы с данными OLE DB. Будучи набором сравнительно низкоуровневых интерфейсов, OLE DB позволяет создавать на C++ высокоэффективный код для работы с данными. Об эффективности OLE DB говорит хотя бы то, что библиотека ADO, крайне распространённая среди пользователей VB, построена на базе OLE DB. OLE DB является универсальным средством работы с данными и краеугольным камнем концепции UDA. По большому счёту, все объекты в OLE DB делятся на 2 группы: Потребители и Поставщики (consumers и providers, соответственно). Суть концепции "Поставщика" в представлении любого необходимого набора данных в виде совокупности строк упорядоченной некоторым образом информации. Очевидно, любую информацию можно представить в виде строк данных (хотя бы для этого и пришлось поместить её в малопонятный снаружи BLOB). Концепция "Потребителя" ещё проще: данные, предоставляемые "Поставщиком", используются для извлечения из них информации общепринятым образом: при помощи запросов или манипуляции с отдельным полями структур, которыми физически являются строки, предоставляемые "Поставщиком". Microsoft предоставляет пользователям своих продуктов целый ряд "Поставщиков". С их списком можно ознакомиться в описании к MDAC - the Microsoft Data Access Components - которое можно найти в MSDN. Кроме задач обеспечения возможности написания кода, который впоследствии будет использоваться в объектах-"поставщиках" или объектах-"потребителях", OLE DB предоставляет своим пользователям целый ряд средств, применение которых не связано непосредственно с "базами данных". Одним из таких средств является интерфейс IDataConvert. Круг решаемых задач Актуальность задач конвертирования данных очевидна: в том случае, когда из типа DATE необходимо получить его ts-эквивалент лучше знать, как это делается, вместо того, чтобы придумывать своё, возможно, оригинальное, но требующее дополнительного тестирования решение. Вместо столь неэффективной траты времени предлагается использовать библиотеку преобразования типов OLE DB. Её существенно преимущество по сравнению с прочими решениями заключается в том, что предлагаемыми средствами можно пользоваться в любом проекте на C++, с какой бы другой (MFC и/или, ATL) библиотекой он ни работал. Для использования библиотеки преобразования типов необходимо и достаточно включить два заголовочных файла: #include Используя msdadc.dll становится возможны решение следующих задач:
Иногда даже первая задача являет собой вызов программистскому мастерству, а сложности, связанные со второй могут превосходить все разумные пределы. В то же время IDataConvert позволяет выполнять следующие, не всегда тривиальные, преобразования: Таблица 1. Некоторые преобразования
IDataConvert Интерфейс IDataConvert - сердце библиотеки преобразования типов. Он составлен тремя методами (здесь и далее по ссылке откроется новое окно с кодом примера). Каждый из этих методов отвечает за свою часть работы по преобразованию данных:
Функционирование Проиллюстрирую использование всех трёх функций на задаче, которую недавно пришлось решать: необходимо максимально эффективно решить проблему преобразования даты Windows в её строковое ts-представление. То есть, осуществить преобразование DATE -> DBTIMESTAMP -> CHAR. Алгоритм выполнения этого задания:
Хочу подчеркнуть важность первого шага этого алгоритма. В некоторых местах описание преобразований, предоставляемое MSDN, является неверным, поэтому, несмотря на данные в табл. 1, преобразования может не произойти. Проверка допустимости является обязательной. Выполнить саму проверку просто. Если ds - переменная типа IDataConvert, то проверка возможности преобразования переменной типа DBTYPE_A в DBTYPE_B выглядит следующим образом: HRESULT hr = ds->CanConvert(DBTYPE_A, DBTYPE_B) Возвращаемый результат может принимать одно из трёх значений:
Преобразование из DBTYPE_A в DBTYPE_B выполняется так: hr = dc->DataConvert(DBTYPE_A, DBTYPE_B, sizeof(src_buff), &dest_size, (PVOID)&src_buff, (PVOID)&dest_buff, MAX_SIZE_OF_DEST_BUFFER, DBSTATUS_S_OK, &afterop, 0, 0, DBDATACONVERT_DEFAULT); Листинг 1. Шаблон вызова метода преобразования параметров Так, например, преобразование из типа DBTYPE_DATE в тип DBTYPE_STR выполняется следующим фрагментом кода: char * buffer = new char[BIG_ENOUGH]; DBSTATUS after_operation = -1; DATE date; ULONG size_needed; hr = dc->DataConvert(DBTYPE_DATE, DBTYPE_STR, sizeof(DATE), &size_needed, (PVOID)&date, (PVOID)buffer, BIG_ENOUGH, DB_STATUS_OK, &after_operation, 0, 0, DBDATACONVERT_DEFAULT); Листинг 2. Преобразование из типа DATE в тип char Последний параметр, имеющий тип DBDATACONVERT может принимать одно из трёх значений:
Четвёртый параметр, pcbDstLength, при удачном вызове метода будет содержать размер буфера, в который будут помещены результаты преобразования. Это может быть полезно в случае использования типов данных переменной длины. Шестой параметр, pDst, или в листинге 2, (PVOID)buffer, не так одназначен, как можно подумать, глядя на его сигнатуру. Дело в том, что наряду с одним уровнем косвенности - PVOID - он может работать и с (PVOID*). Более подробная информация об использовании буфера в такой роли может быть получена здесь: mk:@MSITStore:C:\MSDN-I~1\MSDN\oledb.chm::/htm/oledbtype_indicators.htm. Девятый параметр, pdbsStatus, или в листинге 2, &after_operation содержит информацию о состоянии объекта преобразования после выполнения операции и, являясь стандартным индикатором OLE DB, принимает одно из значений перечисления DBSTATUSENUM. Дополнительная польза от этого параметра может быть получена в том случае, когда требуется получить расширенную информацию о произошедшей во время преобразования ошибке. Заключительное замечание: при компиляции кода, написанного в соответствии с последними спецификациями Microsoft, можно столкнуться с тем, что в некоторых случаях код не будет компилироваться, выдавая нечто вроде: "undefined symbol DBLENGTH", когда вы будете пользоваться этим типом. Причина проста: в настоящее время существуют по меньшей мере две различные версии заголовочных файлов OLE DB. Одна из этих версий входит в состав Visual C++, а другая, более новая, в состав Platform SDK. Если проект, в котором вы сейчас работаете, позволяет это, я рекомендую использовать ту версию заголовочных файлов, которая входит в состав SDK. |
|
2000-2008 г. Все авторские права соблюдены. |
|