· об'єкт Session (сеанс) управляє взаємодією з джерелом даних - виконує запити й створює результуючі набори. Сеанс також може повертати метадані. У сеансі може створюватися одна або кілька команд;
· об'єкт Rowset (результуючий набір) являє собою дані, що витягають у результаті виконання команди або створювані в сеансі.
На наступній схемі (рис. 3.2) наведений приклад використання інтерфейсів базового рівня для створення результуючого набору.
Специфікація OLE DB визначає об'єкт Command (команда), призначений для виконання текстової команди. Як така команда може виступати й SQL-оператор. При цьому виконання команди може створювати результуючий набір (у випадку SQL-оператора - це оператор SELECT).
Деякі OLE DB провайдери підтримують роботу зі схемою (Schema), що надає метадані по БД. Метадані стають доступні як звичайні результуючі набори. У заголовному файлі oledb.h утримуються унікальні ідентифікатори всіх доступних типів результуючих наборів схеми даних (наприклад, для одержання інформації з таблиць БД варто вказати унікальний ідентифікатор DBSCHEMA_TABLES). Стовпець результуючого набору з ім'ям TABLE_NAME містить ім'я таблиці, стовпець TABLE_TYPE указує один із таких типів таблиці: ALIAS, TABLE, SYNONYM, SYSTEM TABLE, VIEW, GLOBAL TEMPORARY, LOCAL TEMPORARY, SYSTEM VIEW.
Рисунок 3.2 – Схема створення результуючого набору
Подання (View) визначає підмножину рядків і стовпців із набору даних, але саме не містить їх. Подання не можуть поєднувати дані з декількох наборів даних.
Для забезпечення розширених можливостей керування транзакціями об'єктна модель OLE DB включає об'єкт Transaction.
Для кожного об'єктного типу специфікація OLE DB визначає набір інтерфейсів, що повинен обов'язково бути реалізований для даного об'єкта. Такі інтерфейси відзначаються як [mandatory]. Інтерфейси, які можуть бути відсутніми, відзначаються як [optional]. Усі об'єкти об'єктного типу Rowset повинні реалізовувати такі інтерфейси: інтерфейс IRowset, який використовується для добування рядків; інтерфейс IAccessor, який використовуєтсья для визначення зв'язування; інтерфейс IColumnsInfo, що надає інформацію про стовпці результуючого набору; інтерфейс IRowsetInfo, що надає інформацію про самий результуючий набір; інтерфейс IConvertType, що надає інформацію про перетворення типів даних,
підтримуваних у результуючому наборі.
При реалізації доступу до БД за допомогою OLE DB провайдера спочатку варто створити об'єкт даних й установити з'єднання з БД. Далі необхідно створити об'єкт "сеанс". І тільки потім можна створювати результуючий набір.
Механізм створення об'єкта "сеанс" наведений на схемі (рис. 3.3).
Рисунок 3.3 – Схема механізму створення об’єкта «сеанс»
Результуючий набір може бути створений одним із таких способів:
Для об'єкта "сеанс" викликається метод IOpenRowset::OpenRowset, що виконує безпосереднє створення результуючого набору (інтерфейс IOpenRowset повинен підтримуватися будь-яким провайдером);
Для об'єкта "сеанс" викликається метод IDBCreateCommand::CreateCommand, що створює об'єкт Command. Далі для об'єкта "команда" викликається метод ICommand::Execute. (при використанні інтерфейсу IMultipleResults можна працювати з декількома результуючими наборами);
Викликається один із наступних методів IColumnsRowset::GetColumnsRowset, IDBSchemaRowset::GetRowset, IViewRowset::OpenViewRowset або
ISourcesRowset::GetSourcesRowset.
Щоб результуючий набір, збережений на сервері, можна було використовувати, необхідно виконати зв'язування й добування даних. Для цього слід визначити структури типу DBBINDING, що описують стовпці, і створити аксесор. Далі для одержання рядків результуючого набору можна використати один з наступних методів:
IRowset::GetNextRows;
IRowsetLocate::GetRowsByBookMarks; IRowsetLocate::GetRowAt; IRowsetScroll:: GetRowAtRatio.
На закінчення для запису даних у структуру, визначену аксесором, викликається метод IRowset::GetData.
Після одержання й обробки рядків їх варто звільнити, викликавши метод IRowset::ReleaseRows.
Після перегляду всього результуючого набору слід також звільнити аксесор, викликавши метод IRowset::ReleaseAccessor, і звільнити сам результуючий набір, викликавши метод IRowset::Release.
Інтерфейс IAccessor визначає такі методи:
AddRefAccessor - збільшує число посилань на даний аксесор; CreateAccessor - створює аксесор з набору зв'язувань;
GetBindings - повертає зв'язування, установлені даним аксесором; ReleaseAccessor - звільняє аксесор.
Об'єкт Command повинен реалізовувати такі інтерфейси:
Icommand;
Iaccessor;
IcommandText;
IcolumnInfo;
ICommandProperties.
Для створення команди викликається метод IDBCreateCommand::CreateCommand об'єкта "сеанс".
Алгоритм виконання команди наведений на схемі (рис. 3.4).
Застосування OLE DB дозволяє підтримувати прості, вкладені й розподілені транзакції.
Об'єкт Session для роботи із транзакціями підтримує наступні інтерфейси: інтерфейс ITransactionLocal.
Рисунок 3.4 – Схема виконання методу IDBCreateCommand::CreateCommand
Для початку транзакції викликається метод ITransactionLocal::StartTransaction(). Якщо цей метод викликається з активної транзакції, то відкривається нова вкладена транзакція; інтерфейс ITransaction, що підтримує методи Abort, Commit й GetTransactionInfo; інтерфейс ITransactionJoin, що реалізує підтримку розподілених транзакцій.
Об'єкт Transaction дозволяє реалізовувати більш широкі можливості керування транзакціями, підтримуючи такі інтерфейси:
ITransaction, що дозволяє виконати переривання транзакції (методи Abort, Commit, GetTransactionInfo);
IConnectionPointContainer, що підтримує керування крапками з'єднання для об'єктів, що з'єднують.
VCL-бібліотека класів середовища проектування Delphi надає ряд класів, що дозволяють швидко й ефективно розробляти різні додатки БД. Ці класи подані такими групами:
· компоненти для доступу до даних, реалізуючі: доступ через машину БД BDE (Borland Database Engine), який надає доступ через ODBC-драйвери або через внутрішні драйвери машини БД BDE (компоненти сторінки BDE-палітри інструментів); доступ через ADO-об'єкти (Active Data Objects), в основі якого лежить застосування технології OLE DB (компоненти сторінки ADO); доступ до локального або вилученого SQL-сервера InterBase (компоненти сторінки InterBase); доступ за допомогою легковагих драйверів dbExpress;
доступ до БД при багатоланковій архітектурі (компоненти сторінки DataSnap);
· візуальні компоненти, що реалізують інтерфейс користувача;
· компоненти для зв'язку джерел даних із візуальними компонентами, які надають інтерфейс користувача;
· компоненти для візуального проектування звітів.
Основними механізмами доступу до даних, підтримуваними в Delphi, є:
· ODBC - доступ через ODBC-драйвери БД або BDE-драйвери;
· OLE DB - доступ з використанням провайдерів даних (OLE DB - це метод доступу до будь-яких даних через стандартний COM-інтерфейс);
· засоби dbExpress, що використовують легковагі драйвери БД;
· засоби доступу до розподілених наборів даних у багатоланковій архітектурі.
Найпростіший механізм керування даними, що використовують ODBC-драйвери, може бути реалізований за такою схемою:
У модуль даних (або у форму) додається компонент набору даних (об'єкт класу TDataSet) і встановлюється зв'язок із джерелом даних, обумовлене властивістю DatabaseName. Зв'язок може бути зазначений одним із трьох способів: по імені БД, каталогу або псевдоніму (спосіб вказівки зв'язки може бути обмежений типом джерела даних). Список всіх псевдонімів доступний на етапі проектування.
У модуль даних (або у форму) додається компонент джерела даних (TDataSourse), що є центральною сполучною ланкою між набором даних й елементами керування, що відображають ці дані. Властивість DataSet компонента типу TDataSourse указує набір даних, формована компонентами таких класів як TTable або TQuery. Якщо компоненти набору даних і джерела даних розміщені в модулі даних, то їх варто додати в проект (команда меню File | Use unit).
У форму додаються елементи керування для роботи з даними, такі як TDBGrid, TDBEdit, TDBCheckbox. Вони зв'язуються з компонентом джерела даних, що вказується властивістю DataSource. Ім'я поля набору даних визначається властивістю DataField.
Графічно схему роботи з базами даних для дволанкових архітектур у середовищі Delphi можна представити в спосіб, який показано на рис. 3.5.
Для збереження даних із БД в XML-форматі або двійковому форматі, і назад, для формування набору даних з XML або двійкового файлу застосовується провайдер даних.
Базою всіх класів наборів даних є клас TDataSet. Він визначає основу структури всіх наборів даних - масив компонентів типу TField (кожен елемент масиву відповідає стовпцю таблиці).
Набір даних - це впорядкована послідовність рядків, витягнутих із джерела даних. Кожен рядок набору даних складається з полів, що вказують у властивостях класу.
Залежно від механізму доступу, який використовується додатком, базовими класами набору даних можуть бути:
TTable, TQuery, TStoredProc - для одноланкових або дволанкових додатків, які використовують машину БД BDE. Клас TQuery додатково дозволяє виконувати параметричні запити;
TClientDataSet - для реалізації клієнтського набору даних і для багатоланкової архітектури, яка використовує розподілений доступ;
TADODataSet - для додатків, які використовують ADO-об'єкти;
TSQLDataSet - для доступу до БД за допомогою dbExpress. Цей клас реалізує спрямований набір даних, що функціонує за принципом курсору. Для такого набору даних не створюється кеш пам'яті на клієнті, і серед методів доступу можливі тільки методи Next й First. Редагування записів у спрямованому наборі даних можливо тільки явним виконанням SQL-оператора UPDATE або при установці з'єднання з клієнтським набором даних через провайдера;