Перейти к основному содержанию
`Ctrl`+`K`

# Сессия

## Транзакционный контекст

`GsSession` — компонент, отвечающий за транзакционную обработку данных. Содержит:

- контекст транзакции:

  - кэш, который закрепляет одну объект-строку на весь жизненный цикл транзакции;

  - список изменений
    При завершении транзакции изменения собираются в пачки `insert / update / delete`, которые сбрасываются в БД по 500 записей;

  - методы (`begin` / `commit` / `rollback`);

  - транзакционный кэш (`rowCache`);

  - списки изменений;

- Room-базу данных (`RoomDatabase`);

- методы для работы с сессией базы данных:

  - нативные запросы (`query*`);

- файловую подсистему (`FileManager`);

- инъекции зависимостей для контроллеров сессии (`Api` и `Pkg`).

Любой код, работающий с данными за пределами представления, стоит располагать в контроллерах сессии.
Это позволяет гарантировать целостность транзакций и отсутствие гонок.

## Инъекция зависимостей

Контроллеры сессий создаются с автоматической инициализацией необходимых ссылок (инъекцией зависимостей).
Для управления используются следующие аннотации:

- `@GsApiBean`, `@GsPkgBean`, `@GsBean` — генерируют расширения вида `GsSession.getUserApi()` и фабрику `GlobalFactory`,
  избавляя разработчика от ручного Dagger/Hilt и позволяя создавать компоненты по имени без дополнительного кода.

Примечание

Изменение одного класса приводит лишь к перегенерации связанного файла, сборка проекта остаётся быстрой.

См. также

- модуль `di-processor`

## Контроллеры сессий

Контроллер сессии создаётся один раз на сессию.

### Api

Используется для организации бизнес-логики в разрезе сущности базы данных.
Содержит методы работы со строками таблицы:

- создание
  При этом автоматически генерируется идентификатор записи;

- удаление;

- обновление;

- загрузка;

- кэширование.

### DbPkg

Используется для организации общей транзакционной бизнес-логики.

#### Выдача пакетов

    val userApi = session.getApi(UserApi::class) // способ без генерации
    val userApi = session.getUserApi()           // способ с генерацией

- При первом запросе объект создаётся, вызывается `enterSession()`, дальше он возвращается из кэша.

- `recreateApi()` удаляет старый экземпляр и тут же создаёт новый — удобно после `logout`.

## Потоковая модель

Контроллеры сессий являются потоконебезопасными объектами, рассчитанными на работу в серверном потоке.

Внимание

Не пытайтесь обращаться к контроллерам сессии из главного потока.

## Работа с транзакцией

- `flush()` — собирает изменения из всех `Api` и применяет их пачками по 500 строк.

- `commit()` — сохраняет изменения.

- `rollback()` — откатывает изменения и очищает кэш.

### Работа с сырыми запросами

- `querySingleMap`

      val map = session.querySingleMap(
          "SELECT * FROM User WHERE gid = ?",
          arrayOf(gid)
      )

- `querySingleData`

      // map → data-class
      data class MiniUser(val name: String, val age: Int?)

      val mu: MiniUser? = session.querySingleData(
          MiniUser::class,
          "SELECT sName AS name, nAge AS age FROM User WHERE id = ?",
          arrayOf("57")
      )