FIBPlus

Native Components for InterBase and Firebird

Этот обзор FIBPlus, написанный Биллом Тоддом, был впервые опубликован в Delphi Informant Magazine и используется с разрешения Informant Communications Group, Inc. Оригинал первода на сайте Мир InterBase.


Borland поставляет компоненты InterBase Express (IBX) как часть Delphi. Зачем же платить за стороннюю библиотеку? Первая причина состоит в том, что FIBPlus (Fast InterBase Plus) предлагает много преимуществ, которых нет в IBX (прочитав эту статью, вы узнаете о них подробнее). А вторая состоит в том, что если вы используете (или даже только собираетесь) IBX вместе с Firebird, то лучше подумайте еще раз.

Хотя сегодня многие все еще успешно используют IBX вместе с Firebird, вполне возможно, что в будущем они уже не смогут этого делать. IBX не тестируется с Firebird, и Borland не планирует поддерживать совместимость с будущими версиями Firebird. Так как разработчики Firebird и InterBase развивают продукты в разных направлениях, то их API почти наверняка станет несовместимым. Мое мнение таково, что если вы используете IBX с Firebird, то вопрос состоит не в том, придется ли вам перейти на другие компоненты, а когда вам придется. С другой стороны, разрабтчики FIBPlus много раз подтверждали, что будут поддерживать и InterBase, и Firebird, так что портирование ваших приложений для работы с будущими версями Firebird должно быть простым, если вы используете FIBPlus.

Что отличает FIBPlus

Вы можете увидеть одну из уникальных особенностей FIBPlus на простом примере. Рисунок 1 показывает data module, который содержит pFIBDatabase, два компонента pFIBTransaction, два pFIBDataSet, и два DataSource. Рисунок 2 показывает Object Inspector со свойствами одного из pFIBDataSet. Обратите внимание на свойства Transaction property и UpdateTransaction.


Рисунок 1: Пример data module.


Рисунок 2: Свойства компонента EmpDataSet.

Одна из проблем при работе с InterBase - это решить, когда же пора подтвердить (Сommit) транзакцию. Все обращения к базе данных, включая операции SELECT, работают в контексте той или иной транзакции. Когда вы закрываете транзакцию, чтобы подтвердить изменения, все dataset-компоненты использующие эту транзакцию будут закрыты, и пользователь больше не увидит эти данные. Вы вынуждены запустить новую транзакцию и переоткрыть все dataset'ы.

Использование разделенных транзакций для чтения и обновления данных позволяет вам подтверждать изменения без необходимости закрывать dataset. Это, в частности, хорошо работает с InterBase 7.1, так как вы можете открыть читающую транзакцию в режиме read-committed и read-only, а это означает, что транзакция может оставаться открытой вечно без какого-либо влияния на производительность.

Компонент pFIBDataSet позволяет вам указать SQL-команды для выборки, вставки, изменения и удаления записей. Задав команды для выборки (SELECT), вы можете использовать редактор компонента для автоматической генерации остальных запросов. Вы также можете добавить на форму экземпляры pFIBUpdateObject и подключить их к pFIBDataSet, если ваш SELECT содержит объединения (joins), и вам нужно обновлять данные более, чем в одной таблице сразу. В каждом pFIBUpdateObject вы можете указать одну SQL-команду, которая будет выполняться, когда в pFIBDataSet происходит изменение, удаление или вставка записи. Это позволяет вам выполнять любое количество SQL-команд при вставке, изменении или удалении записи в pFIBDataSet. Вы также можете в любое время активировать или деактивировать тот или иной pFIBUpdateObject. Это поможет вам при использовании UNION в вашей выборке, чтобы контроллировать, какие команды изменения записи нужно выполнять в зависимости от того, из какой таблицы получена текущая запись в выборке.

FIBPlus Repository - это другая уникальная особенность FIBPlus, которая позволяет вам хранить свойства dataset'ов и их полей в базе данных без необходимости написания кода. Эти свойства автоматически будут загружены в run-time. Вы можете менять их без необходимости перекомпилировать приложения. Для полей в частности сохраняются DisplayLabel, Visible, DisplayFormat, EditFormat и DisplayWidth. Для pFIBDataSet сохраняются свойства SelectSQL, InsertSQL, UpdateSQL, DeleteSQL, RefreshSQL, GeneratorName, KeyFields, UpdateTablename, UpdateOnlyModifiedFields и Conditions.

Использование репозитория - это крайне простая вещь. Чтобы сохранить свойства полей, просто нажмите правой кнопкой мыши на компоненте pFIBDataSet и выберите пункт "Edit Field Information Table" из контекстного меню. Если ваша база данных не содержит таблицы FIB$FIELDS_INFO, то вам предложат автоматически создать ее. Редактор, показанный на рисунке 3, активизируется, если такая таблица уже создана. Нажмите дважды на любой таблице, чтобы добавить ее поля, а затем редактируйте свойства прямо в сетке (grid). Чтобы сохранить свойства pFIBDataSet, нажмите правой кнопкой мыши на компоненте и выберите пункт "Save to DataSet's Repository Table". Вам предложат создать таблицу FIB$DATASETS_INFO, если она не существует. Чтобы редактировать сохраненные свойства, вы можете выбрать в том же контекстном меню пункт "Choose From DataSet's Repository Table".


Рисунок 3: Редактор Data Repository.

Вы также можете добавлять собственные колонки в таблицы, чтобы сохранять в них дополнительную информацию. Предположим, вы хотите показывать названия полей в сетках на английском, французском и испанском языках. Сначала нужно изменить таблицу FIB$FIELDS_INFO, добавив туда новые поля FRENCH_LABEL и SPANISH_LABEL. Все что вам нужно помимо этого, так это добавить обработчик события OnAfterOpen, показанный на рисунке 4 для каждого pFIBDataSet. Этот код предполагает, что пользователь выбрал язык в неком ComboBox

procedure TMainDm.EmpDataSetAfterOpen(DataSet: TDataSet); 
var
  I: Integer; 
  S: string;
begin
  with DataSet do
     for I := 0 to (FieldCount - 1) do begin
       case ComboBox1.ItemIndex of
           1 : Dl := GetOtherFieldInfo(Fields[I], 'SPANISH_LABEL');
           2 : Dl := GetOtherFieldInfo(Fields[I], 'FRENCH_LABEL');
           else
               Dl := GetOtherFieldInfo(Fields[I], 'DISPLAY_LABEL');
       end;
      if Dl <> '' then Fields[I].DisplayLabel := Dl; 
    end;
end;

Рисунок 4: Получение пользовательских полей из репозитория.

Хотя параметризованные SQL-команды легко позволяют менять значения в условии WHERE, изменение названия таблицы или поля в run-time не очень удобно. Вы можете заменять SQL-команду целиком присваивая новое значение соответствующему свойству, но это означает, что вам нужно иметь в вашем приложении несколько копий одной команды, которые отличаются только названием таблицы или поля. Если вам нужно изменить запрос, то приходится быть аккуратным и заменять все копии. Альтернатива состоит в том, чтобы помещать в отдельных строках каждое название таблицы и поля, которые вам возможно потребуется заменить. Тем не менее, это означает, что изменение названия приведет приблизительно к такому коду:

EmpDataSet.SelectSQL[3] := 'Employee';

Это в свою очередь означает, что если вам надо изменить SQL-команду, то нужно быть очень аккуратным, чтобы сохранить порядок линий, иначе ваш код не будет работать. FIBPlus решает эту проблему, позволяя вам писать такие команды как:

SELECT * FROM @TABLE_NAME WHERE DEPT = :DEPT

В этом примере, @TABLE_NAME - это макрос, который заменятся значением в run-time при помощи метода ParamByName, точно также, как вы бы использовали ParamByName, чтобы присвоить значение параметру :DEPT. Использование макросов упрощает ваш код и делает поддержку намного проще. FIBPlus также упрощает работу с NULL-параметрами. Если вы указываете параметр в параметризированной SQL-команде равным NULL, то FIBPlus автоматически изменяет в условии WHERE строки вида SOME_FIELD = :SOME_PARAMETER на SOME_FIELD IS NULL.

Если вам нужно изменить условия в WHERE вашего запроса в run-time, используйте свойство Conditions компонента pFIBDataSet. Редактор свойства позволяет вам вводить сколько угодно условий, с возможностью задать название для каждого условия. В run-time просто задайте свойство Enabled в True у конкретного условия, чтобы включить его в WHERE. Вы можете включить больше одного условия, и все они будут добавлены друг за другом при помощи логического оператора AND.

FIBPlus включает два уникальных компонента, которые позволяют вам централизировать свой код. Во-первых, это DataSetsContainer. У pFIBDataSet существует свойство Container, которое ссылается на компонент DataSetsContainer. Если свойство задано, все события pFIBDataSet'а сначала посылаются в DataSetsContainer. После выполнения кода в обработчике события OnDataSetEvent у DataSetsContainer, управление передается обычным обработчикам событий pFIBDataSet. Обработчик события OnDataSetEvent у DataSetsContainer получает два параметра. Первый параметр - это dataset, который вызвал событие, а второй параметр определяет тип события. Если вам нужно обработать несколько событий у каждого dataset, вы возможно захотите написать код в обработчике OnDataSetEvent в виде переключателя, который вызывает отдельные методы на каждый тип события, в противном случае ваш обработчик OnDataSetEvent может стать очень длинным.

Компонент FIBErrorHandler предоставляет ту же функциональность для обработки ошибок базы данных. Вы можете написать обработчик события OnFIBErrorEvent, перехватывающий все исключения, которые не обрабатываются в блоках try..except в вашем коде.

Хотя InterBase поддерживает поля-массивы (array-fields), в Borland никогда не разрабатывали компоненты, которые давали бы доступ к таким полям. FIBPlus предоставляет полную поддержку полей-массивов, рассматривая их как вариантный массив значений типа Variant (variant array of variants). Просто присваивайте значение поля свойству Value как вариантной переменной и манипулируйте этим значением, как если бы вы работали с любым массивом вариантов. Рисунок 5 показывает кусок кода, который добавляет значения из поля LANGUAGES_REC таблицы JOB базы данных Employee в компонент ListBox.


V := JobDataSet.FieldByName('LANGUAGE_REQ').Value; 

for I := VarArrayLowBound(V,1) to VarArrayHighBound(V,1) do
   if (not VarIsNull(V[I])) then ArrayListBox.Items.Add(V[I]); 

Рисунок 5: Использование поля-массива.

Другая великолепная особенность компонента pFIBDataSet - это его умение сортировать результат в оперативной памяти. Компонент позволяет вам менять порядок сортировки без необходимости изменять секцию ORDER BY в свойстве SelectSQL и без нужды переоткрывать запрос на сервере.

Компоненты FIBPlus

Компоненты FIBPlus представлены на двух закладках палитры компонентов. В таблице на рисунке 6 перечислены все компоненты на закладке FIBPlus. Обратите внимание, что FIBPlus не включает компонентов для миграции с BDE. Нет компонентов со свойствами и методами аналогичными Table или Query. Вместо этого FIBPlus предоставляет только два компонента для доступа к данным - pFIBDataSet и pFIBQuery, оба основанные на работе с SQL. Это может показаться недостатком. Тем не менее, это не так, потому что вынуждает любого, кто портирует свои приложения с Paradox, dBase и прочих файл-серверных СУБД, переделывать все dataset-компоненты на использование SQL. Возможно, это означает немного больше работы, но сконвертированное таким образом приложение будет работать намного лучше, чем если бы оно использовало псевдо-табличные компоненты.

В таблице на рисунке 7 перечислены компоненты на закладке FIBPlus Services. Эти компоненты предоставляют доступ к Services API, появившемся в InterBase 6. Используя эти компоненты вы фактически можете реализовывать все функции, которые представлены в утилитах командной строки InterBase и Firebird.

Компонент Описание
pFIBDatabase Подключение к базе данных
pFIBDataSet dataset в базе данных.
pFIBTransaction Транзакция.
pFIBQuery Облегченный компонент для выполнения SQL.
pFIBStoredProc Вызов неселективных хранимых процедур.
pFIBUpdateObject Позволяет вам выполнять серии дополнительных SQL-команд при вставке, изменении иудалении записи в pFIBDataSet.
DataSetsContainer Централизует обработку событий dataset.
pFIBErrorHandler Централизует обработку ошибок.
pFIBStatistic Собирает статистику о выполнении запросов в рамках приложения.
SibFIBEventAlerter Принимает событие с сервера InterBase.
FIBSQLMonitor Показывает команды SQL-команды, выполненные приложениями.

Рисунок 6: Компоненты FIBPlus.

Компонент Описание
pFIBServerProperties Возвращает информацию о конфигурации сервера.
pFIBConfigService Возвращает наборы параметров сервера, включая sweep-интервал, режим работы базы данных, размер страницы и режим доступа. Позволяет отключать и перезапускать базу данных и тень (shadow).
pFIBLicensingService Вводит сертификаты лицензий и ключи.
pFIBLogService Читает лог-файл сервера.
pFIBStatisticalService Показывает статистику базы данных, включая OIT, OAT, и следующую транзакцию.
pFIBBackupService Делает резервную копию базы данных .
pFIBRestoreService Восстанавливает базу данных из резервной копии.
pFIBValidationService Проверяет или восстанавливает поврежденную базу данных.
pFIBSecurityService Добавляет, удаляет и модифицирует пользователей.
pFIBInstall Устанавливает InterBase или Firebird.
pFIBUninstall Удаляет InterBase или Firebird.

Рисунок 7: Компоненты FIBPlus Services.

Вывод

FIBPlus - это прекрасный выбор, если вы собираетесь работать с InterBase и/или Firebird. Компоненты позволяют вам легко использовать все свойства обеих СУБД в ваших приложениях. Возможность использовать разделенные транзакции для чтения и изменения данных особенно ценна для InterBase 7.1, потому что позволяет вам держать запросы открытыми сколь угодно долго без потери производительности, обычно вызываемую длинными транзакциями. FIBPlus делает использование полей-массивов простым делом, рассматривая их как массивы вариантов. Макросы упрощают модификацию SQL-команд в коде. А возможность сортировки результата запроса в памяти без переоткрытия запроса дают вам гибкость в просмотре данных с минимальным сетевым трафиком и загрузкой сервера. FIBPlus делает разработку приложений для InterBase и Firebird проще, чем когда либо.

Билл Тодд, президент The Database Group, Inc., компании, занимающейся консультированием по вопросам баз данных и разработкой программного обеспечения, расположенной недалеко от Phoenix. Он соавтор 4-х книг по программированию баз данных, автор более чем 100 статей, пишущий редактор журнала Delphi Informant Magazine и член Team B, которая предоставляет техническую поддержку в ньюсгруппах Borland. Билл также всемирно известный тренер, часто выступающий на конференциях Borland в Соединенных Штатах и Европе. Читатели могут связаться с ним по адресу mailto:bill@dbginc.com.

Общие факты

FIBPlus - набор нативных компонентов Delphi, C++ Builder и Kylix, которые представляют доступ ко всем возможностям InterBase и Firebird. Компоненты FIBPlus используют непосредственные вызовы API для получения максимальной производительности, а pFIBDataSet является потомком стандартного класса TDataSet для совместимости со стандартными и сторонними визуальными компонентами Delphi, C++Builder и Kylix.

Компания Devrace

Web Site: http://www.devrace.com

2011123456789101112
2010123456789101112
2009123456789101112
2008123456789101112
2007123456789101112
2006123456789101112
2005123456789101112
2004123456789101112
2003123456789101112
2002123456789101112
2001123456789101112
2000123456789101112
1999123456789101112

Последние статьи
Литература