Initial SQL-only 1C adapter baseline

This commit is contained in:
2026-07-22 03:03:47 +03:00
commit e2503b77e7
545 changed files with 184711 additions and 0 deletions
+162
View File
@@ -0,0 +1,162 @@
"""Small XML metadata extractor used as validation oracle for SQL payloads."""
from __future__ import annotations
import xml.etree.ElementTree as ET
from dataclasses import asdict, dataclass
from pathlib import Path
from typing import Any
def local_name(tag: str) -> str:
return tag.rsplit("}", 1)[-1] if "}" in tag else tag
@dataclass(frozen=True)
class XmlMetadataItem:
category: str
name: str
synonym: str
uuid: str | None
value_type: dict[str, Any] | None = None
parent_category: str | None = None
parent_name: str | None = None
parent_uuid: str | None = None
def to_dict(self) -> dict[str, Any]:
return asdict(self)
def direct_child(parent: ET.Element, name: str) -> ET.Element | None:
for child in list(parent):
if local_name(child.tag) == name:
return child
return None
def child_text(parent: ET.Element, name: str) -> str:
child = direct_child(parent, name)
return (child.text or "").strip() if child is not None else ""
def synonym_text(properties: ET.Element | None) -> str:
if properties is None:
return ""
synonym = direct_child(properties, "Synonym")
if synonym is None:
return ""
for node in synonym.iter():
if local_name(node.tag) == "content" and node.text:
return node.text.strip()
return ""
def value_type(properties: ET.Element | None) -> dict[str, Any] | None:
if properties is None:
return None
type_node = direct_child(properties, "Type")
if type_node is None:
return None
types = []
qualifiers: dict[str, Any] = {}
for node in type_node.iter():
name = local_name(node.tag)
text = (node.text or "").strip()
if name == "Type" and node is not type_node and text:
types.append(text)
elif name in {"Length", "AllowedLength", "Digits", "FractionDigits", "AllowedSign", "DateFractions"} and text:
qualifiers[name] = text
if not types and not qualifiers:
return None
return {
"types": types,
"qualifiers": qualifiers,
"is_composite": len(types) > 1,
}
def item_from_properties(
category: str,
node: ET.Element,
properties: ET.Element | None,
*,
parent: XmlMetadataItem | None = None,
) -> XmlMetadataItem:
return XmlMetadataItem(
category=category,
name=child_text(properties, "Name") if properties is not None else node.attrib.get("name", ""),
synonym=synonym_text(properties),
uuid=node.attrib.get("uuid"),
value_type=value_type(properties),
parent_category=parent.category if parent else None,
parent_name=parent.name if parent else None,
parent_uuid=parent.uuid.lower() if parent and parent.uuid else None,
)
def extract_xml_metadata_items(path: Path) -> list[XmlMetadataItem]:
root = ET.parse(path).getroot()
metadata_node = next(iter(list(root)), None)
if metadata_node is None:
return []
result: list[XmlMetadataItem] = []
properties = direct_child(metadata_node, "Properties")
root_item = item_from_properties(local_name(metadata_node.tag), metadata_node, properties)
result.append(root_item)
internal = direct_child(metadata_node, "InternalInfo")
if internal is not None:
for generated in internal.iter():
if local_name(generated.tag) == "GeneratedType":
result.append(
XmlMetadataItem(
category="GeneratedType",
name=generated.attrib.get("name", ""),
synonym=generated.attrib.get("category", ""),
uuid=None,
)
)
if properties is not None:
standard = direct_child(properties, "StandardAttributes")
if standard is not None:
for node in list(standard):
if local_name(node.tag) == "StandardAttribute":
result.append(
XmlMetadataItem(
category="StandardAttribute",
name=node.attrib.get("name", ""),
synonym=synonym_text(node),
uuid=None,
)
)
child_objects = direct_child(metadata_node, "ChildObjects")
if child_objects is not None:
for node in list(child_objects):
category = local_name(node.tag)
props = direct_child(node, "Properties")
child_item = item_from_properties(category, node, props, parent=root_item)
result.append(child_item)
append_nested_child_objects(result, node, child_item)
return result
def append_nested_child_objects(result: list[XmlMetadataItem], parent_node: ET.Element, parent_item: XmlMetadataItem) -> None:
child_objects = direct_child(parent_node, "ChildObjects")
if child_objects is None:
return
for node in list(child_objects):
category = local_name(node.tag)
props = direct_child(node, "Properties")
child_item = item_from_properties(category, node, props, parent=parent_item)
result.append(child_item)
append_nested_child_objects(result, node, child_item)
def group_xml_items(items: list[XmlMetadataItem]) -> dict[str, list[XmlMetadataItem]]:
grouped: dict[str, list[XmlMetadataItem]] = {}
for item in items:
grouped.setdefault(item.category, []).append(item)
return grouped