ADO - інтерфейс, покликаний забезпечити клієнтське додаток доступом і можливостями маніпулювання зовнішніми даними. ADO є інтерфейсом програмного рівня до OLE DB (інтерфейсом надзвичайно зручним і високопродуктивним). ADO і OLE DB складають разом технологію Універсального Доступу до Даних (UDA). При цьому, будучи інтерфейсом високого рівня до OLE DB, ADO використовує OLE DB постачальники даних (на даний момент це, в основному, провайдери реляційних баз даних, хоча вже з'являються постачальники для нереляційних джерел даних і систем електронної пошти).
Варто зазначити, що корпорація Microsoft на повний голос заявляє, що ADO найближчим часом замінить велике розмаїття моделей і технологій доступу до даних, включаючи такі методи самої Microsoft, як DAO, RDO.
Надалі в статті мається на увазі, що читач знайомий з інтерфейсами OLE DB, такими поняттями, постачальник і споживач даних, має базові знання з COM.
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. Призначені для представлення інформації про помилки, які можуть відбуватися в рамках однієї операції.
3.Немного про директиву #import
Директива препроцесора #import дозволяє автоматично створювати бібліотеку типів COM до класів С ++ для COM інтерфейсів. Це дуже зручно, якщо у вас не маєте доступу до MIDL-файлів. Використання цієї директиви Visual C ++ істотно спрощує роботу з об'єктами, методами і властивостями ADO.
При подібному використанні макросу _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 - забороняє створення основного заголовки
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"
В даному випадку створюються класи з бібліотеки типів 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 застосовується функція
5. Встановлення з'єднання з джерелом даних.
Для цих цілей, як зазначалося вище, використовується об'єкт Connection (підключення до джерела даних і керування цим підключенням здійснюється за допомогою методів Open (), Close () об'єкта Connection) .Хоча, варто зауважити, що ви можете не створювати його самостійно. Можна просто дозволити ADO створити з'єднання, що використовується об'єктами Recordset і Command. Однак вам необхідно створити об'єкт Connection, якщо передбачається управління транзакціями (для створення і управління транзакціями призначені наступні методи Connection: BeginTrans (), CommitTrans () і RoolbackTrans ()).
Отже, створення з'єднання. Для цього робимо наступні кроки:
1. Оголошуємо покажчик на з'єднання:
2. Створюємо об'єкт Connection за допомогою функції CreateInstance ():
HRESULT CreateInstance (const CLSID rclsid, IUnknown * pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
rclsid - CLSID об'єкта;
pUnknown - покажчик на зовнішній інтерфейс при агрегування;
dwClsContext - контекст запуску виконуваного коду.
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)