This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Expo SQLite
提供访问数据库功能的库,可通过 SQLite API 对数据库进行查询。
expo-sqlite 让您的应用可以访问一个能够通过 SQLite API 查询的数据库。该数据库会在您的应用重启后保留。
警告 在 Apple TV 上,根据 Apple 平台指南,底层数据库文件位于缓存目录中,而不是应用程序文稿目录中。
安装
- npx expo install expo-sqliteIf you are installing this in an existing React Native app, make sure to install expo in your project.
The with-sqlite example comes with expo-sqlite already installed and configured:
- npx create-expo-app --example with-sqlite应用配置中的配置
如果你的项目中使用配置插件(持续原生生成(CNG)),则可以使用内置的配置插件对 expo-sqlite 进行高级配置。该插件允许你配置各种无法在运行时设置、且必须构建新的应用二进制文件才能生效的属性。如果你的应用不使用 CNG,则需要手动配置该库。
Example app.json with config plugin
{ "expo": { "plugins": [ [ "expo-sqlite", { "enableFTS": true, "useSQLCipher": true, "android": { // 覆盖 Android 的共享配置 "enableFTS": false, "useSQLCipher": false }, "ios": { // 也可以覆盖 iOS 的共享配置 "customBuildFlags": ["-DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_SNAPSHOT=1"] } } ] ] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
customBuildFlags | - | 要传递给 SQLite 构建过程的自定义构建标志。 |
enableFTS | true | |
useSQLCipher | false | 使用 SQLCipher 实现,而不是默认的 SQLite。 |
useLibSQL | false | 使用 libSQL,而不是默认的 SQLite。 |
withSQLiteVecExtension | false | 将 sqlite-vec 扩展添加到 |
Web 配置
重要 Web 支持处于 alpha 阶段,可能不稳定。如果遇到任何问题,请在 GitHub 上创建 issue。
要在 Web 上使用 expo-sqlite,您需要配置 Metro bundler 以支持 wasm 文件,并添加 HTTP 标头以允许使用 SharedArrayBuffer。
将以下配置添加到您的 metro.config.js 中。如果您还没有 metro.config.js,可以运行 npx expo customize metro.config.js。 详细了解如何自定义 Metro。
如果您将应用部署到 Web 托管服务,还需要将 Cross-Origin-Embedder-Policy 和 Cross-Origin-Opener-Policy 标头添加到 Web 服务器中。详细了解 COEP、COOP 标头以及 SharedArrayBuffer。
如果您将应用部署到 EAS Hosting,可以在应用配置中配置这些标头:
{ "expo": { "plugins": [ [ "expo-router", { "headers": { "Cross-Origin-Embedder-Policy": "credentialless", "Cross-Origin-Opener-Policy": "same-origin" } } ] ] } }
用法
从 expo-sqlite 导入模块。
import * as SQLite from 'expo-sqlite';
基本 CRUD 操作
const db = await SQLite.openDatabaseAsync('databaseName'); // 当你想要一次性执行多个查询时,`execAsync()` 适用于批量查询。 // 注意,`execAsync()` 不会转义参数,可能导致 SQL 注入。 await db.execAsync(` PRAGMA journal_mode = WAL; CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY NOT NULL, value TEXT NOT NULL, intValue INTEGER); INSERT INTO test (value, intValue) VALUES ('test1', 123); INSERT INTO test (value, intValue) VALUES ('test2', 456); INSERT INTO test (value, intValue) VALUES ('test3', 789); `); // 当你想要执行一些写操作时,`runAsync()` 很有用。 const result = await db.runAsync('INSERT INTO test (value, intValue) VALUES (?, ?)', 'aaa', 100); console.log(result.lastInsertRowId, result.changes); await db.runAsync('UPDATE test SET intValue = ? WHERE value = ?', 999, 'aaa'); // 从可变参数中绑定未命名参数 await db.runAsync('UPDATE test SET intValue = ? WHERE value = ?', [999, 'aaa']); // 从数组中绑定未命名参数 await db.runAsync('DELETE FROM test WHERE value = $value', { $value: 'aaa' }); // 从对象中绑定命名参数 // 当你想要从数据库中获取单行数据时,`getFirstAsync()` 很有用。 const firstRow = await db.getFirstAsync('SELECT * FROM test'); console.log(firstRow.id, firstRow.value, firstRow.intValue); // 当你想要将所有结果作为对象数组获取时,`getAllAsync()` 很有用。 const allRows = await db.getAllAsync('SELECT * FROM test'); for (const row of allRows) { console.log(row.id, row.value, row.intValue); } // 当你想要遍历 SQLite 查询游标时,`getEachAsync()` 很有用。 for await (const row of db.getEachAsync('SELECT * FROM test')) { console.log(row.id, row.value, row.intValue); }
预处理语句
预处理语句允许您编译一次 SQL 查询,并使用不同的参数多次执行。它们会自动转义输入参数,以防御 SQL 注入攻击,因此推荐用于包含用户输入的查询。您可以在数据库实例上调用 prepareAsync() 或 prepareSync() 方法来获取预处理语句。通过调用 executeAsync() 或 executeSync() 方法,预处理语句可以执行 CRUD 操作。
注意: 使用完预处理语句后,请记得调用
finalizeAsync()或finalizeSync()方法来释放它。建议使用try-finally代码块,以确保预处理语句最终被释放。
const statement = await db.prepareAsync( 'INSERT INTO test (value, intValue) VALUES ($value, $intValue)' ); try { let result = await statement.executeAsync({ $value: 'bbb', $intValue: 101 }); console.log('bbb and 101:', result.lastInsertRowId, result.changes); result = await statement.executeAsync({ $value: 'ccc', $intValue: 102 }); console.log('ccc and 102:', result.lastInsertRowId, result.changes); result = await statement.executeAsync({ $value: 'ddd', $intValue: 103 }); console.log('ddd and 103:', result.lastInsertRowId, result.changes); } finally { await statement.finalizeAsync(); } const statement2 = await db.prepareAsync('SELECT * FROM test WHERE intValue >= $intValue'); try { const result = await statement2.executeAsync<{ value: string; intValue: number }>({ $intValue: 100, }); // 当您想从数据库中获取单行数据时,`getFirstAsync()` 非常有用。 const firstRow = await result.getFirstAsync(); console.log(firstRow.id, firstRow.value, firstRow.intValue); // 将 SQLite 查询游标重置到开头,以便下一次调用 `getAllAsync()`。 await result.resetAsync(); // 当您想将所有结果作为对象数组获取时,`getAllAsync()` 非常有用。 const allRows = await result.getAllAsync(); for (const row of allRows) { console.log(row.value, row.intValue); } // 将 SQLite 查询游标重置到开头,以便下一次 `for-await-of` 循环。 await result.resetAsync(); // result 对象也是一个异步可迭代对象。您可以在 `for-await-of` 循环中使用它来迭代 SQLite 查询游标。 for await (const row of result) { console.log(row.value, row.intValue); } } finally { await statement2.finalizeAsync(); }
标记模板字面量 API
为了方便使用并提升开发体验,expo-sqlite 通过 db.sql 属性提供了受 Bun 启发的标记模板字面量 API。此 API 会自动转义参数,以防止 SQL 注入攻击,并根据查询类型自动推断类型。
interface User { id: number; name: string; age: number; } const db = await SQLite.openDatabaseAsync('mydb.db'); const sql = db.sql; const age = 21; const users = await sql<User>`SELECT * FROM users WHERE age > ${age}`; // 类型:User[] console.log(users[0].name); // INSERT/UPDATE/DELETE 等可变查询会返回 SQLiteRunResult 元数据 const result = (await sql`INSERT INTO users (name, age) VALUES (${'Alice'}, ${30})`) as SQLite.SQLiteRunResult; console.log(result.lastInsertRowId, result.changes); // 仅获取第一行 const user = await sql<User>`SELECT * FROM users WHERE id = ${1}`.first(); if (user) { console.log(user.name); } // 迭代查询结果 for await (const user of sql<User>`SELECT * FROM users`.each()) { console.log(user.name); } // 同步 API const syncUsers = sql<User>`SELECT * FROM users WHERE age > ${21}`.allSync(); const syncUser = sql<User>`SELECT * FROM users WHERE id = ${1}`.firstSync();
useSQLiteContext() 钩子
import { SQLiteProvider, useSQLiteContext, type SQLiteDatabase } from 'expo-sqlite'; import { useEffect, useState } from 'react'; import { View, Text, StyleSheet } from 'react-native'; export default function App() { return ( <View style={styles.container}> <SQLiteProvider databaseName="test.db" onInit={migrateDbIfNeeded}> <Header /> <Content /> </SQLiteProvider> </View> ); } export function Header() { const db = useSQLiteContext(); const [version, setVersion] = useState(''); useEffect(() => { async function setup() { const result = await db.getFirstAsync<{ 'sqlite_version()': string }>( 'SELECT sqlite_version()' ); setVersion(result['sqlite_version()']); } setup(); }, []); return ( <View style={styles.headerContainer}> <Text style={styles.headerText}>SQLite version: {version}</Text> </View> ); } interface Todo { value: string; intValue: number; } export function Content() { const db = useSQLiteContext(); const [todos, setTodos] = useState<Todo[]>([]); useEffect(() => { async function setup() { const result = await db.getAllAsync<Todo>('SELECT * FROM todos'); setTodos(result); } setup(); }, []); return ( <View style={styles.contentContainer}> {todos.map((todo, index) => ( <View style={styles.todoItemContainer} key={index}> <Text>{`${todo.intValue} - ${todo.value}`}</Text> </View> ))} </View> ); } async function migrateDbIfNeeded(db: SQLiteDatabase) { const DATABASE_VERSION = 1; let { user_version: currentDbVersion } = await db.getFirstAsync<{ user_version: number }>( 'PRAGMA user_version' ); if (currentDbVersion >= DATABASE_VERSION) { return; } if (currentDbVersion === 0) { await db.execAsync(` PRAGMA journal_mode = 'wal'; CREATE TABLE todos (id INTEGER PRIMARY KEY NOT NULL, value TEXT NOT NULL, intValue INTEGER); `); await db.runAsync('INSERT INTO todos (value, intValue) VALUES (?, ?)', 'hello', 1); await db.runAsync('INSERT INTO todos (value, intValue) VALUES (?, ?)', 'world', 2); currentDbVersion = 1; } // 如果 (currentDbVersion === 1) { // 添加更多迁移 // } await db.execAsync(`PRAGMA user_version = ${DATABASE_VERSION}`); } const styles = StyleSheet.create({ // 你的样式... });
useSQLiteContext() hook 与 React.Suspense
与 useSQLiteContext() hook 一样,你也可以将 SQLiteProvider 与 React.Suspense 集成,以便在数据库准备就绪之前显示备用组件。要启用此集成,请将 useSuspense 属性传递给 SQLiteProvider 组件。
import { SQLiteProvider, useSQLiteContext } from 'expo-sqlite'; import { Suspense } from 'react'; import { View, Text, StyleSheet } from 'react-native'; export default function App() { return ( <View style={styles.container}> <Suspense fallback={<Fallback />}> <SQLiteProvider databaseName="test.db" onInit={migrateDbIfNeeded} useSuspense> <Header /> <Content /> </SQLiteProvider> </Suspense> </View> ); }
在异步事务中执行查询
const db = await SQLite.openDatabaseAsync('databaseName'); await db.withTransactionAsync(async () => { const result = await db.getFirstAsync('SELECT COUNT(*) FROM USERS'); console.log('Count:', result.rows[0]['COUNT(*)']); });
由于 async/await 的特性,事务处于活动状态时运行的任何查询都会包含在该事务中。这包括位于传递给 withTransactionAsync() 的作用域函数之外的查询语句,因此可能会产生令人意外的行为。例如,下面的测试用例会在传递给 withTransactionAsync() 的作用域函数内外运行查询。不过,由于第二个 UPDATE 查询在事务结束前运行,因此所有查询实际上都会在同一个 SQL 事务中运行。
Promise.all([ // 1. 一个新事务开始 db.withTransactionAsync(async () => { // 2. 将值 "first" 插入测试表,并等待 2 // 秒 await db.execAsync('INSERT INTO test (data) VALUES ("first")'); await sleep(2000); // 4. 两秒后,读取表中的最新数据 const row = await db.getFirstAsync<{ data: string }>('SELECT data FROM test'); // ❌ 表中的数据将为 "second",此断言会失败。 // 此外,此断言会抛出错误并回滚事务,包括下面的 // `UPDATE` 查询,因为它是在事务中运行的。 expect(row.data).toBe('first'); }), // 3. 一秒后,测试表中的数据被更新为 "second"。 // 尽管这段代码位于事务之外,但由于查询运行时事务恰好处于活动状态, // 这个 `UPDATE` 查询仍会在事务中运行。 sleep(1000).then(async () => db.execAsync('UPDATE test SET data = "second"')), ]);
withExclusiveTransactionAsync() 函数可以解决这个问题。只有在传递给 withExclusiveTransactionAsync() 的作用域函数内运行的查询,才会在实际的 SQL 事务中运行。
执行 PRAGMA 查询
const db = await SQLite.openDatabaseAsync('databaseName'); await db.execAsync('PRAGMA journal_mode = WAL'); await db.execAsync('PRAGMA foreign_keys = ON');
提示: 创建新数据库时启用 WAL 日志模式,通常可以提升性能。
导入现有数据库
要使用已有的 .db 文件打开新的 SQLite 数据库,可以将 SQLiteProvider 与 assetSource 一起使用。
import { SQLiteProvider, useSQLiteContext } from 'expo-sqlite'; import { View, Text, StyleSheet } from 'react-native'; export default function App() { return ( <View style={styles.container}> <SQLiteProvider databaseName="test.db" assetSource={{ assetId: require('./assets/test.db') }}> <Header /> <Content /> </SQLiteProvider> </View> ); }
在应用/扩展之间共享数据库(iOS)
要与同一 App Group 中的其他应用/扩展共享数据库,可以按照以下步骤使用共享容器:
1
在应用配置中配置 App Group:
{ "expo": { "ios": { "bundleIdentifier": "com.myapp", "entitlements": { "com.apple.security.application-groups": ["group.com.myapp"] } } } }
2
使用 expo-file-system 库中的 Paths.appleSharedContainers 获取共享容器的路径:
import { SQLiteProvider, defaultDatabaseDirectory } from 'expo-sqlite'; import { Paths } from 'expo-file-system'; import { useMemo } from 'react'; import { Platform, View } from 'react-native'; export default function App() { const dbDirectory = useMemo(() => { if (Platform.OS === 'ios') { return Object.values(Paths.appleSharedContainers)?.[0]?.uri; // 或使用 `Paths.appleSharedContainers['group.com.myapp']?.uri` 选择特定容器 } return defaultDatabaseDirectory; }, []); return ( <View style={styles.container}> <SQLiteProvider databaseName="test.db" directory={dbDirectory}> <Header /> <Content /> </SQLiteProvider> </View> ); }
传递二进制数据
使用 Uint8Array 向数据库传递二进制数据:
await db.execAsync(` DROP TABLE IF EXISTS blobs; CREATE TABLE IF NOT EXISTS blobs (id INTEGER PRIMARY KEY NOT NULL, data BLOB); `); const blob = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0x04, 0x05]); await db.runAsync('INSERT INTO blobs (data) VALUES (?)', blob); const row = await db.getFirstAsync<{ data: Uint8Array }>('SELECT * FROM blobs'); expect(row.data).toEqual(blob);
浏览设备上的数据库
expo-sqlite 库包含一个内置的 DevTools 检查器插件,该插件在开发环境中会自动启用,无需额外设置。它可以让你直接在浏览器中浏览表、查看和编辑行、运行 SQL 查询,以及导出数据库。要打开它,请在 Expo CLI 终端中按 Shift + M 打开开发工具菜单,然后选择 打开 expo-sqlite 以启动检查器。
此外,你还可以使用 drizzle-studio-expo 开发工具插件 来启动 Drizzle Studio。它连接到应用中的数据库,并可直接从 Expo CLI 启动。此插件可与任何 expo-sqlite 配置搭配使用,不需要安装 Drizzle ORM。了解如何安装和使用此插件。
键值存储
expo-sqlite 库提供了 Storage,可作为 @react-native-async-storage/async-storage 库的直接替代品。此键值存储由 SQLite 提供支持。如果你的项目已经使用了 expo-sqlite,则可以使用 expo-sqlite/kv-store,无需添加其他依赖。
Storage 提供与 @react-native-async-storage/async-storage 相同的 API:
// 存储 API 是默认导出,你可以将其称为 Storage、AsyncStorage,或任何你喜欢的名称。 import Storage from 'expo-sqlite/kv-store'; await Storage.setItem('key', JSON.stringify({ entity: 'value' })); const value = await Storage.getItem('key'); const entity = JSON.parse(value); console.log(entity); // { entity: 'value' }
使用 expo-sqlite/kv-store 的一大好处是增加了同步 API,使用起来更加方便:
// 存储 API 是默认导出,你可以将其称为 Storage、AsyncStorage,或任何你喜欢的名称。 import Storage from 'expo-sqlite/kv-store'; Storage.setItemSync('key', 'value'); const value = Storage.getItemSync('key');
如果你的项目当前使用的是 @react-native-async-storage/async-storage,切换到 expo-sqlite/kv-store 只需更改导入语句:
- import AsyncStorage from '@react-native-async-storage/async-storage'; + import AsyncStorage from 'expo-sqlite/kv-store';
localStorage API
expo-sqlite/localStorage/install 模块提供了 localStorage API 的即插即用实现。如果你已经熟悉 Web 上的此 API,或者希望能够在 Web 和其他平台之间共享存储代码,那么这可能会很有用。要使用它,只需导入 expo-sqlite/localStorage/install 模块:
注意:
import 'expo-sqlite/localStorage/install';在 Web 上是无操作的,并且会从生产环境的 JS 包中排除。
import 'expo-sqlite/localStorage/install'; globalThis.localStorage.setItem('key', 'value'); console.log(globalThis.localStorage.getItem('key')); // 'value'
安全
SQL 注入是一类漏洞,攻击者会诱骗你的应用将用户输入作为 SQL 代码执行。你必须对传递给 SQLite 的所有用户输入进行转义,以防御 SQL 注入。预处理语句是防御此问题的有效方法。它们明确地将 SQL 查询的逻辑与其输入参数分离开来,并且 SQLite 在执行预处理语句时会自动对输入进行转义。
第三方库集成
expo-sqlite 库旨在提供稳健的 SQLite 基础。它支持与第三方库进行更广泛的集成,以实现更高级的功能。以下是一些可以与 expo-sqlite 一起使用的库。
Drizzle ORM
Drizzle 是一个"具有头部的无头 TypeScript ORM"。它可以在 Node.js、Bun、Deno 和 React Native 上运行。它还提供了一个名为 drizzle-kit 的 CLI 配套工具,用于生成 SQL 迁移。
如需了解更多详情,请参阅 Drizzle ORM 文档 和 expo-sqlite 集成指南。
Knex.js
Knex.js 是一个 SQL 查询构建器,"灵活、可移植且使用起来很有趣!"
如需了解更多详情,请参阅 expo-sqlite 集成指南。
SQLCipher
注意: SQLCipher 不支持在 Expo Go 上使用。
SQLCipher 是 SQLite 的一个分支,为数据库添加了加密和身份验证功能。expo-sqlite 库支持在 Android、iOS 和 macOS 上使用 SQLCipher。要使用 SQLCipher,您需要按照应用配置中的配置部分所示,将 useSQLCipher 配置添加到 app.json,然后运行 npx expo prebuild。
打开数据库后,需要立即使用 PRAGMA key = 'password' 语句为数据库设置密码。
const db = await SQLite.openDatabaseAsync('databaseName'); await db.execAsync(`PRAGMA key = 'password'`);
API
常用 API 速查表
下表总结了 SQLiteDatabase 和 SQLiteStatement 类的常用 API:
SQLiteDatabase 方法 | SQLiteStatement 方法 | 描述 | 使用场景 |
|---|---|---|---|
runAsync() | executeAsync() | 执行 SQL 查询,并返回所做更改的信息。 | 适用于 INSERT、UPDATE、DELETE 等 SQL 写操作。 |
getFirstAsync() | executeAsync() + getFirstAsync() | 获取查询结果中的第一行。 | 适用于从数据库中获取单行数据。例如:getFirstAsync('SELECT * FROM Users WHERE id = ?', userId)。 |
getAllAsync() | executeAsync() + getFirstAsync() | 一次性获取所有查询结果。 | 最适合结果集较小的场景,例如带有 LIMIT 子句的查询:SELECT * FROM Table LIMIT 100,即需要一次性获取所有结果。 |
getEachAsync() | executeAsync() + for-await-of 异步迭代器 | 提供用于遍历结果集的迭代器。此方法每次从数据库中获取一行,与 getAllAsync() 相比,可能会减少内存使用量。 | 建议用于增量处理大型结果集,例如实现无限滚动时。 |
Constants
Type: SQLiteStorage
This default instance of the SQLiteStorage class is used as a drop-in replacement for the AsyncStorage module from @react-native-async-storage/async-storage.
Type: Record<string, {
entryPoint: string,
libPath: string
} | undefined>
The pre-bundled SQLite extensions.
Type: MemoExoticComponent<(__namedParameters: SQLiteProviderProps) => Element>
Context.Provider component that provides a SQLite database to all children.
All descendants of this component will be able to access the database using the useSQLiteContext hook.
Type: SQLiteStorage
Alias for AsyncStorage, given the storage not only offers asynchronous methods.
Hooks
A global hook for accessing the SQLite database across components.
This hook should only be used within a <SQLiteProvider> component.
SQLiteDatabaseExample
export default function App() { return ( <SQLiteProvider databaseName="test.db"> <Main /> </SQLiteProvider> ); } export function Main() { const db = useSQLiteContext(); console.log('sqlite version', db.getFirstSync('SELECT sqlite_version()')); return <View /> }
Classes
A SQLite database.
SQLiteDatabase Properties
NativeDatabaseSQLiteOpenOptionsSQLiteDatabase Methods
Close the database.
Promise<void>| Parameter | Type | Description |
|---|---|---|
| dbName(optional) | string | The name of the database to create a session for. The default value is Default: 'main' |
| Parameter | Type | Description |
|---|---|---|
| dbName(optional) | string | The name of the database to create a session for. The default value is Default: 'main' |
Create a new session for the database.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLiteSession| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing all the SQL queries. |
Execute all SQL queries in the supplied string.
Note: The queries are not escaped for you! Be careful when constructing your queries.
Promise<void>| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing all the SQL queries. |
Execute all SQL queries in the supplied string.
Note: The queries are not escaped for you! Be careful when constructing your queries.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
void| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareAsync(), SQLiteStatement.executeAsync(), SQLiteExecuteAsyncResult.getAllAsync(), and SQLiteStatement.finalizeAsync().
Promise<T[]>Example
// For unnamed parameters, you pass values in an array. db.getAllAsync('SELECT * FROM test WHERE intValue = ? AND name = ?', [1, 'Hello']); // For unnamed parameters, you pass values in variadic arguments. db.getAllAsync('SELECT * FROM test WHERE intValue = ? AND name = ?', 1, 'Hello'); // For named parameters, you should pass values in object. db.getAllAsync('SELECT * FROM test WHERE intValue = $intValue AND name = $name', { $intValue: 1, $name: 'Hello' });
| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareSync(), SQLiteStatement.executeSync(), SQLiteExecuteSyncResult.getAllSync(), and SQLiteStatement.finalizeSync().
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
T[]| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareAsync(), SQLiteStatement.executeAsync(), SQLiteExecuteAsyncResult AsyncIterator, and SQLiteStatement.finalizeAsync().
AsyncIterableIterator<T>Rather than returning Promise, this function returns an AsyncIterableIterator. You can use for await...of to iterate over the rows from the SQLite query result.
| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareSync(), SQLiteStatement.executeSync(), SQLiteExecuteSyncResult Iterator, and SQLiteStatement.finalizeSync().
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
IterableIterator<T>This function returns an IterableIterator. You can use for...of to iterate over the rows from the SQLite query result.
| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareAsync(), SQLiteStatement.executeAsync(), SQLiteExecuteAsyncResult.getFirstAsync(), and SQLiteStatement.finalizeAsync().
Promise<T | null>| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareSync(), SQLiteStatement.executeSync(), SQLiteExecuteSyncResult.getFirstSync(), and SQLiteStatement.finalizeSync().
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
T | nullAsynchronous call to return whether the database is currently in a transaction.
Promise<boolean>Synchronous call to return whether the database is currently in a transaction.
boolean| Parameter | Type | Description |
|---|---|---|
| libPath | string | The path to the extension library file. |
| entryPoint(optional) | string | The entry point of the extension. If not provided, the default entry point is inferred by |
Load a SQLite extension.
Promise<void>Example
// Load `sqlite-vec` from `bundledExtensions`. You need to enable `withSQLiteVecExtension` to include `sqlite-vec`. const extension = SQLite.bundledExtensions['sqlite-vec']; await db.loadExtensionAsync(extension.libPath, extension.entryPoint); // You can also load a custom extension. await db.loadExtensionAsync('/path/to/extension');
| Parameter | Type | Description |
|---|---|---|
| libPath | string | The path to the extension library file. |
| entryPoint(optional) | string | The entry point of the extension. If not provided, the default entry point is inferred by |
Load a SQLite extension.
voidExample
// Load `sqlite-vec` from `bundledExtensions`. You need to enable `withSQLiteVecExtension` to include `sqlite-vec`. const extension = SQLite.bundledExtensions['sqlite-vec']; db.loadExtensionSync(extension.libPath, extension.entryPoint); // You can also load a custom extension. db.loadExtensionSync('/path/to/extension');
| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
Create a prepared SQLite statement.
Promise<SQLiteStatement>| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
Create a prepared SQLite statement.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLiteStatement| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareAsync(), SQLiteStatement.executeAsync(), and SQLiteStatement.finalizeAsync().
Promise<SQLiteRunResult>| Parameter | Type | Description |
|---|---|---|
| source | string | A string containing the SQL query. |
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
A convenience wrapper around SQLiteDatabase.prepareSync(), SQLiteStatement.executeSync(), and SQLiteStatement.finalizeSync().
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLiteRunResult| Parameter | Type | Description |
|---|---|---|
| databaseName(optional) | string | The name of the current attached databases. The default value is Default: 'main' |
Serialize the database as Uint8Array.
Promise<Uint8Array<ArrayBufferLike>>| Parameter | Type | Description |
|---|---|---|
| databaseName(optional) | string | The name of the current attached databases. The default value is Default: 'main' |
Serialize the database as Uint8Array.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
Uint8Array| Parameter | Type |
|---|---|
| strings | TemplateStringsArray |
| ...values | unknown[] |
Execute SQL queries using tagged template literals (Bun-style API). Queries are automatically protected against SQL injection using prepared statements.
The query result is directly awaitable and returns an array of objects by default.
Use .values(), .first(), or .each() for different result formats.
SQLiteTaggedQuery<T>Example
// Direct await - returns array of objects const users = await sql<User>`SELECT * FROM users WHERE age > ${21}`; // Get first row only const user = await sql<User>`SELECT * FROM users WHERE id = ${userId}`.first(); // Get values as arrays const rows = await sql`SELECT name, age FROM users`.values(); // Returns: [["Alice", 30], ["Bob", 25]] // INSERT/UPDATE/DELETE - returns SQLiteRunResult const result = await sql`INSERT INTO users (name, age) VALUES (${name}, ${age})` as SQLiteRunResult; console.log('Inserted row:', result.lastInsertRowId); // Iteration for await (const user of db<User>`SELECT * FROM users`.each()) { console.log(user.name); } // Synchronous API const users = sql<User>`SELECT * FROM users WHERE age > ${21}`.allSync(); const user = sql<User>`SELECT * FROM users WHERE id = ${userId}`.firstSync();
Synchronize the local database with the remote libSQL server. This method is only available from libSQL integration.
Promise<void>| Parameter | Type | Description |
|---|---|---|
| task | (txn: Transaction) => Promise<void> | An async function to execute within a transaction. Any queries inside the transaction must be executed on the |
Execute a transaction and automatically commit/rollback based on the task result.
The transaction may be exclusive.
As long as the transaction is converted into a write transaction,
the other async write queries will abort with database is locked error.
Note: This function is not supported on web.
Promise<void>Example
db.withExclusiveTransactionAsync(async (txn) => { await txn.execAsync('UPDATE test SET name = "aaa"'); });
| Parameter | Type | Description |
|---|---|---|
| task | () => Promise<void> | An async function to execute within a transaction. |
Execute a transaction and automatically commit/rollback based on the task result.
Note: This transaction is not exclusive and can be interrupted by other async queries.
Promise<void>Example
db.withTransactionAsync(async () => { await db.execAsync('UPDATE test SET name = "aaa"'); // // We cannot control the order of async/await order, so order of execution is not guaranteed. // The following UPDATE query out of transaction may be executed here and break the expectation. // const result = await db.getFirstAsync<{ name: string }>('SELECT name FROM Users'); expect(result?.name).toBe('aaa'); }); db.execAsync('UPDATE test SET name = "bbb"');
If you worry about the order of execution, use withExclusiveTransactionAsync instead.
| Parameter | Type | Description |
|---|---|---|
| task | () => void | An async function to execute within a transaction. |
Execute a transaction and automatically commit/rollback based on the task result.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
voidA class that represents an instance of the SQLite session extension.
See: Session Extension
SQLiteSession Methods
| Parameter | Type | Description |
|---|---|---|
| changeset | Changeset | The changeset to apply. |
| Parameter | Type | Description |
|---|---|---|
| changeset | Changeset | The changeset to apply. |
Apply a changeset synchronously.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
void| Parameter | Type | Description |
|---|---|---|
| table | string | null | The table to attach. If |
| Parameter | Type | Description |
|---|---|---|
| table | string | null | The table to attach. |
Attach a table to the session synchronously.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
voidClose the session synchronously.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
voidCreate a changeset synchronously.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
ChangesetCreate an inverted changeset asynchronously.
This is a shorthand for createChangesetAsync() + invertChangesetAsync().
Create an inverted changeset synchronously.
This is a shorthand for createChangesetSync() + invertChangesetSync().
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
Changeset| Parameter | Type | Description |
|---|---|---|
| enabled | boolean | Whether to enable or disable the session. |
| Parameter | Type | Description |
|---|---|---|
| enabled | boolean | Whether to enable or disable the session. |
Enable or disable the session synchronously.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
void| Parameter | Type | Description |
|---|---|---|
| changeset | Changeset | The changeset to invert. |
A prepared statement returned by SQLiteDatabase.prepareAsync() or SQLiteDatabase.prepareSync() that can be binded with parameters and executed.
SQLiteStatement Methods
| Parameter | Type | Description |
|---|---|---|
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
Run the prepared statement and return the SQLiteExecuteAsyncResult instance.
Promise<SQLiteExecuteAsyncResult<T>>| Parameter | Type | Description |
|---|---|---|
| params | SQLiteBindParams | The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See |
Run the prepared statement and return the SQLiteExecuteSyncResult instance.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLiteExecuteSyncResult<T>Finalize the prepared statement. This will call the sqlite3_finalize() C function under the hood.
Attempting to access a finalized statement will result in an error.
Note: While
expo-sqlitewill automatically finalize any orphaned prepared statements upon closing the database, it is considered best practice to manually finalize prepared statements as soon as they are no longer needed. This helps to prevent resource leaks. You can use thetry...finallystatement to ensure that prepared statements are finalized even if an error occurs.
Promise<void>Finalize the prepared statement. This will call the sqlite3_finalize() C function under the hood.
Attempting to access a finalized statement will result in an error.
Note: While
expo-sqlitewill automatically finalize any orphaned prepared statements upon closing the database, it is considered best practice to manually finalize prepared statements as soon as they are no longer needed. This helps to prevent resource leaks. You can use thetry...finallystatement to ensure that prepared statements are finalized even if an error occurs.
voidGet the column names of the prepared statement.
Promise<string[]>Key-value store backed by SQLite. This class accepts a databaseName parameter in its constructor, which is the name of the database file to use for the storage.
SQLiteStorage Methods
Alias for clearAsync() method.
Promise<void>Clears all key-value pairs from the storage asynchronously.
Promise<boolean>Alias for closeAsync() method.
Promise<void>Closes the database connection asynchronously.
Promise<void>Alias for getAllKeysAsync() method.
Promise<string[]>Retrieves all keys stored in the storage asynchronously.
Promise<string[]>| Parameter | Type |
|---|---|
| key | string |
Retrieves the value associated with the given key asynchronously.
Promise<string | null>| Parameter | Type |
|---|---|
| key | string |
Retrieves the value associated with the given key synchronously.
string | null| Parameter | Type |
|---|---|
| index | number |
Retrieves the key at the given index asynchronously.
Promise<string | null>| Parameter | Type |
|---|---|
| index | number |
Retrieves the key at the given index synchronously.
string | nullRetrieves the number of key-value pairs stored in the storage asynchronously.
Promise<number>Retrieves the number of key-value pairs stored in the storage synchronously.
number| Parameter | Type |
|---|---|
| key | string |
| value | string |
Merges the given value with the existing value for the given key asynchronously. If the existing value is a JSON object, performs a deep merge.
Promise<void>| Parameter | Type |
|---|---|
| keys | string[] |
Retrieves the values associated with the given keys asynchronously.
Promise<undefined>| Parameter | Type |
|---|---|
| keyValuePairs | undefined |
Merges multiple key-value pairs asynchronously. If existing values are JSON objects, performs a deep merge.
Promise<void>| Parameter | Type |
|---|---|
| keys | string[] |
Removes the values associated with the given keys asynchronously.
Promise<void>| Parameter | Type |
|---|---|
| keyValuePairs | undefined |
Sets multiple key-value pairs asynchronously.
Promise<void>| Parameter | Type |
|---|---|
| key | string |
Removes the value associated with the given key asynchronously.
Promise<boolean>| Parameter | Type |
|---|---|
| key | string |
Removes the value associated with the given key synchronously.
boolean| Parameter | Type |
|---|---|
| key | string |
| value | string | SQLiteStorageSetItemUpdateFunction |
Alias for setItemAsync().
Promise<void>| Parameter | Type |
|---|---|
| key | string |
| value | string | SQLiteStorageSetItemUpdateFunction |
Sets the value for the given key asynchronously. If a function is provided, it computes the new value based on the previous value.
Promise<void>| Parameter | Type |
|---|---|
| key | string |
| value | string | SQLiteStorageSetItemUpdateFunction |
Sets the value for the given key synchronously. If a function is provided, it computes the new value based on the previous value.
voidType: Class implements PromiseLike<SQLiteTaggedQueryResult<T>>
A SQL query with tagged template literals API that can be awaited directly (returns array of objects by default), or transformed using .values() or .first() methods.
This API is inspired by Bun's SQL interface:
Example
// Default: returns array of objects const users = await sql`SELECT * FROM users WHERE age > ${21}`; // Get values as arrays const values = await sql`SELECT name, age FROM users`.values(); // Returns: [["Alice", 30], ["Bob", 25]] // Get first row only const user = await sql`SELECT * FROM users WHERE id = ${1}`.first(); // With type parameter const users = await sql<User>`SELECT * FROM users`; // Mutable queries return SQLiteRunResult const result = await sql`INSERT INTO users (name) VALUES (${"Alice"})` as SQLiteRunResult; console.log(result.lastInsertRowId, result.changes); // Synchronous API const users = sql<User>`SELECT * FROM users WHERE age > ${21}`.allSync(); const user = sql<User>`SELECT * FROM users WHERE id = ${userId}`.firstSync();
SQLiteTaggedQuery Methods
Execute a query synchronously that returns rows or metadata based on query type.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLiteTaggedQueryResult<T>Execute the query and return an async iterator over the rows.
AsyncIterableIterator<T>Example
for await (const user of sql`SELECT * FROM users`.each()) { console.log(user.name); }
Execute the query synchronously and return an iterator.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
IterableIterator<T>Execute the query and return the first row only. Returns null if no rows match.
Promise<T | null>Example
const user = await sql`SELECT * FROM users WHERE id = ${1}`.first();
Execute the query synchronously and return the first row.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
T | nullExecute the query and return rows as arrays of values (Bun-style). Each row is an array where values are in column order.
Promise<any[][]>Example
const rows = await sql`SELECT name, age FROM users`.values(); // Returns: [["Alice", 30], ["Bob", 25]]
Props
SQLiteProviderAssetSourceImport a bundled database file from the specified asset module.
Example
assetSource={{ assetId: require('./assets/db.db') }}
string • Default: defaultDatabaseDirectoryThe directory where the database file is located.
(error: Error) => void • Default: rethrow the errorHandle errors from SQLiteProvider.
(db: SQLiteDatabase) => Promise<void>A custom initialization handler to run before rendering the children. You can use this to run database migrations or other setup tasks.
boolean • Default: falseEnable React.Suspense integration.
Example
export default function App() { return ( <Suspense fallback={<Text>Loading...</Text>}> <SQLiteProvider databaseName="test.db" useSuspense={true}> <Main /> </SQLiteProvider> </Suspense> ); }
Methods
| Parameter | Type | Description |
|---|---|---|
| options | {
destDatabase: SQLiteDatabase,
destDatabaseName: string,
sourceDatabase: SQLiteDatabase,
sourceDatabaseName: string
} | The backup options |
| Parameter | Type | Description |
|---|---|---|
| options | {
destDatabase: SQLiteDatabase,
destDatabaseName: string,
sourceDatabase: SQLiteDatabase,
sourceDatabaseName: string
} | The backup options |
Backup a database to another database.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
void| Parameter | Type |
|---|---|
| a | undefined | undefined |
| b | undefined | undefined |
Compares two objects deeply for equality.
boolean| Parameter | Type | Description |
|---|---|---|
| databaseName | string | The name of the database file to delete. |
| directory(optional) | string | The directory where the database file is located. The default value is |
Delete a database file.
Promise<void>| Parameter | Type | Description |
|---|---|---|
| databaseName | string | The name of the database file to delete. |
| directory(optional) | string | The directory where the database file is located. The default value is |
Delete a database file.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
void| Parameter | Type | Description |
|---|---|---|
| serializedData | Uint8Array | The binary array to deserialize from |
| options(optional) | SQLiteOpenOptions | Open options. |
Given a Uint8Array data and deserialize to memory database.
Promise<SQLiteDatabase>| Parameter | Type | Description |
|---|---|---|
| serializedData | Uint8Array | The binary array to deserialize from |
| options(optional) | SQLiteOpenOptions | Open options. |
Given a Uint8Array data and deserialize to memory database.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLiteDatabase| Parameter | Type | Description |
|---|---|---|
| databaseName | string | The name of the database file to open. |
| options(optional) | SQLiteOpenOptions | Open options. |
| directory(optional) | string | The directory where the database file is located. The default value is |
Open a database.
Promise<SQLiteDatabase>| Parameter | Type | Description |
|---|---|---|
| databaseName | string | The name of the database file to open. |
| options(optional) | SQLiteOpenOptions | Open options. |
| directory(optional) | string | The directory where the database file is located. The default value is |
Open a database.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLiteDatabaseEvent subscriptions
| Parameter | Type | Description |
|---|---|---|
| listener | (event: DatabaseChangeEvent) => void | A function that receives the |
Add a listener for database changes.
Note: to enable this feature, you must set
enableChangeListenertotruewhen opening the database.
EventSubscriptionA Subscription object that you can call remove() on when you would like to unsubscribe the listener.
Interfaces
Extends: AsyncIterableIterator<T>
A result returned by SQLiteStatement.executeAsync().
Example
The result includes the lastInsertRowId and changes properties. You can get the information from the write operations.
const statement = await db.prepareAsync('INSERT INTO test (value) VALUES (?)'); try { const result = await statement.executeAsync(101); console.log('lastInsertRowId:', result.lastInsertRowId); console.log('changes:', result.changes); } finally { await statement.finalizeAsync(); }
Example
The result implements the AsyncIterator interface, so you can use it in for await...of loops.
const statement = await db.prepareAsync('SELECT value FROM test WHERE value > ?'); try { const result = await statement.executeAsync<{ value: number }>(100); for await (const row of result) { console.log('row value:', row.value); } } finally { await statement.finalizeAsync(); }
Example
If your write operations also return values, you can mix all of them together.
const statement = await db.prepareAsync('INSERT INTO test (name, value) VALUES (?, ?) RETURNING name'); try { const result = await statement.executeAsync<{ name: string }>('John Doe', 101); console.log('lastInsertRowId:', result.lastInsertRowId); console.log('changes:', result.changes); for await (const row of result) { console.log('name:', row.name); } } finally { await statement.finalizeAsync(); }
| Property | Type | Description |
|---|---|---|
| changes | number | The number of rows affected. Returned from the |
| lastInsertRowId | number | The last inserted row ID. Returned from the |
SQLiteExecuteAsyncResult Methods
Get all rows of the result set. This requires the SQLite cursor to be in its initial state. If you have already retrieved rows from the result set, you need to reset the cursor first by calling resetAsync(). Otherwise, an error will be thrown.
Promise<T[]>Get the first row of the result set. This requires the SQLite cursor to be in its initial state. If you have already retrieved rows from the result set, you need to reset the cursor first by calling resetAsync(). Otherwise, an error will be thrown.
Promise<T | null>Reset the prepared statement cursor. This will call the sqlite3_reset() C function under the hood.
Promise<void>Extends: IterableIterator<T>
A result returned by SQLiteStatement.executeSync().
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
Example
The result includes the lastInsertRowId and changes properties. You can get the information from the write operations.
const statement = db.prepareSync('INSERT INTO test (value) VALUES (?)'); try { const result = statement.executeSync(101); console.log('lastInsertRowId:', result.lastInsertRowId); console.log('changes:', result.changes); } finally { statement.finalizeSync(); }
Example
The result implements the Iterator interface, so you can use it in for...of loops.
const statement = db.prepareSync('SELECT value FROM test WHERE value > ?'); try { const result = statement.executeSync<{ value: number }>(100); for (const row of result) { console.log('row value:', row.value); } } finally { statement.finalizeSync(); }
Example
If your write operations also return values, you can mix all of them together.
const statement = db.prepareSync('INSERT INTO test (name, value) VALUES (?, ?) RETURNING name'); try { const result = statement.executeSync<{ name: string }>('John Doe', 101); console.log('lastInsertRowId:', result.lastInsertRowId); console.log('changes:', result.changes); for (const row of result) { console.log('name:', row.name); } } finally { statement.finalizeSync(); }
| Property | Type | Description |
|---|---|---|
| changes | number | The number of rows affected. Returned from the |
| lastInsertRowId | number | The last inserted row ID. Returned from the |
SQLiteExecuteSyncResult Methods
Get all rows of the result set. This requires the SQLite cursor to be in its initial state. If you have already retrieved rows from the result set, you need to reset the cursor first by calling resetSync(). Otherwise, an error will be thrown.
T[]Get the first row of the result set. This requires the SQLite cursor to be in its initial state. If you have already retrieved rows from the result set, you need to reset the cursor first by calling resetSync(). Otherwise, an error will be thrown.
T | nullReset the prepared statement cursor. This will call the sqlite3_reset() C function under the hood.
voidOptions for opening a database.
| Property | Type | Description |
|---|---|---|
| enableChangeListener(optional) | boolean | Whether to call the Default: false |
| libSQLOptions(optional) | {
authToken: string,
remoteOnly: boolean,
url: string
} | Options for libSQL integration. |
| useNewConnection(optional) | boolean | Whether to create new connection even if connection with the same database name exists in cache. Default: false |
| Property | Type | Description |
|---|---|---|
| assetId | number | The asset ID returned from the |
| forceOverwrite(optional) | boolean | Force overwrite the local database file even if it already exists. Default: false |
A result returned by SQLiteDatabase.runAsync or SQLiteDatabase.runSync.
| Property | Type | Description |
|---|---|---|
| changes | number | The number of rows affected. Returned from the |
| lastInsertRowId | number | The last inserted row ID. Returned from the |
Types
The event payload for the listener of addDatabaseChangeListener
| Property | Type | Description |
|---|---|---|
| databaseFilePath | string | The absolute file path to the database. |
| databaseName | string | The database name. The value would be |
| rowId | number | The changed row ID. |
| tableName | string | The table name. |
Literal type: union
Bind parameters to the prepared statement. You can either pass the parameters in the following forms:
Example
A single array for unnamed parameters.
const statement = await db.prepareAsync('SELECT * FROM test WHERE value = ? AND intValue = ?'); const result = await statement.executeAsync(['test1', 789]); const firstRow = await result.getFirstAsync();
Example
Variadic arguments for unnamed parameters.
const statement = await db.prepareAsync('SELECT * FROM test WHERE value = ? AND intValue = ?'); const result = await statement.executeAsync('test1', 789); const firstRow = await result.getFirstAsync();
Example
A single object for named parameters
We support multiple named parameter forms such as :VVV, @VVV, and $VVV. We recommend using $VVV because JavaScript allows using $ in identifiers without escaping.
const statement = await db.prepareAsync('SELECT * FROM test WHERE value = $value AND intValue = $intValue'); const result = await statement.executeAsync({ $value: 'test1', $intValue: 789 }); const firstRow = await result.getFirstAsync();
Acceptable values are: string | number | null | boolean | SQLiteBindBlobValue
Update function for the setItemAsync() or setItemSync() method. It computes the new value based on the previous value. The function returns the new value to set for the key.
| Parameter | Type | Description |
|---|---|---|
| prevValue | string | null | The previous value associated with the key, or |
string
Type: SQLiteBindValue[]