Создание InterBase UDF на Delphi для Linux


Создание InterBase UDF на Delphi для Linux

Тема для этого поста была подсказана вопросами пользователей, которые интересовались, можно ли создавать UDF для СУБД InterBase в Delphi 10.2. Вместе с ведущим экспертом по InterBase Дмитрием Кузьменко, мы решили выяснить детали этого и составить рекомендации для наших пользователей.

Популярная реляционная СУБД Embarcadero InterBase имеет ограниченное число встроенных функций для использования в SQL-запросах, однако с самых первых версий отличалась наличием возможности у пользователей создавать двоичные модули, загружать их на сервер и применять содержащиеся в них функции в точности, как "родные" из поставки InterBase. Пользователи имеют возможность реализовывать функции, выполняющие нужную им обработку данных в соответствии с необходимой логикой любой изощренной сложности и переносить эту обработку непосредственно на центральный сервер БД - упрощая управление и администрирование таких функций и обеспечивая максимально возможное быстродействие в условиях одновременной работы множества клиентов. До появления Delphi 10.2 код UDF можно было писать на Delphi только для платформ Windows, на Linux-сервера (наиболее часто используемые в реальной работе) приходилось писать UDF на языке C.

В этой статье мы рассмотрим процесс создания UDF для InterBase 2017 на платформах Linux (64 бит) и Windows 64 с помощью Delphi 10.2 Tokyo - проверим, как передаются и возвращаются параметры, и рассмотрим некоторые особенности компиляции и переноса модулей на сервер. Это критически важно для успешного одновременного использования UDF многими пользователями. Здесь я воспользовался примерами Д.Кузьменко из статьи  "Правила написания thread-safe UDF" с этого же сайта. 

Подробная документация и руководство по написанию UDF (на английском языке) содержится в Embarcadro docwiki.

Мы выполняли тестирование на основе несколько устаревшей, но зато простой и понятной статьи "Как научиться писать UDF на Delphi за 21 минуту?" с сайта iBase.ru, где также приведены отличия для создания UDF для СУБД Firebird.

Итак, приступим!

Если у вас еще нет Linux-стенда для разработки и тестирования Linux-приложений, ознакомьтесь с предыдущими статьями:

Я использовал VirtualBox VM с Ubuntu 16.04 server, на которую был установлен InterBase 2017. Для удобства переноса модулей в Ubuntu я пользуюсь утилитой WinSCP и PuTTY-терминалом для SSH-соединения с Linux. Перенос модулей я выполнял вручную, поэтому PAServer не запускался.

Запускаем Delphi IDE. Для простейшей UDF можно создать проект 'Dynamic DLL' Я воспользовался исходным текстом примера из первой статьи, в котором имеется демо-функция ADD_A(var i1: integer; var i2: integer): integer; которая складывает числовые первый и второй параметры, возвращая их сумму.

Обратите внимание на необходимые атрибуты cdecl; export; для этой функции, а также секцию exports в конце модуля.

На картинке Target Platforms активной является Win64 - так я проверял практическую работоспособность этой UDF в Windows InterBase-сервере для разработчиков, который бесплатно поставляется вместе с Delphi или RAD Studio. Все, что требуется сделать, чтобы скомпилировать модуль для Linux, это изменить активную target-платформу на 64-bit Linux, и выполнить Build - сборку двоичного модуля. Обратите внимание, что в IDE Project Manager имя выходного файла автоматически сменилось с simpleudf.dll на libsimpleudf.so.

Теперь нужно создать внутри сервера InterBase описание, чтобы он "знал", как обращаться с этой функцией и откуда ее вызывать.

Для создания и выполнения DDL-скрипта из среды Windows на моем рабочем ПК я воспользовался RapidSQL - интерактивным инструментом разработки для баз данных из набора DB Tools, который входит в состав редакции RAD Studio Architect, но можно использовать стандартную IBConsole или другие средства соединения с InterBase.

 

Если сервер InterBase еще не был запущен в Linux, надо воспользоваться окном терминала Linux и запустить сервер:

Подключившись к серверу InterBase по IP-адресу виртуальной машины к базе данных Employee.gdb, я выполнил приведенный на картинке выше DDL-скрипт. Следует убедиться, что точка входа (имя функции) UDF написана в точности, как в исходном модуле, который был скомпилирован, а MODULE_NAME в точности равен имени выходного файла, но без расширения .so . В данном случае функция возвращает результат по значению, что указано в  строке

RETURNS integer BY VALUE

Скрипт должен успешно выполниться даже несмотря на то, что созданный двоичный модуль еще отсутствует на Linux-сервере. InterBase обращается к этому модулю только в момент вызова функции в запросе.

Настало время для переноса модуля UDF на Linux-сервер. Для этого я воспользовался WinSCP - удобной и безопасной утилитой для обмена файлами между  Windows и Linux.

Собранный в Windows выходной файл libsimpleudf.so находится в каталоге с вашим Delphi-проектом (или подкаталоге Linux64).

Стандартно, сервер InterBase устанавливается на Linux в каталог /opt/interbase. В этом случае все двоичные файлы динамических библиотек UDF нужно помещать в каталог /opt/interbase/UDF

Я также изменил права доступа к этому модулю, дав всем права на его исполнение.

Перезапустим сервер Interbase из окна терминала 

asovtsov@ubuntu16srv:~$ sudo /opt/interbase/bin/ibmgr -shut -password ******* server shutdown completed asovtsov@ubuntu16srv:~$ sudo /opt/interbase/bin/ibmgr -start server has been successfully started asovtsov@ubuntu16srv:~$

Чтобы проверить работоспособность UDF достаточно выполнить SQL запрос  

и увидеть корректный результат сложения 10+120 =  130

Итак, простейший вариант Delphi UDF отличным образом собирается и исполняется в среде Linux, а результат возвращается по значению.  Для успеха всего лишь потребовалось указать Linux64 вместо Windows как target-платформу - остальное Delphi делает автоматически. Однако, необходимо обеспечить четкое соответствие имен в исходном коде и DDL-описаниях.

А если требуется более сложный вариант возврата результата, например строкового значения? 

Об этом я расскажу в следующем посте.


Страница сайта http://185.71.96.61
Оригинал находится по адресу http://185.71.96.61/home.asp?artId=39284