-
Notifications
You must be signed in to change notification settings - Fork 17
Файловая база данных
Работа с файловой базой данных в Гонце реализована с помощью библиотеки BoltDB.
База данных представляет из себя набор таблиц, в каждой из которых есть записи произвольного содержимого, но имеющих только один уникальный строковый ключ. Все записи таблицы сортируются в порядке сортировки строкового значения ключей. Все значения храняться в компактном бинарном представлении, т.е. не занимают лишнее место.
Составные ключи (из нескольких полей) необходимо реализовывать через конкатенацию (сложение) строк индивидуальных ключей фиксированной ширины. Индексы необходимо реализовывать просто с помощью других таблиц, в которых ключ формируется по другому сочетанию полей. Благодаря такой простоте, база данных реализует гибкий и очень быстрый функционал доступа к хранящимся данным.
Для получения сложных выборок путем соединения таблиц, есть два способа решения. Первый, но не самый эффективный - реализовать алгоритмы соединения отсортированных таблиц, а второй, более эффективный - создавать и наполнять таблицы, точно соответствующие планируемым в будущем запросам.
Для работы с базой данных, сначала необходимо открыть соединение с ней. Это выполняется с помощью конструкции:
база = Новый ФайловаяБазаДанных
база.Открыть("test.db") // путь к файлу базы данных
Если файла еще не существует, то он создается, в противном случае, он открывается и блокируется платформой от изменения другими процессами. Если в пути к файлу не указана папка, то файл создается/открывается в рабочей папке работающего экземпляра платформы Гонец.
Открытая таким образом база должна передаваться как значение между всеми горутинами, которые планируют с ней работать.
По окончании работы с базой данных необходимо ее закрыть, чтобы освободить блокировку файловой системы. Это делается с помощью метода база.Закрыть()
Любая работа с базой данных производится в транзакциях. Транзакции должны создаваться в тех горутинах, в которых они планируют использоваться. Нельзя передавать транзакции между горутинами. Одновременно можно открывать только одну транзакцию, в противном случае может возникнуть deadlock.
Есть два вида транзакций - на чтение и на чтение-запись. Транзакции чтения-записи являются блокирующими друг для друга и для транзакций чтения (для разных горутин), а транзакции чтения - неблокирующими (несколько горутин могут читать данные параллельно).
Начало транзакции гарантирует неизменность данных со стороны других горутин, в течение выполнения транзакции вплоть до отката или фиксации.
Открытие транзакции производится с помощью конструкции:
тран = база.НачатьТранзакцию(Истина) // Истина - для вида Чтение-Запись, Ложь - для вида Чтение
Транзакции всегда должны быть либо зафиксированы, либо отменены. В противном случае, база заблокируется для других горутин. Транзакции на чтение всегда только отменяются (при попытке зафиксировать будет выдаваться ошибка). Предпочтительно далее в коде использовать конструкцию Попытка-Исключение, чтобы отлавливать ошибки и откатывать транзакцию в этом случае:
тран = база.НачатьТранзакцию(Истина)
Попытка
//...
тран.ЗафиксироватьТранзакцию()
Исключение
тран.ОтменитьТранзакцию()
//...
КонецПопытки
Каждая транзакция обладает методами для работы с данными в базе данных:
-
таб = тран.Таблица("имя")
- возвращает объект "Таблица", внутри которого производится работа с данными этой таблицы. Если таблицы нет в базе, то для транзакции вида Чтение-Запись она создается, а для вида Чтение - возникает ошибка-исключение. Поэтому, предпочтительным вариантом является ранний запуск транзакций Чтения-Записи и получение всех таблиц (своеобразная миграция), которые будут в дальнейшем исползованы в транзакциях Чтения. -
тран.УдалитьТаблицу("имя")
- полностью удаляет таблицу из базы данных -
тран.ПолныйБэкап("имя файла")
- делает полный бэкап базы данных в указанный файл
Каждая открытая таблица имеет методы:
-
значение, ok = таб.Получить(ключ)
- получает значение по ключу (с учетом регистра). Если значение по ключу не найдено, то ok = Ложь, иначе Истина. -
таб.Установить(ключ, значение)
- устанавливает значение по ключу в таблице. Значение может быть структурой (со вложенными массивами и структурами), массивом (со вложенными массивами и структурами), числом, целым числом, строкой. -
таб.Удалить(ключ)
- удаляет значение по ключу из таблицы -
ид = таб.СледующийИдентификатор()
- получает следующий уникальный идентификатор для таблицы в виде числа. Его можно использовать в качестве ключа (дополнив нулями слева, через функциюФормат
) или значения. -
структ = таб.ПолучитьДиапазон(мин,макс)
- находит и возвращает в виде структуры диапазон записей по ключам, расположенным междумин
имакс
значениями. Не забываем, что сравнение производится в виде стравнения ключей как строк UTF-8. -
структ = таб.ПолучитьПрефикс(префикс)
- находит и возвращает в виде структуры диапазон записей по ключам, имеющим префикс (левую часть), равный значению параметрапрефикс
-
структ = таб.ПолучитьВсе()
- получает всю таблицу как структуру языка Гонец -
таб.УстановитьСтруктуру(структ)
- записывает содержимое структуры в таблицу (каждую пару ключ-значение). Отсутствующие в структуре, но, при этом, присутствующие в таблице пары ключ-значение, не удаляются.