Release skill-template v1.0.99: table registry contract and drop_deprecated_user_table
All checks were successful
技能自动化发布 / release (push) Successful in 7s

This commit is contained in:
2026-08-25 13:40:08 +08:00
parent d35d04f779
commit b5d120469b
10 changed files with 229 additions and 5 deletions

View File

@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
"""旧库废弃表迁移样例(复制到 tests/ 并按技能改写)。
验收:给定旧库含废弃物理表 + 元数据 + 历史行 → init_db() 后表与元数据均清除。
见 references/SCHEMA.md「表增删改与退役」。
"""
from __future__ import annotations
import unittest
from _support import IsolatedDataRoot
class TestTableDeprecationMigration(unittest.TestCase):
def test_init_db_drops_legacy_task_logs(self) -> None:
with IsolatedDataRoot():
from db.connection import get_conn, init_db
from db.display_metadata import iter_user_tables
# 1) 模拟升级前的旧库
init_db()
conn = get_conn()
try:
cur = conn.cursor()
cur.execute(
"""
CREATE TABLE task_logs (
id INTEGER PRIMARY KEY,
task_type TEXT,
status TEXT
)
"""
)
cur.execute(
"""
INSERT INTO _jiangchang_tables
(table_name, display_name, visible, readonly)
VALUES ('task_logs', '任务日志', 1, 0)
"""
)
cur.execute("INSERT INTO task_logs (task_type, status) VALUES ('run', 'ok')")
conn.commit()
finally:
conn.close()
# 2) 新代码 init_db() 应幂等清除(在 connection.init_db 中调用 drop_deprecated_user_table)
init_db()
conn = get_conn()
try:
cur = conn.cursor()
cur.execute(
"SELECT 1 FROM sqlite_master WHERE type='table' AND name='task_logs'"
)
self.assertIsNone(cur.fetchone())
cur.execute(
"SELECT COUNT(*) FROM _jiangchang_tables WHERE table_name='task_logs'"
)
self.assertEqual(int(cur.fetchone()[0]), 0)
self.assertNotIn("task_logs", list(iter_user_tables(cur)))
finally:
conn.close()
if __name__ == "__main__":
unittest.main()

View File

@@ -738,6 +738,73 @@ metadata:
finally:
conn.close()
def test_drop_deprecated_user_table_removes_physical_and_metadata(self) -> None:
conn = sqlite3.connect(":memory:")
try:
cur = conn.cursor()
cur.execute(
"""
CREATE TABLE _jiangchang_tables (
table_name TEXT PRIMARY KEY,
display_name TEXT,
description TEXT,
sort_order INTEGER,
visible INTEGER,
readonly INTEGER
)
"""
)
cur.execute(
"""
CREATE TABLE _jiangchang_columns (
table_name TEXT,
column_name TEXT,
display_name TEXT,
description TEXT,
display_order INTEGER,
visible INTEGER,
searchable INTEGER,
editable INTEGER,
display_type TEXT,
options_json TEXT,
PRIMARY KEY (table_name, column_name)
)
"""
)
cur.execute(
"""
CREATE TABLE task_logs (
id INTEGER PRIMARY KEY,
status TEXT,
created_at INTEGER,
updated_at INTEGER
)
"""
)
cur.execute(
"INSERT INTO _jiangchang_tables VALUES ('task_logs', '任务日志', NULL, 1, 1, 0)"
)
cur.execute(
"INSERT INTO _jiangchang_columns VALUES "
"('task_logs', 'id', '编号', NULL, 1, 1, 1, 0, 'text', NULL)"
)
cur.execute("INSERT INTO task_logs (status) VALUES ('success')")
from db.display_metadata import drop_deprecated_user_table, iter_user_tables
drop_deprecated_user_table(cur, "task_logs")
cur.execute(
"SELECT 1 FROM sqlite_master WHERE type='table' AND name='task_logs'"
)
self.assertIsNone(cur.fetchone())
cur.execute(
"SELECT COUNT(*) FROM _jiangchang_tables WHERE table_name='task_logs'"
)
self.assertEqual(int(cur.fetchone()[0]), 0)
self.assertNotIn("task_logs", list(iter_user_tables(cur)))
finally:
conn.close()
if __name__ == "__main__":
unittest.main()

View File

@@ -360,6 +360,9 @@ class TestDocsStandards(unittest.TestCase):
"列筛选与全局搜索",
"searchable: 1",
"筛选栏控件",
"表增删改与退役",
"drop_deprecated_user_table",
"孤儿物理表",
):
self.assertIn(marker, text, msg=f"SCHEMA.md missing {marker!r}")