1. Руководство по разработке приложений / 1.2. Программный интерфейс репозитория
1. Руководство по разработке приложений / 1.2. Программный интерфейс репозитория

1.2. Программный интерфейс репозитория

1.2. Программный интерфейс репозитория

Приложение, взаимодействующее с TDG, использует программный интерфейс репозитория (выборки) как в качестве строительного блока для реализации GraphQL-запросов, так и во фрагментах кода, исполняемых, например, в тестовой среде («песочнице»).

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

repository.get(type_name, index_name, value, options, context)

repository.find(type_name, filter, options, context)

repository.map_reduce(type_name, filter, version, map_fn, reduce_fn, zero_state, batch_count)

repository.update(type_name, filter, updaters, options, context)

repository.delete(type_name, filter, options, context)

где:

Функции get, find, update, delete поддерживают порядковую нумерацию страниц («пагинацию») с помощью параметров first и after.

Чтобы фильтровать объекты, запросы (все, кроме get) используют условия-предикаты (filter) – булевы выражения, синтаксис которых описан ниже.

1.2.1. Синтаксис предикатов

В запросах предикаты (filter) записываются в виде:

{{left, comparator, right}, ...}

где:

  • left и right – это левая и правая части выражения.

    Правая часть выражения (right) может содержать:

    • либо полный путь к полю объекта ($foo.bar), где имя поля начинается со знака $;

    • либо строковое или численное значение.

    Левая часть (left) может содержать только полный путь к полю.

  • comparator – оператор сравнения: ">", ">=", "==", "<=" или "<".

Если в предикате несколько условий, по умолчанию они объединяются логической операцией and (конъюнкцией).

Примеры предикатов:

{{"$id", ">", 10}}
{{"$id", ">", 10}, {"$id", "<", 100}}
{{"$name", "==", "foo"}, {"$birth_year", "==", 1990}}
{{"$name", "==", "foo"}, {"$reg_date", "==", {1990, 04, 23}}}

1.2.2. Исторические данные

Запросы позволяют получить объекты, которые предшествуют или равны определённой версии. За это отвечает параметр options.version.

В запросах модифицирующих данные параметр options.version устанавливает создаваемую версию объекта.

1.2.3. Оптимистичные блокировки

В случае конкурентной модификации объекта необходимо указать параметр options.only_if_version и модификация пройдет только в случае если данная версия объекта является последней и совпадает с указанной версией.

1.2.4. Управление объектами модели

Приложение TDG может управлять объектами модели при помощи запросов на обновление (update) и удаление (delete).

1.2.4.1. Запрос на обновление данных

Хранение данных в TDG представлено в виде «леса» из «деревьев». Деревья имеют свой уникальный идентификатор (ключевое поле), на основе которого они распределяются по хранилищам.

Поэтому запрос на обновление данных (update) выполняется в две стадии:

  • исполнение запроса на каждом хранилище;

  • сбор результатов на роутере.

Синтаксис update-запроса

Запрос на обновление объекта выглядит следующим образом:

repository.update(type_name, filter, updaters, options, context)

где:

  • type_name – имя объекта для обновления;

  • filter – список условий-предикатов для выбора (фильтрации) объектов агрегата.

  • updaters – список обновлений для объекта, состоящий из:

    • списка мутаторов {{mutator, path, new_value}, ...}, где:

      • mutator – имя мутатора, например, set (устанавливает значение).

      • path – строковый путь до поля объекта с точкой-разделителем (.).

        Путь до объекта(ов) массива должен включать индекс массива или символ * для захвата всех подобъектов.

      • new_value – новое значение.

  • options – параметры для управления запросом:

    • first – количество элементов для обновления.

    • after – курсор пагинации на первый элемент.

    • version – версия объекта для основы.

    • dont_skip_deleted – использовать в поиске удаленные версии объектов

  • context – контекст выполнения запроса

    • tenant – тенант

Примеры update-запроса

Для модели, рассмотренной в примере:

  • Чтобы обновить имя клиента с идентификатором 42, используйте следующий запрос:

    repository.update(
     "Client",
     {{"$id", "==", 42}},
     {{"set", "first_name", "John"},
      {"set", "last_name", "Doe"}})
    
  • Если у того же клиента истек срок действия первого паспорта и необходимо обновить соответствующее поле expired_flag, используйте следующий запрос:

    repository.update(
     "Client",
     {{"$id", "==", 42}},
     {{"set", "passports.1.expired_flag", "true"}}
    

    где .1. – индекс массива, содержащего экземпляры сущности Passport агрегата Client, т.е. первый паспорт клиента.

1.2.4.2. Запрос на удаление объектов модели

Чтобы прозрачно и удобно исключить объект из потенциальных результатов запросов, используйте запрос на удаление (delete). Он помещает объект или его версию в «удаленное состояние» и исключает его из выборки.

Синтаксис delete-запроса

Чтобы удалить объект, используйте следующий запрос:

repository.delete(type_name, filter, options, context)

где:

  • type_name имя объекта для удаления.

  • filter – список условий-предикатов для выбора (фильтрации) объектов агрегата.

  • options параметры для управления запросом:

    • first количество элементов для удаления.

    • after курсор пагинации на первый элемент.

    • version версия объекта для копирования в удаленное состояние.

  • context – контекст выполнения запроса

    • tenant – тенант

Пример delete-запроса

Чтобы удалить клиентов с именем «QWERTY» для модели из примера, используйте следующий запрос:

repository.delete(
 "Client",
 {{"$first_name", "==", "QWERTY"}})