Обращение к внешней системе (EXTERNAL)
Оператор обращения к внешней системе выполняет заданный код на языке / в парадигме заданной внешней системы. Кроме того этот оператор позволяет передавать объекты встроенных классов, в качестве параметров такого обращения, а также записывать результаты обращения в заданные свойства (без параметров).
На данный момент в платформе поддерживаются следующие типы взаимодействий / внешних систем:
HTTP - выполнение http-запроса Web-сервера
Для этого типа взаимодействия задается только строка запроса (URL), которая одновременно определяет как адрес сервера, так и непосредственно запрос, который необходимо выполнить.
Параметры
Параметры могут передаваться как в строке запроса (для обращения к параметру используется спецсимвол $
и номер этого параметра, начиная с 1
), так и в его теле (BODY). Предполагается, что в BODY передаются все параметры, не использованные в строке запроса.
При обработке параметров файловых классов (FILE
, PDFFILE
и т.п.) в BODY, тип контента параметра, в зависимости от расширения файла, определяется в соответствии со следующей таблицей. Если расширение файла отсутствует в этой таблице, тип контента устанавливается равным application/<расширение файла>
.
Расширение файла при этом определяется автоматически по аналогии с оператором WRITE
.
Во всех трех верхних случаях, если значение параметра равняется NULL
, то вместо расширения файла в тип контента подставляется null
(например application/null
), а в качестве самого параметра передается пустая строка.
Параметры классов, отличных от файловых, преобразуются к строкам и передаются с типом контента text/plain
. NULL
значения передаются как пустые строки.
При необходимости, при помощи специальной опции (HEADERS
), можно задать заголовки выполняемого запроса. Для этого нужно указать свойство, с ровно одним параметром строкового класса, в котором будет храниться название заголовка, и значением строкового класса, в котором будет храниться значение этого заголовка.
Результаты
При обработке ответа запроса, результаты с типом контента из следующей таблицы считаются файлами, и могут записываться только в свойства, класс значений которых равен FILE
. При этом в расширение файла записывается соответствующее расширение из упомянутой таблицы. Если тип контента отсутствует в этой таблице, но начинается на application
, то результат все равно считается файлом, а в расширение этого файла записывается правая часть типа контента (например для типа application/abc
в расширение файла записывается abc
). Результаты с типом контента application/null
считаются равными NULL
.
Результаты с типами контента, отличными от вышеупомянутых, считаются строками, и при записи автоматически преобразуются к классам значения свойств, в которые они записываются. Пустые строки при этом преобразуются в NULL
.
При необходимости, при помощи специальной опции (HEADERSTO
), можно записать заголовки полученного ответа запроса в заданное свойство. Это свойство должно иметь ровно один параметр строкового класса, в котором будет храниться название заголовка, и значение строкового класса, в котором будет храниться значение этого заголовка.
Все результаты возвращаются в кодировке UTF-8.
Несколько результатов / параметров в BODY
Если в BODY передается больше одного параметра, то:
- Если задана опция
BODYURL
- тип контента BODY при передаче устанавливается равнымapplication/x-www-form-urlencoded
, в качестве BODY передается заданная строка, в которой параметры кодируются так, как если бы они передавались в строке запроса. - Иначе - тип контента BODY при передаче устанавливается равным
multipart/mixed
, а параметры передаются как составные части этого BODY.
В свою очередь, если ответ запроса имеет тип multipart/*
или application/x-www-form-urlencoded
, то он разбирается на части, и каждая из этих частей считается отдельным результатом выполнения. При этом порядок этих результатов совпадает с порядком соответствующих частей в ответе запроса.
Отметим, что обработка параметров и результатов http запроса во многом аналогична их обработке в обращении из внешней системы по протоколу HTTP (параметры при этом обрабатываются как результаты, и, наоборот, результаты обрабатываются как параметры)
SQL - выполнение команды SQL-сервера.
Для этого типа взаимодействия задается строка подключения и SQL-команда(ы), которую необходимо выполнить. Параметры могут передаваться как в строке подключения, так и в SQL-команде. Для обращения к параметру используется спецсимвол $
и номер этого параметра (начиная с 1
).
Параметры
Параметры файловых классов (FILE
, PDFFILE
и т.п.) можно использовать только в SQL-команде. При этом, если какой-либо из параметров, при выполнении является файлом формата TABLE
(TABLEFILE
или FILE
с расширением table
), то такой параметр считается таблицей и в этом случае:
- перед выполнением SQL-команды, значение каждого такого параметра загружается на сервер во временную таблицу
- при подстановке параметров, подставляется не само значение параметра, а имя созданной временной таблицы
Результаты
Результатами выполнения являются: для DML-запросов - числа, равные количеству обработанных записей, для SELECT-запросов - файлы формата TABLE
(FILE
с расширением table
), содержащие результаты этих запросов. При этом порядок этих результатов совпадает с порядком выполнения соответствующих запросов в SQL-команде.
В качестве строки подключения можно использовать предопределенное значение LOCAL
. В этом случае подключение будет осуществляться к серверу БД используемому платформой.
LSF - вызов действия другого lsFusion-сервера
Для этого типа взаимодействия задается строка подключения к lsFusion-серверу (или его веб-серверу, при наличии такового), действие, которые необходимо выполнить, а также список свойств (без параметров), в значения которых будут записаны результаты обращения. Передаваемые параметры должны по количеству и по классам совпадать с параметрами выполняемого действия.
Способ задания действия в этом типе взаимодействия полностью соответствует способу задания действия при обращении из внешней системы.
По умолчанию этот тип взаимодействия реализуется по протоколу HTTP с использованием соответствующих интерфейсов обращений к и из внешней системы.
Язык
Для объявления действия, обращающегося к внешней системе, используется оператор EXTERNAL
.
Примеры
testExportFile = DATA FILE ();
externalHTTP() {
EXTERNAL HTTP GET 'https://www.cs.cmu.edu/~chuck/lennapg/len_std.jpg' TO exportFile;
open(exportFile());
// фигурные скобки escape'ся так как используются в интернационализации
EXTERNAL HTTP 'http://tryonline.lsfusion.org/exec?action=getExamples' PARAMS JSONFILE('\{"mode"=1\}') TO exportFile;
IMPORT FROM exportFile() FIELDS () TEXT caption, TEXT code DO
MESSAGE 'Example : ' + caption + ', code : ' + code;
// передает в BODY url-encoded второй и третий параметры
EXTERNAL HTTP 'http://tryonline.lsfusion.org/exec?action=doSomething&someprm=$1'
BODYURL 'otherprm=$2&andonemore=$3'
PARAMS 1,2,'3';
}
externalSQL () {
// получаем все штрих-коды товаров с именем мясо
EXPORT TABLE FROM bc=barcode(Article a) WHERE name(a) LIKE '%Мясо%';
// читаем цены для считанных штрих-кодов
EXTERNAL SQL 'jdbc:mysql://$1/test?user=root&password='
EXEC 'select price AS pc, articles.barcode AS brc from $2 x JOIN articles ON x.bc=articles.barcode'
PARAMS 'localhost', exportFile()
TO exportFile;
// для всех товаров с полученными штрих-кодами записываем цены
LOCAL price = INTEGER (INTEGER);
LOCAL barcode = STRING[30] (INTEGER);
IMPORT FROM exportFile() TO price=pc,barcode=brc;
FOR barcode(Article a) = barcode(INTEGER i) DO
price(a) <- price(i);
}
externalLSF() {
EXTERNAL LSF 'http://localhost:7651' EXEC 'System.testAction[]';
};