141 lines
3.9 KiB
Python
141 lines
3.9 KiB
Python
"""Storage-route helpers based on DBNames records.
|
|
|
|
This module maps platform DBNames roles to physical SQL name candidates. It
|
|
does not infer business semantics or concrete metadata object names.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import asdict, dataclass
|
|
from typing import Iterable
|
|
|
|
from .dbnames import DBNamesRecord
|
|
|
|
|
|
TABLE_ROLE_PREFIX = {
|
|
"Reference": "_Reference",
|
|
"ReferenceChngR": "_ReferenceChngR",
|
|
"Document": "_Document",
|
|
"DocumentChngR": "_DocumentChngR",
|
|
"Enum": "_Enum",
|
|
"InfoRg": "_InfoRg",
|
|
"InfoRgChngR": "_InfoRgChngR",
|
|
"AccumRg": "_AccumRg",
|
|
"AccumRgChngR": "_AccumRgChngR",
|
|
"AccumRgOpt": "_AccumRgOpt",
|
|
"AccumRgT": "_AccumRgT",
|
|
"AccRg": "_AccRg",
|
|
"AccRgAT0": "_AccRgAT0",
|
|
"AccRgCT": "_AccRgCT",
|
|
"AccRgChngR": "_AccRgChngR",
|
|
"AccRgOpt": "_AccRgOpt",
|
|
"Const": "_Const",
|
|
"ConstChngR": "_ConstChngR",
|
|
"DocumentJournal": "_DocumentJournal",
|
|
"Node": "_Node",
|
|
"ScheduledJobs": "_ScheduledJobs",
|
|
"BPr": "_BPr",
|
|
"BPrPoints": "_BPrPoints",
|
|
"BPrChngR": "_BPrChngR",
|
|
"Task": "_Task",
|
|
"TaskChngR": "_TaskChngR",
|
|
"Acc": "_Acc",
|
|
"AccSInf": "_AccSInf",
|
|
"AccChngR": "_AccChngR",
|
|
"CKinds": "_CKinds",
|
|
"CKindsChngR": "_CKindsChngR",
|
|
"IntegServiceSettings": "_IntegServiceSettings",
|
|
"IntegServiceMsgBody": "_IntegServiceMsgBody",
|
|
"IntegServiceExtMsgBody": "_IntegServiceExtMsgBody",
|
|
"IntegChannelInQueue": "_IntegChannelInQueue",
|
|
"IntegChannelOutQueue": "_IntegChannelOutQueue",
|
|
}
|
|
|
|
|
|
FIELD_ROLE_PREFIX = {
|
|
"Fld": "_Fld",
|
|
}
|
|
|
|
|
|
STRUCTURAL_ROLES = {
|
|
"VT",
|
|
"LineNo",
|
|
"ByDims",
|
|
"ByField",
|
|
"ByResource",
|
|
"ByProperty",
|
|
"TurnoverDt",
|
|
"TurnoverCt",
|
|
"Turnover",
|
|
}
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class StorageRoute:
|
|
guid: str
|
|
storage_role: str
|
|
sql_number: int
|
|
source: str
|
|
route_kind: str
|
|
physical_name_candidate: str | None
|
|
note: str
|
|
|
|
def to_dict(self) -> dict[str, object]:
|
|
return asdict(self)
|
|
|
|
|
|
def storage_route(record: DBNamesRecord) -> StorageRoute:
|
|
"""Return the mechanical SQL route candidate for one DBNames record."""
|
|
|
|
role = record.storage_role
|
|
if role in TABLE_ROLE_PREFIX:
|
|
return StorageRoute(
|
|
guid=record.guid,
|
|
storage_role=role,
|
|
sql_number=record.sql_number,
|
|
source=record.source,
|
|
route_kind="table",
|
|
physical_name_candidate=f"{TABLE_ROLE_PREFIX[role]}{record.sql_number}",
|
|
note="table-like DBNames storage role",
|
|
)
|
|
if role in FIELD_ROLE_PREFIX:
|
|
return StorageRoute(
|
|
guid=record.guid,
|
|
storage_role=role,
|
|
sql_number=record.sql_number,
|
|
source=record.source,
|
|
route_kind="field",
|
|
physical_name_candidate=f"{FIELD_ROLE_PREFIX[role]}{record.sql_number}",
|
|
note="field DBNames storage role; value suffixes depend on type evidence",
|
|
)
|
|
if role in STRUCTURAL_ROLES:
|
|
return StorageRoute(
|
|
guid=record.guid,
|
|
storage_role=role,
|
|
sql_number=record.sql_number,
|
|
source=record.source,
|
|
route_kind="structural",
|
|
physical_name_candidate=None,
|
|
note="structural DBNames role; requires parent object/section context",
|
|
)
|
|
return StorageRoute(
|
|
guid=record.guid,
|
|
storage_role=role,
|
|
sql_number=record.sql_number,
|
|
source=record.source,
|
|
route_kind="unknown",
|
|
physical_name_candidate=None,
|
|
note="unclassified DBNames storage role",
|
|
)
|
|
|
|
|
|
def group_records_by_guid(records: Iterable[DBNamesRecord]) -> dict[str, list[DBNamesRecord]]:
|
|
grouped: dict[str, list[DBNamesRecord]] = {}
|
|
for record in records:
|
|
grouped.setdefault(record.guid, []).append(record)
|
|
return grouped
|
|
|
|
|
|
def storage_routes(records: Iterable[DBNamesRecord]) -> list[StorageRoute]:
|
|
return [storage_route(record) for record in records]
|