mcpField
S
sqlite-to-fast-sql

sqlite-to-fast-sql

github.com/cap-go开发73712 次安装2 周前更新
代码仓库

关于 sqlite-to-fast-sql

sqlite-to-fast-sql 是将 Capacitor 应用从桥接式 SQLite 插件迁移到 @capgo/capacitor-fast-sql 的技能,适用于需要保留本地数据的开发者。内容涵盖 API 替换、平台配置、加密选项及数据迁移方案。

主要功能

  1. 01盘点现有 SQL 插件与数据结构
  2. 02映射查询、写入和事务 API
  3. 03配置 iOS、Android 与 Web
  4. 04迁移旧数据库并验证数据
  5. 05配置可选 SQLCipher 加密

适用场景

  1. 01将 SQLite 插件替换为 Fast SQL
  2. 02迁移期间保留已有本地数据库
  3. 03排查大查询或批量写入性能问题
  4. 04为数据库启用加密并测试迁移

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/cap-go/capgo-skills --skill sqlite-to-fast-sql

安装后在 Claude Code 中输入/sqlite-to-fast-sql确认已加载。

附带文件metadata.json

详细介绍

SQLite 到 Fast SQL 迁移

将基于桥接的 SQL 插件替换为 @capgo/capacitor-fast-sql,同时保留用户数据。

适用场景

满足以下情况时触发:

  • package.json 中包含 @capacitor-community/sqlite、cordova-sqlite-storage、@capawesome-team/capacitor-sqlite、ORM capacitor 驱动或其他 SQLite 插件,且用户希望使用 Fast SQL。
  • 大型 SELECT 查询或同步写入速度缓慢,因为每一行都要以 JSON 格式通过 Capacitor 桥接传输。
  • 应用需要加密、事务、批量写入、BLOB 或加密键值存储。

以下情况不适用:

  • 仅使用 @capacitor/preferences 或 IndexedDB 的应用 -> capacitor-offline-first。
  • 使用 @ionic-enterprise/secure-storage / Identity Vault 的应用 -> ionic-enterprise-sdk-migration。
  • 已使用 Fast SQL、需要设计架构或同步逻辑的应用 -> capacitor-offline-first。

当前项目快照

检测到与 SQL 相关的软件包: !node -e "const fs=require('fs');if(!fs.existsSync('package.json'))process.exit(0);const pkg=JSON.parse(fs.readFileSync('package.json','utf8'));const needles=['sqlite','sqlcipher','typeorm','watermelondb','pouchdb','@capacitor-community/sqlite','@capawesome-team/capacitor-sqlite','@capgo/capacitor-fast-sql'];const out=[];for(const section of ['dependencies','devDependencies']){for(const [name,version] of Object.entries(pkg[section]||{})){if(needles.some((needle)=>name.includes(needle)))out.push(section+'.'+name+'='+version)}}console.log(out.sort().join('\n'))"

Fast SQL 的区别

  • 原生 SQLite 通过 localhost 上受令牌保护的 HTTP 服务访问,而非通过 Capacitor 桥接,因此大型结果集和批次可以避免桥接序列化。这就是为什么必须配置 iOS ATS 和 Android 明文传输。
  • 插件主版本与 Capacitor 主版本一致(Capacitor 8 对应 v8)。当前版本:8.2.x。
  • 数据库文件:iOS 为 Documents/<database>.db,Android 为 <filesDir>/<database>.db。其他插件使用不同的路径和名称,因此不会自动读取现有数据。
  • Web:使用官方 @sqlite.org/sqlite-wasm 和 OPFS 持久化(依赖已打包,无需安装 sql.js)。旧版本使用 sql.js + IndexedDB;这些数据不会自动迁移。
  • 加密:SQLCipher,按平台选择启用。

流程

第 1 步:盘点

阅读 package.json 并搜索数据层。记录:插件及版本、数据库名称、架构/迁移机制(user_version、升级语句、ORM 迁移)、事务使用情况、BLOB、加密(以及密钥来源)、JSON 导入/导出、Web 支持情况和大致数据量。更改代码前先报告这些信息。

第 2 步:映射 API
import { FastSQL, KeyValueStore } from '@capgo/capacitor-fast-sql';

const db = await FastSQL.connect({ database: 'app' });            // { encrypted, encryptionKey, readOnly }
const rows = await db.query('SELECT * FROM todo WHERE done = ?', [0]);
const { rowsAffected, insertId } = await db.run('INSERT INTO todo (title) VALUES (?)', ['A']);
await db.execute('CREATE TABLE IF NOT EXISTS todo (id INTEGER PRIMARY KEY, title TEXT, done INTEGER DEFAULT 0)');
await db.executeBatch([{ statement: 'INSERT INTO log (m) VALUES (?)', params: ['x'] }]);
await db.transaction(async (tx) => { await tx.run('UPDATE a SET n = n - 1'); await tx.run('UPDATE b SET n = n + 1'); });
await FastSQL.disconnect('app');
@capacitor-community/sqliteFast SQL
new SQLiteConnection(CapacitorSQLite)、createConnection(name, encrypted, mode, version, readonly)、db.open()FastSQL.connect({ database, encrypted, encryptionKey, readOnly })
db.query(sql, values) -> { values }db.query(sql, params) -> rows array
db.run(sql, values) -> { changes: { changes, lastId } }db.run(sql, params) -> { rowsAffected, insertId }
db.execute(multiStatementSql)每条语句调用一次 db.execute(sql),或使用 executeBatch
db.executeSet([{ statement, values }])db.executeBatch([{ statement, params }])
beginTransaction/commitTransaction/rollbackTransaction、调用中的 transaction 标志db.transaction(cb) 或 beginTransaction() / commit() / rollback()
addUpgradeStatement + 版本号使用自己的 PRAGMA user_version 迁移运行器
closeConnection(name)FastSQL.disconnect(name)
importFromJson / exportToJson不提供;使用 executeBatch 写入行
cordova-sqlite-storage db.executeSql(sql, params, ok, err) / db.transaction(tx => tx.executeSql(...))db.query/db.run 和 db.transaction(async tx => ...)

键值数据(Ionic Storage、类似 Preferences 的封装)-> 使用 KeyValueStore.open({ database, encrypted, encryptionKey, store }),并配合 set/get/has/remove/clear/keys 使用。

步骤 3:安装和配置
npm install @capgo/capacitor-fast-sql
npx cap sync

iOS ios/App/App/Info.plist(仅限回环地址;不会削弱其他主机的 ATS):

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

Android android/app/src/main/res/xml/network_security_config.xml,并在 <application> 上通过 android:networkSecurityConfig="@xml/network_security_config" 引用:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="false">localhost</domain>
        <domain includeSubdomains="false">127.0.0.1</domain>
    </domain-config>
</network-security-config>

如果应用已有网络安全配置,请合并 domain-config,而不是替换整个文件。

加密(仅当 encrypted: true 时):

  • Android:在 android/app/build.gradle 的 dependencies 中添加 implementation 'net.zetetic:sqlcipher-android:4.13.0'(或当前版本)。
  • iOS(CocoaPods):在 ios/App/Podfile 中添加 pod 'CapgoCapacitorFastSql/SQLCipher', :path => '../../node_modules/@capgo/capacitor-fast-sql',然后运行 pod install。对于 SPM 项目,请查看插件 README,了解当前的 SQLCipher 选项。
  • 不要将密钥放在 JS 源代码中:使用 @capgo/capacitor-native-biometric 存储密钥,或从后端获取密钥。

Web(仅当应用面向 Web 发布时):提供 Cross-Origin-Opener-Policy: same-origin 和 Cross-Origin-Embedder-Policy: require-corp,并在 Vite 中添加 optimizeDeps.exclude: ['@sqlite.org/sqlite-wasm']。在首次 connect() 之前调用 CapgoCapacitorFastSql.configureWeb({ ... }) 是可选的,在原生平台上则不会执行任何操作。

步骤 4:保留现有数据

与用户一起选择一种方案:

  1. 双插件发布(最安全):保留旧插件一个发布周期。首次启动时,如果缺少 migrated 标记,则从旧插件读取表,在事务中通过 executeBatch 将其写入 Fast SQL,验证计数,然后设置该标记。下一次发布时移除旧插件。
  2. 复制文件:在首次 connect() 之前,将旧 .db 文件复制到 Fast SQL 的路径(旧版社区插件的文件通常命名为 <name>SQLite.db;请先在设备上确认实际路径)。加密文件只有在使用相同密钥和兼容的 SQLCipher 版本时才能继续使用。
  3. 从服务器重新同步:当本地数据只是缓存时可以接受;请与用户确认。
步骤 5:替换代码并移除旧插件

在现有数据访问层中替换导入和调用;保留架构和迁移步骤。然后(如果选择方案 1,则在过渡发布之后):

npm uninstall @capacitor-community/sqlite   # or the plugin in use
npx cap sync

验证

  • 清理后,rg -n "@capacitor-community/sqlite|cordova-sqlite|CapacitorSQLite|SQLiteConnection" -g '!node_modules' src 不应返回任何内容。
  • 升级测试:安装当前商店版本,创建数据,再覆盖安装新版本;行数应一致。
  • 在两个平台上进行冒烟测试:创建、读取、更新、删除、事务回滚(在 transaction 中抛出异常并确认没有部分写入)、BLOB 往返(Uint8Array)。
  • 加密数据库:使用错误密钥无法打开;使用普通 sqlite3 无法读取该文件。
  • 前后测量大型查询,确认达到性能目标。

错误处理

错误 / 症状修复方法
iOS:对 http://localhost:<port> 的请求失败,提示 The resource could not be loaded because the App Transport Security policy requires the use of a secure connection添加 NSAllowsLocalNetworking
Android:出现 net::ERR_CLEARTEXT_NOT_PERMITTED 或 CLEARTEXT communication to localhost not permitted by network security policy添加 localhost 的 network_security_config.xml,并在清单中引用它
iOS:出现 Encryption is not available in this build. Add SQLCipher to enable encryption.安装 SQLCipher 子规范,或使用 encrypted: false
Android:出现 Encryption is not available. ... to your app's build.gradle to enable encryption.在应用模块中添加 net.zetetic:sqlcipher-android
Encryption key is required when encrypted is true在设置 encrypted: true 时传入 encryptionKey
更新后应用启动时数据库为空文件路径已更改;执行步骤 4 的数据迁移
Web:出现 OPFS / SharedArrayBuffer 错误缺少 COOP/COEP 标头,或 Vite 预打包了 sqlite-wasm
query 返回对象,但代码预期的是 { values }这是旧社区插件的结果格式;更新调用方以使用行数组

评论

支持 Markdown