SPM (SQL Programming Macroprocessor): создайте свой предметный язык

| рубрика: Программирование | автор: st
Метки: ,

Пример использования технологии представлен в статье "SQL и модульное тестирование".

Назначение

Разработка серверного кода на процедурном расширении SQL имеет свои особенности. Во-первых, SQL - декларативный язык, и потому обычная для традиционного программирования функциональная декомпозиция зачастую является неэффективной. Во-вторых, SQL - специализированный язык манипуляции данными, и достичь наглядности и читаемости прикладного кода бывает нелегко.

Обе проблемы могут быть решены введением над SQL макроязыка. А поможет нам в этом достаточно простая утилита SPM (SQL Programming Macroprocessor), основанная на фактически стандартном для UNIX-среды макропроцессоре GNU m4.

Принципы работы

На входе имеем исходники в виде программного кода на процедурном расширении SQL. Так как мы используем макросы, то необходимо давать файлам расширения, отличные от *.SQL, используемого для выходных файлов. Пусть, например, это будут расширения *.SQM для файлов исходников и *.SQH для файлов макроопределений.

На первом этапе файлы с макросами обрабатываются и преобразуются в SQL-файлы, содержащие чистый SQL-код, пригодный для трансляции на сервер БД.

На втором этапе полученные файлы транслируются на сервер БД при помощи прилагаемой к любой СУБД утилиты типа iSQL.exe или сливаются в единый SQL-скрипт, полезный в дальнейшем для развертывания

Рис.1. Принципы работы SPM

Файл проекта

Кроме исходников потребуется файл, в котором содержится:

  • информация о вызове m4
  • информация об утилите iSQL для трансляции выходного файла в СУБД
  • информация о расположении файлов макроопределений (если они находятся, например, в общей директории)
  • информация об исходных файлах включая расположение и управляющие опции (транслировать, включать в итоговый скрипт...)

Такой файл в виде XML называется файлом проекта и по умолчанию имеет расширение *.spm2. Вот пример файла проекта:

<?xml version="1.0" encoding="utf-8"?>
<spm2>
  <m4Info>
    <application>%M4_BIN%\m4.exe</application>
  </m4Info>

  <!-- Interactive SQL (ISQL) tool info -->
  <isqlInfo>
    <!-- ISQL should return exit code to check errors.
         You can use system or custom environement variables like %MyVar%, %PATH% etc.
         Variable #FILE_NAME# is used as name for currently processed source file (see section sourceFiles)
    -->
    <commandLine>osql -b -n -S%SERVER_NAME% -d%DATABASE_NAME% -E -i#FILE_NAME#</commandLine>
  </isqlInfo>

  <!-- Paths to search included files (usually common macro definitions) -->
  <includes>
    <include>..\..\..\Include</include>
  </includes>

  <sourceFiles>
  <!-- Default file settings (change if need):
       compile = "true"
       script = "true"
  -->
    <file compile="false" script="false">CreateCatalog.sqm</file>
    <file>Utils.sqm</file>
    <file>SalesForecast.sqm</file>
  </sourceFiles>
</spm2>

Макроязык и примеры

Подробное описание макроязыка и настроек m4 приводятся на его основном сайте. По умолчанию, SPM использует минимально необходимые опции для запуска макропроцессора, но вы можете добавить к ним свои, используя секцию m4info в файле проекта или передавая SPM опции для m4  в командной строке.

Разнообразные макроопределения можно найти в прилагающихся примерах файлах *.SQH. Например, в директории \sample\Include файл SqlUnit.sqh содержит необходимые макросы для весьма простой организации модульного тестирования (см. подробную статью по ссылке). Поэтому ниже мы приведем только несколько простых макросов, чтобы было понятно, о чем ведется речь.

Простой макрос:

define({RC_ERROR}, {-1})

Макрос с параметрами, вызывающий другой макрос:

define({ReturnIfError}, {if ($1 != RC_SUCCESS) return RC_ERROR})

Макрос с параметрами, вызывающий другой макрос с параметрами.

define({RaiseSysError}, {raiserror($1, SYS_ERROR_SEVERITY, 1)})
define({CheckReturnError}, {if ($1 != RC_SUCCESS) BEGIN RaiseSysError({'Error status returned. ifelse($2,{},{},$2)'}) END})

Как запустить

Прежде всего необходимо загрузить дистрибутивный пакет (ссылка в конце страницы) и распаковать его дистрибутив в созданный каталог, например C:\Utils\SPM2.

Для работы с сервером БД вам необходимо как минимум установить ее клиентскую часть и знать о существовании консоли iSQL. Для MS SQL Server утилита iSQL не поддерживается, рекомендуется использовать sqlcmd и osql.

Перейдите в каталог SQL-проекта (в котором лежит главный файл проекта *.spm2). Например, используйте прилагающиеся примеры из директории Samples Выполните из командной строки запуск:

spm2[.exe] <файл проекта> [опции]

Опции запуска приведены ниже в таблице.

Опция Назначение
/script SMP только обрабатывает исходные файлы и создает результирующий скрипт с именем <файл проекта>.SQL, не транслируя код на сервер.
/build SPM транслирует все файлы на сервер независимо от того, изменялся текст или нет (аналог Rebuild All в различных средах разработки)
/debug SMP определяет макро SPM_DEBUG, который можно использовать для условной трансляции в коде, например:ifdef({SPM_DEBUG}, {SELECT 'Debug mode' AS mode})
/m4: Передает в M4 параметр командной строки. Можно задавать более одной опции /m4

Как настроить FAR Manager

Для работы с FAR потребуется установленный модуль Colorer (входит в дистрибутив, надо отметить при установке). Открываем файл C:\Program Files\Far\Plugins\Colorer\hrc\proto.hrc, находим в нем элемент prototype name="sql" и значение

<filename>/\.sql$/i</filename>

меняем на

<filename>/\.(sql|sqh|sqm)$/i<filename>

Перестартуем FAR, теперь файлы с макросами имеют подсветку SQL-синтаксиса.

Информация об изменениях и версиях

В дистрибутив помимо исходных файлов и исполняемого модуля (EXE) включаются файлы:

  • changes.txt - хронологический лист регистрации изменений
  • license.txt - лицензионная информация

Пакет с исходными текстами (никак не доходят руки выложить на гихаб): SPM2_full.zip