news 2026/9/12 21:01:03

Turso React Native SDK 完全指南:在移动端构建可离线同步的嵌入式副本数据库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Turso React Native SDK 完全指南:在移动端构建可离线同步的嵌入式副本数据库

Turso React Native SDK 完全指南:在移动端构建可离线同步的嵌入式副本数据库

【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso

导读

本文围绕 bindings/react-native/README.md 展开,完整讲解 Turso React Native 绑定(@tursodatabase/sync-react-native)的安装、配置与使用:它允许你的 iOS / Android 应用在本地以 SQLite 兼容的嵌入式副本(embedded replica)方式运行数据库,并在有网络时与 Turso 云端数据库双向同步。读完本文,你将掌握本地数据库、云同步数据库、加密远程库的完整接入方案,以及 SDK 的底层架构(JSI 桥接、异步 IO 处理)原理。

Turso 本身是一个用 Rust 编写的 SQL 数据库引擎,兼容 SQLite,并新增了同步引擎能力。本 SDK 把这一能力桥接进 React Native:核心逻辑位于 TypeScript 与 Rust 中,C++ 层只是一个薄薄的 JSI 桥接层。


1. 安装与平台配置

1.1 安装 npm 包

npm install @tursodatabase/sync-react-native

从仓库的 bindings/react-native/package.json 可以看到该包的元信息:主入口为lib/commonjs/index.js(构建产物由react-native-builder-bob生成),TypeScript 类型定义位于lib/typescript/index.d.ts,源码位于src/index.ts。它要求react >= 18.0.0react-native >= 0.76.0(peerDependencies),运行环境 Node 需>= 18

1.2 iOS:pod install

cd ios && pod install

iOS 依赖一个预编译的 Rust XCFramework(turso-sync-sdk-kit.xcframework)。CocoaPods 配置见 bindings/react-native/turso-sync-react-native.podspec:

  • 平台要求ios >= 13.0
  • vendored_frameworks方式引入 Rust 构建产物,设备与模拟器架构自动切换;
  • 内置script_phase,若libs/ios/turso-sync-sdk-kit.xcframework不存在,会先执行make ios编译 Rust 库(C++ 标准c++20,链接-lc++)。

如果你需要从源码重新构建 Rust 原生库,可参考 bindings/react-native/Makefile:make ios会通过rustup target add添加aarch64-apple-iosaarch64-apple-ios-sim目标后执行cargo build --releasemake android则交叉编译aarch64-linux-androidarmv7-linux-androideabix86_64-linux-androidi686-linux-android四个 ABI 的.so文件。

1.3 Android:minSdkVersion

Android 侧要求minSdkVersion不低于21,在android/build.gradle中配置。原生桥接模块实现位于 bindings/react-native/android/src/main/java/com/turso/sync/reactnative/TursoModule.java:

  • 通过System.loadLibrary("turso_sync_sdk_kit")加载 Rust 动态库;
  • 通过getConstants()暴露ANDROID_DATABASE_PATH(应用的数据库目录)、ANDROID_FILES_PATHANDROID_EXTERNAL_FILES_PATH等常量;
  • 暴露install()同步方法,把 JSI 桥接安装到 JS 运行时。

iOS 侧对应实现见 bindings/react-native/ios/TursoModule.mm:它读取应用 Documents 目录(若配置了Turso_AppGroup,则使用 App Group 容器路径,便于 App 与扩展共享数据),并通过turso::install(*runtime, callInvoker, ...)安装 JSI 模块。

注意:SDK 依赖 React Native 的New Architecture(新架构)src/index.ts在模块加载时会检查原生模块与__TursoProxy全局对象,若 JSI 绑定安装失败会直接抛错提示。


2. 快速开始:同步数据库

import { Database, getDbPath } from '@tursodatabase/sync-react-native'; // 获取平台可写路径 const dbPath = getDbPath('myapp.db'); // 创建带同步功能的数据库 const db = new Database({ path: dbPath, url: 'libsql://your-db.turso.io', authToken: 'your-auth-token', }); // 连接(若本地为空则从远端引导初始化) await db.connect(); // 查询本地副本(快速) const users = await db.all('SELECT * FROM users'); // 本地写入 await db.run('INSERT INTO users (name) VALUES (?)', ['Alice']); // 与远端同步 await db.push(); // 推送本地变更 await db.pull(); // 拉取远端变更 // 用完关闭 await db.close();

关键点说明:

  • getDbPath(filename):返回平台特定的可写目录下的绝对路径。iOS 为 Documents 目录,Android 为数据库目录(见 src/index.ts 与paths.databasegetter)。
  • connect():本地库直接打开;同步库则会执行create()(bootstrap)并建立连接(见 src/Database.ts)。
  • url是判据Database构造函数通过isSyncConfig(opts)判断——只要url非空,即进入同步模式(见 src/Database.ts)。
  • 你还可以使用便捷函数connect(opts),它会new Database(opts)并立即connect()后返回实例(见 src/index.ts)。

3. 纯本地数据库(Local-Only Database)

不传url即为纯本地数据库,无需网络、无需鉴权:

const db = new Database({ path: getDbPath('local.db') }); await db.connect(); await db.exec('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)'); await db.run('INSERT INTO users (name) VALUES (?)', ['Bob']); const user = await db.get('SELECT * FROM users WHERE id = ?', [1]); await db.close();

本地模式在原生层以阻塞 IO打开(async_io: false),而同步模式使用异步 IOasync_io: true),因为同步引擎需要外部网络 IO 循环配合(见 src/Database.ts)。所有数据库操作均为异步 API,统一了本地与同步两种场景的调用方式。

另外,路径可以是相对路径(自动放入可写目录)、绝对路径,甚至是:memory:内存数据库(见 src/index.ts 中的connect文档注释)。


4. 加密远程数据库(Encrypted Remote Database)

当云端数据库启用了加密时,通过remoteEncryption传入加密配置:

const db = new Database({ path: getDbPath('encrypted.db'), url: 'libsql://your-db.turso.io', authToken: 'your-auth-token', remoteEncryption: { cipher: 'aes256gcm', key: 'base64-encoded-key', }, });

加密参数详解(定义见 src/types.ts):

cipher 取值密钥要求reservedBytes(保留字节数)
aes256gcm/aes128gcm/chacha20poly1305base64 编码,16 或 32 字节(视 cipher)28
aegis128l/aegis128x2/aegis128x4base64 编码32
aegis256/aegis256x2/aegis256x4base64 编码48

Database内部通过getReservedBytesForCipher()根据 cipher 计算保留字节数并传入同步引擎(见 src/Database.ts),这些保留字节数与 Turso Cloud 的加密设置保持一致。同步引擎会收到remoteEncryptionKeyremoteEncryptionCipher,密钥用于构造 HTTP 请求头。


5. API 参考

5.1 Database 方法

方法说明
connect()打开 / 引导初始化数据库
exec(sql)执行 SQL(无返回结果,支持多条语句)
run(sql, params?)执行 SQL,返回{ changes, lastInsertRowid }
get(sql, params?)查询单行
all(sql, params?)查询所有行
prepare(sql)创建预编译语句(返回Statement
close()关闭数据库

5.2 同步方法(提供url时可用)

方法说明
push()推送本地变更到远端
pull()拉取远端变更到本地(有变更返回true,无变更返回false
sync()先 push 再 pull
stats()获取同步统计信息

说明:sync()在当前仓库的Database类中体现为push()pull()的组合使用(文档 API 表中列出,源码中push()/pull()分别对应原生pushChanges()waitChanges()+applyChanges()两个阶段,见 src/Database.ts)。同步库还额外提供checkpoint()用于触发检查点。

5.3 同步统计(stats()返回值)

SyncStats结构定义见 src/types.ts:

字段含义
cdcOperationsCDC(变更数据捕获)操作数
mainWalSize主 WAL 大小
revertWalSize回滚 WAL 大小
lastPullUnixTime最近一次拉取时间(Unix 时间戳)
lastPushUnixTime最近一次推送时间
networkSentBytes网络发送字节数
networkReceivedBytes网络接收字节数
revision远端版本号(字符串或null

5.4 事务(Transactions)

await db.transaction(async () => { await db.run('INSERT INTO users (name) VALUES (?)', ['Alice']); await db.run('INSERT INTO users (name) VALUES (?)', ['Bob']); // 成功则提交,出错则回滚 });

transaction<T>(fn)的实现非常直观(见 src/Database.ts):先exec('BEGIN'),回调成功则exec('COMMIT'),抛出异常则exec('ROLLBACK')并重新抛出错误。此外还提供了inTransactiongetter(内部通过connection.getAutocommit()判断)与lastInsertRowidgetter 便于事务内取最近插入行 ID。

5.5 预编译语句(Statement)

prepare(sql)返回Statement,支持链式bind()run()get()all()reset()finalize()。参数绑定支持三种形态(见 src/Statement.ts):

  • 位置参数数组stmt.run(1, 'Alice')stmt.run([1, 'Alice'])
  • 命名参数对象stmt.run({ $id: 1 })(内部通过namedPosition(name)解析占位符位置);
  • 单个标量值stmt.run(42)

值类型映射(见 src/Statement.ts):null/undefined→ NULL,整数number→ INTEGER,浮点number→ REAL,string→ TEXT,ArrayBuffer/ TypedArray → BLOB。查询结果统一按列名组织为RowRecord<string, SQLiteValue>),其中SQLiteValue = null | number | string | ArrayBuffer


6. 高级配置参数(DatabaseOpts 全解)

pathurlauthTokenremoteEncryption之外,DatabaseOpts还支持以下配置(完整定义见 src/types.ts):

参数类型默认值说明
clientNamestring'turso-sync-react-native'客户端标识,SDK 会追加唯一后缀保证clientId唯一
longPollTimeoutMsnumber不设则无超时拉取操作的长轮询超时
bootstrapIfEmptybooleantrue本地为空时是否从远端引导初始化;设为false则客户端仅在联网时才能连接全新数据库
pushOperationsThresholdnumber不设则一次推送全部变更单个 push HTTP 批次中 CDC 操作数上限,达到后按事务边界拆分(单个用户事务永不被拆散)
pullBytesThresholdnumber不设则单次往返完成 bootstrapbootstrap 下载按字节拆分多个/pull-updates请求;对query引导策略无效
logicalMvccPullbooleanfalse强制增量拉取使用 MVCC 逻辑日志流;默认自动探测远端协议并持久化,仅在需要时作为逃生舱口开启
partialSyncExperimentalobject未启用实验性局部同步(见下)

6.1 实验性局部同步(partialSyncExperimental)

const db = new Database({ path: getDbPath('partial.db'), url: 'libsql://your-db.turso.io', authToken: 'your-auth-token', partialSyncExperimental: { // 前缀策略:启动时仅本地加载前 N 字节 bootstrapStrategy: { kind: 'prefix', length: 1024 * 1024 }, // 或查询策略:仅加载指定 SQL 触及的页面 // bootstrapStrategy: { kind: 'query', query: 'SELECT * FROM users' }, segmentSize: 128 * 1024, // 按段加载,128KB 约 32 页 prefetch: true, // 预取可能即将访问的页面 }, });

三种引导策略说明(见 src/types.ts):

  • prefix:启动时仅下载数据库文件前 N 字节;
  • query:仅下载指定 SQL 语句访问过的页面;
  • segmentSize:让同步引擎按段批量加载页面(如 128KB 段即加载约 32 页);
  • prefetch:预取未来可能访问的页面。

当局部同步遇到缺失页面时,语句执行会返回TursoStatus.IO,SDK 通过drainSyncIo()驱动同步引擎的 IO 队列补页后继续执行(见 src/Statement.ts 中的executeWithIo/stepWithIo循环,以及 src/internal/ioProcessor.ts)。


7. 底层架构解析:TypeScript 驱动、C++ 薄桥、Rust 引擎

理解 SDK 的分层有助于排查问题与评估性能:

┌─────────────────────────────────────────────┐ │ TypeScript 层(Database / Statement / │ │ asyncOperation / ioProcessor) │ ├─────────────────────────────────────────────┤ │ JSI 桥接层(C++:TursoHostObject、 │ │ TursoDatabaseHostObject、TursoSync...) │ ├─────────────────────────────────────────────┤ │ 原生模块(iOS: TursoModule.mm / │ │ Android: TursoModule.java) │ ├─────────────────────────────────────────────┤ │ Rust 引擎(sdk-kit + sync/sdk-kit, │ │ 以 .xcframework / .so 形式内置) │ └─────────────────────────────────────────────┘

架构要点:

  1. JSI 直连,无 JSON 序列化:原生层通过 JSI(JavaScript Interface)把__TursoProxy注入全局对象(见 src/index.ts),TypeScript 直接调用原生方法,避免传统 Bridge 的序列化开销。原生侧 Host Object 源码位于 bindings/react-native/cpp/(TursoHostObject.cppTursoDatabaseHostObject.cppTursoConnectionHostObject.cppTursoStatementHostObject.cppTursoSyncDatabaseHostObject.cpp等)。

  2. 异步 IO 全部由 JavaScript 驱动:同步引擎产生三类 IO 请求(见 src/internal/ioProcessor.ts 与NativeSyncIoItemgetKind()):

    • HTTP:使用 React Native 标准fetch()发出,URL 会从libsql:///turso://规范化为https://,并自动注入Authorization: Bearer <token>头;
    • FULL_READ / FULL_WRITE:整库文件的原子读写,默认走内置 JSI 文件系统函数;
    • NONE:空操作。

    这一设计的好处是:网络请求在 RN 调试器中可见、可自定义 fetch 行为(如代理、自定义头)、可 mock 测试、使用平台原生网络栈而非 C++ HTTP 库。

  3. 异步操作驱动循环:同步操作(createconnectpushChangeswaitChangesapplyChangescheckpointstats)返回NativeSyncOperation,由 src/internal/asyncOperation.ts 的driveOperation()循环调用resume():状态为TursoStatus.IO时先处理 IO 队列再继续,TursoStatus.DONE时按resultKind提取连接 / 变更 / 统计结果。

  4. 并发安全Database内部持有一个AsyncLock,所有语句执行(run/get/all/finalize)在锁内完成“绑定参数 → 执行 → 重置”,避免并发绑定/执行竞态;exec()则利用prepareFirst+tailIdx循环处理多语句 SQL。

  5. 状态码体系TursoStatus枚举(src/types.ts)涵盖OK/DONE/ROW/IO/BUSY/INTERRUPT/ERROR/MISUSE/CONSTRAINT/READONLY/DATABASE_FULL/NOTADB/CORRUPT/IOERR等,TursoType枚举则对应 SQLite 值类型(INTEGER/REAL/TEXT/BLOB/NULL),用于结果行读取。

  6. 可插拔文件系统:通过setFileSystemImpl(readFile, writeFile)可覆盖内置文件读写实现(如加密、压缩等自定义需求),默认使用 JSI 内置函数(见 src/internal/ioProcessor.ts)。


8. 调试与日志

SDK 提供setup()用于配置引擎日志,应在任何数据库操作之前调用(见 src/index.ts):

import { setup } from '@tursodatabase/sync-react-native'; setup({ logLevel: 'debug', logger: (log) => { console.log(`[${log.level}] ${log.target}: ${log.message}`); }, });

日志级别为'error' | 'warn' | 'info' | 'debug' | 'trace',每条日志包含messagetargetfilelinetimestamplevel字段(类型定义见 src/types.ts)。


9. 最佳实践与注意事项

  1. 离线优先(Offline-first):把bootstrapIfEmpty设为false可避免网络不可用时对全新库的无谓 bootstrap 尝试;日常读写全部落在本地副本,响应快且离线可用。
  2. 路径管理:优先使用getDbPath()或相对路径(SDK 自动归一化到可写目录);Android 上数据库目录为/data/data/<应用包名>/databases/,iOS 为 Documents 目录;同步库会在主文件旁生成-info-wal等伴随文件。
  3. 善用stats():通过cdcOperationsnetworkSentBytesnetworkReceivedBytes等指标监控同步负载与网络消耗。
  4. 局部同步是实验特性:仅当数据库体积较大、需要控制启动下载量时才启用partialSyncExperimental,并理解其“按需补页”的 IO 行为。
  5. 事务边界pushOperationsThreshold会按事务边界拆分推送批次,单个用户事务不会被拆散——这保证了远端回放的一致性语义。
  6. 版本与平台约束:当前包版本为0.8.0-pre.10(预发布);要求 RN 新架构(New Architecture)、iOS 13+、Android minSdk 21+;如需从源码构建原生库,参考 bindings/react-native/Makefile 的make ios/make android

10. 继续深入仓库

  • SDK 入口与类型: bindings/react-native/src/index.ts、bindings/react-native/src/types.ts
  • 数据库与语句实现: bindings/react-native/src/Database.ts、bindings/react-native/src/Statement.ts
  • 异步 IO 与操作驱动: bindings/react-native/src/internal/ioProcessor.ts、bindings/react-native/src/internal/asyncOperation.ts
  • 原生桥接: bindings/react-native/ios/TursoModule.mm、bindings/react-native/android/src/main/java/com/turso/sync/reactnative/TursoModule.java、bindings/react-native/cpp/
  • Rust 引擎底层: sync/engine/、sync/sdk-kit/、sdk-kit/
  • 完整示例工程: examples/react-native/

【免费下载链接】tursoA SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.项目地址: https://gitcode.com/GitHub_Trending/tu/turso

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 21:00:36

AI智能体如何10倍提升营销效率:架构与应用

1. 项目概述&#xff1a;AI如何重构营销生产力当我在2023年首次部署AI营销系统时&#xff0c;团队用3天完成了过去20人月的客户分析工作。这不是未来幻想&#xff0c;而是正在发生的营销革命——通过AI智能体&#xff08;AI Agent&#xff09;技术&#xff0c;单个AI员工可同时…

作者头像 李华
网站建设 2026/9/12 21:00:11

树莓派GPS定位数据NB-IoT回传:串口接线、AT指令与坐标转换

简介&#xff1a;面向毕业设计、物联网课程设计或嵌入式开发学习者&#xff0c;本资源演示了树莓派结合NBIoT模块采集GPS数据并上传的完整项目。项目聚焦NBIoT低功耗广覆盖特性与GPS定位精度&#xff0c;涵盖设备连接、软件配置、数据解析、云端上传等工程环节&#xff0c;适合…

作者头像 李华
网站建设 2026/9/12 20:59:35

无人机河道污染巡检 河道漂浮物检测数据集 河道环保识别数据集 yolo数据集第10791期

无人机河道污染巡检 河道漂浮物检测数据集项目详情任务类型目标检测样本总量2400张 类别索引识别类别名称0废弃物1漂浮物 数据集简介 烟火检测数据集&#xff0c;一共2430张图像&#xff0c;配套YOLO格式标签文件。数据集面向火情视觉监测场景&#xff0c;可识别画面中的废弃物…

作者头像 李华
网站建设 2026/9/12 20:58:38

缓存双写一致性问题

当我们更新数据库的时候&#xff0c;需要保持数据可的数据和缓存中的数据保持一致在业务背景的不同&#xff0c;所对应的就有两种解决方式1.必须保证强一致性的业务&#xff1a;解决方案&#xff1a;i&#xff1a;延迟双删&#xff0c;先去删除缓存&#xff0c;再去更新数据库&…

作者头像 李华