Новое в версии 2.0

Сервер

Внешние источники аутентификации

Доработано взаимодействие с данными от внешних источников аутентификации (CAS/AD).

Раньше информация о пользователе доставлялась в прикладную базу данных только при подключении пользователя в приложение. Теперь она актуализируется каждый раз при входе в приложение.

Эта информация теперь доступна во встроенном языке.

Изменена сигнатура метода Пользователи.Подключить(), теперь через нее нельзя передавать утверждения. Для передачи утверждений используйте методы

  • Пользователи.УстановитьУтверждение(),
  • Пользователи.УдалитьУтверждение(),
  • Пользователи.УстановитьУтверждения() — новый «пакетный» метод.
Двухфакторная аутентификация

Реализована возможность подключать и использовать второй фактор в виде СМС-сообщения на мобильное устройство пользователя при аутентификации (подробнее).

В приложение добавлена настройка Разрешенные способы входа — множество способов входа, которые приложение позволяет использовать. Если разрешенные способы не указаны, значит ограничений нет. У каждого способа входа также есть дополнительная опция ТребоватьВторойФактор, которая по умолчанию выставляется в Ложь.

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

Архив и выгрузка проекта

Добавлены расширения имен файлов:

  • XPRJ — расширение файла архива проекта приложения;
  • XDUMP — расширение выгрузки приложения.
Хранилища данных

В панели управления добавлена возможность работы с хранилищами данных:

  • Добавить новое хранилище можно в разделе Инфраструктура > Объектные хранилища;
  • Подключить добавленные ранее хранилища данных к приложению можно на странице Объектные хранилища карточки приложения.
Динамическое обновление
Реализована возможность динамически обновлять приложения и получать информацию об ошибках проекта до остановки приложения. Для этого диалоговом окне обновления добавлен флажок Проверить возможность динамического обновления.
Конвертация приложений
Реализована возможность конвертации приложений, которая позволяет автоматически конвертировать данные, которые используются в приложении, чтобы они были совместимы с обновленной версией сервера (подробнее).
Режим совместимости
Реализована возможность изменения режима совместимости, которая позволяет, например, увеличить режим совместимости до обновленной версии сервера. Теперь пользователь может сам решить, переводить ли свой проект на новую версию платформы. Для упрощения перехода на новую версию доступна опция с полной конвертацией проекта, включая исходный код (подробнее).
API панели управления
Добавлен API панели управления, который предоставляет основной функционал панели управления через http-запросы (подробнее).
Блокировка файловой базы данных
Реализована исключительная блокировка файловой базы данных при начале транзакции. Это сделано для предотвращения конфликтов блокировок (deadlock), которые могут возникнуть в результате того, что разделяемые блокировки, устанавливаемые при чтении таблиц, удерживаются до конца транзакции.

Среда разработки

Точки останова по исключению

Добавлена поддержка точек останова по исключению. В панели Отладка в группе Точки останова появились два флажка:

  • Выброшенные исключения — включает остановку по любому исключению в момент его выброса;
  • Необработанные исключения — останавливается в момент выброса исключения, для которого нет соответствующего обработчика, и которое вылетит наверх стека.
Расширение отладчика для Google Chrome
Расширение отладчика для Google Chrome устанавливается теперь из магазина приложений Chrome Store.

Элементы проекта

Настройки языков локализации

Добавлены настройки для указания языков локализации и языка проекта по умолчанию. Язык по умолчанию — это язык, используемый для описания локализованных сообщений по умолчанию.

Настройки находятся в файле Проект.yaml, их указание является обязательным. Пример:

ЯзыкиЛокализации: Русский 
ЯзыкПоУмолчанию: Русский
Поиск элемента справочника по коду

Изменено поведение метода имя-справочника.НайтиПоКоду():

  • Добавлен необязательный параметр Владелец для подчиненных справочников;
  • Удален вариант метода, возвращавший массив найденных элементов для справочников с неуникальными кодами;
  • При неоднозначном поиске, если найдено несколько записей, метод выдает исключение ИсключениеПоискаСущности.
Запланированные задания в журнале событий

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

По завершении задания, успешном или с любой ошибкой, регистрируется событие с именем ScheduledJobFinish, в котором в свойстве Status указывается статус задания:

  • SUCCEEDED,
  • CANCELLED,
  • SYSTEM_ERROR,
  • APPLICATION_ERROR,
  • INTERRUPTED.

В событиях операции ScheduledJobFinish и событии ScheduledJob ключ задания указывается в свойстве с именем JobKey.

Длина числового реквизита
Общая доступная длина числового реквизита уменьшена с 32 до 30 знаков.
Конвертация значений между типами дат при реструктуризации

Реализована конвертация значений между типами дат при реструктуризации.

Конвертация срабатывает если из состава типов удален любой из типов Дата, ДатаВремя, Момент при этом в составе типов остался как минимум один из типов Дата, ДатаВремя, Момент.

Правила работы:

Исключен типа «Дата»
  • Если есть тип ДатаВремя, то значения Дата преобразуются в него;
  • Иначе если есть тип Момент, то значения Дата преобразуются в него.
Исключен тип «ДатаВремя»
  • Если есть тип Момент, то значения ДатаВремя преобразуются в него;
  • Иначе если есть тип Дата, то значения ДатаВремя преобразуются в него.
Исключен тип «Момент»
  • Если есть тип ДатаВремя, то значения Момент преобразуются в него;
  • Иначе если есть тип Дата, то значения Момент преобразуются в него.
При преобразовании из / в Момент используется часовой пояс UTC.
Тип «ГрупповаяОперация»

Реализован тип ГрупповаяОперация, выполняющий пакетную запись данных в оптимизированном режиме:

  • отключение контроля целостности (режим загрузки данных);
  • отложенный расчет прав доступа (права рассчитываются в конце транзакции, а не при каждой записи).

Язык запросов

Литерал запроса

Для типов запросов введена иерархия (подробнее):

  • Запрос;
    • ПроизвольныйЗапрос — замена того что называлось «Запрос» для значений, создаваемых конструктором;
    • ТипизированныйЗапрос — запрос на выборку данных, порождаемый литералом;
    • ЗапросБезВыборки — все остальные запросы, порождаемые литералом.

Тип результата запроса изменен на Обходимое<тип-строки-результата-запроса>;

  • СтрокаРезультатаПроизвольногоЗапроса — это динамический тип для произвольных запросов;
  • На основе литерала запроса, выбирающего данные, генерируется тип структуры для строк результата запроса, который используется как значение параметра типа:
    • Имя типа задается специальным синтаксисом с тексте запроса;
    • Если не задано, то имя будет синтетическим.

В типизированных запросах изменен способ задания параметров:

  • Параметры задаются в виде выражений встроенного языка прямо в теле литерала;
  • Параметры вычисляются сразу при конструировании значения из литерала;
  • Использовать именованные параметры в типизированных запросах нельзя;
  • Менять значения параметров в литеральном запросе нельзя.

В типизированных запросах теперь можно использовать временные таблицы объявленные в других типизированных запросах. Обращение к такой таблице выполняется по имени временной таблицы, если из другого модуля, то с именем модуля.

В типе ОписаниеКолонкиРезультатаЗапроса удалены «встроенные» свойства для описания типа значения. Вместо них введено свойство Тип типа ТипДанных.

Тип ОбластьВидимостиВременныхТаблиц:

  • На английском языке переименован в TempTableVisibilityScope;
  • Теперь его базовым типом является Контекст;
  • Можно открыть вложенную область, (по умолчанию) она перекрывает ранее открытую.
Синтаксис строковых литералов запроса

Изменен синтаксис строковых литералов в языке запросов.

Для экранирования двойных кавычек нужно так же как и во встроенном языке использовать последовательность: \". Для экранирования обратного слеша его нужно удвоить: \\.

Так же добавлены escape-последовательности для управляющих символов, имеющиеся во встроенном языке:

  • Перевод строки: \п
  • Возврат каретки:
  • Табуляция:
Пространства имен в запросах

Доработано использование пространств имен в языке запросов.

В запросах, заданных литералами (через Запрос{...}), используются такие же правила видимости имен (таблиц и типов) как во встроенном языке. Импорты используются от модуля, в котором расположен литерал. Ранее были видны все имена и приоритеты при разрешении конфликтов не действовали.

В произвольных запросах (новый Запрос()) реализовано использование приоритетов при разрешении неоднозначности неквалифицированных имен. Имена из пространств имен Стд (и вложенных) имеют более низкий приоритет, чем из других пространств имен. При наличии неоднозначности из двух имен будет выбрано имя из пространства имен проекта.

Например, при наличии в проекте таблицы МояПодсистема::Пользователи обращение к Пользователи будет разрешено в пользу МояПодсистема::Пользователи (ранее в такой ситуации выдавалась ошибка о неоднозначном имени).

Размер экземпляра «Байты» и длина строки

В язык запросов добавлены:

  • Функция вычисления размера экземпляра типа Байты;
  • Функция вычисления длины строки.

Примеры:

ВЫБРАТЬ "строка".Длина() 
ВЫБРАТЬ Байты{AD}.Размер() 

Переименования

В файле Проект.yaml:

  • Название -> Представление
  • Разработчик -> ПредставлениеРазработчика

В YAML-файлах:

  • ВидОбъектаПроекта -> ВидЭлемента

Во встроенном языке:

  • любой -> неизвестно

В системе типов:

  • Проект.Название -> Проект.Представление
  • Проект.Разработчик -> Проект.ПредставлениеРазработчика

Встроенный язык

Ключевое слово «ничто»

Добавлено ключевое слово ничто. Его можно использовать только в качестве:

  • типа возвращаемого значения метода (для общности), что равносильно отсутствию указания типа;
  • типа результата функционального типа.

ничто нельзя никуда присвоить и с ним нельзя никак взаимодействовать.

(XXX)→YYY можно присвоить в (XXX)→ничто.

Запрещено вызывать «процедуры» как «функции»

Запрещено вызывать методы, не возвращающие значение, так, как будто они возвращают значение.

Исключение составляет системный метод Вычислить():

  • При этом вызов процедуры должен быть последним, т. е. результатом всего Вычислить();
  • Результатом вычисления будет значение Неопределено .
Системные обобщенные методы

Реализованы системные обобщенные методы — методы, имеющие тип-параметр, влияющий на типизацию метода.

Такой метод может быть вызван для аргумента (аргументов), типы которых определяются типом-параметром метода. Таким же образом тип результата метода может быть связан с типом-параметром метода.

Синтаксис вызова с указанием типа:
имя-метода<имя-типа-1, ..., имя-типа-N>(параметры)

Методы, которые становятся обобщенными:

Минимум<имя-типа это Сравнимое>(имя-типа, имя-типа) 
ЧитаемоеСоответствие<тип-ключа, тип-значения>
.ПолучитьИлиУмолчание<тип-умолчания>(
     ключ: тип-ключа, 
     умолчаниетип-значения|тип-умолчания
): тип-значения|тип-умолчания 
ЗапланированныеЗадания.Создать<имя-типа-1, имя-типа-2>(
     обработчик: (имя-типа-1, имя-типа-2)->Объект?, 
     параметр-1: имя-типа-1, 
     параметр-2: имя-типа-2
) 
ФоновыеЗадания.Выполнить<имя-типа-1, имя-типа-2>(
     обработчик: (имя-типа-1, имя-типа-2)->Объект?, 
     параметр-1: имя-типа-1, 
     параметр-2: имя-типа-2
) 
Аннотации окружений

Введены аннотации окружений для методов и типов, объявленных в модуле (структур, исключений, перечислений) (подробнее):

  • @Клиент,
  • @Сервер,
  • @ДоступноСКлиента.
Аннотации во встроенном языке

Реализованы аннотации во встроенном языке.

Доступна аннотация @ИменованныеПараметры, которая может быть размещена на методах и конструкторах. Данная аннотация запрещает вызывать метод с позиционными аргументами (допускаются только именованные аргументы).

Пример метода с аннотацией:
@ИменованныеПараметры 
метод Тест(Параметр: Число) 
;
Модификатор «статический»

Введен модификатор методовключевое слово статический. Статические методы не могут использовать контекст объекта и обращения к этот.

Любой тип, порожденный элементом проекта и имеющий модуль, может иметь статические методы, в том числе перечисления.

Статический метод может быть вызван из модуля типа без квалификатора типа. Из статического метода нельзя вызывать обычные методы в данном модуле.

Запрещается иметь статический и обычный метод с сигнатурами, имеющими пересечения по типам параметров.

У клиентских типов все серверные методы должны быть статическими.

Аннотация @ДоступноСКлента допускается только на статических методах.

Создание экземпляра по известному типу
Реализовано создание экземпляра типа по известному типу во время работы приложения. Добавлен метод Тип.СоздатьЭкземпляр().
Регулярные выражения

Реализованы регулярные выражения.

Доступность: клиент, сервер, мобильный, исполнитель.

Для работы с регулярными выражениями используется новый тип Образец. Для него реализован литерал вида '\W+'.

Для работы с совпадениями используется новый тип Совпадение. Он описывает очередное совпадение и работает с подстроками, захваченными группами захвата.

Расширен тип Строка:

  • добавлены методы Строка.Содержит(), Строка.ПолноеСовпадение();
  • добавлены перегрузки для методов Строка.Разделить(), Строка.Заменить().

В случае некорректного синтаксиса регулярных выражений выбрасывается исключение ИсключениеНекорректноеРегулярноеВыражение.

Отражение свойств типов

Реализовано отражение свойств типов:

  • перечисление имеющихся свойств,
  • установка значений и чтение значений свойств через отражение.
Форматирование и округление чисел

Добавлена возможность форматирования чисел через вызов метода Число.Представление(Формат: Строка) по строке форматирования Формат.

Поведение метода Число.Представление() (без параметров) изменилось. Теперь результатом будет строка, содержащая исходное число, отформатированное в соответствии с форматной строкой "_".

Добавлено перечисление РежимОкругления с режимами округления чисел. Метод Число.Округлить() теперь принимает режим округления. Добавлена перегрузка метода Число.Округлить(), принимающая только режим округления и округляющая число до целого в соответствии с заданным режимом.

Добавлена перегрузка метода Число.ВСтроку(), позволяющая переводить число в другие системы счисления.

Прикладная функциональность

Списки отозванных сертификатов ЭЦП

Добавлена поддержка чтения и генерации списков отозванных сертификатов электронной цифровой подписи (ЭЦП) в формате CRL.

Добавлены типы криптографии:

  • СписокОтозванныхСертификатов,
  • ГенераторСпискаОтозванныхСертификатов.

Тип генерации сертификатов ЭЦП ПараметрыСертификата переименован в ГенераторСертификата.

Для сертификата добавлена возможность при генерации указать адрес сертификата издателя, точки распространения списков отзыва и сервиса OCSP (Online Certificate Status Protocol).

Тип «СредаИсполнения»
На сервере стал доступен тип СредаИсполнения.

С его помощью можно получать информацию о переменных среды операционной системы и Java. Например, можно узнать версию JVM, количество процессоров и т. п.

Доступность типа определяется разрешениями приложения.

Чтение даты и времени из JSON

Методы ЧтениеJSON.ПрочитатьСодержимоеКакДата() и ЧтениеJSON.ПрочитатьСодержимоеКакВремя() теперь умеют читать значения из представления даты и времени. Например, из строки "2021-01-01 10:11:12". Контроль «отсечения» лишних частей даты и времени лежит на параметрах этих методов ИгнорироватьДату и ИгнорироватьВремя.

Методы СериализацияJSON.ПрочитатьМассив(), СериализацияJSON.ПрочитатьОбъект() и СериализацияJSON.ПрочитатьСоответствие() умеют считывать значения из представления даты и времени в поля структур с типами Дата или Время. Например, из строки "2021-01-01 10:11:12". Контроль «отсечения» лишних частей даты и времени лежит на свойстве НастройкиЧтенияОбъектовJson.ИгнорироватьЛишниеЧастиДатыВремени.

Пустые части даты и времени игнорируются по умолчанию. Например, "2021-01-01 00:00" для типа Дата и "0001-01-01 10:11:12" для типа Время.

Работа с пустыми значениями и коллекциями в JSON

У типа НастройкиЗаписиОбъектовJson, используемого в методе СериализацияJson.ЗаписатьОбъект(), появились новые свойства:

  • НастройкиЗаписиОбъектовJson.ПропускатьНеопределено — при записи объекта в JSON будут пропущены свойства со значением Неопределено;
  • НастройкиЗаписиОбъектовJson.ПропускатьПустыеКоллекции — при записи объекта в JSON будут пропущены свойства со значениями с типом коллекций, если они пусты.

У типа НастройкиЧтенияОбъектовJson, используемого в методах СериализацияJSON.ПрочитатьМассив(), СериализацияJSON.ПрочитатьОбъект() и СериализацияJSON.ПрочитатьСоответствие(), появились новые свойства:

  • НастройкиЧтенияОбъектовJson.ИнициализироватьОтсутствующиеПоля — при чтении из JSON, отсутствующие поля у структур будут заполнены явными значениями инициализации (Неопределено имеет приоритет);
  • НастройкиЧтенияОбъектовJson.ИнициализироватьПустыеКоллекции — при чтении из JSON, отсутствующие поля структур с типами коллекций будут инициализированы пустыми значениями этого типа.
Тип «ХешированиеДанных»

Тип ХешированиеДанных теперь умеет вычислять хеш на основе различных типов данных. Ранее это было возможно только для типов Байты и ПотокЧтения.

Реализован новый метод ХешированиеДанных.Хеш(), который упрощает вычисление хеша. Например:

знч Значение = новый ДатаВремя(2022, 4, 1) 
знч Хеш = ХешированиеДанных.Хеш(Значение, АлгоритмХеширования.Sha1) 

Для хеширования строк появилась возможность указать кодировку, например:

знч Хеш = ХешированиеДанных.Хеш("Какое-то строковое значение", 
                                 АлгоритмХеширования.Sha1, 
                                 "UTF-16")