confdb
by Zom31C
README.md
# 1confdb-knw (confdb)
Экстрактор конфигурации 1С:Предприятие 8 в базу данных SQLite.
Назначение: распаковать бинарный файл конфигурации (`.cf`, `.cfe`, `.epf`)
без технологической платформы 1С и разложить его содержимое в реляционную базу,
пригодную для генерации кода 1С (LLM/RAG и скрипты).
Алгоритм распаковки портирован из проекта [v8unpack](https://github.com/saby-integration/v8unpack)
(MIT, см. NOTICE.md) — только в одну сторону: распаковка и разбор, без обратной сборки.
## Использование
```bat
:: установка в venv (один раз)
.venv\Scripts\python.exe -m pip install -e .
:: распаковка cf в базу данных (+ дерево распакованных файлов для отладки)
confdb extract file.cf --db out.db --dump _out\file
:: то же через confdb.bat
confdb.bat extract file.cf --db out.db
:: текстовый консольный интерфейс (меню с обновлением экрана:
:: извлечение, запросы, проверка СКД, запуск MCP-сервера
:: с одной базой, несколькими базами или несколькими группами баз, опции)
confdb-ui.bat
:: проверка корректности запросов СКД в готовой базе (пункт 5 в confdb-ui)
confdb check out.db
:: бенчмарк: подбор числа процессов под железо
:: (в confdb-ui — внутри пункта 3 «Опции извлечения»)
confdb bench file.cf
```
По умолчанию любая ошибка декодирования объекта прерывает извлечение.
Флаг `--skip-errors` (в консольном интерфейсе — опция 6 «Пропускать
ошибки объектов») пропускает сбойные объекты и продолжает разбор:
каждый пропуск печатается с внутренней причиной, в конце — итоговое
число. Дамп и база при этом неполные (пропущенные объекты и их
подобъекты отсутствуют) — режим для больших конфигураций, где единичный
сбойный объект не должен блокировать всю выгрузку.
Повторное извлечение одного и того же файла отсекается до распаковки: `extract`
считает SHA-256 исходного `.cf/.cfe/.epf` (885 МБ — 1,7 с) и сравнивает его
с отпечатком в таблице `source` целевой базы. Совпало — база уже содержит ровно
эту конфигурацию, извлечение не запускается (код возврата 0), а сообщение
называет отпечаток и дату сборки; `--force` пересобирает принудительно. Если
база собрана из другого файла, печатается предупреждение о перезаписи. Сам
отпечаток и размер исходника видны в `configuration_info` (полностью) и в
`db_list` (первые 16 символов) — по ним две базы сравниваются на происхождение
без повторной выгрузки. В консольном интерфейсе вместо `--force` задаётся
вопрос «Пересобрать базу всё равно?».
## Проверка запросов СКД
`confdb check <база>` (и пункт 5 консольного интерфейса) прогоняет все запросы
таблицы `skd_query` через встроенный разборщик языка запросов 1С
(`src/confdb/query_lang.py`):
- синтаксис: ПОМЕСТИТЬ/УНИЧТОЖИТЬ, ОБЪЕДИНИТЬ [ВСЕ], соединения (включая вложенные
и перечислением), вложенные запросы, ВЫБОР/ВЫРАЗИТЬ, виртуальные таблицы
с аргументами, параметры `&…`, необязательные области СКД `{…}`, `ДЛЯ ИЗМЕНЕНИЯ`;
- семантика по метаданным: существование таблиц (`Справочник.Х`, `РегистрНакопления.Х.Обороты`
и т.п.), существование полей первого уровня (meta_attribute + стандартные поля +
общие реквизиты, без учёта регистра), цепочки разыменования ссылок через
`attribute_ref` (второй и далее уровни — мягко: составные/абстрактные типы
не всегда раскрываются).
Код возврата 1 и список сообщений — если какой-то запрос не прошёл.
## 1confdb-knw — MCP-сервер для внешних LLM
```bat
:: сервер знаний по конфигурации 1С и BSL; stdio (JSON-RPC, read-only)
1confdb-knw.bat out.db
:: то же через CLI: confdb 1confdb-knw out.db
:: несколько баз сразу: основная конфигурация + расширения/обработки
1confdb-knw.bat main.db extension.db processor.db
:: несколько групп конфигураций одновременно — повтор флага добавляет базу
:: в ту же группу, а группы остаются раздельными (запрос к одной — group=<имя>)
1confdb-knw.bat --group УНФ=unf.db --group УНФ=unf_ext.cfe.db --group БП=bp.db
```
Путь к базе можно не указывать: `1confdb-knw.bat` без аргумента берёт
`last_db` из `~/.confdb/config.json`, а при его отсутствии сам ищет
`*.db`/`*.sqlite` — в текущем каталоге, `db/` и `_out/` (и в корне
установки при запуске из venv). Одна база — запускается; несколько —
сервер печатает список и просит указать путь явно. С флагом `--group`
автопоиск не срабатывает: нужные базы названы в группах. Несуществующий путь —
сразу «Файл базы не найден» (код 2), без падения на первом запросе.
Свежая установка с базой, привезённой с другого компьютера, работает
без ручной правки конфига: достаточно положить файл в `db/` рядом
с `1confdb-knw.bat`.
32 инструмента: `find_objects`, `object_card` (паспорт объекта: реквизиты,
табличные части, модули, формы и команды, ссылки; у регистров — измерения,
ресурсы и реквизиты отдельными группами плюс периодичность и режим записи),
`object_tree`, `find_field`, `refs_of`, `role_rights` (явные права одной роли:
по строке на цель — объект, его реквизит/поле табличной части или его табличная
часть, — с текстом ограничения доступа на уровне записей и шаблонами RLS роли;
право показывается первыми знаками своего uuid, потому что имён прав в
конфигурации нет), `object_rights` (какие роли несут явные права на объект,
включая права на его реквизиты и табличные части; параметр `role` сужает ответ
до одной роли), `module_outline`, `get_method`,
`find_method_context` (окно строк вокруг нужного вызова с номерами строк
модуля и маркерами точки вставки), `method_dependencies` (что использует
метод: общие модули и их экспортные методы, метаданные, таблицы и поля
запросов, параметры; если рядом открыта основная конфигурация, её объекты и
общие модули находятся там, а не объявляются отсутствующими),
`method_result_schema` (из чего состоит возвращаемая методом таблица
значений/структура — эвристика по тексту), `find_methods` (поиск по имени,
сигнатуре и описанию, а параметр `text` — по текстам тел методов: все места
обращения к объекту с номером строки модуля, без полнотекстового `sql`),
`skd_of`, `find_skd`, `xdto_of` (состав пакета XDTO: целевое пространство
имён, импорты, типы с базовым типом, ограничениями и значениями перечислений,
свойства с обязательностью, признаком списка и формой — атрибут или элемент,
вложенные анонимные типы; параметр `type` показывает один тип),
`find_xdto` (поиск имён типов и свойств по всем пакетам XDTO базы),
`check_query` (валидатор запроса 1С), `sql` (только
SELECT), `compare_object` (различия одного объекта в двух базах),
`extension_diff` (что делает расширение относительно основной конфигурации),
`configuration_info` (тип загруженного файла — конфигурация `.cf`, расширение
`.cfe`, внешняя обработка `.epf`, внешний отчёт `.erf`; имя и версия, режим
совместимости, источник и дата выгрузки) и управление базами
`db_list` / `db_open` / `db_use` / `db_close` плюс управление группами
конфигураций `group_create` / `group_add_db` / `group_remove_db` /
`group_list` / `group_use` / `group_close`. Инструкции протокола
(`initialize.instructions`)
и описания инструментов содержат справочник по схеме базы, глоссарий 1С
и рекомендуемый рабочий процесс — любая модель пользуется сервером без
контекста этого проекта.
**Пагинация поиска.** `find_objects`, `find_field`, `find_methods`, `find_skd`,
`find_xdto` и `refs_of` отдают одну страницу совпадений: `limit` задаёт её
размер (1..200), `offset` — сколько совпадений того же поиска пропустить.
Последняя строка ответа сообщает итог и продолжение —
`… всего найдено 317; показано 1–20; есть ещё 297 — следующий вызов с offset=20`
(когда страница последняя — «это все результаты»). Порядок совпадений строгий,
поэтому страницы не пересекаются и не теряют строки. У `find_xdto` типы и
свойства считаются одним списком (сначала типы, потом свойства), у `refs_of`
свой итог у каждой из двух секций, а `offset` у них общий.
Синтаксис текстов модулей этот сервер **не** проверяет: полный разбор BSL
(блок-конструкции, препроцессор, типы, область видимости) делает BSL
Language Server, который поднимает вариант `1confdb-knw-lsp`. Ошибки
инструментов возвращаются с кодом категории — `BAD_ARGS`, `BAD_REQUEST`,
`DB_LOCKED`, `DB_SCHEMA`, `DB_ERROR`, `IO_ERROR`, `INTERNAL`; при занятой
базе (`SQLITE_BUSY`) вызов повторяется автоматически.
#### Несколько баз одновременно (расширения и обработки)
Сервер держит несколько баз сразу: перечислите их при запуске либо
открывайте на ходу инструментом `db_open` (без перезапуска сервера).
Каждая база получает алиас (по умолчанию — имя файла без расширения;
при совпадении — с суффиксом `_2`, `_3`…). Все инструменты по умолчанию
работают с активной базой (при запуске — первая указанная); чтобы
запросить другую базу без переключения, передайте её алиас параметром
`db` (есть у всех инструментов). Переключение активной базы — `db_use`,
список открытых баз со статистикой — `db_list`, закрытие — `db_close`.
Типовой сценарий: извлечь основную конфигурацию, расширение и обработку
в отдельные базы и запустить сервер со всеми тремя —
```bat
confdb extract main.cf --db main.db
confdb extract ext.cfe --db ext.db
confdb extract proc.epf --db proc.db
1confdb-knw.bat main.db ext.db proc.db
```
— после чего LLM видит метаданные и код всех трёх и может, например,
искать методы расширения (`find_methods` с `db='ext'`) поверх основной
конфигурации. Специальное значение `db='*'` выполняет инструмент сразу
по всем открытым базам (ответ приходит секциями по базам) — один вызов,
чтобы сравнить основную конфигурацию с расширениями. Если база
пересобрана (повторный `extract`), её достаточно закрыть и открыть
заново: `db_close` + `db_open`.
**Идентификатор базы в ответах:** каждый ответ инструмента данных начинается
с заголовка `=== база <алиас> (<путь>) ===`, идентифицирующего источник данных.
Если база входит в группу, заголовок называет и её —
`=== группа <имя> / база <алиас> (<путь>) ===`, а при вхождении в несколько
групп — `=== группы A, B / база …`.
Это позволяет LLM сравнивать конфигурации (типовая vs доработанная, основная vs
расширение) и понимать, в какой базе находится метод или объект. Например:
```
=== база основная (C:\path\main.db) ===
Справочник.Контрагенты: 150 объектов
=== база расширение (C:\path\ext.db) ===
Справочник.Контрагенты: 155 объектов
```
Инструменты управления базами (`db_list`, `db_open`, `db_use`, `db_close`) не
содержат заголовок — они сами управляют базами.
#### Группы конфигураций: несколько наборов баз одновременно
Группа объединяет связанные базы (основная конфигурация + расширения +
обработки) под одним именем. Групп может быть открыто **несколько
одновременно** — например две разные конфигурации или две версии одной, —
и деление при этом сохраняется: сервер знает, какая база в какой группе,
и печатает это в `db_list`, в `group_list` и в заголовке каждого ответа.
- запуск с группами: `1confdb-knw.bat --group УНФ=unf.db --group УНФ=unf_ext.db
--group БП=bp.db` — повтор флага добавляет базу в ту же группу, несколько
путей можно перечислить через `;`. Первая группа становится активной, а её
первая база — активной базой;
- запрос к ОДНОЙ группе: параметр `group='БП'` у инструмента данных — он
выполнится по всем базам группы и вернёт ответ секциями
`=== группа БП / база <алиас> (<путь>) ===`;
- запрос сразу ко всем группам: `group='*'` — секции по группам, каждая со
своими базами (в отличие от `db='*'`, который смешивает все открытые базы);
- **без `group` выполняется только активная база**, а не вся активная группа:
при нескольких открытых группах группу нужно называть явно. `group_use`
переключает активную группу и делает её первую базу активной;
- отказ одной базы не рвёт групповой вызов (`group=<имя>`, `group='*'`,
`db='*'`): её секция несёт `ошибка [КАТЕГОРИЯ]: …` (`DB_LOCKED` —
транзитная, тот же вызов может пройти повторно), остальные базы отвечают
штатно, а ответ заканчивается строкой `баз с ошибкой N из M: <алиасы>`,
чтобы частичный ответ не читался как полный. `isError` вызов получает
только когда отказали **все** базы — их секции при этом остаются видны;
- на ходу: `group_create`, `group_add_db`, `group_remove_db`, `group_list`,
`group_use`, `group_close` (удаление группы базы не закрывает).
`compare_object` и `extension_diff` групп не знают: они принимают явные
алиасы баз (`db_left`/`db_right`, `extension_db`/`base_db`), которые
берутся из `db_list` или `group_list`.
В консольном интерфейсе наборы баз сохраняются в **именованные группы**
(пункт 6 главного меню): одна база может входить в несколько групп. Пункт 1
запускает сервер с **несколькими группами сразу** — номер отмечает или
снимает группу, `*N` делает N-ю выбранной первой (её база станет активной),
`m` добавляет отдельные базы вне групп. В сетевом режиме панель после
запуска позволяет подключать/закрывать базы и работать с группами из
конфига без перезапуска сервера: добавить группу (остальные группы и базы
останутся открытыми), заменить весь набор одной группой, убрать группу (её
базы закроются, если не нужны другим группам) и сделать группу активной.
Пример конфигурации MCP-клиента, в т.ч. через SSH:
```json
{
"mcpServers": {
"1confdb-knw": {
"command": "ssh",
"args": ["user@host", "python", "-m", "confdb.mcp_server", "/path/out.db"]
}
}
}
```
### Сетевой режим (когда stdio не подходит)
Сервер слушает порт и отдаёт MCP по HTTP (Streamable HTTP: `POST /mcp`;
legacy SSE для старых клиентов: `GET /sse` + `POST /messages`):
```bat
1confdb-knw.bat out.db --port 8765
```
С другой машины подключение — через SSH-туннель:
```bat
ssh -L 8765:127.0.0.1:8765 user@host
```
```json
{
"mcpServers": {
"1confdb-knw": { "url": "http://127.0.0.1:8765/mcp" }
}
}
```
По умолчанию слушает `127.0.0.1` (без аутентификации, база read-only);
`--host 0.0.0.0` открывает порт наружу — используйте только в доверенной сети.
В консольном интерфейсе — пункт 1 → «Сеть (HTTP-порт)».
Запросы выполняются по одному за раз: соединения баз и приставных шардов FTS на
сервер общие, поэтому вызовы инструмента сериализованы — в stdio, в HTTP и когда
консольный интерфейс обращается к работающему серверу. Долгий запрос (`sql` по
большой таблице, поиск по телам в базе без индекса) задерживает остальных
клиентов; параллельные подключения работу не ускоряют.
Опции `extract`:
- `--db FILE` — записать результат в SQLite;
- `--dump DIR` — сохранить распакованное дерево файлов (нужен хотя бы один из `--db`/`--dump`);
- `--temp-dir DIR`, `--keep-temp` — рабочий каталог стадий 0–1 и его сохранение.
Без `--temp-dir` он создаётся рядом с базой (`--db`) или дампом (`--dump`), а не
в `%TEMP%`: на системном томе удаление ~125 тысяч файлов рабочего каталога стоит
~30 с и почти не распараллеливается, на несистемном — ~10 с, и прогон УНФ целиком
занимает 70 с вместо 97 с. Если каталог результата недоступен — откат на `%TEMP%`;
- `--prefix STR` — снять префикс с имён объектов;
- `--store-blobs` — хранить бинарные файлы (картинки, макеты) в БД как BLOB;
- `--workers N` — число процессов стадии 3 и записи БД (по умолчанию — результат
`confdb bench` или 1; на многоядерной машине несколько процессов ускоряют разбор
в несколько раз). В консольном интерфейсе — меню «Опции извлечения». При вызове
`extract()` из собственного скрипта на Windows с `workers > 1` вызов должен быть
обёрнут в `if __name__ == '__main__':` (требование multiprocessing spawn).
- `--no-fts` — не строить FTS-индекс по телам методов. Индекс — приставные файлы
`<база>.fts\0.db…`, по одному на процесс (на УНФ 7.5 с в 8 шардов, ~1.1 ГБ); сама
база остаётся одним файлом и без индекса работоспособна — поиск по телам идёт
полным проходом (~0.3 с на запрос). Достраивается позже командой
`confdb fts <база> [--workers N]`, каталог `.fts` можно удалить в любой момент.
- `--dump-indent` — писать JSON дампа с отступами, как это делает v8unpack. Нужно
только для побайтового сравнения дампов при проверке эквивалентности декодера:
по умолчанию вывод компактный, с ним стадия 3 быстрее (28.0 с против 30.8 с на УНФ),
а дерево дампа примерно втрое меньше. На содержимое базы флаг не влияет.
- `--force` — пересобрать базу, даже если она уже собрана из этого же файла.
Без флага `extract` сравнивает SHA-256 исходника с `source.file_sha256` целевой
базы и при совпадении не запускает распаковку вовсе (~70 с на УНФ против 1,7 с
на отпечаток).
## Бенчмарк и автонастройка
`confdb bench <file>` один раз прогоняет стадии 0/1, затем нелинейный сэмпл
объектов верхнего уровня (шаг по всему списку + покрытие всех типов объектов,
чтобы задеть и лёгкие справочники, и тяжёлые формы/отчёты) через стадию 3 и
запись БД при 1/2/4/8/CPU процессах. Лучшее число процессов сохраняется в
`~/.confdb/config.json` и подставляется по умолчанию в `extract` и в консольный
интерфейс; `--workers N` переопределяет вручную.
Стадии конвейера (повторяют v8unpack, только распаковка):
0. чтение внешних V8-контейнеров (32/64-бит) в файлы как есть;
1. inflate (raw deflate) + рекурсивные вложенные контейнеры;
3. декодирование метаданных: скобкофайлы `{}` → JSON, тексты модулей → `.bsl`.
## Схема базы данных
Ревизия схемы штампуется в сам файл базы: `PRAGMA user_version = writer.SCHEMA_VERSION`
(с 2026-10-08). MCP-сервер отвечает только на базы своей ревизии, а на устаревшую
возвращает просьбу пересобрать её (`confdb extract <файл> --db <база> --force`) — вместо
ошибки схемы посреди запроса. Совместимого режима чтения старых схем нет: новые колонки
(например `role_right.target_flags`) заполняются только из исходника, миграции не
существует. У баз, собранных до появления штампа, `user_version = 0` — они считаются
устаревшими. Ревизию открытых баз показывают `db_list`, `db_open` и список баз в TUI.
- `source` — исходный файл: путь, дата, тип/имя/uuid корневого объекта;
- `meta_object` — объект метаданных: `path` (например `Catalog/Контрагенты/CatalogForm/ФормаЭлемента`),
`type` (Catalog, Document, CommonModule, …), `type_ru` (русское имя «как в конфигураторе»:
Справочник, Документ, Общий модуль, …), `name`, `uuid`, `comment`, `obj_version`,
`header_json` (полный разобранный заголовок), `parent_id` + `ord` (иерархия и порядок
братьев — как в дереве конфигуратора);
- `meta_attribute` — реквизиты объекта: `ord`, `name`, `type_str` в порядке объявления.
Примитивы — Строка(50)/Число/Дата/Булево; ссылки — `Ссылка: <путь>` (таблица ссылочных
uuid из потока `.10` корневого объекта, коллизии имён дизамбигуируются по типу объекта);
определяемые типы — `ОпределяемыйТип: <путь> (<состав>)` (состав раскрывается);
составные типы — члены через ` | `; обобщённые типы платформы («ЛюбаяСсылка» и т.п.),
чей uuid не соответствует ни одному объекту конфигурации, — `Ссылка` (это не ошибка
извлечения, у такого типа нет конкретной цели); `Ссылка: <имя> (объект не найден
в базе)` — имя цели известно из таблицы `.10`, но самого объекта в этой базе нет
(типично для ссылки из расширения на объект основной конфигурации); `NULL` —
в заголовке объекта описание типа этого реквизита отсутствует; `uuid` — собственный
идентификатор поля в метаданных: по нему цель права роли (`role_right.target_uuid`)
разрешается в конкретный реквизит, `NULL`, когда в заголовке поля uuid нет;
- `attribute_ref` — связи реквизитов с объектами метаданных: `uuid` (ссылочный uuid
из дескриптора типа, для составных/определяемых типов — по строке на член) и
`object_id` — объект, на который ведёт ссылка (NULL для абстрактных типов);
зависимость «реквизит ↔ объекты» строится join'ом без разбора строк `type_str`;
- `enum_value` — значения перечислений (`ord`, `name`) в порядке объявления;
- `predefined` — предопределённые элементы из «Предустановленные данные.bin»: `ord`
(номер в обходе в глубину), `parent_ord` (ord родителя; NULL только у корневого узла
«Счета»/«Элементы», который элементом не является), `uuid` элемента, `name`, `code`,
`display`;
- `predefined_subconto` — виды субконто предопределённого счёта плана счетов:
`predefined_id`, `ord`, `uuid` вида субконто, `kind_id` — предопределённый элемент
плана видов характеристик, которым он разрешается, `flags` — включённые флаги через
«;» («Суммовой», «Валютный», «Количественный»);
- `common_target` — привязка общих реквизитов к объектам метаданных;
- `meta_tabular` — табличные части объекта (`ord`, `name`, `uuid`) в порядке объявления;
поля табличных частей лежат в `meta_attribute` с заполненной колонкой
`tabular` (имя секции) — цепочки вида `Т.Товары.Наименование` в запросах
проверяются по этим данным; `uuid` секции разрешает право роли, заданное на
табличной части.
- `module` — паспорт модуля: `code_name` (obj, mgr, mod, con, app …) и для общих
модулей `context` (Сервер/Клиент/Вызов сервера/…), плюс `body` — текст модуля как есть
без кода методов: комментарии, препроцессор `#Если…`, `#Область…`, директивы и сигнатуры
вида `Процедура Имя(п1, п2) Экспорт` сохранены; подстановка `method.body` вместо каждой
сигнатуры восстанавливает исходный модуль;
- `method` — только процедуры/функции: вид, имя, сигнатура, `is_export`, `directives`
(строка `&НаКлиенте, &НаСервере` без скобок), `description` (блок комментариев
непосредственно над методом, как есть с `//`), `line_start/line_end`, `body` — строго
с `Процедура/Функция` по `КонецПроцедуры/КонецФункции`; `#…` и комментарии вне тела
в метод не попадают;
- `subsystem_content` — состав подсистем (ссылки на объекты в порядке объявления) —
для обхода дерева подсистем, как в конфигураторе;
- `skd_query` — запросы, извлечённые из макетов СКД объекта (`ord`, `query`), —
для проверки корректности запросов 1С;
- `role_right` — объектные права ролей из файла `Role/<имя>/Role.0.c1brace`. Хранятся
только ЯВНЫЕ записи (sparse): отсутствие строки означает «право не задано», а не
«запрещено». Цель права — объект, его реквизит/поле табличной части или его
табличная часть: `target_object_id` — объект-владелец (заполнен и для подобъекта,
поэтому все права, затрагивающие объект, выбираются одним условием),
`target_attr_id`/`target_tabular_id` — сам подобъект, `target_uuid` — uuid цели как
он записан в роли (подобъект, которого проект не извлекает, остаётся только с ним);
`right_uuid` — идентификатор права платформы (русского имени права в конфигурации
нет, словарь «uuid → имя» из неё не извлекается), `value` — значение права,
`sub_index`/`collection_uuid` — адресация «подобъект №-K внутри коллекции»,
`target_flags` — флаги записи цели дословно, без толкования (их смысл не
подтверждён; без них две цели с одним uuid слились бы в одну),
`rls_text` — ограничение доступа на уровне записей для этой цели и права;
- `role_rls_template` — именованные шаблоны RLS роли (`name`, `text`);
- `role_rights_state` — состояние извлечения прав каждой роли: `parsed=0` — данные
недоступны (файла прав нет или формат не распознан, причина в `error`),
`parsed=1` при `rights=0` — права роли действительно не заданы;
- `xdto_type`, `xdto_property`, `xdto_import` — содержимое пакетов XDTO
(файл `XDTOPackage.bin` — это открытый XML, реверс бинарного формата не
потребовался): типы `objectType`/`valueType`/`typeDef` с базовым типом,
ограничениями и значениями перечислений, их свойства (обязательность,
признак списка, форма — атрибут или элемент, вложенные анонимные типы) и
импортируемые пространства имён; `type_id IS NULL` означает свойство,
объявленное самим пакетом вне типов; целевое пространство имён пакета
берётся из его `header_json`. Инструменты `xdto_of` и `find_xdto`;
- `file` — прочие файлы дампа (help.html, инфо-JSON, картинки): путь, тип, размер,
содержимое для текстовых (BLOB — только при `--store-blobs`).
Пример запроса:
```sql
-- реквизиты справочника с типами
SELECT a.name, a.type_str
FROM meta_attribute a JOIN meta_object o ON o.id = a.object_id
WHERE o.path = 'Catalog/Контрагенты' ORDER BY a.ord;
-- краткое представление модуля (текст без кода методов)
SELECT m.body FROM module m JOIN meta_object o ON o.id = m.object_id
WHERE o.path = 'Catalog/Контрагенты' AND m.code_name = 'obj';
-- тело конкретного метода
SELECT mt.body FROM method mt JOIN module m ON m.id = mt.module_id
JOIN meta_object o ON o.id = m.object_id
WHERE o.path = 'Document/Заказ' AND m.code_name = 'obj'
AND mt.name = 'ПриПроведении';
```
## Состав
- `src/confdb/v8` — ядро распаковки (контейнеры 1С, inflate, скобкофайлы, метаданные);
- `src/confdb/extract.py` — конвейер стадий 0/1/3 (контейнеры → inflate → разбор). Рабочий
каталог по умолчанию создаётся на томе результата (`make_temp_dir`), а не в `%TEMP%`, и
удаляется параллельно (`remove_tree`): удаление ~125 тыс. файлов стоит ~30 с на системном
томе против ~10 с на другом. Здесь же отпечаток источника — `file_sha256` (1.7 с для
885 МБ) пишется в `source.file_sha256`, а `check_same_source(src, db, force)` позволяет
CLI и TUI не распаковывать тот же файл повторно; в старых базах отпечатка нет, и это
читается как «неизвестно», а не как «файл другой»;
- `src/confdb/__main__.py` — CLI: `extract`, `check`, `fts`, `bench`, `1confdb-knw`;
- `src/confdb/db/writer.py` — схема SQLite и запись результата: пакетные вставки, разбор BSL
в несколько процессов (`workers`); права ролей пишутся после объектов и разрешаются по
uuid объектов, реквизитов и табличных частей (`_write_role_rights`, `_right_targets`);
ревизия схемы (`SCHEMA_VERSION`) штампуется в файл базы (`PRAGMA user_version`);
- `src/confdb/query_lang.py` — разбор и семантический контроль языка запросов 1С
(подкоманда `confdb check`);
- `src/confdb/mcp_server.py` — MCP-сервер `1confdb-knw <база…>`: read-only инструменты,
самомописываемый (схема, глоссарий и порядок работы отдаются в `initialize.instructions`).
Несколько баз (алиас на базу, необязательный параметр `db`, `db='*'` — по всем сразу) и
ГРУППЫ конфигураций: `--group ИМЯ=ПУТЬ` (повторяемый) открывает несколько групп,
`group=<имя>` опрашивает одну, `group='*'` — все, а без `group` работает только активная
база (`group_use` переключает активную). Шесть поисковых инструментов страничные
(`limit` 1..200 и `offset`, последняя строка ответа называет общее число совпадений и
следующий `offset`); кросс-базовые инструменты принимают явные алиасы (`compare_object`,
`extension_diff`); ошибки категоризованы (`error_text`), `SQLITE_BUSY` повторяется
(`call_with_retry`). Транспорт — stdio, `--port N` включает HTTP/SSE; вызовы
инструментов сериализованы общей блокировкой (`_synchronized`): соединения баз и
приставных шардов FTS на сервер общие, а потоков несколько — HTTP-обработчик
создаётся на запрос, панель работающего сервера в TUI дёргает тот же объект;
- `src/confdb/tui.py` — консольный интерфейс (выбор пользователя: консоль, а не GUI).
В списках файлов и баз число выбирает элемент, а любой другой текст читается как введённый
путь. Запуск MCP выбирает несколько групп баз сразу (в сервер они попадают как `--group`
в stdio-режиме и как `McpServer(groups=…)` в сетевом), а панель работающего сервера
добавляет, заменяет все, удаляет и активирует группу без перезапуска;
- `src/confdb/bsl_parser.py` — разбиение модулей BSL на процедуры и функции;
- `src/confdb/bsl_analyzer.py` — лексический анализ BSL для `method_dependencies` и
`method_result_schema`: маскирование строк и комментариев с пониманием многострочных
литералов 1С с `|`, извлечение и проверка запросов через `query_lang`, разрешение общих
модулей и метаданных, клиентский и серверный контекст. Синтаксис модулей он намеренно
**не** проверяет — это делает BSL Language Server, который есть только в варианте
`1confdb-knw-lsp`;
- `src/confdb/header_props.py` — читает `meta_object.header_json` без повторной распаковки:
версию конфигурации, синоним, режим совместимости и префикс расширения; коллекции
измерений, ресурсов и реквизитов регистра с периодичностью и флагами режима записи;
целевое пространство имён XDTO-пакета; вид загруженного файла — по расширению
`source.file`, а не по типу корневого объекта (`.erf` и `.epf` раскрываются в
`ExternalDataProcessor`);
- `src/confdb/xdto.py` — разбор `XDTOPackage.bin` (обычный UTF-8 XML с BOM) в таблицы
`xdto_*`; проверено на всех 334 пакетах тестовой конфигурации;
- `src/confdb/compare.py` — снимки объектов и сравнение двух баз (`compare_object`,
`extension_diff`); тела методов и модулей сравниваются по sha1;
- `src/confdb/rights.py` — разбор файла прав роли `Role/<имя>/Role.0.c1brace` (объектные
права, RLS по объектам, шаблоны RLS) для записи в базу; нераспознанный формат бросает
`ValueError`, поэтому одна «чужая» роль не останавливает запись;
- `src/confdb/bench.py` — бенчмарк железа, сохраняет лучшее число `workers` в
`~/.confdb/config.json` (`src/confdb/config.py` — общий конфиг пользователя, его же
читает TUI);
- `tests` — тесты на малых фикстурах (`test.bat`); `_tmp` — одноразовые пробники
(игнорируются git).
## Требования
- Python 3.9+, только стандартная библиотека.
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessNo issues