mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-08 03:00:52 +03:00
feat(meta-info): чтение внешних источников данных
На источнике и его таблице навык печатал только заголовок и строку поддержки: вида он не знал, а универсальный блок «Реквизиты» ищет <Attribute>, тогда как у таблицы поля — <Field>. Источник показывает режим блокировки, список таблиц и функции с выражением и типом результата. Таблица — вид (таблица/выражение), имя или выражение в источнике, объектность, признак «только чтение», ссылки на поля (ключ, представление, родитель, версия данных, ввод по строке) короткими именами, и список полей. У поля отмечается имя колонки в источнике, если оно отличается от имени поля, а также «только чтение» и допустимость NULL. Заодно два типа перестали печататься сырыми: xs:base64Binary → ДвоичныеДанные (касается всех объектов, не только внешних источников) и ExternalDataSourceTableRef → русское имя, как у прочих ссылочных типов. 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
97c8478382
commit
bb56a7e898
@@ -1,4 +1,4 @@
|
||||
# meta-info v1.11 — Compact summary of 1C metadata object
|
||||
# meta-info v1.12 — Compact summary of 1C metadata object
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
param(
|
||||
@@ -104,6 +104,7 @@ $typeNameMap = @{
|
||||
"DefinedType"="Определяемый тип"; "CommonModule"="Общий модуль"
|
||||
"ScheduledJob"="Регламентное задание"; "EventSubscription"="Подписка на событие"
|
||||
"HTTPService"="HTTP-сервис"; "WebService"="Веб-сервис"
|
||||
"ExternalDataSource"="Внешний источник данных"; "Table"="Таблица внешнего источника"
|
||||
}
|
||||
|
||||
$refTypeMap = @{
|
||||
@@ -112,6 +113,7 @@ $refTypeMap = @{
|
||||
"ChartOfCharacteristicTypesRef"="ПВХСсылка"; "ChartOfCalculationTypesRef"="ПВРСсылка"
|
||||
"ExchangePlanRef"="ПланОбменаСсылка"; "BusinessProcessRef"="БизнесПроцессСсылка"
|
||||
"TaskRef"="ЗадачаСсылка"
|
||||
"ExternalDataSourceTableRef"="ВнешнийИсточникДанныхТаблицаСсылка"
|
||||
}
|
||||
|
||||
$regTypeMap = @{
|
||||
@@ -231,6 +233,7 @@ function Format-SingleType([string]$raw, $parentNode) {
|
||||
}
|
||||
"v8:ValueStorage" { return "ХранилищеЗначения" }
|
||||
"v8:UUID" { return "УникальныйИдентификатор" }
|
||||
"xs:base64Binary" { return "ДвоичныеДанные" }
|
||||
"v8:Null" { return "Null" }
|
||||
default {
|
||||
# Normalize d5p1:/dNpN: -> cfg:
|
||||
@@ -1347,6 +1350,80 @@ if (-not $drillDone) {
|
||||
}
|
||||
}
|
||||
|
||||
# --- Внешний источник данных: таблицы и функции ---
|
||||
if ($mdType -eq "ExternalDataSource") {
|
||||
$dlcm = $props.SelectSingleNode("md:DataLockControlMode", $ns)
|
||||
if ($dlcm) { Out "Блокировка данных: $($dlcm.InnerText)" }
|
||||
if ($childObjs) {
|
||||
$tables = @(Get-SimpleChildren $childObjs "Table")
|
||||
if ($tables.Count -gt 0) {
|
||||
Out ""
|
||||
Out "Таблицы ($($tables.Count)): $($tables -join ', ')"
|
||||
}
|
||||
$fns = @($childObjs.SelectNodes("md:Function", $ns))
|
||||
if ($fns.Count -gt 0) {
|
||||
Out ""
|
||||
Out "Функции ($($fns.Count)):"
|
||||
foreach ($fn in $fns) {
|
||||
$fp = $fn.SelectSingleNode("md:Properties", $ns)
|
||||
$fnName = $fp.SelectSingleNode("md:Name", $ns).InnerText
|
||||
$fnExpr = $fp.SelectSingleNode("md:ExpressionInDataSource", $ns)
|
||||
$fnType = Format-Type $fp.SelectSingleNode("md:Type", $ns)
|
||||
$retNode = $fp.SelectSingleNode("md:ReturnValue", $ns)
|
||||
$ret = if ($retNode -and $retNode.InnerText -eq "false") { "процедура" } else { $fnType }
|
||||
Out " $fnName → $(if ($fnExpr) { $fnExpr.InnerText })$(if ($ret) { " : $ret" })"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- Таблица внешнего источника: свойства и поля ---
|
||||
if ($mdType -eq "Table") {
|
||||
$g = { param($tag) $n = $props.SelectSingleNode("md:$tag", $ns); if ($n) { $n.InnerText } else { "" } }
|
||||
$short = { param($ref) if ($ref) { ($ref -split '\.')[-1] } else { "" } }
|
||||
|
||||
$head = @()
|
||||
$tableType = & $g "TableType"
|
||||
$head += "Вид: $(if ($tableType -eq 'Expression') { 'выражение' } else { 'таблица' })"
|
||||
$src = if ($tableType -eq "Expression") { & $g "ExpressionInDataSource" } else { & $g "NameInDataSource" }
|
||||
if ($src) { $head += "в источнике: $src" }
|
||||
$head += "данные: $(if ((& $g 'TableDataType') -eq 'ObjectData') { 'объектные' } else { 'необъектные' })"
|
||||
if ((& $g "ReadOnly") -eq "true") { $head += "только чтение" }
|
||||
Out ($head -join " | ")
|
||||
|
||||
$keys = @($props.SelectNodes("md:KeyFields/xr:Field", $ns) | ForEach-Object { & $short $_.InnerText })
|
||||
$refs = @()
|
||||
if ($keys.Count -gt 0) { $refs += "ключ: $($keys -join ', ')" }
|
||||
foreach ($pair in @(@("PresentationField","представление"), @("ParentField","родитель"), @("DataVersionField","версия данных"))) {
|
||||
$v = & $short (& $g $pair[0])
|
||||
if ($v) { $refs += "$($pair[1]): $v" }
|
||||
}
|
||||
$ibs = @($props.SelectNodes("md:InputByString/xr:Field", $ns) | ForEach-Object { & $short $_.InnerText })
|
||||
if ($ibs.Count -gt 0) { $refs += "ввод по строке: $($ibs -join ', ')" }
|
||||
if ($refs.Count -gt 0) { Out ($refs -join " | ") }
|
||||
|
||||
if ($childObjs) {
|
||||
$fields = @(Get-Attributes $childObjs "Field")
|
||||
if ($fields.Count -gt 0) {
|
||||
Out ""
|
||||
Out "Поля ($($fields.Count)):"
|
||||
$ml = Get-MaxNameLen $fields
|
||||
foreach ($f in $fields) {
|
||||
$fp = $f.Props
|
||||
$marks = @()
|
||||
$nids = $fp.SelectSingleNode("md:NameInDataSource", $ns)
|
||||
if ($nids -and $nids.InnerText -and $nids.InnerText -ne $f.Name) { $marks += "→ $($nids.InnerText)" }
|
||||
$ro = $fp.SelectSingleNode("md:ReadOnly", $ns)
|
||||
if ($ro -and $ro.InnerText -eq "true") { $marks += "только чтение" }
|
||||
$an = $fp.SelectSingleNode("md:AllowNull", $ns)
|
||||
if ($an -and $an.InnerText -eq "true") { $marks += "NULL" }
|
||||
$tail = if ($marks.Count -gt 0) { " [$($marks -join ', ')]" } else { "" }
|
||||
Out (" $($f.Name.PadRight($ml)) $($f.Type)$tail")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- Attributes ---
|
||||
if ($childObjs -and $mdType -ne "Enum") {
|
||||
$attrs = @(Get-Attributes $childObjs)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# meta-info v1.11 — Compact summary of 1C metadata object (Python port)
|
||||
# meta-info v1.12 — Compact summary of 1C metadata object (Python port)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import os
|
||||
@@ -177,6 +177,7 @@ type_name_map = {
|
||||
"DefinedType": "Определяемый тип", "CommonModule": "Общий модуль",
|
||||
"ScheduledJob": "Регламентное задание", "EventSubscription": "Подписка на событие",
|
||||
"HTTPService": "HTTP-сервис", "WebService": "Веб-сервис",
|
||||
"ExternalDataSource": "Внешний источник данных", "Table": "Таблица внешнего источника",
|
||||
}
|
||||
|
||||
ref_type_map = {
|
||||
@@ -185,6 +186,7 @@ ref_type_map = {
|
||||
"ChartOfCharacteristicTypesRef": "ПВХСсылка", "ChartOfCalculationTypesRef": "ПВРСсылка",
|
||||
"ExchangePlanRef": "ПланОбменаСсылка", "BusinessProcessRef": "БизнесПроцессСсылка",
|
||||
"TaskRef": "ЗадачаСсылка",
|
||||
"ExternalDataSourceTableRef": "ВнешнийИсточникДанныхТаблицаСсылка",
|
||||
}
|
||||
|
||||
reg_type_map = {
|
||||
@@ -317,6 +319,8 @@ def format_single_type(raw, parent_node):
|
||||
return "ХранилищеЗначения"
|
||||
if raw == "v8:UUID":
|
||||
return "УникальныйИдентификатор"
|
||||
if raw == "xs:base64Binary":
|
||||
return "ДвоичныеДанные"
|
||||
if raw == "v8:Null":
|
||||
return "Null"
|
||||
# Normalize d5p1:/dNpN: → cfg: (both map to same namespace)
|
||||
@@ -1363,6 +1367,85 @@ if not drill_done:
|
||||
for r in res:
|
||||
out(format_attr_line(r, ml))
|
||||
|
||||
# Внешний источник данных: таблицы и функции
|
||||
if md_type == "ExternalDataSource":
|
||||
dlcm = props.find("md:DataLockControlMode", NS)
|
||||
if dlcm is not None:
|
||||
out(f"Блокировка данных: {dlcm.text or ''}")
|
||||
if child_objs is not None:
|
||||
tables = get_simple_children(child_objs, "Table")
|
||||
if tables:
|
||||
out("")
|
||||
out(f"Таблицы ({len(tables)}): {', '.join(tables)}")
|
||||
fns = child_objs.findall("md:Function", NS)
|
||||
if fns:
|
||||
out("")
|
||||
out(f"Функции ({len(fns)}):")
|
||||
for fn in fns:
|
||||
fp = fn.find("md:Properties", NS)
|
||||
fn_name = fp.find("md:Name", NS).text or ""
|
||||
fn_expr = fp.find("md:ExpressionInDataSource", NS)
|
||||
fn_type = format_type(fp.find("md:Type", NS))
|
||||
ret_node = fp.find("md:ReturnValue", NS)
|
||||
ret = "процедура" if (ret_node is not None and ret_node.text == "false") else fn_type
|
||||
expr = (fn_expr.text or "") if fn_expr is not None else ""
|
||||
out(f" {fn_name} → {expr}" + (f" : {ret}" if ret else ""))
|
||||
|
||||
# Таблица внешнего источника: свойства и поля
|
||||
if md_type == "Table":
|
||||
def _g(tag):
|
||||
n = props.find(f"md:{tag}", NS)
|
||||
return (n.text or "") if n is not None else ""
|
||||
|
||||
def _short(ref):
|
||||
return ref.split(".")[-1] if ref else ""
|
||||
|
||||
table_type = _g("TableType")
|
||||
head = ["Вид: " + ("выражение" if table_type == "Expression" else "таблица")]
|
||||
src = _g("ExpressionInDataSource") if table_type == "Expression" else _g("NameInDataSource")
|
||||
if src:
|
||||
head.append(f"в источнике: {src}")
|
||||
head.append("данные: " + ("объектные" if _g("TableDataType") == "ObjectData" else "необъектные"))
|
||||
if _g("ReadOnly") == "true":
|
||||
head.append("только чтение")
|
||||
out(" | ".join(head))
|
||||
|
||||
keys = [_short(f.text) for f in props.findall("md:KeyFields/xr:Field", NS)]
|
||||
refs = []
|
||||
if keys:
|
||||
refs.append(f"ключ: {', '.join(keys)}")
|
||||
for tag, label in (("PresentationField", "представление"), ("ParentField", "родитель"),
|
||||
("DataVersionField", "версия данных")):
|
||||
v = _short(_g(tag))
|
||||
if v:
|
||||
refs.append(f"{label}: {v}")
|
||||
ibs = [_short(f.text) for f in props.findall("md:InputByString/xr:Field", NS)]
|
||||
if ibs:
|
||||
refs.append(f"ввод по строке: {', '.join(ibs)}")
|
||||
if refs:
|
||||
out(" | ".join(refs))
|
||||
|
||||
if child_objs is not None:
|
||||
fields = get_attributes(child_objs, "Field")
|
||||
if fields:
|
||||
out("")
|
||||
out(f"Поля ({len(fields)}):")
|
||||
ml = get_max_name_len(fields)
|
||||
for f in fields:
|
||||
fp = f["Props"]
|
||||
marks = []
|
||||
nids = fp.find("md:NameInDataSource", NS)
|
||||
if nids is not None and nids.text and nids.text != f["Name"]:
|
||||
marks.append(f"→ {nids.text}")
|
||||
ro = fp.find("md:ReadOnly", NS)
|
||||
if ro is not None and ro.text == "true":
|
||||
marks.append("только чтение")
|
||||
an = fp.find("md:AllowNull", NS)
|
||||
if an is not None and an.text == "true":
|
||||
marks.append("NULL")
|
||||
tail = f" [{', '.join(marks)}]" if marks else ""
|
||||
out(f" {f['Name'].ljust(ml)} {f['Type']}{tail}")
|
||||
|
||||
# Attributes
|
||||
if child_objs is not None and md_type != "Enum":
|
||||
attrs = get_attributes(child_objs)
|
||||
|
||||
Reference in New Issue
Block a user