Недокументированные функции Ninox

Некоторых функций нет в официальной документации Ninox. Мы обнаружили их, изучая код и разбираясь в их поведении.

TypeOf

Функция typeof возвращает тип указанного поля.

Пример:

typeof(first(select Customer).'First Name');

Eval

Функция eval выполняет переданный ей скрипт в контексте указанной записи. Она возвращает либо значение, либо текст с описанием ошибки в скрипте.

Пример:

eval("---{this.'First Name'} {this.'Last Name'}---", first(select Customer));

Результат:

Sofia Young

DebugValueInfo

Функция debugValueInfo возвращает текст с типом и значением переданного параметра.
Это особенно удобно при проверке кусочков кода в консоли Ninox.

Пример:

debugValueInfo(eval("---{this.'First Name'} {this.'Last Name'}---", first(select Customer)));

Результат:
any("Sofia Young")

Debug

Функция debug — это аналог console.log из JavaScript.
Она отправляет переданное значение в консоль разработчика браузера. Это помогает отлаживать код формул.

Пример:

(select Customer where 'First Name' like "a").(
  var 'firstName' := this.'First Name';
  var lastName := this.'Last Name';
  debug("Debug info: " + 'firstName' + " " + lastName);
)

Результат появляется в консоли разработчика браузера (она открывается через инструменты разработчика).

Records

Функция records возвращает записи по заданному массиву чисел.

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

Пример:

records(Customer, [1, 3, 6]).'First Name';

Так извлекаются имена записей с идентификаторами 1, 3 и 6.

nx-file

Функция http() в Ninox позволяет получать данные с удалённого сервера. Она возвращает объект JSON из двух ключей: error и/или result. Ключ result содержит то, что вернул сервер.

Если это содержимое текстовое (HTML, JavaScript, JSON или другие текстовые файлы), всё работает как надо. Но если это двоичный файл (изображение, PDF, документ Word и т. п.) или файл, частично двоичный, Ninox пытается сохранить содержимое в переменной типа текст. И тут возникает проблема, потому что некоторые двоичные значения экранируются (например, значение 92, то есть 0x5C в шестнадцатеричном виде, соответствующее символу экранирования «\»).

Причина в том, что Ninox не умеет работать с массивами байтов напрямую. Обойти это можно с помощью Base64, который переводит двоичные данные в текстовый вид. Подробнее о Base64 см. здесь:
https://www.freecodecamp.org/news/what-is-base64-encoding/?utm_source=chatgpt.com

В Ninox есть функции для работы с данными в Base64, например loadFileAsBase64() и loadFileAsBase64URL(). Они позволяют получить файл (хранящийся в записи) в формате Base64.

Вернёмся к нашей задаче: нужно прочитать удалённый двоичный файл и сохранить его в записи Ninox. В функции http() можно задать параметры заголовка. Обычно достаточно указать нужный формат чтения ключом content-type. Но для двоичных данных приходится добавить ещё один, недокументированный ключ — nx-file — со значением "base64url".

С ключом nx-file Ninox меняет способ обработки того, что вернул сервер. Обычно Ninox отдаёт содержимое «как есть». С nx-file он преобразует ответ в Base64URL. Так что вместо чего-то вроде:

{"result":"�PNG\r\n\u001a\n\u0000\rIHDR\u0000\u0002�\u0000\u0002\u001f\b\u0006\u0000����\u0000\u0001DiCCPicc\u0000\u0018�c``<���[�$����WR\u0014��\u0010\u0011..."}

… вы получаете:

{"result":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAqoAAAIfCAYAAAC4gv6sAAABRGlDQ1BpY2MAABiVY2BgPJGTnFvMJMDAkJtXUhTk7qQQERmlwP6IgZlBhIGTgY9BNjG5uM..."}

Этот новый формат (Base64URL) напрямую совместим с функцией importFile() в Ninox, которая воспринимает его как локальный адрес Base64 и сохраняет в указанную запись.

Учтите, что большинство удалённых серверов принимают запросы только от других серверов, но не от клиента. Поэтому функцию http() важно выполнять в контексте do as server.

Ниже приведён пример глобальной функции Ninox, позволяющей читать двоичные данные (изображения, PDF, документы Word, файлы Excel и т. д.) в виде Base64URL:

function loadFileOnBase64FromUrl(URL : text) do
 var fileName := extractx(URL, "\/([^\/?#]+)[^\/]*$", "$1");
 {
  fileName: fileName,
  content: do as server
    http("get", URL, {
      'content-type': "application/octet-stream",
      'nx-file': "base64url"
    }, null).result
  end
 }
end;

А вот пример использования этой функции:

var base64UrlFile := loadFileOnBase64FromUrl(url);
importFile(this, text(base64UrlFile.content), text(base64UrlFile.fileName));

Таким образом можно получить удалённый двоичный файл, преобразовать его в Base64URL и импортировать прямо в запись Ninox.