Смекни!
smekni.com

Введение в ADO (стр. 1 из 3)

1. Введение.

ADO - интерфейс, призванный обеспечить клиентское приложение доступом и возможностями манипулирования внешними данными. ADO является интерфейсом программного уровня к OLE DB (интерфейсом чрезвычайно удобным и высокопроизводительным). ADO и OLE DB составляют вместе технологию Универсального Доступа к Данным(UDA). При этом, являясь интерфейсом высокого уровня к OLE DB, ADO использует OLE DB поставщики данных (на данный момент это, в основном, провайдеры реляционных баз данных, хотя уже появляются поставщики для нереляционных источников данных и систем электронной почты).

Стоит отметить, что корпорация Microsoft во всеуслышанье заявляет, что ADO в ближайшее время заменит огромное разнообразие моделей и технологий доступа к данным, включая такие методы самой Microsoft, как DAO, RDO.

Примечание:

В дальнейшем в статье подразумевается, что читатель знаком с интерфейсами OLE DB, такими понятиями, поставщик и потребитель данных, имеет базовые знания по COM.

Также хотелось бы отметить, что данная статья явилась результатом попытки автора тщательно разобраться в технологии ADO и систематизировать полученные в итоге знания (а также сведения из лит.источников) и, естественно, статья не может на что-то претендовать (кроме критики J,) тем более на оригинальность.

2. Объектная модель ADO.

ADO состоит из следующих основных компонентов:

Объекты:

Connection. ADO использует объекты Connection для предоставления отдельных соединений с источником данных.

Command. Объекты Command используются для предоставления конкретных команд, выполняемых над источником данных. Эти объекты используются для отслеживания параметров, связанных с командой.

Parameter. Объекты Command содержат коллекцию Parameters, включающую все связанные с командой параметры. Каждый отдельный объект Parameter служит для хранения информации о параметре, передаваемом в исполняемую команду или возвращаемом в ней.

Recordset. Объекты Recordset обеспечивают взаимодействие с данными. Они используются для хранения набора записей, возвращаемого из источника данных.

Field. Объекты Recordset содержат коллекцию объектов Field, используемых для для работы с отдельными столбцами группы строк.

Property. Объекты Connection, Command, Recordset, Field содержатколлекциюProperties объектов Property. Объекты Property служат для представления дополнительных параметров или свойств объекта ADO, которые не могут управляться встроенными свойствами объекта.

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

Коллекции:

Fields.

Properties.

Parameters.

Errors.

3.Немного о директиве #import

Директива препроцессора #import позволяет автоматически создавать библиотеку типов COM с классами С++ для COM интерфейсов. Это очень удобно, если у вас отсутствует доступ к MIDL-файлам. Использование этой директивы Visual C++ существенно упрощает работу с объектами, методами и свойствами ADO.

При включении директивы #import препроцессор компилятора формирует два заголовочных файла, содержащих библиотеку типов в виде исходного текста на С++. Главный заголовочный файл (с расширением .tlh) содержит описание классов плюс объявление интеллектуального указателя (smart pointer - _com_ptr_t):

_COM_SMARTPTR_TYPEDEF(INameOfInterface, __uuidof(INameOfInterface));

При подобном использовании макроса _COM_SMARTPTR_TYPEDEF компилятор объявляет интеллектуальный указатель INameInterfacePtr.

Примечание: _com_ptr_t - шаблонный класс, инкапсулирующий указатель на COM-интерфейс. Объект _com_ptr_t автоматически вызывает методы инкапсулированного в нем интерфейса AddRef() при создании объекта и Release() при выходе объекта из области видимости, корректно управляя существованием COM-объекта.

Вспомогательный заголовочный файл (.tli) содержит реализацию классов библиотеки типов.

Директива #import имеет вид:

#import "имя_файла" [атрибуты]

или

#import <имя_файла> [атрибуты]

имя_файла - обычно файл следующих типов: .tlb, .odl, .dll, .exe, .ocx.

атрибуты:

exclude - исключает генерируемого в заголовочных файлах кода определенные элементы или библиотеки типов

high_method_prefix - задает префикс, который будет ставится в начале имен методов и свойств верхнего уровня

high_property_prefixes - задает префикс для стандартных имен Get, Put и PutRef, который будет поставлен в начале имени метода при обращении к свойству.

implementation_only - запрещает создание основного заголовочного файла

include(…) - включает объявления других библиотек типов, определение которых встречаются в других системных файлах

inject_statement - помещает строку текста в начале объявления объявления пространства имен заголовочного файла для библиотеки типов.

named_guides - указывает компилятору определить и инициализировать переменные со старыми GUID

no_auto_exclude - запрещает автоматическое исключение определений элементов

no_implementation - запрещает генерацию файла .tli

no_namespace - Не используется пространство имен, спецификация которого находится в операторе library

raw_dispinterfaces - указывает компилятору генерировать все вызовы методов и свойств посредством функции Invoke и возвращать код ошибки HRESULT. Оболочки верхнего уровня не генерируются.

raw_interfaces_only - позволяет предоставить содержимое библиотеки типов только нижнего уровня, подавляя генерацию заготовок функций верхних уровней

raw_method_prefix - присоединяет к заданному имени префикс raw_, который обычно подключается к функциям-членам низкого уровня

raw_native_types - заставляет использовать типы данных нижнего уровня (вместо _bstr_t - BSTR, вместо _variant_t - VARIANT)

raw_property_prefixes - позволяет задать префикс нижнего уровня для методов-свойств put, get и putref

rename - переименовывает библиотеку типов и предотвратить повторное использование имен

rename_namespace - указывает пространство имен, содержащее информацию о библиотеке типов.Итак, после нудных разъяснений по директиве #import, рассмотрим, каким образом ее (директиву) можно использовать для включения интерфейсов ADO в наше приложение.

Пропишем в файл stdafx.h (например) пресловутую директиву следующим образом:

#import "c:Program FilesCommon FilesSystemADOmsado15.dll"

no_namespace rename("EOF","ADOEOF")

В данном случае создаются классы из библиотеки типов msado15.dll, реализующей объекты ADO и поставляемой в рамках OLE DB SDK.

В параметре rename приходится переименовывать ADO константу EOF, так как она уже используется в заголовочных файлах stdio.h, ios.h, stream.h, включенных в afxwin.h.

4. Инициализация COM.

Здесь все просто:

перед работой с объектами ADO необходимо инициализировать среду COM. Делается это посредством вызова API функции

HRESULT CoInitialize(LPVOID pvReserved );

где

pvReserved пареметр, равный NULL .

Для выгрузки COM применяется функция

void CoUninitialize();

5. Установка соединения с источником данных.

Для этих целей, как отмечалось выше, используется объект Connection (подключение к источнику данных и управление этим подключением осуществляется с помощью методов Open(), Close() объекта Connection) .Хотя, стоит заметить, что вы можете не создавать его самостоятельно. Можно просто позволить ADO создать соединение, используемое объектами Recordset и Command. Однако вам необходимо создать объект Connection, если предполагается управление транзакциями (для создания и управления транзакциями предназначены следующие методы Connection: BeginTrans(), CommitTrans() и RoolbackTrans()).

Итак, создание соединения. Для этого предпринимаем следующие шаги:

1. Объявляем указатель на соединение:

_ConnectionPtr pConn;

2. Создаем объект Connection с помощью функции CreateInstance():

HRESULT CreateInstance( const CLSID& rclsid, IUnknown* pOuter=NULL, DWORD dwClsContext = CLSCTX_ALL )

где

rclsid - CLSID объекта;

pUnknown - указатель на внешний интерфейс при агрегировании;

dwClsContext - контекст запуска исполняемого кода.

Пример:

HRESULT hr;

hr = pConn.CreateInstance(__uuidof(Connection));

или

hr = pConn.CreateInstance(__uuidof(Connection), NULL,CLSCTX_INPROC_SERVER );

3. после создания экземпляра класса Connection создаем соединение. Сэтойцельювызываемметод Open объекта Connection.

HRESULT Open(_bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options=NULL);

ConnectionString - строка соединения (см.табл.1.1 и 1.2).

UserID - имя пользователя для подключения к источнику данных

Password - пароль пользователя

Options - позволяет указать, каким образом будет осуществляться соединение - синхронно (adConnectUnspecified) или асинхронно(adAsyncConnect).

Таблица 1.1. Вид строки соединения, передаваемой в метод Open(...) объекта Connection для различных OLE DB поставщиков (MSDN)

Источник данных Строка соединения OLE DB
Microsoft® Access Provider=Microsoft.Jet.OLEDB.4.0;Data Source=physical path to .mdb file
Microsoft SQL Server Provider=SQLOLEDB.1;Data Source=path to database on server
Oracle Provider=MSDAORA.1;Data Source=path to database on server
Microsoft Indexing Service Provider=MSIDXS.1;Data Source=path to file

Таблица 1.2. Вид строки соединения, передаваемой в метод Open(...) объекта Connection для различных ODBC поставщиков данных (MSDN)

Источник данных Строка соединения ODBC
Microsoft Access Driver={Microsoft Access Driver (*.mdb)};DBQ=physical path to .mdb file
SQL Server DRIVER={SQL Server};SERVER=path to server
Oracle DRIVER={Microsoft ODBC for Oracle};SERVER=path to server
Microsoft Excel Driver={Microsoft Excel Driver (*.xls)};DBQ=physical path to .xls file; DriverID=278
Microsoft Excel 97 Driver={Microsoft Excel Driver (*.xls)};DBQ=physical path to .xls file;DriverID=790
Paradox Driver={Microsoft Paradox Driver (*.db)};DBQ=physical path to .db file;DriverID=26
Text Driver={Microsoft Text Driver (*.txt;*.csv)};DefaultDir=physical path to .txt file
Microsoft Visual FoxPro® (with a database container) Driver={Microsoft Visual FoxPro Driver};SourceType=DBC;SourceDb=physical path to .dbc file
Microsoft Visual FoxPro (without a database container) Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDb=physical path to .dbf file

Следующий пример показывает установку соединения с базой данных pubs, входящей в стандартный пакет поставки MS SQL Server 7.0 с помощью OLE DB поставщика:

_ConnectionPtr pConn = NULL;

_bstr_t strConn = "Provider=sqloledb;Data Source=(local);Initial Catalog=pubs";

try

{

pConn.CreateInstance(__uuidof(Connection));

pConn->Open(strConn,"sa","",adConnectUnspecified);

}

catch(_com_error e)

{

//Обработка ошибок соединения

}

Примечание:

Исключения в ADO. Для обработки исключений ADO необходимо обеспечить блок catch для объекта _com_error. Этот класс используется для возврата ошибок из классов, сгенерированных директивой #import. Класс _com_error инкапсулирует генерируемые значения HRESULT и любые объекты IErrorInfo, сгенерированные поставщиком OLE DB.