Оператор INTERNAL
Оператор INTERNAL - создание действия или оператора-действия, выполняющего внутренний вызов.
Синтаксис
Оператор INTERNAL может объявлять самостоятельное действие:
INTERNAL [CLIENT] [syncType] className [(classId1, ..., classIdN)] [NULL]
INTERNAL [syncType] <{anyTokens}> [NULL]
либо использоваться встраиваемо как действие-оператор:
INTERNAL internalCall [PARAMS paramExpr1, ..., paramExprN] [TO propertyId1, ..., propertyIdM]
internalCall — цель внутреннего вызова, задаваемая одним из следующих синтаксисов:
DB execStrExpr
CLIENT [syncType] execStrExpr
Описание
Оператор INTERNAL создаёт действие или оператор-действие, выполняющее либо Java-код в JVM сервера приложений, либо ресурс в веб-клиенте пользователя, либо SQL против собственной БД платформы — совокупно это внутренний вызов. Встраиваемая форма используется там, где цель вызова (имя ресурса или SQL-команда) должна вычисляться в момент вызова.
Параметры
-
CLIENTКлючевое слово. Переключает цель с JVM сервера приложений на веб-клиент пользователя — JavaScript-функцию, уже загруженную в клиенте, либо клиентский файл (правила разрешения — у
execStrExpr/classNameниже). БезCLIENTцелью является JVM (Java-класс, унаследованный отInternalAction, либо встраиваемый Java-сниппет). Во встраиваемой формеCLIENTиDBвзаимоисключающи, и одно из них обязательно. -
syncTypeКлючевое слово. Одно из:
WAIT- синхронно.NOWAIT- асинхронно.
Имеет эффект только на
CLIENT-вызовах. БезsyncTypeвызов асинхронный; во встраиваемой форме непустойTOдополнительно делает вызов синхронным. Для не-CLIENTсамостоятельных вызовов ключевое слово принимается грамматикой, но игнорируется. -
classNameСтроковый литерал. Без
CLIENT- полное имя Java-класса, доступного в classpath сервера приложений; класс должен быть унаследован отlsfusion.server.physics.dev.integration.internal.to.InternalAction. ПриCLIENT- имя клиентского ресурса (правила разрешения совпадают сexecStrExprниже). -
classId1, ..., classIdNСписок идентификаторов классов параметров создаваемого действия. Пустой список (
()) означает, что действие не принимает параметров. Если список не указан вовсе, классы параметров берутся из типизированных параметров окружающего объявления действия. Применим только к форме сclassName. -
NULLКлючевое слово, разрешающее передавать в параметры создаваемого действия значения
NULL. БезNULLлюбой вызов сNULL-аргументом молча пропускается, и управление передаётся следующему оператору. Молча игнорируется при указанииCLIENT. -
anyTokensИсходный код на языке Java. Используется в качестве тела метода
executeInternalв автоматически сгенерированном классе. В нём доступна единственная переменнаяcontextтипаlsfusion.server.logics.action.controller.context.ExecutionContext<ClassPropertyInterface>. Тело фрагмента дополнительно оборачивается вtry { ... } catch (Exception e) { e.printStackTrace(); }: любое исключение, выброшенное из фрагмента, перехватывается, печатается в stderr сервера приложений и не прерывает выполнение действия. Чтобы исключение распространялось обычным образом, используйте форму сclassName. -
DBКлючевое слово. Выполняет SQL против собственной БД платформы. Семантика совпадает с
EXTERNAL SQL: подстановка$N, параметры форматаTABLEкак временные таблицы,.sql-выражение как ресурс classpath, запись результатов DML/SELECTвTO-свойства; разница в том, что строка подключения не задаётся, а вызов выполняется внутри текущей сессии изменений. Взаимоисключающе сCLIENT. -
execStrExprВыражение.
DB: SQL-команда.CLIENT: имя ресурса — простой идентификатор ([a-zA-Z0-9_$]+) интерпретируется как JavaScript-функция, определённая в коде, уже загруженном клиентом; любое другое значение считается ссылкой на клиентский файл — ищется сначала в classpath подкаталогаweb/, а если там не найден, проходит через преобразование путей/URL на сервере приложений, в которое допускаются и абсолютные URL. Скрипты, стили и шрифты (.js,.css,.ttf,.otf) распознаются по расширению и обрабатываются на клиенте специальным образом; все остальные типы файлов, включая изображения, доставляются на клиент как обобщённые файлы. Значение с префиксомremoveвыгружает ранее загруженный файл соответствующего вида вместо его вызова; этот префикс действует только на файловую ветку — при JavaScript-функции как цели он молча игнорируется. Файловые ресурсы не принимают параметры. -
paramExpr1, ..., paramExprNСписок выражений, передаваемых как параметры вызова (подстановки
$NдляDB; позиционные аргументы дляCLIENT). БезPARAMSу вызова нет параметров. -
propertyId1, ..., propertyIdMСписок идентификаторов свойств (без параметров), в которые записываются результаты. Для
DBрезультаты пишутся в порядке соответствующих запросов; дляCLIENTдопускается не более одного свойства, и его указание также делает вызов синхронным. БезTOрезультат не захватывается.
Примеры
// Java-класс с явным списком классов параметров
showOnMap 'Показать на карте'
INTERNAL 'lsfusion.server.logics.classes.data.utils.geo.ShowOnMapAction' (DOUBLE, DOUBLE, MapProvider, BPSTRING[100]);
// Java-класс, принимающий NULL
serviceDBMT 'Обслуживание БД (многопоточно, threadCount, timeout)'
INTERNAL 'lsfusion.server.physics.admin.service.action.ServiceDBMultiThreadAction' (INTEGER, INTEGER) NULL;
// встраиваемый Java-сниппет — вывод в консоль сервера приложений
printlnAction 'Вывести текст в консоль' INTERNAL <{ System.out.println("action test"); }>;
// клиентская JS-функция, объявленная как действие, с классами параметров
QZPrint INTERNAL CLIENT 'QZPrint' (JSON, JSON, JSON);
// клиентская JS-функция, объявленная как действие, без параметров
reload INTERNAL CLIENT 'reload';
// встраиваемый клиентский вызов — ссылка на ресурс это абсолютный URL, загружается синхронно
loadMarkdownLibrary() {
INTERNAL CLIENT WAIT r'https://cdn.jsdelivr.net/npm/marked/marked.min.js';
}
// встраиваемый клиентский вызов — JS-функция с PARAMS и единственным результатом через TO
getCookie(STRING name) {
LOCAL cookie = STRING();
INTERNAL CLIENT 'getCookie' PARAMS name TO cookie;
}
// встраиваемый SQL — команда, получаемая из выражения свойства и вычисляемая в момент вызова
runScript(STRING script) {
INTERNAL DB script;
}
// встраиваемый SQL — параметризованный запрос, результат записывается в TABLE-файл через TO
loadPrices() {
EXPORT TABLE FROM bc=barcode(Article a) WHERE name(a) LIKE '%Мясо%';
INTERNAL DB 'select price, barcode from $1' PARAMS exportFile() TO exportFile;
}