FirebirdSQL logo

CLOOP

CLOOP — Cross Language Object Oriented Programming. Этот инструмент невходит в поставку Firebird. Его можно найти в исходных кодахhttps://github.com/FirebirdSQL/firebird/tree/B3_0_Release/extern/cloop.После того как инструмент будет собран, можно на основе файла описанияинтерфейсов include/firebird/FirebirdInterface.idl сгенерировать APIдля вашего языка программирования (IdlFbInterfaces.h илиFirebird.pas).

Для Object pascal это делается следующей командой:

cloop FirebirdInterface.idl pascal Firebird.pas Firebird --uses SysUtils \
  --interfaceFile Pascal.interface.pas \
  --implementationFile Pascal.implementation.pas \
  --exceptionClass FbException --prefix I \
  --functionsFile fb_get_master_interface.pas

Файлы Pascal.interface.pas, Pascal.implementation.pas иfb_get_master_interface.pas можно найти по адресуhttps://github.com/FirebirdSQL/firebird/tree/B3_0_Release/src/misc/pascal.

Note
Замечание

В данном случае для интерфейсов Firebird API будет добавлен префикс I, так как это принято в Object Pascal.

Константы

В полученном файле Firebird.pas отсутствуют isc_* константы. Этиконстанты для языков C/C++ можно найти под адресуhttps://github.com/FirebirdSQL/firebird/blob/B3_0_Release/src/include/consts_pub.h.Для получения констант для языка Pascal воспользуемся AWK скриптом дляпреобразования синтаксиса. В Windows вам потребуется установить Gawk forWindows или воспользоваться Windows Subsystem for Linux (доступно вWindows 10). Это делается следующей командой:

awk -f Pascal.Constants.awk consts_pub.h > const.pas

Содержимое полученного файла необходимо скопировать в пустую секциюconst файла Firebird.pas сразу после implementation. ФайлPascal.Constants.awk, можно найти по адресуhttps://github.com/FirebirdSQL/firebird/tree/B3_0_Release/src/misc/pascal.

Управление временем жизни

Интерфейсы Firebird не основываются на спецификации COM, поэтомууправление их временем жизни осуществляется иначе.

В Firebird существует два интерфейса, имеющих дело с управлениемвременем жизни: IDisposable и IReferenceCounted. Последний особенноактивен при создании других интерфейсов: IPlugin подсчитывает ссылки,как и многие другие интерфейсы, используемые подключаемыми модулями. Кним относятся интерфейсы, которые описывают соединение с базой данных,управление транзакциями и операторы SQL.

Не всегда нужны дополнительные издержки интерфейса с подсчетом ссылок.Например, IMaster, основной интерфейс, который вызывает функции,доступные для остальной части API, имеет неограниченное время жизни поопределению. Для других интерфейсов API время жизни строго определяетсявременем жизни родительского интерфейса; интерфейс IStatus не являетсямногопоточным. Для интерфейсов с ограниченным временем жизни полезноиметь простой способ их уничтожения, то есть функцию dispose().

Tip
Подсказка

Если вы не знаете, как уничтожается объект, посмотрите его иерархию,если в ней есть интерфейс IReferenceCounted. Для интерфейсов с подсчётомссылок, по завершению работы с объектом необходимо уменьшить счётчикссылок вызовом метода release().

Example 1. Важно

Некоторые методы интерфейсов производных от IReferenceCounted, освобождают интерфейспосле успешного выполнения. После вызова таких методов не надо вызывать release().

Так сделано по историческим причинам, потому что аналогичные функции из ISC API освобождали соответствующий хендл.

Приведу список таких методов:

  • Интерфейс IAttachment

    • detach(status: IStatus) - отключение соединения с базой данной. При успешном выполнении освобождает интерфейс.

    • dropDatabase(status: IStatus) - удаление базы данных. При успешном выполнении освобождает интерфейс.

  • Интерфейс ITransaction

    • commit(status: IStatus) - подтверждение транзакции. При успешном выполнении освобождает интерфейс.

    • rollback(status: IStatus) - откат транзакции. При успешном выполнении освобождает интерфейс.

  • Интерфейс IStatement

    • free(status: IStatus) - удаляет подготовленный запрос. При успешном выполнении освобождает интерфейс.

  • Интерфейс IResultSet

    • close(status: IStatus) - закрывает курсор. При успешном выполнении освобождает интерфейс.

  • Интерфейс IBlob

    • cancel(status: IStatus) - отменяет все изменения сделанные во временном BLOB (если они были) и закрывает BLOB. При успешном выполнении освобождает интерфейс.

    • close(status: IStatus) - сохраняет все изменения сделанные во временном BLOB (если они были) и закрывает BLOB. При успешном выполнении освобождает интерфейс.

  • Интерфейс IService

    • detach(status: IStatus) - отключение соединения с менеджером сервисов. При успешном выполнении освобождает интерфейс.

  • Интерфейс IEvents

    • cancel(status: IStatus) - отменяет подписку на события. При успешном выполнении освобождает интерфейс.

Объявления UDR

UDR могут быть добавлены или удалены из базы данных с помощью DDL командподобно тому, как вы добавляете или удаляете обычные PSQL процедуры,функции или триггеры. В этом случае вместо тела триггера указываетсяместо его расположения во внешнем модуле с помощью предложения EXTERNAL NAME.

Рассмотрим синтаксис этого предложения, он будет общим для внешнихпроцедур, функций и триггеров.

Синтаксис
EXTERNAL NAME '<extname>' ENGINE <engine>
[AS <extbody>]

<extname> ::= '<module name>!<routine name>[!<misc info>]'

Аргументом этого предложения EXTERNAL NAME является строка, указывающаяна расположение функции во внешнем модуле. Для внешних модулей,использующих движок UDR, в этой строке через разделитель указано имявнешнего модуля, имя функции внутри модуля и определённая пользователеминформация. В качестве разделителя используется восклицательный знак(!).

В предложении ENGINE указывается имя движка для обработки подключениявнешних модулей. В Firebird для работы с внешними модулями написанных накомпилируемых языках (C, C++, Pascal) используется движок UDR. Длявнешних функций написанных на Java требуется движок Java.

После ключевого слова AS может быть указан строковый литерал — "тело"внешнего модуля (процедуры, функции или триггера), оно может бытьиспользовано внешним модулем для различных целей. Например, может бытьуказан SQL запрос для доступа к внешней БД или текст на некотором языкедля интерпретации вашей функцией.