mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-07 18:50:53 +03:00
docs(meta-dsl-spec): полное описание DSL внешних источников данных
Раздел 18 был указателем на reference навыка — это ломало принятое разделение: спецификация в docs описывает DSL полно (для нас), инструкция навыка — только как применять (для модели). Указатель экономил дублирование ценой того, что полного описания не оказалось нигде. Теперь §18 описывает источник, таблицы, поля и функции целиком: ключи, XML-теги, умолчания, конвенции ссылок на поля, presence-aware inputByString, различение BinaryData и ValueStorage, запрет составного типа, и границы — почему в DSL нет значения незаполненного родителя (платформа сбрасывает его при любой загрузке XML) и почему нет кубов OLAP. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBsZA5cr2WFThtgp7i5WVi
This commit is contained in:
co-authored by
Claude Opus 5
parent
89ce1af9fa
commit
938db35c85
+158
-19
@@ -1961,30 +1961,169 @@ ChildObjects и модулей.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 18. Внешние источники данных (tables / functions)
|
## 18. Внешние источники данных (ExternalDataSource)
|
||||||
|
|
||||||
Только для `ExternalDataSource`. Полное описание — `.claude/skills/meta-compile/reference/external-data-source.md`:
|
Источник описывается одним JSON целиком: сам источник, его таблицы с полями и функции. Компилятор
|
||||||
таблицы, поля и функции, их свойства и умолчания. Здесь — только форма и связи с общими конвенциями,
|
пишет `ExternalDataSources/<Имя>.xml` плюс по файлу на таблицу в `<Имя>/Tables/` — единственный вид,
|
||||||
чтобы таблица свойств не жила в двух местах и не разъезжалась.
|
у которого объект складывается более чем из одного XML.
|
||||||
|
|
||||||
|
Параметров соединения в конфигурации нет: строка соединения, пользователь, пароль и тип СУБД
|
||||||
|
задаются в режиме «Предприятие» (стандартная функция «Управление внешними источниками данных»)
|
||||||
|
и хранятся в информационной базе.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{ "type": "ExternalDataSource", "name": "PG",
|
{
|
||||||
|
"type": "ExternalDataSource",
|
||||||
|
"name": "PG",
|
||||||
|
"dataLockControlMode": "AutomaticAndManaged",
|
||||||
"tables": {
|
"tables": {
|
||||||
"prices": ["product_id: Number(10,0)", "price: Number(15,2)"],
|
"prices": ["product_id: Number(10,0)", "period: Date", "price: Number(15,2)"],
|
||||||
"products": { "keyFields": ["id"], "presentationField": "name",
|
"products": {
|
||||||
"fields": ["id: Number(10,0)", "name: String(150)"] }
|
"nameInDataSource": "eds.public.products",
|
||||||
|
"tableDataType": "ObjectData",
|
||||||
|
"keyFields": ["id"],
|
||||||
|
"presentationField": "name",
|
||||||
|
"parentField": "parent_id",
|
||||||
|
"fields": [
|
||||||
|
"id: Number(10,0)",
|
||||||
|
"name: String(150)",
|
||||||
|
"article: String(50) | nullable",
|
||||||
|
"parent_id: ExternalDataSourceTableRef.PG.products | nullable"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"functions": { "total": { "expression": "public.f_total(&1, &2)", "returns": "Number(15,2)" } } }
|
"functions": {
|
||||||
|
"total": { "expression": "public.f_total(&1, &2)", "returns": "Number(15,2)" },
|
||||||
|
"nextKey": "NEXT VALUE FOR public.seq_key"
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`tables`** — dict имя → массив полей ЛИБО объект со свойствами и ключом `fields`: та же двойственность,
|
### 18.1 Свойства источника
|
||||||
что у `tabularSections` (§5).
|
|
||||||
- **Поле** — обычный реквизит (§4) плюс три своих ключа: `nameInDataSource`, `readOnly`, `allowNull`
|
|
||||||
(флаги строковой формы — `readonly`, `nullable`). Составной тип у поля платформа запрещает.
|
|
||||||
- **Ссылки на поля** (`keyFields`, `presentationField`, `parentField`, `dataVersionField`, `inputByString`,
|
|
||||||
`dataLockFields`) — короткими именами полей этой же таблицы, как `inputByString` у справочника (§7.1.5).
|
|
||||||
- **`functions`** — dict имя → строка (выражение) ЛИБО объект, как `urlTemplates` (§16) и `operations` (§17).
|
|
||||||
Параметры не объекты: они записаны в самом выражении как `&1`, `&2`.
|
|
||||||
|
|
||||||
Кубы OLAP не поддерживаются. Таблица — отдельный файл, поэтому `meta-compile` описывает источник целиком,
|
| Ключ | Умолчание | Значения |
|
||||||
а дописать таблицу или функцию в существующий умеет `meta-edit` (`add.tables` / `add.functions`).
|
|------|-----------|----------|
|
||||||
|
| `synonym` / `comment` | авто из имени / пусто | как у прочих объектов (§2, §4.4) |
|
||||||
|
| `dataLockControlMode` | `Automatic` | `Automatic` / `Managed` / `AutomaticAndManaged` |
|
||||||
|
| `tables` | `{}` | таблицы (§18.2) |
|
||||||
|
| `functions` | `{}` | функции (§18.4) |
|
||||||
|
|
||||||
|
`AutomaticAndManaged` — значение, которого нет у прочих объектов: оно отдаёт решение о режиме
|
||||||
|
блокировок каждой таблице. При конкретном значении (`Automatic`/`Managed`) одноимённое свойство
|
||||||
|
таблицы платформа игнорирует.
|
||||||
|
|
||||||
|
### 18.2 Таблицы
|
||||||
|
|
||||||
|
Ключ — имя таблицы в конфигурации. Значение — **массив полей** либо **объект** со свойствами и
|
||||||
|
ключом `fields`: та же двойственность, что у `tabularSections` (§5).
|
||||||
|
|
||||||
|
| Ключ | XML | Умолчание | Значения |
|
||||||
|
|------|-----|-----------|----------|
|
||||||
|
| `synonym` / `comment` | Synonym / Comment | авто из имени / пусто | ML (§4.4) |
|
||||||
|
| `tableType` | TableType | `Table` | `Table` — реальная таблица или представление; `Expression` — табличная функция/выражение |
|
||||||
|
| `nameInDataSource` | NameInDataSource | = имя таблицы | имя физической таблицы; платформа пишет три части `<база>.<схема>.<таблица>`. У `Expression` — пусто |
|
||||||
|
| `expressionInDataSource` | ExpressionInDataSource | пусто | выражение для `Expression`, напр. `public.f_by_parent(&1)`; имя базы в нём НЕ указывается |
|
||||||
|
| `tableDataType` | TableDataType | `NonobjectData` | `ObjectData` — запись определяется одним полем (аналог справочника); `NonobjectData` — составным ключом (аналог регистра сведений) |
|
||||||
|
| `keyFields` | KeyFields | `[]` | имена ключевых полей |
|
||||||
|
| `presentationField` | PresentationField | пусто | имя поля представления (осмысленно только у `ObjectData`) |
|
||||||
|
| `parentField` | ParentField | пусто | имя поля родителя; его тип обязан быть ссылкой на эту же таблицу |
|
||||||
|
| `inputByString` | InputByString | = `[presentationField]` | имена полей ввода по строке |
|
||||||
|
| `dataVersionField` | DataVersionField | пусто | имя поля, растущего при каждой записи (ловит конкурентное изменение) |
|
||||||
|
| `dataLockFields` | DataLockFields | `[]` | имена полей управляемой блокировки |
|
||||||
|
| `readOnly` | ReadOnly | `false` | запрет записи |
|
||||||
|
| `transactionsIsolationLevel` | TransactionsIsolationLevel | `Auto` | `Auto` / `ReadUncommitted` / `ReadCommitted` / `RepeatableRead` / `Serializable` |
|
||||||
|
| `dataLockControlMode` | DataLockControlMode | `Automatic` | `Automatic` / `Managed` / `AutomaticAndManaged` |
|
||||||
|
| `basedOn` | BasedOn | `[]` | ввод на основании, `MDObjectRef` verbatim (`Catalog.Контрагенты`) |
|
||||||
|
| `useStandardCommands` | UseStandardCommands | `true` | bool |
|
||||||
|
| `quickChoice` | QuickChoice | `false` | bool |
|
||||||
|
| `editType` | EditType | `InDialog` | `InDialog` / `InList` |
|
||||||
|
| `fields` | ChildObjects/Field | `[]` | поля (§18.3); синоним ключа — `columns` |
|
||||||
|
|
||||||
|
Прочие свойства — представления (`objectPresentation`, `extendedObjectPresentation`,
|
||||||
|
`recordPresentation`, `extendedRecordPresentation`, `listPresentation`, `extendedListPresentation`),
|
||||||
|
формы по умолчанию (`defaultObjectForm`, `defaultRecordForm`, `defaultListForm`, `defaultChoiceForm`),
|
||||||
|
`characteristics`, `explanation`, `includeHelpInContents`, `createOnInput`,
|
||||||
|
`searchStringModeOnInputByString`, `choiceDataGetModeOnInputByString`, `choiceHistoryOnInput` —
|
||||||
|
общий слой, как у справочника.
|
||||||
|
|
||||||
|
**Ссылки на поля** (`keyFields`, `presentationField`, `parentField`, `dataVersionField`,
|
||||||
|
`inputByString`, `dataLockFields`) задаются короткими именами полей этой же таблицы — конвенция §7.1.5.
|
||||||
|
Компилятор разворачивает их в полный путь `ExternalDataSource.<Источник>.Table.<Таблица>.Field.<Поле>`,
|
||||||
|
декомпилятор сворачивает обратно. Это единственные **шестичастные** ссылки в метаданных, поэтому
|
||||||
|
разбор с конца (как в ролях) на них не работает.
|
||||||
|
|
||||||
|
**`inputByString` — presence-aware.** Ключа нет → компилятор выводит список из `presentationField`
|
||||||
|
(так делает платформа при загрузке). Явный список, в том числе пустой `[]`, уважается как есть.
|
||||||
|
|
||||||
|
**Значение незаполненного родителя в DSL отсутствует намеренно.** Платформа сбрасывает его в пустое
|
||||||
|
при любой загрузке XML — включая загрузку собственной выгрузки (измерено на 8.3.24.1691 тремя
|
||||||
|
независимыми прогонами: значением `0` от Конфигуратора, `5` из XML и `1`, выставленным в Конфигураторе
|
||||||
|
осознанно). Задать его можно только интерактивно, поэтому компилятор эмитит форму, которая получается
|
||||||
|
после загрузки: `xsi:type="xs:string"` пусто при заданном `parentField`, иначе `xsi:nil="true"`.
|
||||||
|
|
||||||
|
### 18.3 Поля таблицы
|
||||||
|
|
||||||
|
Строковая и объектная форма — те же, что у реквизитов (§4). Своих ключа три:
|
||||||
|
|
||||||
|
| Ключ | XML | Умолчание | Значения |
|
||||||
|
|------|-----|-----------|----------|
|
||||||
|
| `nameInDataSource` | NameInDataSource | = имя поля | имя колонки. Значение в одинарных кавычках уходит в SQL как есть; без кавычек экранируется двойными при спецсимволах |
|
||||||
|
| `readOnly` | ReadOnly | `false` | поле не записывается (вычисляемые, автоинкрементные, ключевые) |
|
||||||
|
| `allowNull` | AllowNull | `false` | допускает `NULL`; в форме показывается как «Не заполнено» |
|
||||||
|
|
||||||
|
Флаги строковой формы: `readonly`, `nullable`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"fields": [
|
||||||
|
"id: Number(10,0) | readonly",
|
||||||
|
{ "name": "article", "type": "String(50)", "nameInDataSource": "art_code", "allowNull": true }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Допустимые типы поля: `Number`, `String`, `Date`, `Boolean`, `UUID`, `BinaryData` (и `BinaryData(N)`
|
||||||
|
с ограничением длины) и ссылка на таблицу внешнего источника —
|
||||||
|
`ExternalDataSourceTableRef.<Источник>.<Таблица>`.
|
||||||
|
|
||||||
|
`BinaryData` (ДвоичныеДанные) — **не** `ValueStorage`: платформа пишет его как `xs:base64Binary`
|
||||||
|
с `BinaryDataQualifiers`, тогда как ХранилищеЗначения — как `v8:ValueStorage`. Декомпилятор
|
||||||
|
различает их по наличию квалификаторов.
|
||||||
|
|
||||||
|
**Составной тип у поля платформа запрещает** — при загрузке отвечает «Поле не может иметь составной
|
||||||
|
тип», хотя «Руководство разработчика» (17.5.2.3.4) его разрешает. Документация опережает реализацию.
|
||||||
|
|
||||||
|
Набор свойств поля — канонический блок реквизита (§4) без `ChoiceFoldersAndItems`, `LinkByType`,
|
||||||
|
`Indexing`, `Use`, `FullTextSearch`, `DataHistory`: индексами и полнотекстовым поиском чужой таблицы
|
||||||
|
1С не владеет. `ChoiceForm` у поля стоит ПОСЛЕ `ChoiceHistoryOnInput`, а не перед — порядок снят
|
||||||
|
с выгрузки платформы.
|
||||||
|
|
||||||
|
### 18.4 Функции
|
||||||
|
|
||||||
|
Ключ — имя функции. Значение — строка (интерпретируется как `expression`) либо объект: как
|
||||||
|
`urlTemplates` (§16) и `operations` (§17).
|
||||||
|
|
||||||
|
| Ключ | XML | Умолчание | Значения |
|
||||||
|
|------|-----|-----------|----------|
|
||||||
|
| `expression` | ExpressionInDataSource | — | выражение в источнике, обязательный |
|
||||||
|
| `returns` | Type | `String` | тип возвращаемого значения |
|
||||||
|
| `returnValue` | ReturnValue | `true` | `false` — процедура, тип не пишется |
|
||||||
|
| `synonym` / `comment` | Synonym / Comment | авто из имени / пусто | ML (§4.4) |
|
||||||
|
|
||||||
|
Функция лежит полным узлом внутри файла источника, отдельного файла у неё нет.
|
||||||
|
|
||||||
|
**Параметры функции не являются объектами метаданных.** Формальные параметры записываются прямо
|
||||||
|
в выражении как `&1`, `&2`; необязательные — в фигурных скобках `f(&1{, &2})`; переменное число —
|
||||||
|
`&n[]` (только последним в списке). Отдельного ключа для них нет и быть не может.
|
||||||
|
|
||||||
|
### 18.5 Границы
|
||||||
|
|
||||||
|
- **Кубы OLAP** (`Cube`, `DimensionTable`, `Dimension`, `Resource`) не поддерживаются: проверить их
|
||||||
|
платформой нечем — SSAS в контейнер не ставится, а эмит вслепую по документации уже давал осечку.
|
||||||
|
- **Формы, макеты и модули** таблиц компилятор не создаёт — как и у прочих объектов (`form-add`,
|
||||||
|
`form-compile`, `template-add`).
|
||||||
|
- **Таблица без ключевых полей** собирается: загрузку XML платформа принимает молча, хотя
|
||||||
|
Конфигуратор интерактивно ключ требует. `meta-validate` предупреждает, но не отвергает — рабочие
|
||||||
|
конфигурации без ключей существуют. Без ключа недоступны форма записи и набор записей.
|
||||||
|
- `meta-compile` описывает источник **целиком**: повторный запуск заменяет его файл, выдаёт новый uuid,
|
||||||
|
а таблицы, которых нет в описании, остаются на диске сиротами. Дописать таблицу или функцию
|
||||||
|
в существующий источник умеет `meta-edit` (`add.tables` / `add.functions`), удалить таблицу —
|
||||||
|
`meta-remove ExternalDataSource.<Источник>.Table.<Таблица>`.
|
||||||
|
|||||||
Reference in New Issue
Block a user