Repository navigation
open-sdbl 0.7.0
Релиз после 0.6.0: слой работы с СУБД вынесен из консоли в отдельную библиотеку open-sdbl-db. Это перенос, а не переписывание — поведение консоли не изменилось ни в одном месте: те же коды возврата, те же сообщения об ошибках, тот же вывод \users, \roles, \role, \rls, \as, \restrict, \session, \d. Изменение оформлено спецификацией OpenSpec (crate-architecture).
Зачем
Подключение в проверенной read-only транзакции, чтение метаданных, права ролей, разворачивание RLS-ограничений пользователя и декодирование ячеек результата жили в crates/open-sdbl-cli/src под pub(crate) и были доступны только консоли. Это security-логика: копировать её во второе приложение — значит получить две копии, которые разойдутся. Поэтому она стала библиотекой, а консоль — её первым потребителем.
Три крейта
open-sdbl(корень) — без изменений: ноль production-зависимостей,#![forbid(unsafe_code)], никакого I/O. Декодирует переданные байты и генерирует SQL.open-sdbl-db(новый) — I/O СУБД и сети: оба драйвера (tokio-postgres, Tiberius), конвейер чтения метаданных, транспорт SOCKS5, ячейки результата,AccessStoreс выводом ограничений пользователя,RestrictionStore, кеш параметров сеанса БСП и индекс ролей расширений конфигурации. Ничего не печатает, не разбирает командную строку, не читает переменные окружения и файл паролей.open-sdbl-cli— процесс, терминал и файловая система: разбор аргументов, REPL, форматирование вывода, отрисовка прогресса,~/.pgpassи работа с секретами.
Публичный API библиотеки
use open_sdbl_db::{DatabaseSession, Limits, NoProgress};
let mut session =
DatabaseSession::connect(&connection, &credentials, Limits::default()).await?;
let (snapshot, report) = session.metadata(&mut NoProgress).await?;
let rows = session.query(&sql, columns).await?;
session.close().await?;Доступны DatabaseSession, DatabaseDialect, QueryCancellation, MetadataSource, acquire_metadata, AccessStore, role_restrictions, user_restrictions, derive_restrictions, RestrictionStore, read_current_user, read_template_parameters, ExtensionIndex, read_extension_index, read_extension_roles, Cell, QueryRows, декодеры ячеек обоих диалектов, DbError, типы описания подключения, Credentials и трейт прогресса. Всё публичное документировано по-английски; cargo doc проходит с -D warnings.
Где проведена граница
DbError— ошибки СУБД с предикатамиis_database_timeout,is_mssql_connection_failure,requires_mssql_disconnect.CliErrorполучил вариантDb(DbError)иFrom, коды возврата и тексты сообщений сохранены до байта.- Отчёт резолвера не печатается библиотекой:
acquire_metadataвозвращает(snapshot, layout, report), печатает вызывающий — в том же месте последовательности, что и раньше. - Прогресс — трейт
MetadataProgressс пустыми телами по умолчанию и готовой реализациейNoProgress. Терминальная отрисовка осталась в консоли. - Описание подключения и носитель секрета — обычные типы библиотеки. Чтение
PGPASSWORD/MSSQL_PASSWORD/SOCKS5_PASSWORDиPGPASSFILE/~/.pgpass, вместе с проверкой владельца и прав файла, осталось в консоли: она отдаёт библиотеке уже готовый секрет в зачищаемой памяти. - Параметры сеанса: библиотечные функции принимают
&SessionParameters. Команды\users…\as, которые пишут в стор параметров REPL, остались в консоли. Limits— одна структура вместо четырёх констант: таймаут соединения, таймаут запроса, таймаут закрытия PostgreSQL и размер пакета декодирования Config.Defaultдаёт ровно прежние значения (10 с, 120 с, 5 с, 256), сессия применяет то, с чем открыта, внешний потребитель задаёт своё.
Чего нет
Фич postgres/mssql для отключения ненужного драйвера в этом релизе нет: они потребовали бы #[cfg] на вариантах DatabaseSession, DatabaseDialect, DbError и примерно на двадцати ветвях match, то есть переписывания того самого кода, который переносится без изменений. Обоснование — в openspec/changes/archive/2026-09-20-extract-database-crate/design.md.
Новых production-зависимостей не добавлено: все зависимости нового крейта переехали из манифеста консоли. cargo tree -p open-sdbl -e normal по-прежнему пуст.