fix(recovery): register lazy state.db tables in one schema map; cover .recover lane and count-mismatch loss
Follow-up to the salvaged #100350 commits: replace the per-table 'if table == "delivery_obligations"' branches in session_recovery.py and session_lost_and_found.py with a single _AUXILIARY_TABLE_SCHEMAS registry (table -> destination DDL initializer) that both the SQL-level and the lost_and_found lanes consume, so the next lazily-created state.db table is one entry, not three code paths. The .recover lane now iterates _CANONICAL_TABLES + _AUXILIARY_TABLES instead of a duplicated literal list. Tests: the .recover direct-copy lane creates the missing ledger on the destination; a source-vs-destination obligation count mismatch fails verification (complete=False) instead of reporting a clean salvage. Docs: state.db table inventory lists delivery_obligations. Addresses #100313
This commit is contained in:
@@ -45,12 +45,26 @@ _TOPIC_TABLES = (
|
||||
"telegram_dm_topic_bindings",
|
||||
)
|
||||
|
||||
# Durable gateway outbox. Created lazily by gateway.delivery_ledger, so a
|
||||
# fresh SessionDB destination does not have the table until we initialize it.
|
||||
# Omitting it from the copy inventory drops owed replies (#100313, #86236).
|
||||
_AUXILIARY_TABLES = (
|
||||
"delivery_obligations",
|
||||
)
|
||||
|
||||
|
||||
def _init_delivery_ledger_schema(conn: sqlite3.Connection) -> None:
|
||||
from gateway.delivery_ledger import _initialize_schema
|
||||
|
||||
_initialize_schema(conn)
|
||||
|
||||
|
||||
# Tables that live in state.db but are created lazily by a gateway module on
|
||||
# first use, so base ``SessionDB`` never creates them on a fresh destination.
|
||||
# Every entry maps the table to the initializer that owns its DDL; recovery
|
||||
# creates the table on the destination before copying, so owed rows survive
|
||||
# instead of silently vanishing from a "complete" salvage (#100313, #86236).
|
||||
# Add new lazily-created state.db tables HERE, never as one-off ``if table ==``
|
||||
# branches.
|
||||
_AUXILIARY_TABLE_SCHEMAS: dict[str, Callable[[sqlite3.Connection], None]] = {
|
||||
"delivery_obligations": _init_delivery_ledger_schema,
|
||||
}
|
||||
|
||||
_AUXILIARY_TABLES = tuple(_AUXILIARY_TABLE_SCHEMAS)
|
||||
|
||||
_INVENTORY_TABLES = (
|
||||
*_CANONICAL_TABLES,
|
||||
@@ -410,10 +424,12 @@ def _ensure_auxiliary_destination_schema(
|
||||
would report ``missing`` / ``no compatible columns`` and drop the rows.
|
||||
"""
|
||||
|
||||
if table == "delivery_obligations":
|
||||
from gateway.delivery_ledger import _initialize_schema
|
||||
|
||||
_initialize_schema(destination)
|
||||
initialize = _AUXILIARY_TABLE_SCHEMAS.get(table)
|
||||
if initialize is None:
|
||||
raise SessionRecoverySafetyError(
|
||||
f"no destination schema initializer registered for table {table!r}"
|
||||
)
|
||||
initialize(destination)
|
||||
|
||||
|
||||
def _copy_table(
|
||||
|
||||
Reference in New Issue
Block a user