"""SQLite 连接与幂等初始化。 ``init_db`` 建两张表: 1. ``todos`` — 业务表(demo:待办事项) 2. ``_jiangchang_tables`` / ``_jiangchang_columns`` — 宿主数据管理展示元数据 业务表字段顺序就是宿主列展示顺序(cid 顺序)。 """ from __future__ import annotations import sqlite3 from db.display_metadata import ( init_display_metadata_tables, seed_column_metadata_batch, upsert_table_metadata, ) from util.runtime_paths import get_db_path from db.timestamp_columns import init_updated_at_trigger ALL_BUSINESS_TABLES:tuple[str, ...] = ("todos") # ---- 业务表 DDL(待办事项)---- # 字段顺序 = 数据管理列展示顺序;状态/优先级用 options_json 给宿主做下拉筛选 _TODOS_DDL = """ CREATE TABLE IF NOT EXISTS todos ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', priority TEXT NOT NULL DEFAULT 'normal', due_at INTEGER, created_at INTEGER NOT NULL DEFAULT (unixepoch()), updated_at INTEGER NOT NULL DEFAULT (unixepoch()) ) """ _TODOS_INDEX = """ CREATE INDEX IF NOT EXISTS idx_todos_status ON todos(status) """ def get_conn() -> sqlite3.Connection: return sqlite3.connect(get_db_path()) def _init_business_timestamp_triggers(cursor) -> None: """ for table_name in ALL_BUSINESS_TABLES: init_updated_at_trigger(cursor, table_name) """ init_updated_at_trigger(cursor, "todos") def _seed_todos_display_metadata(cursor) -> None: """写 ``todos`` 表与字段的中文展示元数据。""" upsert_table_metadata( cursor, table_name="todos", display_name="待办事项", description="本技能的核心业务表:每条待办事项一行。", grid_help="所有的待办事项,包括待办、已办、已删除。", visible=1, readonly=1, # 整表只读:增删改通过技能 Action 走,宿主不直写 default_sort_json='[{"column":"created_at","direction":"desc"}]', default_visible_columns_json='["title","status","priority","due_at","created_at"]', ) seed_column_metadata_batch( cursor, table_name="todos", columns=[ {"column_name": "id", "display_name": "编号", "description": "主键", "visible": 1, "searchable": 1, "editable": 0, "display_type": "number"}, {"column_name": "title", "display_name": "标题", "description": "待办事项内容", "grid_help": "简明描述要做的事", "visible": 1, "searchable": 1, "editable": 1, "display_type": "text"}, {"column_name": "status", "display_name": "状态", "description": "pending/done", "grid_help": "pending=待办,done=完成", "visible": 1, "searchable": 1, "editable": 0, "display_type": "enum", "options_json": '[{"value":"pending","label":"待办"},{"value":"done","label":"完成"}]'}, {"column_name": "priority", "display_name": "优先级", "description": "high/normal/low", "visible": 1, "searchable": 1, "editable": 1, "display_type": "enum", "options_json": '[{"value":"high","label":"高"},{"value":"normal","label":"中"},{"value":"low","label":"低"}]'}, {"column_name": "due_at", "display_name": "截止时间", "description": "Unix 秒;可空", "visible": 1, "searchable": 1, "editable": 1, "display_type": "datetime_unix_seconds"}, {"column_name": "created_at", "display_name": "创建时间", "description": "Unix 秒", "visible": 1, "searchable": 0, "editable": 0, "display_type": "datetime_unix_seconds"}, {"column_name": "updated_at", "display_name": "更新时间", "description": "Unix 秒", "visible": 0, "searchable": 0, "editable": 0, "display_type": "datetime_unix_seconds"}, ], ) def init_db() -> None: """幂等创建/迁移本地 SQLite 与数据管理元数据。""" conn = get_conn() try: cur = conn.cursor() # 1. 元数据表(先建,方便其它步骤 upsert) init_display_metadata_tables(cur) # 2. 业务表 cur.execute(_TODOS_DDL) cur.execute(_TODOS_INDEX) _init_business_timestamp_triggers(cur) # 3. 业务表展示元数据 _seed_todos_display_metadata(cur) conn.commit() finally: conn.close()