FileMaker 18 — новые возможности (обзор)

Теперь, после выхода новой версии, любой желающий может открыть справку по FileMaker 18, изучить перечень новых возможностей (features), благо они перечислены все в отдельной статье.  В этом обзоре я не ставлю целью рассмотреть все изменения, но хотел бы отметить те, которые считаю наиболее значимыми. То есть я хочу написать не о том, что изменилось, а какие горизонты это нам открывает. В таком вот ракурсе.
Порядок произвольный

1. Вернули зуммирование с помощью колесика мыши, которое в 17 версии почему-то не работало (и я страдал). Мелочь, но чертовски приятно.

2. Разработчики платформы очень сильно вложились в диалог, сопровождающий процедуру импорта. Импорт стал реально удобным. Помимо того, что в новой реализации эта процедура может производиться намного быстрее, появились возможности:
а) внести изменения в структуру базы данных (добавить поля, изменить свойства полей в результирующей таблице), не прерывая импорта (настроеные поля остаются настроенными).
б) указать конкретно для каждого поля, следует ли его при импорте заполнить значениями по умолчанию или следует обойти Auto-Enter.

3. То, о чем уже давно сообщили в видеообзорах: возможность применять цикл в вычислениях (выражениях, калькулируемых полях). Технически это реализовано как во всех языках программирования. Я очень ожидаю, что конкретными примерами практического применения функции While коллеги поделятся на форуме.

4. Может пройти незамеченным (хотя в справке упомянуто): В Web-Direct теперь можно прочитать содержимое Веб-вьюера. Раньше было такое ограничение, что в браузере функция GetLayoutObjectAttribute(«object»; «source») не работала для веб-вьюера. Приходилось искать обходные пути для реализации некоторых вещей. Теперь станет проще.
Очевидно, мне в связи с изменениями придется выложить на форуме обновленную версию веб-лаунчера, удалив из нее все лишнее.

5. Возможность записи в текстовый файл с конвертацией в UTF-8 (в том числе на сервере). Имеются в виду те самые новые команды для работы с Data Files из группы команд Files. Да, это круто. Реальной пользы и вариантов применения мы пока не осознаем в полной мере. Вообще возможность создать текстовый файл и выгрузить его на жесткий диск командой Export Field Contents была и раньше. Но такие файлы имели формат UTF-16. Таким способом нельзя было получить валидный xml, например: требовались дополнительные пляски с бубном. Сейчас можно обойтись без извращений.

Этим вот способом (командой Export Field Contents) мы раньше делали выгрузку данных из файлмейкера в Эксель: подсовывая «мелкософтному» текстовые файлики в формате csv. Для этих целей нам требовалось всегда иметь специальное глобальное текстовое поле. Как бы оно и не сложно, да вот приходилось следить за тем, чтобы макет с этим полем был в каждом файле базы данных, и чтобы это одинаково называлось всегда…

Еще одно применение — это логирование событий, происходящих во время исполнения отдельной процедуры или во время всего сеанса. В этом плане реализация очень удобная: файлмейкер позволяет открывать для записи одновременно несколько файлов и записывать в каждый что-то свое, обращаясь к каждому файлу по его идентификатору. Даже если приложение обрушится во время исполнения — лог будет заполнен. Для тестирования новых функций и отладки нестабильных процедур — очень полезно.

Не испытывал, но предвижу возможность использовать новшества для организации семафора на сервере. Реализация крайне простая. Пользователь запускает скрипт на сервере, который пытается «открыть» общий файл. Если возникает ошибка — значит, файл занят другим пользователем, следует дождаться завершения его сессии. Здесь нам не понадобится специальная таблица. Это пока в теории.

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

6. Возможность экспортировать контейнеры и вставлять файлы в контейнере на сервере. Нет, команды Export Field Contents, Insert File и Insert PDF не стали работать по-новому. Но все эти операции можно выполнять с помощью команд, рассмотренных выше — команд для работы с Data Files: Write to Data File и Read from Data File. Да, новые команды, обрабатывающие Data Files, поддерживаются серверными процедурами, и да, они работают не только с текстовыми, но и бинарными данными. Поэтому теперь у разработчиков нет проблем.

7. Новая команда Set Error Logging. Это реально крутая вещь, хотя поначалу у меня сложились двойственные впечатления. Первым делом я проверил, поддерживается ли эта команда сервером, потому как на сервере как раз с тестированием проблемы и возникают — там ведь невозможно запустить Debugger и произвести трассировку. Оказалось — не поддерживается.
И все-таки это не причина для расстройства. Ведь на сервере уже и так работает логирование ошибок в Event.log. Причем работает ровно так же, как теперь реализовано в клиентском приложении: то есть сервер пишет дату и время, идентификатор сессии (имя пользователя + номер сессии), код ошибки, имя файла, имя скрипта, номер строки и название команды, которая генерит ошибку.

В клиентском приложении точно такой же лог, только к имени скрипта добавлен его идентификатор, а в самом конце добавляется еще информация, вычисленная контекстно в момент ошибки (если задана такая настройка). Получается, серверный лог почти идентичен логу клиентского приложения и им можно пользоваться. А если требуется что-то большее, то это можно организовать средствами записи в Data Files.

После многократных испытаний команды, я пришел к выводу, что реализовано все более чем рационально. Смотрите. Флаг Set Error Logging (ON) задается глобально. То есть логированию подлежат все скрипты, которые будут исполняться после запуска команды и до отмены логирования командой Set Error Logging (Off) либо до завершения работы приложения. Проверяемые скрипты трогать не придется, а все действия, связанные с обработкой лога, можно вынести в отдельный скрипт. При запуске приложения флаг по умолчанию сброшен.
Дополнительная опция, которая предоставлена разработчику для логирования ошибок в клиентском приложении, действует тоже очень хитро. В качестве параметра можно указать, например, переменную $log или калькулируемое поле или формулу. Тогда в лог попадет то, что вычисляется этой переменной или полем или формулой в момент ошибки. Идеально.

Теперь давайте ловить бонусы от наших нововведений. Мы знаем, в какой файл будет записываться лог ошибок: это всегда один и тот же файл ScriptErrors.log, который располагается в папке Documents. Перед тем как начать логирование ошибок, прочитаем и запомним размер лога.
Get File Size [ "ScriptError.log" ; Target: $$start_log_size ]

После завершения логирования скриптов вызовем сценарий со следующими командами.

Set Error Logging [ Off]
Get File Size [ "ScriptError.log" ; Target: $$end_log_size ]
Set variable [ $length ; Value: $$end_log_size - $$start_log_size]
Open Data File [ "ScriptError.log" ; Target: $$LOG_ID ]
Set Data File Position[ File ID: $$LOG_ID; New position: $$start_log_size ]
Read from Data File [ File ID: $$LOG_ID ; Amount (bytes): $length; Target: $result ; Read as: UTF-8 ]
Close Data File [ File ID: $$LOG_ID ]

Теперь в нашем распоряжении переменная $result, которая содержит всю информацию, записанную в лог с начала логирования. То есть это фрагмент файла ScriptError.log с актуальными последними данными. Это текстовые данные, их можно немедленно отправить по почте администратору. Если администратору не достаточно этих данных, чтобы локализовать проблему, он может вставить дополнительные «маяки»: командой Set Field (без параметров) заставит файлмейкер генерировать ошибку и производить запись в лог в нужном фрагменте сценария.

8. Завершаем обзор новой возможностью, предоставленной разработчикам в 18 версии. Это возможность отправлять почту в любом формате, включая HTML. Реализовано это не так, как ожидалось многими: изначально ожидалось, что это будет какой-нибудь дополнительный параметр в стандартном диалоге Send Email. Но нет. Стандартный диалог не претерпел изменений.

Почту теперь предложено отправлять командой Insert From URL. В описании этой команды в справке содержится пример, как отправить письмо в формате HTML. В этой команде два параметра потребуют настройки: Target URL должен получить адрес smtp сервера и порт. В cURL options указываются параметры доступа к серверу, отправитель, получатель, и собственно тело письма.
Если не прикреплять файлы, то все выглядит очень просто, освоить не составит труда. Если озаботиться прикреплением файлов, то все несколько сложнее, но не критично (недаром почтовый протокол и называется SMTP — Simple Message Transfer Protocol). Нюансы работы с SMTP в файлмейкер мы сейчас не будем раскрывать, это большая тема и этому будет посвящена отдельная статья.
Сейчас я готов ответить лишь на вопрос, почему этот способ лучше, чем стандартный диалог. Доводов у меня будет много

1). Стандартный диалог лично меня не устраивает тем, что не позволяет динамически изменить ВСЕ опции. Например, я не могу программно изменить флаг «Использовать SSL». Это ужасно. Практически во всех сценариях мне приходится делать ветвление с проверкой, будет ли использоваться защищенное соединение или нет. В зависимости от проверки я применяю либо одну, либо другую команду. То есть вместо одной строки у меня целый блок If — Else — End If….
Команда Insert From URL может отправить письмо любого типа, все настройки будут переданы через параметры. И отправка почты возможна всего лишь одной командой.

2) Стандартный диалог многое делает автоматически. При этом нам становится удобно использовать часть функциональности, но мы не можем использовать ВСЕ возможности работы с SMTP сервером.

Пример: мы отправляем письмо и можем указать, кому письмо предназначено, от кого отправляется, кому адресуется ответ, какова тема письма, что содержит тело письма, какие файлы прикрепить…. и все. Команда Insert From Url позволяет задействовать ВСЕ возможности протокола SMTP.
например, помимо стандартных заголовков в тело письма можно передать Message-ID, Keywords, Comments (идентификатор, ключевые слова, комментарии). Причем в ключевые слова и комментарии можно запихать все, что угодно. Зачем? Да просто: если в приложении используется загрузка почты c почтового сервера, то загружаемые сообщения содержат все эти заголовки, а письма, написанные в ответ на отправленное файлмейкером письмо, будут обязательно содержать ссылку на Message-ID. По этим признакам можно легко выстраивать «цепочки» писем в файлмейкере, отображая, какое письмо какому письму является ответом. По этим признакам письма можно фильтровать и упорядочивать. В комментарии, например, можно указать, каким скриптом письмо отправлено и т.п.

Другой пример. Стандартный диалог позволяет лишь прикрепить файл-картинку к письму, такой файл отобразится у получателя в почтовом приложении как аттачмент, но не отобразится в теле письма. Между тем SMTP позволяет определять, как именно файлы прикрепляются — в виде аттачмента или inline картинки. А можно потребовать, чтобы они отобразились и как инлайн картинка, и как аттачмент.

Еще пример. SMTP позволяет отправить получателю разные варианты письма с указанием, какой из вариантов является приоритетным. Например, можно отправить HTML текст, но если он по каким-то причинам не отображается у пользователя в его почтовой программе, то будет отображен альтернативный неформатированный текст. То есть возможностей у SMTP много, вариантов компоновки и отправки писем много, но в стандартном диалоге варианты не доступны.

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

3. Чтобы прикрепить файлы в стандартном диалоге, требуется, чтобы файлы находились на жестком диске. Диалог требует указать путь к файлу.
Соответственно, если прикрепляются файлы из контейнера, требуется, чтобы эти файлы предварительно были скачаны на диск. Это неудобно. В случае использования Insert From URL ничего скачивать не нужно.

4. Если используется стандартный диалог или даже плагин, в случае ошибки возвращается лишь код ошибки. Используя Insert From URL, мы можем получить все заголовки сообщений, которые присланы почтовым сервером, в том числе и с описанием ошибки.

5. Если вы научились пользоваться командой Insert From URL и если вы освоили стандарты почтовых сообщений SMTP, то это значит, что вы готовы к следующему шагу: диалогу с почтовым сервером по протоколам POP и IMAP, к парсингу входящих писем. Кто знает, может быть, такая функция появится в файлмейкере уже через год.