Станьте совладельцем корпорации
Главная  
  • Программы  
  • Методички  
  • Рефераты  
  • Дипломы  
  • Разное  
  • Фото  
  • Контакты  
  • Карта сайта  
  • Я:
    Найти:
    Возраст:
    -

    Информационная система для предприятия розничной торговли мобильными телефонами и аксессуарами



    Объектная модель OLE DB


    OLE DB представляет собой набор COM-интерфейсов (Component Object Model), которые предоставляют приложению-клиенту унифицированный доступ к различным источникам данных.

    Можно сказать, что OLE DB - это метод доступа к любым данным через стандартные COM-интерфейсы, вне зависимости от типа данных и места их расположения. В качестве данных могут выступать базы данных, простые документы, таблицы Excel и любые другие источники данных. В отличие от доступа, предоставляемого посредством драйверов OBDC, OLE DB позволяет реализовывать доступ к источникам данных, как с применением языка SQL (к SQL-серверам), так и к любым другим произвольным источникам данных.

    Средства, предоставляющие доступ к источнику данных с использованием технологии OLE DB, называются OLE DB провайдерами. Программы-клиенты, использующие для доступа OLE DB провайдеры, называются потребителями данных.

    В том случае, если существует только ODBC-драйвер для доступа к конкретному источнику данных, то для применения технологии OLE DB можно использовать OLE DB провайдер, предназначенный для доступа к ODBC-источнику данных.

    Так как архитектура OLE DB основана на COM, то механизм создания результирующих наборов состоит из последовательностей шагов типа: 1. создание объекта -> 2. запрос указателя на интерфейс созданного объекта -> 3. вызов метода интерфейса.

    Аналогично комплексу действий, который производится после создания результирующего набора при применении технологии ODBC - выполнению связывания, в технологии OLE DB используется механизм аксессоров. Аксессоры описывают, каким образом данные записываются в область памяти потребителя данных, устанавливая адресное соответствие между областью памяти в буфере потребителя данных и столбцами данных в результирующем наборе. Иногда такой набор связей называют картой столбцов (column map).

    Спецификация OLE DB описывает набор интерфейсов, реализуемых объектами OLE DB. Каждый объектный тип определен как набор интерфейсов. Спецификация OLE DB определяет набор интерфейсов базового уровня, которые должны реализовываться любыми OLE DB провайдерами.

    В базовую модель OLE DB входят следующие объекты:

    1) объект DataSource (источник данных), используемый для соединения с источником данных и создания одного или нескольких сеансов. Этот объект управляет соединением, использует информацию о полномочиях и аутентификации пользователя;

    2) объект Session (сеанс) управляет взаимодействием с источником данных - выполняет запросы и создает результирующие наборы. Сеанс также может возвращать метаданные. В сеансе может создаваться одна или несколько команд;

    3) объект Rowset (результирующий набор) представляет собой данные, извлекаемые в результате выполнения команды или создаваемые в сеансе.

    На схеме приведен пример использования интерфейсов базового уровня для создания результирующего набора (рисунок 1).

    Спецификация 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.

    Представление (View) определяет подмножество строк и столбцов из набора данных, но само не содержит их. Представления не могут объединять данные из нескольких наборов данных.

    Для обеспечения расширенных возможностей управления транзакциями объектная модель OLE DB включает объект Transaction.

    OLE DB провайдеры, как и все COM-компоненты, регистрируются в реестре Windows. Для поиска информации о зарегистрированных источниках данных используются специальные объекты, называемые нумераторами. Нумератор - это обычный СОМ-сервер, позволяющий получить информацию об источниках данных в виде результирующего набора. Для создания такого результирующего набора в объектном типе DataSource специфицирован интерфейс IDBEnumerateSources.

    Для каждого объектного типа спецификация OLE DB определяет набор интерфейсов, который должен обязательно быть реализован для данного объекта. Такие интерфейсы отмечаются как [mandatory]. Интерфейсы, которые могут отсутствовать, отмечаются как [optional].

    Для объекта "источник данных" специфицирован следующий набор интерфейсов:

    CoType TDataSource {
         [mandatory] interface IDBCreateSession;
         [mandatory] interface IDBInitialize;
         [mandatory] interface IDBProperties;
         [mandatory] interface IPersist;
         [optional] interface IConnectionPointContainer;
         [optional] interface IDBAsynchStatus;
         [optional] interface IDBDataSourceAdmin;
         [optional] interface IDBInfo;
         [optional] interface IPersistFile;
         [optional] interface ISupportErrorInfo;
    }

    Для объекта "сеанс" специфицирован следующий набор интерфейсов:

    CoType TSession {
         [mandatory] interface IGetDataSource;
         [mandatory] interface IOpenRowset; // Создание набора данных
         [mandatory] interface ISessionProperties;
         [optional] interface IAlterIndex;
         [optional] interface IAlterTable;
         [optional] interface IBindResource;
         [optional] interface ICreateRow;
         [optional] interface IDBCreateCommand;
         [optional] interface IDBSchemaRowset;
         [optional] interface IIndexDefinition;
         [optional] interface ISupportErrorInfo;
         [optional] interface ITableCreation;
         [optional] interface ITableDefinition; // Для создания таблицы
         [optional] interface ITableDefinitionWithConstraints;
         [optional] interface ITransaction;
         [optional] interface ITransactionJoin;
         [optional] interface ITransactionLocal;
         [optional] interface ITransactionObject;
    }

    Для объекта "результирующий набор" специфицирован следующий набор интерфейсов:

    CoType TRowset {
        [mandatory] interface IAccessor;
         [mandatory] interface IColumnsInfo;
         [mandatory] interface IConvertType;
         [mandatory] interface IRowset;// Последовательное
         // чтение таблицы
         [mandatory] interface IRowsetInfo;
         [optional] interface IChapteredRowset;
         [optional] interface IColumnsInfo2;
         [optional] interface IColumnsRowset;
         [optional] interface IConnectionPointContainer;
         [optional] interface IDBAsynchStatus;
         [optional] interface IGetRow;
         [optional] interface IRowsetChange; // Для удаления, изменения и добавления
         // строк в набор данных
         [optional] interface IRowsetChapterMember;
         [optional] interface IRowsetCurrentIndex;
         [optional] interface IRowsetFind;
         [optional] interface IRowsetIdentity;
         [optional] interface IRowsetIndex;
         [optional] interface IRowsetLocate; // Прямое
         // позиционирование на запись набора данных
         [optional] interface IRowsetRefresh; // Для
         // обновления данных в созданном наборе данных
         [optional] interface IRowsetScroll; // Поддержка
         // скроллинга по набору данных
         [optional] interface IRowsetUpdate;
         [optional] interface IRowsetView;
         [optional] interface ISupportErrorInfo;
         [optional] interface IRowsetBookmark;
    }

    Все объекты объектного типа Rowset должны реализовывать следующие интерфейсы:

    1) интерфейс IRowset, используемый для извлечения строк;

    2) интерфейс IAccessor, используемый для определения связывания;

    3) интерфейс IColumnsInfo, предоставляющий информацию о столбцах результирующего набора;

    4) интерфейс IRowsetInfo, предоставляющий информацию о самом результирующем наборе;

    5) интерфейс IConvertType, предоставляющий информацию о преобразовании типов данных, поддерживаемых в результирующем наборе.

    Создание результирующего набора

    При реализации доступа к БД посредством OLE DB провайдера сначала следует создать объект данных и установить соединение с базой данных. Далее необходимо создать объект "сеанс". И только потом можно создавать результирующий набор.

    Механизм создания объекта "сеанс" приведен на рисунке 2.



    Рисунок 2 - Механизм создания объекта "сеанс"

    Результирующий набор может быть создан одним из следующих способов:

    1) для объекта "сеанс" вызывается метод IOpenRowset::OpenRowset, выполняющий непосредственное создание результирующего набора (интерфейс IOpenRowset должен поддерживаться любым провайдером);

    2) для объекта "сеанс" вызывается метод IDBCreateCommand::CreateCommand, создающий объект Command. Далее для объекта "команда" вызывается метод ICommand::Execute. (при использовании интерфейса IMultipleResults можно работать с несколькими результирующими наборами);

    3) вызывается один из следующих методов IColumnsRowset::GetColumnsRowset, IDBSchemaRowset::GetRowset, IViewRowset::OpenViewRowset или ISourcesRowset::GetSourcesRowset.

    Чтобы результирующий набор, хранимый на сервере, можно было использовать, необходимо выполнить связывание и извлечение данных. Для этого следует определить структуры типа DBBINDING, описывающие столбцы, и создать аксессор. Далее для получения строк результирующего набора можно использовать один из следующих методов:

    1) IRowset::GetNextRows;
    2) IRowsetLocate::GetRowsByBookMarks;
    3) IRowsetLocate::GetRowAt;
    4) IRowsetScroll:: GetRowAtRatio.

    В заключение для записи данных в структуру, определенную аксессором, вызывается метод IRowset::GetData.

    После получения и обработки строк их следует освободить, вызвав метод IRowset::ReleaseRows.

    После просмотра всего результирующего набора следует также освободить аксессор, вызвав метод IRowset::ReleaseAccessor, и освободить сам результирующий набор, вызвав метод IRowset::Release.

    Интерфейс IAccessor определяет следующие методы:
    1) AddRefAccessor - увеличивает число ссылок на данный аксессор;
    2) CreateAccessor - создает аксессор из набора связываний;
    3) GetBindings - возвращает связывания, установленные данным аксессором;
    4) ReleaseAccessor - освобождает аксессор.

    Для создания аксессора следует запросить интерфейс IAccessor и выполнить следующий код:

    HRESULT hr=pIAccessor-> CreateAccessor();

    Метод CreateAccessor имеет следующее формальное описание:
    HRESULT CreateAccessor (
    DBACCESSORFLAGS dwAccessorFlags, // Свойства
    // аксессора и как он используется
    DBCOUNTITEM cBindings, // Число связей
    // в аксессоре
    const DBBINDING rgBindings[], // Описание
    // столбца или параметра
    DBLENGTH cbRowSize, // Число байтов,
    // используемых для одного набора параметров
    HACCESSOR *phAccessor, // Указатель
    //на созданный аксессор
    DBBINDSTATUS rgStatus[]); // Массив значений,
    // определяющий статус
    // каждого связывания

    Каждый столбец формируемого результирующего набора или параметр описывается структурой DBBINDING, которая имеет следующее формальное описание:

    typedef struct tagDBBINDING {
    DBORDINAL iOrdinal; // Порядковый номер
    // столбца или параметра (начиная с 1)
    DBBYTEOFFSET obValue; // Сдвиг в байтах для
    // значения столбца или параметра в буфере
    // (указатель на буфер задается при
    // создании аксессора)
    DBBYTEOFFSET obLength;
    DBBYTEOFFSET obStatus;
    ITypeInfo *pTypeInfo;
    DBOBJECT *pObject;
    DBBINDEXT *pBindExt;
    DBPART dwPart;
    DBMEMOWNER dwMemOwner;
    DBPARAMIO eParamIO;
    DBLENGTH cbMaxLen;
    DWORD dwFlags;
    DBTYPE wType;
    BYTE bPrecision;
    BYTE bScale;
    } DBBINDING;

    Поле wType определяет тип столбца или параметра, который описывается следующим образом:

    typedef WORD DBTYPE;

    enum DBTYPEENUM {
    // Следующие значения точно соответствуют VARENUM
    // при автоматизации и не могут быть использованы
    // как VARIANT.
    DBTYPE_EMPTY = 0, // Значение отсутствует,
    // соответствующего типа С нет
    DBTYPE_NULL = 1, // Значение равно NULL,
    // соответствующего типа С нет
    DBTYPE_I2 = 2, // Двухбайтовое целое со знаком,
    // соответствует С типу short
    DBTYPE_I4 = 3, // Четырехбайтовое целое со знаком,
    // соответствует С типу long
    DBTYPE_R4 = 4,
    DBTYPE_R8 = 5, // Вещественное двойной точности,
    // соответствует С типу Double
    DBTYPE_CY = 6, // Тип для значения Cyrrency
    DBTYPE_DATE = 7, // Тип для значения даты
    // (дата хранится в виде вещественного числа:
    // целочисленная часть определяет дату,
    // а дробная - время)
    DBTYPE_BSTR = 8, // Указатель на строку BSTR
    DBTYPE_IDISPATCH = 9, // Указатель на интерфейс
    // IDispatch
    DBTYPE_ERROR = 10, // 32-битовый код ошибки
    DBTYPE_BOOL = 11, // Для логического значения
    DBTYPE_VARIANT = 12, // Для значения VARIANT
    DBTYPE_IUNKNOWN = 13, // Указатель на интерфейс
    // IUnknown
    DBTYPE_DECIMAL = 14,
    DBTYPE_UI1 = 17, // Однобайтовое беззнаковое целое,
    // соответствует С типу byte
    DBTYPE_ARRAY = 0x2000,
    DBTYPE_BYREF = 0x4000,
    DBTYPE_I1 = 16,
    DBTYPE_UI2 = 18,
    DBTYPE_UI4 = 19,
    // Следующие значения точно соответствуют VARENUM
    // при автоматизации, но не могут быть использованы
    // как VARIANT.
    DBTYPE_I8 = 20,
    DBTYPE_UI8 = 21,
    DBTYPE_GUID = 72, // Для уникального идентификатора GUID
    DBTYPE_VECTOR = 0x1000,
    DBTYPE_FILETIME = 64,
    DBTYPE_RESERVED = 0x8000,
    // Следующие значения недопустимы в VARENUM для OLE.
    DBTYPE_BYTES = 128,
    DBTYPE_STR = 129,
    DBTYPE_WSTR = 130,
    DBTYPE_NUMERIC = 131,
    DBTYPE_UDT = 132,
    DBTYPE_DBDATE = 133,// Для даты, определяемой
    // как структура

    // Typedef struct tagDBDATE {
    // SHORT year;
    // USHORT month;
    // USHORT day;
    // } DBDATE;
    DBTYPE_DBTIME = 134,
    DBTYPE_DBTIMESTAMP = 135 // Для даты и времени,

    // определяемых как структура
    // Typedef struct tagDBTIMESTAMP {
    // SHORT year;
    // USHORT month;
    // USHORT day;
    // USHORT hour;
    // USHORT minute;
    // USHORT second;
    // ULONG fraction;
    } DBTIMESTAMP;
    DBTYPE_HCHAPTER = 136
    DBTYPE_PROPVARIANT = 138,
    DBTYPE_VARNUMERIC = 139
    };

    Объекты COMMAND

    Перед использованием объекта Command следует определить, поддерживается ли данный объект. Для этого с помощью метода QueryInterface следует запросить интерфейс IDBCreateCommand объекта "сеанс".

    Объект Command должен реализовывать следующие интерфейсы:
    1) Icommand;
    2) Iaccessor;
    3) IcommandText;
    4) IcolumnInfo;
    5) ICommandProperties.

    Для создания команды вызывается метод IDBCreateCommand::CreateCommand объекта "сеанс".
    Например:

    ICommandText pICommandText;
    HRESULT hr= pIDBCreateCommand-> CreateCommand(
    NULL, // если есть агрегирование, то указатель
    // на управляющий IUnknown
    IID_ICommandText, // Запрашиваемый интерфейс
    (IUnknown**)& pICommandText); // Указатель
    // на запрашиваемый интерфейс

    Текст, выполняемый командой, устанавливается при вызове метода ICommandText::SetCommandText. При этом указывается уникальный идентификатор GUID синтаксиса команды (например, DBGUID_SQL (только для версий OLE DB начиная с 1.5)).
    Например:
    pICommandText->SetCommandText(DBGUID_SQL, "SELECT * FROM TBL1");

    Для выполнения команды вызывается метод ICommand::Execute (этот метод наследуется интерфейсом ICommandText) (рисунок 3).
    Например:
    ULONG ulRs=0;
    IRowset** ppRowsets=NULL;

    HRESULT hr= pICommandText->Execute (
    NULL, // если есть агрегирование, то указатель
    // на управляющий IUnknown
    IID_IRowset, // Запрашиваемый интерфейс
    NULL, // Указатель на структуру типа
    // struct DBPARAMS {
    // void *pData;
    // DB_UPARAMS cParamSets;
    // HACCESSOR hAccessor;
    //};
    ulRs, // Количество строк, на которые
    // воздействовала команда INSERT, UPDATE
    //или DELETE
    (IUnknown**)& ppRowsets); // Указатель на
    // указатели наборов данных



    Рисунок 3 - Алгоритм выполнения команды


    До выполнения команды можно определить поведение создаваемого результирующего набора вызовом метода ICommandProperties::SetProperties.

    Для многократного выполнения запроса и при использовании параметров следует вызвать метод ICommandPrepare::Prepare, а затем определить параметры вызовом метода ICommandWithParameters::SetParameterInfo.

    Если в результате выполнения команды возвращается несколько результирующих наборов, то используется метод IMultipleResults::GetResult.

    Объекты TRANSACTION

    Применение OLE DB позволяет поддерживать простые, вложенные и распределенные транзакции.

    Объект Session для работы с транзакциями поддерживает следующие интерфейсы:

    1) интерфейс ITransactionLocal. Для начала транзакции вызывается метод ITransactionLocal::StartTransaction(). Если этот метод вызывается из активной транзакции, то открывается новая вложенная транзакция;

    2) интерфейс ITransaction, поддерживающий методы Abort, Commit и GetTransactionInfo;

    3) интерфейс ITransactionJoin, реализующий поддержку распределенных транзакций.

    Объект Transaction позволяет реализовывать более широкие возможности управления транзакциями, поддерживая следующие интерфейсы:

    1) ITransaction, позволяющий выполнить прерывание транзакции (методы Abort, Commit, GetTransactionInfo);

    2) IConnectionPointContainer, поддерживающий управление точками соединения для соединяемых объектов.


    © Copyright 2006-2024. Все права защищены. Сайт бесплатно.