SQL 插件
查看 MarkdownKasumi SQL 驱动、连接生命周期、参数规则和安全边界
理解 SQL 插件的驱动可用性、连接生命周期、参数规则和 SQLite 安全边界。
SQL 插件只提供连接管理、参数化查询和参数化执行,不负责 ORM、迁移、连接池配置或业务
事务编排。它通过 sql.drivers 报告宿主实际注册的驱动,不把协议中的驱动标识当成已安装
客户端。
| 层级 | 入口 | 责任 |
|---|---|---|
| 前端 API | frontend/src/api/sql.ts | 参数守卫、Promise 和命令封装 |
| 协议插件 | protocol/plugins.json | sql 插件与五个命令的归属 |
| Windows 运行时 | windows/src/plugins/ksm_sql_plugin.cpp | 命令分发和错误映射 |
| Windows 驱动 SPI | windows/src/platform/ksm_sql_driver.h | 连接、查询和执行抽象 |
| Android 运行时 | KSMSqlPlugin.kt | 命令分发和错误映射 |
| Android 驱动 SPI | KSMSqlDriver.kt | 连接、查询、执行和关闭 |
协议保留四个驱动标识:
| 驱动 | 内置状态 | URL 约定 |
|---|---|---|
sqlite | Windows / Android 内置 | :memory: 或可写虚拟路径 |
mysql | Windows 检测到系统 ODBC 驱动后内置;Android 宿主注册 | Windows 使用 mysql://host[:port]/database?ssl-mode=required |
postgres | Windows 检测到系统 ODBC 驱动后内置;Android 宿主注册 | Windows 使用 postgresql://host[:port]/database?sslmode=require |
mongodb | 宿主注册后可用 | 由 MongoDB 驱动定义 |
sql.drivers 只返回当前宿主注册表里的驱动。调用方必须先查询,再调用 sql.open。
远程驱动可以按应用需要选择原生客户端、托管连接层或业务自己的网络适配器;Kasumi 不把
数据库凭据写入前端配置或能力缓存。Windows 的 ODBC 路由要求系统安装 MySQL / MariaDB
或 PostgreSQL ODBC 驱动,SDK 不随包分发对应客户端。远程 URL 支持可选用户名和密码,
TLS 默认开启,只有显式查询参数才允许关闭;凭据不会进入错误消息、日志或 sql.drivers。
| 方法 | 参数 | 返回 | 说明 |
|---|---|---|---|
sql.drivers | {} | { drivers } | 查询当前可用驱动 |
sql.open | { driver, url } | { connectionId } | 创建独立连接 |
sql.query | { connectionId, statement, params? } | { columns, rows } | 执行返回行的语句 |
sql.execute | { connectionId, statement, params? } | { rowsAffected, lastInsertId } | 执行写操作 |
sql.close | { connectionId } | { closed } | 关闭连接 |
connectionId 是宿主生成的短生命周期句柄,不是数据库连接串。连接关闭后再次使用返回
NOT_FOUND,应用不得把旧 ID 复用为新的业务会话。
params 只允许字符串、有限数值、布尔值和 null。SQL 方言的占位符由驱动决定:
SQLite 和 MySQL 通常使用 ?,PostgreSQL 通常使用 $1。调用方必须使用目标驱动支持的
占位符,不得把用户输入拼接到 statement。
sql.query 返回列名数组和行对象:
{
"columns": ["id", "name"],
"rows": [
{ "id": 1, "name": "first" }
]
}sql.execute 返回:
{
"rowsAffected": 1,
"lastInsertId": 1
}驱动无法提供主键时,lastInsertId 为 null。rowsAffected 必须是非负整数,不能用
数据库驱动的内部错误字符串冒充成功结果。
SQLite 只接受以下连接目标:
| 目标 | 允许 | 说明 |
|---|---|---|
:memory: | 是 | 每个连接独立的内存库 |
app://data/** | 是 | 持久应用数据 |
app://cache/** | 是 | 可清理缓存 |
app://tmp/** | 是 | 临时文件 |
app://picked/** | 否 | 用户选择文件不自动成为数据库 |
app://res/**、app://assets/** | 否 | 只读资源 |
真实文件路径、content:// | 否 | 不暴露宿主路径 |
目录不存在时由驱动创建;路径包含父目录穿越、空字节、只读根或无法解析的 picked 句柄时,
返回 PERMISSION_DENIED。SQLite 打开后启用外键约束,语句错误返回 INVALID_ARGS,
打开或写入失败返回 IO_ERROR。
const available = await KSM.sql.drivers();
if (!available.drivers.includes('sqlite')) {
throw new Error('SQLite is not available on this host.');
}
const { connectionId } = await KSM.sql.open({
driver: 'sqlite',
url: 'app://data/app.db'
});
try {
await KSM.sql.execute({
connectionId,
statement: 'CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT NOT NULL)'
});
await KSM.sql.execute({
connectionId,
statement: 'INSERT INTO notes (body) VALUES (?)',
params: ['hello']
});
const result = await KSM.sql.query({
connectionId,
statement: 'SELECT id, body FROM notes ORDER BY id'
});
console.info(result.rows);
} finally {
await KSM.sql.close({ connectionId });
}业务层必须在 finally 中关闭连接。请求超时或页面销毁时,宿主会取消活动命令并释放连接;
应用不应依赖浏览器垃圾回收。
Windows 实现 KSMSqlDriver 和 KSMSqlConnection,由
KSMHostServices::RegisterSqlDriver 注册。Android 实现 KSMSqlDriver 和
KSMSqlConnection,由 KSMAndroidHostServices.registerSqlDriver 注册。驱动必须:
sql.open 创建独立连接对象。sql.drivers 中泄漏用户名、密码或完整 URL。远程驱动的 URL、TLS 策略、证书校验和连接超时由驱动实现负责。默认应使用 TLS,并在部署 文档中说明自签名证书、代理和证书轮换策略。
| 项 | Windows | Android |
|---|---|---|
| SQLite | 内置 | 内置 |
| MySQL / PostgreSQL | 系统 ODBC 驱动自动发现 | 宿主 SPI 注册 |
| MongoDB | 宿主 SPI 注册 | 宿主 SPI 注册 |
| 远程驱动注册 | KSMHostServices::RegisterSqlDriver | KSMAndroidHostServices.registerSqlDriver |
| 连接执行线程 | 宿主工作线程 | IO 协程 |
| 取消 | 现有请求取消链路 | 协程取消与活动连接清理 |
| 后台生命周期 | 窗口宿主关闭时释放 | onTrimMemory / onDestroy 时清理 |
Android 低内存回调会取消活动下载和命令;驱动必须响应中断并关闭连接。Windows 窗口或 WebView 关闭后,驱动不得再向前端投递迟到响应。
| 错误码 | 场景 |
|---|---|
INVALID_ARGS | 驱动名、URL、语句、参数或 SQL 语法非法 |
PERMISSION_DENIED | SQLite 路径越界或驱动业务授权失败 |
NOT_FOUND | 连接 ID 不存在或已关闭 |
IO_ERROR | 打开、网络、磁盘、执行或关闭失败 |
NOT_SUPPORTED | 驱动未注册或平台没有对应适配器 |
TIMEOUT | 请求超过前端或宿主时限 |
CANCELLED | 请求被应用或宿主取消 |
KSM.sql.drivers(),确认目标驱动存在。finally 中关闭,或是否被宿主生命周期取消。
评论