mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-07 18:50:53 +03:00
feat(meta-decompile): разбор внешних источников данных и раундтрип
Декомпилятор собирает DSL источника целиком: читает файл источника, подтягивает файлы таблиц из <Источник>/Tables/ и складывает поля, ключи, ссылки и функции обратно в тот же синтаксис, который принимает meta-compile. Ссылки на поля возвращаются короткими именами, таблица без собственных свойств — коротким массивом полей, функция с типом по умолчанию — одной строкой. Это замыкает дешёвый контур проверки: XML → декомпиляция → компиляция → сравнение с исходником, без 1С и без Docker. На нём и проверено: наша выгрузка, выгрузка платформы и четыре таблицы внешних источников из чужого рабочего проекта возвращаются байт в байт. У выгрузки платформы остаются два известных расхождения: значение незаполненного родителя (платформа сама сбрасывает его при любой загрузке) и формы (декомпилятор их не захватывает — так задумано). Побочно закрыт дефект, к внешним источникам не относящийся: xs:base64Binary разбирался как ХранилищеЗначения, хотя это ДвоичныеДанные. Различать их можно по квалификаторам — у ХранилищеЗначения платформа пишет v8:ValueStorage, а у двоичных данных есть BinaryDataQualifiers. Компилятор научен типу BinaryData (и BinaryData(N)) — до этого он принимал такое имя, но эмитил его как есть, то есть невалидный XML. 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
123d6e326b
commit
24cfe6a0a6
@@ -97,8 +97,9 @@
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Допустимые типы: `Number`, `String`, `Date`, `Boolean`, `UUID`, `BinaryData` и ссылка на таблицу
|
Допустимые типы: `Number`, `String`, `Date`, `Boolean`, `UUID`, `BinaryData` (двоичные данные;
|
||||||
внешнего источника — `ExternalDataSourceTableRef.<Источник>.<Таблица>`.
|
`BinaryData(N)` — с ограничением длины) и ссылка на таблицу внешнего источника —
|
||||||
|
`ExternalDataSourceTableRef.<Источник>.<Таблица>`.
|
||||||
|
|
||||||
**Составной тип у поля недопустим** — платформа такую конфигурацию не загружает.
|
**Составной тип у поля недопустим** — платформа такую конфигурацию не загружает.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# meta-compile v1.106 — Compile 1C metadata object from JSON
|
# meta-compile v1.107 — Compile 1C metadata object from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
[CmdletBinding(PositionalBinding=$false)]
|
[CmdletBinding(PositionalBinding=$false)]
|
||||||
param(
|
param(
|
||||||
@@ -604,6 +604,10 @@ $script:typeSynonyms["bool"] = "Boolean"
|
|||||||
# ValueStorage / UUID — прощающий ввод (модель может написать base64Binary / рус. форму → канон).
|
# ValueStorage / UUID — прощающий ввод (модель может написать base64Binary / рус. форму → канон).
|
||||||
$script:typeSynonyms["valuestorage"] = "ValueStorage"
|
$script:typeSynonyms["valuestorage"] = "ValueStorage"
|
||||||
$script:typeSynonyms["base64binary"] = "ValueStorage"
|
$script:typeSynonyms["base64binary"] = "ValueStorage"
|
||||||
|
# ДвоичныеДанные — ОТДЕЛЬНЫЙ тип, не ХранилищеЗначения: платформа пишет его как
|
||||||
|
# xs:base64Binary с квалификаторами. Встречается у полей внешних источников данных.
|
||||||
|
$script:typeSynonyms["binarydata"] = "BinaryData"
|
||||||
|
$script:typeSynonyms["двоичныеданные"] = "BinaryData"
|
||||||
$script:typeSynonyms["хранилищезначений"] = "ValueStorage"
|
$script:typeSynonyms["хранилищезначений"] = "ValueStorage"
|
||||||
$script:typeSynonyms["хранилищезначения"] = "ValueStorage"
|
$script:typeSynonyms["хранилищезначения"] = "ValueStorage"
|
||||||
$script:typeSynonyms["uuid"] = "UUID"
|
$script:typeSynonyms["uuid"] = "UUID"
|
||||||
@@ -807,6 +811,17 @@ function Emit-TypeContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ValueStorage (ХранилищеЗначения) — канон v8:ValueStorage (не xs:base64Binary, хоть 1С и принимает оба).
|
# ValueStorage (ХранилищеЗначения) — канон v8:ValueStorage (не xs:base64Binary, хоть 1С и принимает оба).
|
||||||
|
# ДвоичныеДанные — xs:base64Binary с квалификаторами (у полей внешних источников).
|
||||||
|
if ($typeStr -eq "BinaryData" -or $typeStr -match '^BinaryData\(') {
|
||||||
|
$blen = if ($typeStr -match '^BinaryData\((\d+)\)$') { $Matches[1] } else { "4294967292" }
|
||||||
|
$ballowed = if ($typeStr -match '^BinaryData\(\d+\)$') { "Variable" } else { "Fixed" }
|
||||||
|
X "$indent<v8:Type>xs:base64Binary</v8:Type>"
|
||||||
|
X "$indent<v8:BinaryDataQualifiers>"
|
||||||
|
X "$indent`t<v8:Length>$blen</v8:Length>"
|
||||||
|
X "$indent`t<v8:AllowedLength>$ballowed</v8:AllowedLength>"
|
||||||
|
X "$indent</v8:BinaryDataQualifiers>"
|
||||||
|
return
|
||||||
|
}
|
||||||
if ($typeStr -eq "ValueStorage") {
|
if ($typeStr -eq "ValueStorage") {
|
||||||
X "$indent<v8:Type>v8:ValueStorage</v8:Type>"
|
X "$indent<v8:Type>v8:ValueStorage</v8:Type>"
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# meta-compile v1.106 — Compile 1C metadata object from JSON
|
# meta-compile v1.107 — Compile 1C metadata object from JSON
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -735,6 +735,10 @@ type_synonyms = {
|
|||||||
# ValueStorage / UUID — прощающий ввод (base64Binary / рус. форма → канон).
|
# ValueStorage / UUID — прощающий ввод (base64Binary / рус. форма → канон).
|
||||||
'valuestorage': 'ValueStorage',
|
'valuestorage': 'ValueStorage',
|
||||||
'base64binary': 'ValueStorage',
|
'base64binary': 'ValueStorage',
|
||||||
|
# ДвоичныеДанные — ОТДЕЛЬНЫЙ тип, не ХранилищеЗначения: платформа пишет его как
|
||||||
|
# xs:base64Binary с квалификаторами. Встречается у полей внешних источников данных.
|
||||||
|
'binarydata': 'BinaryData',
|
||||||
|
'двоичныеданные': 'BinaryData',
|
||||||
'хранилищезначений': 'ValueStorage',
|
'хранилищезначений': 'ValueStorage',
|
||||||
'хранилищезначения': 'ValueStorage',
|
'хранилищезначения': 'ValueStorage',
|
||||||
'uuid': 'UUID',
|
'uuid': 'UUID',
|
||||||
@@ -927,6 +931,17 @@ def emit_type_content(indent, type_str):
|
|||||||
if re.match(r'^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|ExchangePlanRef|BusinessProcessRef|TaskRef|AnyRef|AnyIBRef)$', type_str):
|
if re.match(r'^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|ExchangePlanRef|BusinessProcessRef|TaskRef|AnyRef|AnyIBRef)$', type_str):
|
||||||
X(f'{indent}<v8:TypeSet>cfg:{type_str}</v8:TypeSet>')
|
X(f'{indent}<v8:TypeSet>cfg:{type_str}</v8:TypeSet>')
|
||||||
return
|
return
|
||||||
|
# ДвоичныеДанные — xs:base64Binary с квалификаторами (у полей внешних источников).
|
||||||
|
m_bin = re.match(r'^BinaryData(?:\((\d+)\))?$', type_str)
|
||||||
|
if m_bin:
|
||||||
|
blen = m_bin.group(1) or '4294967292'
|
||||||
|
ballowed = 'Variable' if m_bin.group(1) else 'Fixed'
|
||||||
|
X(f'{indent}<v8:Type>xs:base64Binary</v8:Type>')
|
||||||
|
X(f'{indent}<v8:BinaryDataQualifiers>')
|
||||||
|
X(f'{indent}\t<v8:Length>{blen}</v8:Length>')
|
||||||
|
X(f'{indent}\t<v8:AllowedLength>{ballowed}</v8:AllowedLength>')
|
||||||
|
X(f'{indent}</v8:BinaryDataQualifiers>')
|
||||||
|
return
|
||||||
# ValueStorage (ХранилищеЗначения) — канон v8:ValueStorage (не xs:base64Binary).
|
# ValueStorage (ХранилищеЗначения) — канон v8:ValueStorage (не xs:base64Binary).
|
||||||
if type_str == 'ValueStorage':
|
if type_str == 'ValueStorage':
|
||||||
X(f'{indent}<v8:Type>v8:ValueStorage</v8:Type>')
|
X(f'{indent}<v8:Type>v8:ValueStorage</v8:Type>')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# meta-decompile v0.65 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
# meta-decompile v0.66 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
#
|
#
|
||||||
# Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes, Document,
|
# Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes, Document,
|
||||||
@@ -93,7 +93,7 @@ foreach ($c in $rootEl.ChildNodes) { if ($c.NodeType -eq 'Element') { $objNode =
|
|||||||
if (-not $objNode) { [Console]::Error.WriteLine("meta-decompile: пустой MetaDataObject"); exit 3 }
|
if (-not $objNode) { [Console]::Error.WriteLine("meta-decompile: пустой MetaDataObject"); exit 3 }
|
||||||
$objType = $objNode.LocalName
|
$objType = $objNode.LocalName
|
||||||
|
|
||||||
if ($objType -notin @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes', 'ChartOfAccounts', 'ChartOfCalculationTypes', 'Document', 'InformationRegister', 'AccumulationRegister', 'AccountingRegister', 'CalculationRegister', 'BusinessProcess', 'Task', 'Enum', 'Report', 'DataProcessor', 'Constant', 'DefinedType', 'FunctionalOption', 'DocumentJournal', 'Sequence', 'FilterCriterion', 'DocumentNumerator', 'SettingsStorage', 'CommonModule', 'EventSubscription', 'ScheduledJob', 'CommonForm', 'SessionParameter', 'CommonCommand', 'CommandGroup', 'CommonAttribute', 'FunctionalOptionsParameter', 'WSReference', 'CommonPicture', 'CommonTemplate', 'HTTPService', 'WebService')) {
|
if ($objType -notin @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes', 'ChartOfAccounts', 'ChartOfCalculationTypes', 'Document', 'InformationRegister', 'AccumulationRegister', 'AccountingRegister', 'CalculationRegister', 'BusinessProcess', 'Task', 'Enum', 'Report', 'DataProcessor', 'Constant', 'DefinedType', 'FunctionalOption', 'DocumentJournal', 'Sequence', 'FilterCriterion', 'DocumentNumerator', 'SettingsStorage', 'CommonModule', 'EventSubscription', 'ScheduledJob', 'CommonForm', 'SessionParameter', 'CommonCommand', 'CommandGroup', 'CommonAttribute', 'FunctionalOptionsParameter', 'WSReference', 'CommonPicture', 'CommonTemplate', 'HTTPService', 'WebService', 'ExternalDataSource')) {
|
||||||
[Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (…, CommonPicture, CommonTemplate)"); exit 3
|
[Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (…, CommonPicture, CommonTemplate)"); exit 3
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +206,18 @@ function Get-TypeShorthand {
|
|||||||
if ($dq) { $dn = $dq.SelectSingleNode('v8:DateFractions', $nsm); if ($dn) { $fr = $dn.InnerText } }
|
if ($dq) { $dn = $dq.SelectSingleNode('v8:DateFractions', $nsm); if ($dn) { $fr = $dn.InnerText } }
|
||||||
$parts += $fr; break # Date | DateTime
|
$parts += $fr; break # Date | DateTime
|
||||||
}
|
}
|
||||||
'(^|:)base64Binary$' { $parts += 'ValueStorage'; break }
|
'(^|:)base64Binary$' {
|
||||||
|
# xs:base64Binary — это ДвоичныеДанные, если рядом есть свои квалификаторы;
|
||||||
|
# ХранилищеЗначения платформа пишет как v8:ValueStorage, но принимает и эту форму.
|
||||||
|
$bq = $typeNode.SelectSingleNode('v8:BinaryDataQualifiers', $nsm)
|
||||||
|
if ($bq) {
|
||||||
|
$blen = $bq.SelectSingleNode('v8:Length', $nsm)
|
||||||
|
$bal = $bq.SelectSingleNode('v8:AllowedLength', $nsm)
|
||||||
|
if ($blen -and $bal -and $bal.InnerText -eq 'Variable') { $parts += "BinaryData($($blen.InnerText))" }
|
||||||
|
else { $parts += 'BinaryData' }
|
||||||
|
} else { $parts += 'ValueStorage' }
|
||||||
|
break
|
||||||
|
}
|
||||||
default { $parts += (Strip-NsPrefix $raw) } # cfg:CatalogRef.X → CatalogRef.X
|
default { $parts += (Strip-NsPrefix $raw) } # cfg:CatalogRef.X → CatalogRef.X
|
||||||
}
|
}
|
||||||
} elseif ($ln -eq 'TypeSet') {
|
} elseif ($ln -eq 'TypeSet') {
|
||||||
@@ -288,12 +299,19 @@ function Attr-ToDsl {
|
|||||||
param($attrNode)
|
param($attrNode)
|
||||||
$ap = $attrNode.SelectSingleNode('md:Properties', $nsm)
|
$ap = $attrNode.SelectSingleNode('md:Properties', $nsm)
|
||||||
$nm = ($ap.SelectSingleNode('md:Name', $nsm)).InnerText
|
$nm = ($ap.SelectSingleNode('md:Name', $nsm)).InnerText
|
||||||
|
# Поле внешнего источника: три своих свойства. Имя колонки по умолчанию равно имени поля,
|
||||||
|
# поэтому в DSL попадает только отличающееся.
|
||||||
|
$edsNids = $ap.SelectSingleNode('md:NameInDataSource', $nsm)
|
||||||
|
$edsRo = $ap.SelectSingleNode('md:ReadOnly', $nsm)
|
||||||
|
$edsNull = $ap.SelectSingleNode('md:AllowNull', $nsm)
|
||||||
$ts = Get-TypeShorthand ($ap.SelectSingleNode('md:Type', $nsm))
|
$ts = Get-TypeShorthand ($ap.SelectSingleNode('md:Type', $nsm))
|
||||||
$flags = @()
|
$flags = @()
|
||||||
$fc = $ap.SelectSingleNode('md:FillChecking', $nsm); if ($fc -and $fc.InnerText -eq 'ShowError') { $flags += 'req' }
|
$fc = $ap.SelectSingleNode('md:FillChecking', $nsm); if ($fc -and $fc.InnerText -eq 'ShowError') { $flags += 'req' }
|
||||||
$ix = $ap.SelectSingleNode('md:Indexing', $nsm)
|
$ix = $ap.SelectSingleNode('md:Indexing', $nsm)
|
||||||
if ($ix) { if ($ix.InnerText -eq 'Index') { $flags += 'index' } elseif ($ix.InnerText -eq 'IndexWithAdditionalOrder') { $flags += 'indexAdditional' } }
|
if ($ix) { if ($ix.InnerText -eq 'Index') { $flags += 'index' } elseif ($ix.InnerText -eq 'IndexWithAdditionalOrder') { $flags += 'indexAdditional' } }
|
||||||
$ml = $ap.SelectSingleNode('md:MultiLine', $nsm); if ($ml -and $ml.InnerText -eq 'true') { $flags += 'multiline' }
|
$ml = $ap.SelectSingleNode('md:MultiLine', $nsm); if ($ml -and $ml.InnerText -eq 'true') { $flags += 'multiline' }
|
||||||
|
if ($edsRo -and $edsRo.InnerText -eq 'true') { $flags += 'readonly' }
|
||||||
|
if ($edsNull -and $edsNull.InnerText -eq 'true') { $flags += 'nullable' }
|
||||||
|
|
||||||
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}).
|
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}).
|
||||||
$synNode = $ap.SelectSingleNode('md:Synonym', $nsm)
|
$synNode = $ap.SelectSingleNode('md:Synonym', $nsm)
|
||||||
@@ -407,6 +425,7 @@ function Attr-ToDsl {
|
|||||||
# Пустой <Type/> (реквизит без типа / произвольный) → $ts=''. Отличаем от «дефолтного» отсутствия:
|
# Пустой <Type/> (реквизит без типа / произвольный) → $ts=''. Отличаем от «дефолтного» отсутствия:
|
||||||
# заставляем объектную форму с явным type:'' (компилятор без маркера подставил бы xs:string).
|
# заставляем объектную форму с явным type:'' (компилятор без маркера подставил бы xs:string).
|
||||||
$typeEmpty = ($ts -eq '')
|
$typeEmpty = ($ts -eq '')
|
||||||
|
if ($edsNids -and $edsNids.InnerText -and $edsNids.InnerText -cne $nm) { $extra['nameInDataSource'] = $edsNids.InnerText }
|
||||||
if ($synCustom -or $synEmpty -or ($null -ne $ttVal) -or $extra.Count -gt 0 -or $typeEmpty) {
|
if ($synCustom -or $synEmpty -or ($null -ne $ttVal) -or $extra.Count -gt 0 -or $typeEmpty) {
|
||||||
$o = [ordered]@{ name = $nm }
|
$o = [ordered]@{ name = $nm }
|
||||||
if ($ts) { $o['type'] = $ts } elseif ($typeEmpty) { $o['type'] = '' }
|
if ($ts) { $o['type'] = $ts } elseif ($typeEmpty) { $o['type'] = '' }
|
||||||
@@ -1658,6 +1677,116 @@ if ($objType -eq 'ExchangePlan') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# --- Внешний источник данных: таблицы (отдельные файлы) и функции (узлы внутри файла) ---
|
||||||
|
if ($objType -eq 'ExternalDataSource') {
|
||||||
|
$dlcmVal = P 'DataLockControlMode'
|
||||||
|
if ($dlcmVal -and $dlcmVal -cne 'Automatic') { $dsl['dataLockControlMode'] = $dlcmVal }
|
||||||
|
|
||||||
|
# Короткое имя из полного пути ExternalDataSource.И.Table.Т.Field.П
|
||||||
|
function Short-FieldRef { param([string]$ref) if ($ref) { return ($ref -split '\.')[-1] } else { return $null } }
|
||||||
|
function Field-RefList { param($parent, [string]$tag)
|
||||||
|
$out = [System.Collections.ArrayList]@()
|
||||||
|
foreach ($f in @($parent.SelectNodes("md:$tag/xr:Field", $nsm))) { [void]$out.Add((Short-FieldRef $f.InnerText)) }
|
||||||
|
# Запятая обязательна: return разворачивает коллекцию из одного элемента в скаляр,
|
||||||
|
# и список ключевых полей из одного поля уехал бы в JSON строкой вместо массива.
|
||||||
|
return ,$out
|
||||||
|
}
|
||||||
|
|
||||||
|
$srcDir = Join-Path (Split-Path -Parent (Resolve-Path -LiteralPath $ObjectPath).Path) $objName
|
||||||
|
$childObjsEds = $objNode.SelectSingleNode('md:ChildObjects', $nsm)
|
||||||
|
if ($childObjsEds) {
|
||||||
|
$tablesMap = [ordered]@{}
|
||||||
|
foreach ($tNode in @($childObjsEds.SelectNodes('md:Table', $nsm))) {
|
||||||
|
$tblName = $tNode.InnerText.Trim()
|
||||||
|
$tblPath = Join-Path (Join-Path $srcDir 'Tables') "$tblName.xml"
|
||||||
|
if (-not (Test-Path -LiteralPath $tblPath)) {
|
||||||
|
[Console]::Error.WriteLine("meta-decompile: файл таблицы не найден: $tblPath")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
$tdoc = New-Object System.Xml.XmlDocument
|
||||||
|
$tdoc.PreserveWhitespace = $true
|
||||||
|
$tdoc.Load($tblPath)
|
||||||
|
$tObjNode = $null
|
||||||
|
foreach ($c in $tdoc.DocumentElement.ChildNodes) { if ($c.NodeType -eq 'Element') { $tObjNode = $c; break } }
|
||||||
|
$tp = $tObjNode.SelectSingleNode('md:Properties', $nsm)
|
||||||
|
function TP { param([string]$tag) $n = $tp.SelectSingleNode("md:$tag", $nsm); if ($n) { return $n.InnerText } else { return $null } }
|
||||||
|
|
||||||
|
$tbl = [ordered]@{}
|
||||||
|
$tSynNode = $tp.SelectSingleNode('md:Synonym', $nsm)
|
||||||
|
$tSyn = Get-MLValue $tSynNode
|
||||||
|
if ($tSyn -is [string]) { if ($tSyn -cne (Split-CamelWords $tblName)) { $tbl['synonym'] = $tSyn } }
|
||||||
|
elseif ($null -ne $tSyn) { $tbl['synonym'] = $tSyn }
|
||||||
|
# Пустой <Synonym/> ≠ авто-синоним из имени: без явного '' компилятор до-генерит его из имени.
|
||||||
|
elseif ($tSynNode) { $tbl['synonym'] = '' }
|
||||||
|
$tCmt = TP 'Comment'; if ($tCmt) { $tbl['comment'] = $tCmt }
|
||||||
|
$tType = TP 'TableType'; if ($tType -and $tType -cne 'Table') { $tbl['tableType'] = $tType }
|
||||||
|
$nids = TP 'NameInDataSource'; if ($nids -and $nids -cne $tblName) { $tbl['nameInDataSource'] = $nids }
|
||||||
|
$expr = TP 'ExpressionInDataSource'; if ($expr) { $tbl['expressionInDataSource'] = $expr }
|
||||||
|
$tdt = TP 'TableDataType'; if ($tdt -and $tdt -cne 'NonobjectData') { $tbl['tableDataType'] = $tdt }
|
||||||
|
$keys = Field-RefList $tp 'KeyFields'; if ($keys.Count -gt 0) { $tbl['keyFields'] = $keys }
|
||||||
|
foreach ($pair in @(@('PresentationField','presentationField'), @('ParentField','parentField'), @('DataVersionField','dataVersionField'))) {
|
||||||
|
$v = Short-FieldRef (TP $pair[0]); if ($v) { $tbl[$pair[1]] = $v }
|
||||||
|
}
|
||||||
|
$ibs = Field-RefList $tp 'InputByString'
|
||||||
|
# Ввод по строке компилятор выводит из поля представления: совпадающий список не пишем.
|
||||||
|
$ibsAuto = if ($tbl['presentationField']) { @($tbl['presentationField']) } else { @() }
|
||||||
|
if (($ibs -join ',') -cne ($ibsAuto -join ',')) { $tbl['inputByString'] = $ibs }
|
||||||
|
$dlf = Field-RefList $tp 'DataLockFields'; if ($dlf.Count -gt 0) { $tbl['dataLockFields'] = $dlf }
|
||||||
|
if ((TP 'ReadOnly') -eq 'true') { $tbl['readOnly'] = $true }
|
||||||
|
$til = TP 'TransactionsIsolationLevel'; if ($til -and $til -cne 'Auto') { $tbl['transactionsIsolationLevel'] = $til }
|
||||||
|
$tdlcm = TP 'DataLockControlMode'; if ($tdlcm -and $tdlcm -cne 'Automatic') { $tbl['dataLockControlMode'] = $tdlcm }
|
||||||
|
if ((TP 'UseStandardCommands') -eq 'false') { $tbl['useStandardCommands'] = $false }
|
||||||
|
if ((TP 'QuickChoice') -eq 'true') { $tbl['quickChoice'] = $true }
|
||||||
|
$tet = TP 'EditType'; if ($tet -and $tet -cne 'InDialog') { $tbl['editType'] = $tet }
|
||||||
|
$basedOn = [System.Collections.ArrayList]@()
|
||||||
|
foreach ($it in @($tp.SelectNodes('md:BasedOn/xr:Item', $nsm))) { [void]$basedOn.Add($it.InnerText) }
|
||||||
|
if ($basedOn.Count -gt 0) { $tbl['basedOn'] = $basedOn }
|
||||||
|
|
||||||
|
$fieldsArr = [System.Collections.ArrayList]@()
|
||||||
|
$tChild = $tObjNode.SelectSingleNode('md:ChildObjects', $nsm)
|
||||||
|
if ($tChild) {
|
||||||
|
foreach ($f in @($tChild.SelectNodes('md:Field', $nsm))) { [void]$fieldsArr.Add((Attr-ToDsl $f)) }
|
||||||
|
}
|
||||||
|
# Таблица без собственных свойств — короткая форма: просто массив полей.
|
||||||
|
if ($tbl.Count -eq 0) { $tablesMap[$tblName] = $fieldsArr }
|
||||||
|
else { $tbl['fields'] = $fieldsArr; $tablesMap[$tblName] = $tbl }
|
||||||
|
}
|
||||||
|
if ($tablesMap.Count -gt 0) { $dsl['tables'] = $tablesMap }
|
||||||
|
|
||||||
|
$fnMap = [ordered]@{}
|
||||||
|
foreach ($fnNode in @($childObjsEds.SelectNodes('md:Function', $nsm))) {
|
||||||
|
$fp = $fnNode.SelectSingleNode('md:Properties', $nsm)
|
||||||
|
$fnName = ($fp.SelectSingleNode('md:Name', $nsm)).InnerText
|
||||||
|
$fnExprNode = $fp.SelectSingleNode('md:ExpressionInDataSource', $nsm)
|
||||||
|
$fnExpr = if ($fnExprNode) { $fnExprNode.InnerText } else { '' }
|
||||||
|
$fnRetNode = $fp.SelectSingleNode('md:ReturnValue', $nsm)
|
||||||
|
$fnReturns = Get-TypeShorthand ($fp.SelectSingleNode('md:Type', $nsm))
|
||||||
|
$fnSyn = Get-MLValue ($fp.SelectSingleNode('md:Synonym', $nsm))
|
||||||
|
$fnCmtNode = $fp.SelectSingleNode('md:Comment', $nsm)
|
||||||
|
$fnCmt = if ($fnCmtNode) { $fnCmtNode.InnerText } else { '' }
|
||||||
|
$fnNoValue = ($fnRetNode -and $fnRetNode.InnerText -eq 'false')
|
||||||
|
$synCustomFn = ($fnSyn -isnot [string]) -and ($null -ne $fnSyn)
|
||||||
|
if ($fnSyn -is [string]) { $synCustomFn = ($fnSyn -cne (Split-CamelWords $fnName)) -and ($fnSyn -ne '') }
|
||||||
|
# Умолчание `returns` компилятора — String, а он даёт String(10): с ним и сверяем,
|
||||||
|
# иначе короткая форма (одна строка выражения) не срабатывала бы никогда.
|
||||||
|
if (-not $fnNoValue -and -not $fnCmt -and -not $synCustomFn -and ($fnReturns -cne 'String(10)')) {
|
||||||
|
$fo = [ordered]@{ expression = $fnExpr; returns = $fnReturns }
|
||||||
|
$fnMap[$fnName] = $fo
|
||||||
|
} elseif (-not $fnNoValue -and -not $fnCmt -and -not $synCustomFn) {
|
||||||
|
# Тип по умолчанию String — короткая форма: одна строка выражения.
|
||||||
|
$fnMap[$fnName] = $fnExpr
|
||||||
|
} else {
|
||||||
|
$fo = [ordered]@{ expression = $fnExpr }
|
||||||
|
if ($fnNoValue) { $fo['returnValue'] = $false } elseif ($fnReturns) { $fo['returns'] = $fnReturns }
|
||||||
|
if ($synCustomFn) { $fo['synonym'] = $fnSyn }
|
||||||
|
if ($fnCmt) { $fo['comment'] = $fnCmt }
|
||||||
|
$fnMap[$fnName] = $fo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($fnMap.Count -gt 0) { $dsl['functions'] = $fnMap }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# === Вывод ===
|
# === Вывод ===
|
||||||
$json = ConvertTo-CompactJson $dsl 0
|
$json = ConvertTo-CompactJson $dsl 0
|
||||||
if ($OutputPath) {
|
if ($OutputPath) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# meta-decompile v0.65 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
# meta-decompile v0.66 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
#
|
#
|
||||||
# Зеркало meta-decompile.ps1 (КАНОН). Структура 1:1 — те же имена функций, порядок, комментарии.
|
# Зеркало meta-decompile.ps1 (КАНОН). Структура 1:1 — те же имена функций, порядок, комментарии.
|
||||||
@@ -311,7 +311,18 @@ def get_type_shorthand(type_node):
|
|||||||
fr = _text(dn)
|
fr = _text(dn)
|
||||||
parts.append(fr) # Date | DateTime
|
parts.append(fr) # Date | DateTime
|
||||||
elif re.search(r'(^|:)base64Binary$', raw, re.I):
|
elif re.search(r'(^|:)base64Binary$', raw, re.I):
|
||||||
parts.append('ValueStorage')
|
# xs:base64Binary — это ДвоичныеДанные, если рядом есть свои квалификаторы;
|
||||||
|
# ХранилищеЗначения платформа пишет как v8:ValueStorage, но принимает и эту форму.
|
||||||
|
bq = type_node.find('v8:BinaryDataQualifiers', NS)
|
||||||
|
if bq is not None:
|
||||||
|
blen = bq.find('v8:Length', NS)
|
||||||
|
bal = bq.find('v8:AllowedLength', NS)
|
||||||
|
if blen is not None and bal is not None and _text(bal) == 'Variable':
|
||||||
|
parts.append(f'BinaryData({_text(blen)})')
|
||||||
|
else:
|
||||||
|
parts.append('BinaryData')
|
||||||
|
else:
|
||||||
|
parts.append('ValueStorage')
|
||||||
else:
|
else:
|
||||||
parts.append(strip_ns_prefix(raw)) # cfg:CatalogRef.X → CatalogRef.X
|
parts.append(strip_ns_prefix(raw)) # cfg:CatalogRef.X → CatalogRef.X
|
||||||
elif ln == 'TypeSet':
|
elif ln == 'TypeSet':
|
||||||
@@ -420,6 +431,11 @@ def parse_choice_parameters(parent, tag):
|
|||||||
def attr_to_dsl(attr_node):
|
def attr_to_dsl(attr_node):
|
||||||
ap = _single(attr_node, 'md:Properties')
|
ap = _single(attr_node, 'md:Properties')
|
||||||
nm = _text(_single(ap, 'md:Name'))
|
nm = _text(_single(ap, 'md:Name'))
|
||||||
|
# Поле внешнего источника: три своих свойства. Имя колонки по умолчанию равно имени поля,
|
||||||
|
# поэтому в DSL попадает только отличающееся.
|
||||||
|
eds_nids = _single(ap, 'md:NameInDataSource')
|
||||||
|
eds_ro = _single(ap, 'md:ReadOnly')
|
||||||
|
eds_null = _single(ap, 'md:AllowNull')
|
||||||
ts = get_type_shorthand(_single(ap, 'md:Type'))
|
ts = get_type_shorthand(_single(ap, 'md:Type'))
|
||||||
flags = []
|
flags = []
|
||||||
fc = _single(ap, 'md:FillChecking')
|
fc = _single(ap, 'md:FillChecking')
|
||||||
@@ -435,6 +451,10 @@ def attr_to_dsl(attr_node):
|
|||||||
ml = _single(ap, 'md:MultiLine')
|
ml = _single(ap, 'md:MultiLine')
|
||||||
if ml is not None and _text(ml) == 'true':
|
if ml is not None and _text(ml) == 'true':
|
||||||
flags.append('multiline')
|
flags.append('multiline')
|
||||||
|
if eds_ro is not None and _text(eds_ro) == 'true':
|
||||||
|
flags.append('readonly')
|
||||||
|
if eds_null is not None and _text(eds_null) == 'true':
|
||||||
|
flags.append('nullable')
|
||||||
|
|
||||||
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}).
|
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}).
|
||||||
syn_node = _single(ap, 'md:Synonym')
|
syn_node = _single(ap, 'md:Synonym')
|
||||||
@@ -618,6 +638,8 @@ def attr_to_dsl(attr_node):
|
|||||||
|
|
||||||
# Пустой <Type/> (реквизит без типа) → ts=''. Отличаем от «дефолтного» отсутствия: явный type:''.
|
# Пустой <Type/> (реквизит без типа) → ts=''. Отличаем от «дефолтного» отсутствия: явный type:''.
|
||||||
type_empty = (ts == '')
|
type_empty = (ts == '')
|
||||||
|
if eds_nids is not None and _text(eds_nids) and _text(eds_nids) != nm:
|
||||||
|
extra['nameInDataSource'] = _text(eds_nids)
|
||||||
if syn_custom or syn_empty or (tt_val is not None) or len(extra) > 0 or type_empty:
|
if syn_custom or syn_empty or (tt_val is not None) or len(extra) > 0 or type_empty:
|
||||||
o = {'name': nm}
|
o = {'name': nm}
|
||||||
if ts:
|
if ts:
|
||||||
@@ -2112,6 +2134,7 @@ SUPPORTED_TYPES = (
|
|||||||
'FilterCriterion', 'DocumentNumerator', 'SettingsStorage', 'CommonModule', 'EventSubscription', 'ScheduledJob',
|
'FilterCriterion', 'DocumentNumerator', 'SettingsStorage', 'CommonModule', 'EventSubscription', 'ScheduledJob',
|
||||||
'CommonForm', 'SessionParameter', 'CommonCommand', 'CommandGroup', 'CommonAttribute', 'FunctionalOptionsParameter',
|
'CommonForm', 'SessionParameter', 'CommonCommand', 'CommandGroup', 'CommonAttribute', 'FunctionalOptionsParameter',
|
||||||
'WSReference', 'CommonPicture', 'CommonTemplate', 'HTTPService', 'WebService',
|
'WSReference', 'CommonPicture', 'CommonTemplate', 'HTTPService', 'WebService',
|
||||||
|
'ExternalDataSource',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -2154,6 +2177,150 @@ def main():
|
|||||||
|
|
||||||
build_dsl()
|
build_dsl()
|
||||||
|
|
||||||
|
# --- Внешний источник данных: таблицы (отдельные файлы) и функции (узлы внутри файла) ---
|
||||||
|
if obj_type == 'ExternalDataSource':
|
||||||
|
dlcm_val = P('DataLockControlMode')
|
||||||
|
if dlcm_val and dlcm_val != 'Automatic':
|
||||||
|
dsl['dataLockControlMode'] = dlcm_val
|
||||||
|
|
||||||
|
def short_field_ref(ref):
|
||||||
|
"""Короткое имя из полного пути ExternalDataSource.И.Table.Т.Field.П"""
|
||||||
|
return ref.split('.')[-1] if ref else None
|
||||||
|
|
||||||
|
def field_ref_list(parent, tag):
|
||||||
|
return [short_field_ref(_text(f)) for f in parent.findall('md:%s/xr:Field' % tag, NS)]
|
||||||
|
|
||||||
|
src_dir = os.path.join(os.path.dirname(os.path.abspath(args.ObjectPath)), obj_name)
|
||||||
|
child_objs_eds = _single(obj_node, 'md:ChildObjects')
|
||||||
|
if child_objs_eds is not None:
|
||||||
|
tables_map = {}
|
||||||
|
for t_node in child_objs_eds.findall('md:Table', NS):
|
||||||
|
tbl_name = (_text(t_node) or '').strip()
|
||||||
|
tbl_path = os.path.join(src_dir, 'Tables', tbl_name + '.xml')
|
||||||
|
if not os.path.isfile(tbl_path):
|
||||||
|
sys.stderr.write("meta-decompile: файл таблицы не найден: %s\n" % tbl_path)
|
||||||
|
continue
|
||||||
|
t_root = etree.parse(tbl_path).getroot()
|
||||||
|
t_obj_node = next((c for c in t_root if isinstance(c.tag, str)), None)
|
||||||
|
tp = _single(t_obj_node, 'md:Properties')
|
||||||
|
|
||||||
|
def TP(tag, _tp=None):
|
||||||
|
n = _single(_tp if _tp is not None else tp, 'md:%s' % tag)
|
||||||
|
return _text(n) if n is not None else None
|
||||||
|
|
||||||
|
tbl = {}
|
||||||
|
t_syn_node = _single(tp, 'md:Synonym')
|
||||||
|
t_syn = get_ml_value(t_syn_node)
|
||||||
|
if isinstance(t_syn, str):
|
||||||
|
if t_syn != split_camel_words(tbl_name):
|
||||||
|
tbl['synonym'] = t_syn
|
||||||
|
elif t_syn is not None:
|
||||||
|
tbl['synonym'] = t_syn
|
||||||
|
elif t_syn_node is not None:
|
||||||
|
# Пустой <Synonym/> != авто-синоним из имени: без явного '' компилятор до-генерит его.
|
||||||
|
tbl['synonym'] = ''
|
||||||
|
t_cmt = TP('Comment')
|
||||||
|
if t_cmt:
|
||||||
|
tbl['comment'] = t_cmt
|
||||||
|
t_type = TP('TableType')
|
||||||
|
if t_type and t_type != 'Table':
|
||||||
|
tbl['tableType'] = t_type
|
||||||
|
nids = TP('NameInDataSource')
|
||||||
|
if nids and nids != tbl_name:
|
||||||
|
tbl['nameInDataSource'] = nids
|
||||||
|
expr = TP('ExpressionInDataSource')
|
||||||
|
if expr:
|
||||||
|
tbl['expressionInDataSource'] = expr
|
||||||
|
tdt = TP('TableDataType')
|
||||||
|
if tdt and tdt != 'NonobjectData':
|
||||||
|
tbl['tableDataType'] = tdt
|
||||||
|
keys = field_ref_list(tp, 'KeyFields')
|
||||||
|
if keys:
|
||||||
|
tbl['keyFields'] = keys
|
||||||
|
for tag, key in (('PresentationField', 'presentationField'), ('ParentField', 'parentField'),
|
||||||
|
('DataVersionField', 'dataVersionField')):
|
||||||
|
v = short_field_ref(TP(tag))
|
||||||
|
if v:
|
||||||
|
tbl[key] = v
|
||||||
|
ibs = field_ref_list(tp, 'InputByString')
|
||||||
|
# Ввод по строке компилятор выводит из поля представления: совпадающий список не пишем.
|
||||||
|
ibs_auto = [tbl['presentationField']] if tbl.get('presentationField') else []
|
||||||
|
if ibs != ibs_auto:
|
||||||
|
tbl['inputByString'] = ibs
|
||||||
|
dlf = field_ref_list(tp, 'DataLockFields')
|
||||||
|
if dlf:
|
||||||
|
tbl['dataLockFields'] = dlf
|
||||||
|
if TP('ReadOnly') == 'true':
|
||||||
|
tbl['readOnly'] = True
|
||||||
|
til = TP('TransactionsIsolationLevel')
|
||||||
|
if til and til != 'Auto':
|
||||||
|
tbl['transactionsIsolationLevel'] = til
|
||||||
|
tdlcm = TP('DataLockControlMode')
|
||||||
|
if tdlcm and tdlcm != 'Automatic':
|
||||||
|
tbl['dataLockControlMode'] = tdlcm
|
||||||
|
if TP('UseStandardCommands') == 'false':
|
||||||
|
tbl['useStandardCommands'] = False
|
||||||
|
if TP('QuickChoice') == 'true':
|
||||||
|
tbl['quickChoice'] = True
|
||||||
|
t_et = TP('EditType')
|
||||||
|
if t_et and t_et != 'InDialog':
|
||||||
|
tbl['editType'] = t_et
|
||||||
|
based_on = [_text(it) for it in tp.findall('md:BasedOn/xr:Item', NS)]
|
||||||
|
if based_on:
|
||||||
|
tbl['basedOn'] = based_on
|
||||||
|
|
||||||
|
fields_arr = []
|
||||||
|
t_child = _single(t_obj_node, 'md:ChildObjects')
|
||||||
|
if t_child is not None:
|
||||||
|
for f in t_child.findall('md:Field', NS):
|
||||||
|
fields_arr.append(attr_to_dsl(f))
|
||||||
|
# Таблица без собственных свойств — короткая форма: просто массив полей.
|
||||||
|
if not tbl:
|
||||||
|
tables_map[tbl_name] = fields_arr
|
||||||
|
else:
|
||||||
|
tbl['fields'] = fields_arr
|
||||||
|
tables_map[tbl_name] = tbl
|
||||||
|
if tables_map:
|
||||||
|
dsl['tables'] = tables_map
|
||||||
|
|
||||||
|
fn_map = {}
|
||||||
|
for fn_node in child_objs_eds.findall('md:Function', NS):
|
||||||
|
fp = _single(fn_node, 'md:Properties')
|
||||||
|
fn_name = _text(_single(fp, 'md:Name'))
|
||||||
|
fn_expr_node = _single(fp, 'md:ExpressionInDataSource')
|
||||||
|
fn_expr = _text(fn_expr_node) if fn_expr_node is not None else ''
|
||||||
|
fn_ret_node = _single(fp, 'md:ReturnValue')
|
||||||
|
fn_returns = get_type_shorthand(_single(fp, 'md:Type'))
|
||||||
|
fn_syn = get_ml_value(_single(fp, 'md:Synonym'))
|
||||||
|
fn_cmt_node = _single(fp, 'md:Comment')
|
||||||
|
fn_cmt = _text(fn_cmt_node) if fn_cmt_node is not None else ''
|
||||||
|
fn_no_value = fn_ret_node is not None and _text(fn_ret_node) == 'false'
|
||||||
|
if isinstance(fn_syn, str):
|
||||||
|
syn_custom_fn = fn_syn != split_camel_words(fn_name) and fn_syn != ''
|
||||||
|
else:
|
||||||
|
syn_custom_fn = fn_syn is not None
|
||||||
|
# Умолчание `returns` компилятора — String, а он даёт String(10): с ним и сверяем,
|
||||||
|
# иначе короткая форма (одна строка выражения) не срабатывала бы никогда.
|
||||||
|
if not fn_no_value and not fn_cmt and not syn_custom_fn and fn_returns != 'String(10)':
|
||||||
|
fn_map[fn_name] = {'expression': fn_expr, 'returns': fn_returns}
|
||||||
|
elif not fn_no_value and not fn_cmt and not syn_custom_fn:
|
||||||
|
# Тип по умолчанию String — короткая форма: одна строка выражения.
|
||||||
|
fn_map[fn_name] = fn_expr
|
||||||
|
else:
|
||||||
|
fo = {'expression': fn_expr}
|
||||||
|
if fn_no_value:
|
||||||
|
fo['returnValue'] = False
|
||||||
|
elif fn_returns:
|
||||||
|
fo['returns'] = fn_returns
|
||||||
|
if syn_custom_fn:
|
||||||
|
fo['synonym'] = fn_syn
|
||||||
|
if fn_cmt:
|
||||||
|
fo['comment'] = fn_cmt
|
||||||
|
fn_map[fn_name] = fo
|
||||||
|
if fn_map:
|
||||||
|
dsl['functions'] = fn_map
|
||||||
|
|
||||||
|
|
||||||
# === Вывод ===
|
# === Вывод ===
|
||||||
json_str = convert_to_compact_json(dsl, 0)
|
json_str = convert_to_compact_json(dsl, 0)
|
||||||
if args.OutputPath:
|
if args.OutputPath:
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"name": "Декомпиляция внешнего источника: таблицы из отдельных файлов, функции, поля",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "meta-compile/scripts/meta-compile",
|
||||||
|
"input": {
|
||||||
|
"type": "ExternalDataSource",
|
||||||
|
"name": "PG",
|
||||||
|
"dataLockControlMode": "AutomaticAndManaged",
|
||||||
|
"tables": {
|
||||||
|
"prices": ["product_id: Number(10,0)", "price: Number(15,2)"],
|
||||||
|
"products": {
|
||||||
|
"nameInDataSource": "eds.public.products",
|
||||||
|
"tableDataType": "ObjectData",
|
||||||
|
"keyFields": ["id"],
|
||||||
|
"presentationField": "name",
|
||||||
|
"transactionsIsolationLevel": "ReadUncommitted",
|
||||||
|
"fields": [
|
||||||
|
"id: Number(10,0)",
|
||||||
|
"name: String(150)",
|
||||||
|
"photo: BinaryData | nullable",
|
||||||
|
{ "name": "cost", "type": "Number(15,2)", "nameInDataSource": "cost_net", "readOnly": true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"functions": {
|
||||||
|
"total": { "expression": "public.f_total(&1, &2)", "returns": "Number(15,2)" },
|
||||||
|
"nextKey": "NEXT VALUE FOR public.seq_key"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"objectPath": "ExternalDataSources/PG.xml",
|
||||||
|
"outputPath": "draft.json"
|
||||||
|
},
|
||||||
|
"expect": {
|
||||||
|
"files": ["draft.json"],
|
||||||
|
"fileContains": [
|
||||||
|
{
|
||||||
|
"file": "draft.json",
|
||||||
|
"text": [
|
||||||
|
"\"dataLockControlMode\": \"AutomaticAndManaged\"",
|
||||||
|
"\"keyFields\": [\"id\"]",
|
||||||
|
"\"nameInDataSource\": \"eds.public.products\"",
|
||||||
|
"\"transactionsIsolationLevel\": \"ReadUncommitted\"",
|
||||||
|
"photo: BinaryData | nullable",
|
||||||
|
"\"nameInDataSource\": \"cost_net\"",
|
||||||
|
"\"nextKey\": \"NEXT VALUE FOR public.seq_key\""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fileNotContains": [
|
||||||
|
{ "file": "draft.json", "text": "ValueStorage" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<ExternalDataSource uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceManager.PG" category="Manager">
|
||||||
|
<xr:TypeId>UUID-002</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-003</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTablesManager.PG" category="TablesManager">
|
||||||
|
<xr:TypeId>UUID-004</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-005</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceCubesManager.PG" category="CubesManager">
|
||||||
|
<xr:TypeId>UUID-006</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-007</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>PG</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>PG</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<DataLockControlMode>AutomaticAndManaged</DataLockControlMode>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Table>prices</Table>
|
||||||
|
<Table>products</Table>
|
||||||
|
<Function uuid="UUID-008">
|
||||||
|
<Properties>
|
||||||
|
<Name>total</Name>
|
||||||
|
<Synonym/>
|
||||||
|
<Comment/>
|
||||||
|
<ReturnValue>true</ReturnValue>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:decimal</v8:Type>
|
||||||
|
<v8:NumberQualifiers>
|
||||||
|
<v8:Digits>15</v8:Digits>
|
||||||
|
<v8:FractionDigits>2</v8:FractionDigits>
|
||||||
|
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||||
|
</v8:NumberQualifiers>
|
||||||
|
</Type>
|
||||||
|
<ExpressionInDataSource>public.f_total(&1, &2)</ExpressionInDataSource>
|
||||||
|
</Properties>
|
||||||
|
</Function>
|
||||||
|
<Function uuid="UUID-009">
|
||||||
|
<Properties>
|
||||||
|
<Name>nextKey</Name>
|
||||||
|
<Synonym/>
|
||||||
|
<Comment/>
|
||||||
|
<ReturnValue>true</ReturnValue>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>10</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
<ExpressionInDataSource>NEXT VALUE FOR public.seq_key</ExpressionInDataSource>
|
||||||
|
</Properties>
|
||||||
|
</Function>
|
||||||
|
</ChildObjects>
|
||||||
|
</ExternalDataSource>
|
||||||
|
</MetaDataObject>
|
||||||
+170
@@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<Table uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableManager.PG.prices" category="Manager">
|
||||||
|
<xr:TypeId>UUID-002</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-003</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableObject.PG.prices" category="Object">
|
||||||
|
<xr:TypeId>UUID-004</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-005</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRef.PG.prices" category="Ref">
|
||||||
|
<xr:TypeId>UUID-006</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-007</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableList.PG.prices" category="List">
|
||||||
|
<xr:TypeId>UUID-008</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-009</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecord.PG.prices" category="Record">
|
||||||
|
<xr:TypeId>UUID-010</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-011</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecordSet.PG.prices" category="RecordSet">
|
||||||
|
<xr:TypeId>UUID-012</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-013</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecordKey.PG.prices" category="RecordKey">
|
||||||
|
<xr:TypeId>UUID-014</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-015</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecordManager.PG.prices" category="RecordManager">
|
||||||
|
<xr:TypeId>UUID-016</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-017</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>prices</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>prices</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<TableType>Table</TableType>
|
||||||
|
<NameInDataSource>prices</NameInDataSource>
|
||||||
|
<ExpressionInDataSource/>
|
||||||
|
<TableDataType>NonobjectData</TableDataType>
|
||||||
|
<KeyFields/>
|
||||||
|
<PresentationField/>
|
||||||
|
<ParentField/>
|
||||||
|
<UnfilledParentValue xsi:nil="true"/>
|
||||||
|
<Characteristics/>
|
||||||
|
<UseStandardCommands>true</UseStandardCommands>
|
||||||
|
<QuickChoice>false</QuickChoice>
|
||||||
|
<InputByString/>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>
|
||||||
|
<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<DefaultObjectForm/>
|
||||||
|
<DefaultRecordForm/>
|
||||||
|
<DefaultListForm/>
|
||||||
|
<DefaultChoiceForm/>
|
||||||
|
<ObjectPresentation/>
|
||||||
|
<ExtendedObjectPresentation/>
|
||||||
|
<RecordPresentation/>
|
||||||
|
<ExtendedRecordPresentation/>
|
||||||
|
<ListPresentation/>
|
||||||
|
<ExtendedListPresentation/>
|
||||||
|
<Explanation/>
|
||||||
|
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||||
|
<ReadOnly>false</ReadOnly>
|
||||||
|
<TransactionsIsolationLevel>Auto</TransactionsIsolationLevel>
|
||||||
|
<DataVersionField/>
|
||||||
|
<EditType>InDialog</EditType>
|
||||||
|
<BasedOn/>
|
||||||
|
<DataLockFields/>
|
||||||
|
<DataLockControlMode>Automatic</DataLockControlMode>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Field uuid="UUID-018">
|
||||||
|
<Properties>
|
||||||
|
<Name>product_id</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>product_id</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:decimal</v8:Type>
|
||||||
|
<v8:NumberQualifiers>
|
||||||
|
<v8:Digits>10</v8:Digits>
|
||||||
|
<v8:FractionDigits>0</v8:FractionDigits>
|
||||||
|
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||||
|
</v8:NumberQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format/>
|
||||||
|
<EditFormat/>
|
||||||
|
<ToolTip/>
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask/>
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true"/>
|
||||||
|
<MaxValue xsi:nil="true"/>
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:type="xs:decimal">0</FillValue>
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceParameterLinks/>
|
||||||
|
<ChoiceParameters/>
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<ChoiceForm/>
|
||||||
|
<NameInDataSource>product_id</NameInDataSource>
|
||||||
|
<ReadOnly>false</ReadOnly>
|
||||||
|
<AllowNull>false</AllowNull>
|
||||||
|
</Properties>
|
||||||
|
</Field>
|
||||||
|
<Field uuid="UUID-019">
|
||||||
|
<Properties>
|
||||||
|
<Name>price</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>price</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:decimal</v8:Type>
|
||||||
|
<v8:NumberQualifiers>
|
||||||
|
<v8:Digits>15</v8:Digits>
|
||||||
|
<v8:FractionDigits>2</v8:FractionDigits>
|
||||||
|
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||||
|
</v8:NumberQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format/>
|
||||||
|
<EditFormat/>
|
||||||
|
<ToolTip/>
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask/>
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true"/>
|
||||||
|
<MaxValue xsi:nil="true"/>
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:type="xs:decimal">0</FillValue>
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceParameterLinks/>
|
||||||
|
<ChoiceParameters/>
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<ChoiceForm/>
|
||||||
|
<NameInDataSource>price</NameInDataSource>
|
||||||
|
<ReadOnly>false</ReadOnly>
|
||||||
|
<AllowNull>false</AllowNull>
|
||||||
|
</Properties>
|
||||||
|
</Field>
|
||||||
|
</ChildObjects>
|
||||||
|
</Table>
|
||||||
|
</MetaDataObject>
|
||||||
+256
@@ -0,0 +1,256 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<Table uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableManager.PG.products" category="Manager">
|
||||||
|
<xr:TypeId>UUID-002</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-003</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableObject.PG.products" category="Object">
|
||||||
|
<xr:TypeId>UUID-004</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-005</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRef.PG.products" category="Ref">
|
||||||
|
<xr:TypeId>UUID-006</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-007</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableList.PG.products" category="List">
|
||||||
|
<xr:TypeId>UUID-008</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-009</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecord.PG.products" category="Record">
|
||||||
|
<xr:TypeId>UUID-010</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-011</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecordSet.PG.products" category="RecordSet">
|
||||||
|
<xr:TypeId>UUID-012</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-013</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecordKey.PG.products" category="RecordKey">
|
||||||
|
<xr:TypeId>UUID-014</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-015</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
<xr:GeneratedType name="ExternalDataSourceTableRecordManager.PG.products" category="RecordManager">
|
||||||
|
<xr:TypeId>UUID-016</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-017</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>products</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>products</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<TableType>Table</TableType>
|
||||||
|
<NameInDataSource>eds.public.products</NameInDataSource>
|
||||||
|
<ExpressionInDataSource/>
|
||||||
|
<TableDataType>ObjectData</TableDataType>
|
||||||
|
<KeyFields>
|
||||||
|
<xr:Field>ExternalDataSource.PG.Table.products.Field.id</xr:Field>
|
||||||
|
</KeyFields>
|
||||||
|
<PresentationField>ExternalDataSource.PG.Table.products.Field.name</PresentationField>
|
||||||
|
<ParentField/>
|
||||||
|
<UnfilledParentValue xsi:nil="true"/>
|
||||||
|
<Characteristics/>
|
||||||
|
<UseStandardCommands>true</UseStandardCommands>
|
||||||
|
<QuickChoice>false</QuickChoice>
|
||||||
|
<InputByString>
|
||||||
|
<xr:Field>ExternalDataSource.PG.Table.products.Field.name</xr:Field>
|
||||||
|
</InputByString>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>
|
||||||
|
<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<DefaultObjectForm/>
|
||||||
|
<DefaultRecordForm/>
|
||||||
|
<DefaultListForm/>
|
||||||
|
<DefaultChoiceForm/>
|
||||||
|
<ObjectPresentation/>
|
||||||
|
<ExtendedObjectPresentation/>
|
||||||
|
<RecordPresentation/>
|
||||||
|
<ExtendedRecordPresentation/>
|
||||||
|
<ListPresentation/>
|
||||||
|
<ExtendedListPresentation/>
|
||||||
|
<Explanation/>
|
||||||
|
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||||
|
<ReadOnly>false</ReadOnly>
|
||||||
|
<TransactionsIsolationLevel>ReadUncommitted</TransactionsIsolationLevel>
|
||||||
|
<DataVersionField/>
|
||||||
|
<EditType>InDialog</EditType>
|
||||||
|
<BasedOn/>
|
||||||
|
<DataLockFields/>
|
||||||
|
<DataLockControlMode>Automatic</DataLockControlMode>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Field uuid="UUID-018">
|
||||||
|
<Properties>
|
||||||
|
<Name>id</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>id</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:decimal</v8:Type>
|
||||||
|
<v8:NumberQualifiers>
|
||||||
|
<v8:Digits>10</v8:Digits>
|
||||||
|
<v8:FractionDigits>0</v8:FractionDigits>
|
||||||
|
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||||
|
</v8:NumberQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format/>
|
||||||
|
<EditFormat/>
|
||||||
|
<ToolTip/>
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask/>
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true"/>
|
||||||
|
<MaxValue xsi:nil="true"/>
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:type="xs:decimal">0</FillValue>
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceParameterLinks/>
|
||||||
|
<ChoiceParameters/>
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<ChoiceForm/>
|
||||||
|
<NameInDataSource>id</NameInDataSource>
|
||||||
|
<ReadOnly>false</ReadOnly>
|
||||||
|
<AllowNull>false</AllowNull>
|
||||||
|
</Properties>
|
||||||
|
</Field>
|
||||||
|
<Field uuid="UUID-019">
|
||||||
|
<Properties>
|
||||||
|
<Name>name</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>name</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:string</v8:Type>
|
||||||
|
<v8:StringQualifiers>
|
||||||
|
<v8:Length>150</v8:Length>
|
||||||
|
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||||
|
</v8:StringQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format/>
|
||||||
|
<EditFormat/>
|
||||||
|
<ToolTip/>
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask/>
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true"/>
|
||||||
|
<MaxValue xsi:nil="true"/>
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:type="xs:string"/>
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceParameterLinks/>
|
||||||
|
<ChoiceParameters/>
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<ChoiceForm/>
|
||||||
|
<NameInDataSource>name</NameInDataSource>
|
||||||
|
<ReadOnly>false</ReadOnly>
|
||||||
|
<AllowNull>false</AllowNull>
|
||||||
|
</Properties>
|
||||||
|
</Field>
|
||||||
|
<Field uuid="UUID-020">
|
||||||
|
<Properties>
|
||||||
|
<Name>photo</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>photo</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:base64Binary</v8:Type>
|
||||||
|
<v8:BinaryDataQualifiers>
|
||||||
|
<v8:Length>4294967292</v8:Length>
|
||||||
|
<v8:AllowedLength>Fixed</v8:AllowedLength>
|
||||||
|
</v8:BinaryDataQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format/>
|
||||||
|
<EditFormat/>
|
||||||
|
<ToolTip/>
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask/>
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true"/>
|
||||||
|
<MaxValue xsi:nil="true"/>
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:nil="true"/>
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceParameterLinks/>
|
||||||
|
<ChoiceParameters/>
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<ChoiceForm/>
|
||||||
|
<NameInDataSource>photo</NameInDataSource>
|
||||||
|
<ReadOnly>false</ReadOnly>
|
||||||
|
<AllowNull>true</AllowNull>
|
||||||
|
</Properties>
|
||||||
|
</Field>
|
||||||
|
<Field uuid="UUID-021">
|
||||||
|
<Properties>
|
||||||
|
<Name>cost</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>cost</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<Type>
|
||||||
|
<v8:Type>xs:decimal</v8:Type>
|
||||||
|
<v8:NumberQualifiers>
|
||||||
|
<v8:Digits>15</v8:Digits>
|
||||||
|
<v8:FractionDigits>2</v8:FractionDigits>
|
||||||
|
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||||
|
</v8:NumberQualifiers>
|
||||||
|
</Type>
|
||||||
|
<PasswordMode>false</PasswordMode>
|
||||||
|
<Format/>
|
||||||
|
<EditFormat/>
|
||||||
|
<ToolTip/>
|
||||||
|
<MarkNegatives>false</MarkNegatives>
|
||||||
|
<Mask/>
|
||||||
|
<MultiLine>false</MultiLine>
|
||||||
|
<ExtendedEdit>false</ExtendedEdit>
|
||||||
|
<MinValue xsi:nil="true"/>
|
||||||
|
<MaxValue xsi:nil="true"/>
|
||||||
|
<FillFromFillingValue>false</FillFromFillingValue>
|
||||||
|
<FillValue xsi:type="xs:decimal">0</FillValue>
|
||||||
|
<FillChecking>DontCheck</FillChecking>
|
||||||
|
<ChoiceParameterLinks/>
|
||||||
|
<ChoiceParameters/>
|
||||||
|
<QuickChoice>Auto</QuickChoice>
|
||||||
|
<CreateOnInput>Auto</CreateOnInput>
|
||||||
|
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||||
|
<ChoiceForm/>
|
||||||
|
<NameInDataSource>cost_net</NameInDataSource>
|
||||||
|
<ReadOnly>true</ReadOnly>
|
||||||
|
<AllowNull>false</AllowNull>
|
||||||
|
</Properties>
|
||||||
|
</Field>
|
||||||
|
</ChildObjects>
|
||||||
|
</Table>
|
||||||
|
</MetaDataObject>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"type": "ExternalDataSource",
|
||||||
|
"name": "PG",
|
||||||
|
"dataLockControlMode": "AutomaticAndManaged",
|
||||||
|
"tables": {
|
||||||
|
"prices": ["product_id: Number(10,0)", "price: Number(15,2)"],
|
||||||
|
"products": {
|
||||||
|
"nameInDataSource": "eds.public.products",
|
||||||
|
"tableDataType": "ObjectData",
|
||||||
|
"keyFields": ["id"],
|
||||||
|
"presentationField": "name",
|
||||||
|
"transactionsIsolationLevel": "ReadUncommitted",
|
||||||
|
"fields": [
|
||||||
|
"id: Number(10,0)",
|
||||||
|
"name: String(150)",
|
||||||
|
"photo: BinaryData | nullable",
|
||||||
|
{
|
||||||
|
"name": "cost",
|
||||||
|
"type": "Number(15,2)",
|
||||||
|
"nameInDataSource": "cost_net",
|
||||||
|
"flags": ["readonly"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"functions": {
|
||||||
|
"total": {
|
||||||
|
"expression": "public.f_total(&1, &2)",
|
||||||
|
"returns": "Number(15,2)"
|
||||||
|
},
|
||||||
|
"nextKey": "NEXT VALUE FOR public.seq_key"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user