流星雨模块框架文档中心

持久化存储

ctx.store 是本模块专属的持久化存储,自动加密落盘,与其他模块完全隔离。文件路径、数据库连接、密钥都由宿主管理,你碰不到也不用碰。

ctx.storesetup() 阶段就可用,不必等到 on_enable()。耗时的批量读写建议放到启用之后。

KV 层(日常推荐)

方法说明
get(key, default=None)读取并自动反序列化,不存在返回 default
set(key, value)写入(自动序列化 + 落盘),支持 str/int/float/bool/None/list/dict
set_many(mapping)批量写入,只落盘一次,高频写入用这个
get_many(prefix="")按前缀批量读取,返回 {key: value}
delete(key)删除,返回是否删除成功
keys(prefix="")列出键(可前缀过滤)
size()键数量
exists()本模块是否已有存储数据
python
ctx.store.set("token", "abc123")
ctx.store.set("devices", [{"serial": "A"}, {"serial": "B"}])
ctx.store.get("token")
ctx.store.get_many("dev")        # 前缀匹配
ctx.store.delete("token")

SQL 层(需要表结构时)

方法说明
query(sql, params=())只读,返回 [{列名: 值}];只允许 SELECT / PRAGMA / EXPLAIN
execute(sql, params=())写语句(INSERT / UPDATE / DELETE / CREATE 等),自动提交,返回受影响行数
transaction()上下文管理器,块内多次写入合并为一次落盘
python
# 建表
ctx.store.execute(
    "CREATE TABLE IF NOT EXISTS records ("
    " id INTEGER PRIMARY KEY, serial TEXT, ts REAL)")

# 写入(参数化,防注入)
ctx.store.execute("INSERT INTO records(serial, ts) VALUES(?, ?)",
                  ("ABC123", time.time()))

# 查询
rows = ctx.store.query(
    "SELECT * FROM records WHERE serial=? ORDER BY ts DESC LIMIT 10",
    ("ABC123",))

三条规矩:只能访问本模块自己的库;必须用参数化查询(? 占位符);向 query() 传写语句、或向 execute() 传查询语句,都会被拒绝。

批量写优化

每次写入都会落盘并加密,单条循环写明显变慢。

python
# 慢:N 次落盘
for k, v in data.items():
    ctx.store.set(k, v)

# 快:1 次落盘
ctx.store.set_many(data)

# 快:混合 KV 与 SQL,也只落盘一次
with ctx.store.transaction():
    ctx.store.set("last_sync", time.time())
    ctx.store.execute("DELETE FROM records WHERE ts < ?", (cutoff,))

事务块内抛异常会自动回滚。

清空与关闭

python
ctx.store.wipe()     # 清空本模块全部数据(KV + 自建表),不可恢复
ctx.store.close()    # 正常无需手动调用,宿主在卸载/退出时处理

版本升级与数据兼容

升级模块不会自动清除历史数据。数据结构变了要自己兼容:

python
def on_enable(self):
    ver = self.ctx.store.get("schema_version", 0)
    if ver < 2:
        # 先看一眼现有表结构再决定怎么改(PRAGMA 走 query 只读接口)
        cols = [r["name"] for r in self.ctx.store.query("PRAGMA table_info(records)")]
        if "note" not in cols:
            self.ctx.store.execute("ALTER TABLE records ADD COLUMN note TEXT")
        self.ctx.store.set("schema_version", 2)

不要绕过 ctx.store

直接 open 写文件、自己连 sqlite,都会失去加密和隔离,审核也过不去。真要读写宿主管理之外的文件,声明 fs 权限并想清楚理由。