Repository navigation
Релиз после 0.7.0: open-sdbl-db научился отдавать не только имена, которые нужны компилятору, но и саму конфигурацию — одним чтением, из той же read-only транзакции, что и метаданные. Изменение оформлено спецификацией OpenSpec (crate-architecture, onec-metadata, access-rights).
Зачем
Потребителю, которому нужны ресурсы конфигурации, приходилось читать Config второй раз — уже после закрытия сеанса, против базы, о которой он больше ничего не знает. Между двумя чтениями конфигурацию могли обновить, расширение включить, ресурс переписать, и ничто в результате об этом бы не сказало.
Согласованное получение конфигурации
use open_sdbl_db::{DatabaseSession, Limits, NoProgress};
let mut session =
DatabaseSession::connect(&connection, &credentials, Limits::default()).await?;
let configuration = session.configuration(&mut NoProgress).await?;
// Снимок и отчёт — те же, что вернул бы `metadata()`.
let snapshot = &configuration.metadata;
// Каждый ресурс таблицы `Config`, собранный из всех `PartNo`, байтами как
// их хранит база: сырой DEFLATE, без распаковки и перекодирования.
for resource in &configuration.config_resources {
let _ = (&resource.file_name, &resource.compressed);
}
// Расширения в порядке применения платформой, каждое со своими ресурсами.
for extension in &configuration.extensions {
if extension.active == Some(false) {
continue;
}
let _ = (&extension.identity, &extension.name, extension.order, &extension.resources);
}AcquiredConfiguration несёт metadata, report, layout, config_resources и extensions; AcquiredExtension — identity, name, active, order, resources. Операция есть и на DatabaseSession, и на обеих сессиях провайдеров, и как свободная acquire_configuration над MetadataSource.
Что операция обещает и чего не обещает
Второго конвейера метаданных и второго пути к СУБД нет: acquire_metadata стала обёрткой над одним внутренним получением, план различается ровно одним шагом. Возвращаются те самые ресурсы, из которых разрешён снимок, — конфигурация читается один раз, а не дважды.
Это не атомарный снимок базы. Транзакция идёт на READ COMMITTED: каждый оператор видит зафиксированное на момент своего начала, и запись в базу во время чтения может развести соседние операторы. Поднять изоляцию бесплатно нельзя — у SQL Server нет MVCC-уровня без ALLOW_SNAPSHOT_ISOLATION, настройки базы, которой библиотека не вправе требовать, а блокирующие уровни заставили бы read-only инструмент блокировать писателей. Поэтому сужен контракт, а не поднята изоляция: операция убирает второе чтение после закрытия сеанса, а узнать, сдвинулась ли конфигурация, можно сравнением CONFIG_FINGERPRINT до и после. Результат публикуется только после успешного завершения всего чтения; любая ошибка откатывает транзакцию и не отдаёт частичный результат.
Расширения
Ресурсы группируются по корневому индексу каждого расширения, а не по имени в content-addressed ConfigCAS, поэтому одинаковые имена в двух расширениях не сливаются. Идентичность — _IDRRef в hex, переживает переименование; порядок — _ExtensionOrder.
Признак применяемости измерен, а не угадан: на базе с двумя расширениями, одинаковыми во всём, кроме того, что платформа применяет одно и не применяет другое, записи по 177 байт различаются в корневом ключе, одном символе синонима и байте на три от конца — 0x82 у применяемого, 0x81 у остального. Оба блоба легли фикстурами.
active — Option<bool>. Разбор _ExtensionZippedInfo знает свои теги и останавливается на любом другом, а флаг принимается, только если разбор дошёл до терминатора и прошёл этот байт именно как односложный тег, а не как payload неизвестного счётного поля. Иначе активность неизвестна: сообщить false про расширение, которое база применяет, значило бы заставить потребителя пропустить живой код.
Пределы и расход памяти
ConfigResource::compressed — Arc<[u8]>: общая строка хранилища и партии декодера стоят ссылку, а не копию конфигурации. В Limits добавлены config_resource_limit (1 000 000) и config_retained_byte_limit (2 ГиБ). Потолки применяются к каждому собираемому хранилищу по отдельности — сначала Config, затем самостоятельно ConfigCAS, — и оба набора удерживаются одновременно, поэтому пик равен потолку столько раз, сколько хранилищ собирается. Totals проверяются до первой строки ресурсов, а потолок повторно — по фактически пришедшему, поскольку totals это отдельный оператор и может устареть. При превышении возвращается типизированная DbError, а не OOM.
Прочее
DatabaseSession::metadataне изменился: та же сигнатура, тот же результат, та же цена — по-прежнему поток с фильтром, ничего не удерживающий.- Новые SELECT-only выражения
CONFIG_ALL,CONFIG_ALL_LEGACY,CONFIG_ALL_TOTALSу обоих провайдеров, в обоих вариантах раскладки;EXTENSIONSтеперь отдаёт идентичность и порядок рядом с именем. open_sdbl::metadata::is_config_metadata_resourceзадаёт фильтр имён ресурсов один раз — тот же, что кодируют выражения обоих провайдеров.InfoBaseUser::can_authenticate()— владелец правила «есть ли у пользователя способ войти»: стандартная аутентификация или непустой логин ОС. Ни список выбора, ниAdmRole, ни роли на ответ не влияют;AdmRole— право, а не способ входа.
Новых production-зависимостей не добавлено. cargo tree -p open-sdbl -e normal по-прежнему пуст: ядро остаётся без зависимостей и без I/O.