Сессия#

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

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")
    )