提供对可通过 SQLite API 查询的数据库的访问的库。
expo-sqlite
使你的应用可以访问可通过 SQLite API 查询的数据库。数据库在应用重新启动后保留。
¥expo-sqlite
gives your app access to a database that can be queried through a SQLite API. The database is persisted across restarts of your app.
¥Installation
-
npx expo install expo-sqlite
If you are installing this in an existing React Native app (bare workflow), start by installing expo
in your project. Then, follow the additional instructions as mentioned by library's README under "Installation in bare React Native projects" section.
¥Usage
从 expo-sqlite
导入模块。
¥Import the module from expo-sqlite
.
import * as SQLite from 'expo-sqlite';
¥Basic CRUD operations
const db = await SQLite.openDatabaseAsync('databaseName');
// `execAsync()` is useful for bulk queries when you want to execute altogether.
// Please note that `execAsync()` does not escape parameters and may lead to SQL injection.
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()` is useful when you want to execute some write operations.
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'); // Binding unnamed parameters from variadic arguments
await db.runAsync('UPDATE test SET intValue = ? WHERE value = ?', [999, 'aaa']); // Binding unnamed parameters from array
await db.runAsync('DELETE FROM test WHERE value = $value', { $value: 'aaa' }); // Binding named parameters from object
// `getFirstAsync()` is useful when you want to get a single row from the database.
const firstRow = await db.getFirstAsync('SELECT * FROM test');
console.log(firstRow.id, firstRow.value, firstRow.intValue);
// `getAllAsync()` is useful when you want to get all results as an array of objects.
const allRows = await db.getAllAsync('SELECT * FROM test');
for (const row of allRows) {
console.log(row.id, row.value, row.intValue);
}
// `getEachAsync()` is useful when you want to iterate SQLite query cursor.
for await (const row of db.getEachAsync('SELECT * FROM test')) {
console.log(row.id, row.value, row.intValue);
}
¥Prepared statements
预准备语句允许你编译 SQL 查询一次并使用不同的参数执行多次。你可以通过在数据库实例上调用 prepareAsync()
或 prepareSync()
方法来获取准备好的语句。准备好的语句可以通过调用 executeAsync()
或 executeSync()
方法来完成 CRUD 操作。
¥Prepared statement allows you compile your SQL query once and execute it multiple times with different parameters. You can get a prepared statement by calling prepareAsync()
or prepareSync()
method on a database instance. The prepared statement can fulfill CRUD operations by calling executeAsync()
or executeSync()
method.
注意:使用完语句后记得调用
finalizeAsync()
或finalizeSync()
方法来释放 prepared 语句。建议使用try-finally
块以确保准备好的语句最终确定。¥Note: Remember to call
finalizeAsync()
orfinalizeSync()
method to release the prepared statement after you finish using the statement.try-finally
block is recommended to ensure the prepared statement is finalized.
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()` is useful when you want to get a single row from the database.
const firstRow = await result.getFirstAsync();
console.log(firstRow.id, firstRow.value, firstRow.intValue);
// Reset the SQLite query cursor to the beginning for the next `getAllAsync()` call.
await result.resetAsync();
// `getAllAsync()` is useful when you want to get all results as an array of objects.
const allRows = await result.getAllAsync();
for (const row of allRows) {
console.log(row.value, row.intValue);
}
// Reset the SQLite query cursor to the beginning for the next `for-await-of` loop.
await result.resetAsync();
// The result object is also an async iterable. You can use it in `for-await-of` loop to iterate SQLite query cursor.
for await (const row of result) {
console.log(row.value, row.intValue);
}
} finally {
await statement2.finalizeAsync();
}
useSQLiteContext()
钩¥useSQLiteContext()
hook
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;
}
// if (currentDbVersion === 1) {
// Add more migrations
// }
await db.execAsync(`PRAGMA user_version = ${DATABASE_VERSION}`);
}
const styles = StyleSheet.create({
// Your styles...
});
useSQLiteContext()
钩子与 React.Suspense
¥useSQLiteContext()
hook with React.Suspense
与 useSQLiteContext()
钩子一样,你还可以将 SQLiteProvider
与 React.Suspense
集成以显示后备组件,直到数据库准备就绪。要启用集成,请将 useSuspense
属性传递给 SQLiteProvider
组件。
¥As with the useSQLiteContext()
hook, you can also integrate the SQLiteProvider
with React.Suspense
to show a fallback component until the database is ready. To enable the integration, pass the useSuspense
prop to the SQLiteProvider
component.
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>
);
}
¥Executing queries within an async transaction
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()
的作用域函数内部和外部运行查询。但是,所有查询都将在实际 SQL 事务中运行,因为第二个 UPDATE
查询在事务完成之前运行。
¥Due to the nature of async/await, any query that runs while the transaction is active will be included in the transaction. This includes query statements that are outside of the scope function passed to withTransactionAsync()
and may be surprising behavior. For example, the following test case runs queries inside and outside of a scope function passed to withTransactionAsync()
. However, all of the queries will run within the actual SQL transaction because the second UPDATE
query runs before the transaction finishes.
Promise.all([
// 1. A new transaction begins
db.withTransactionAsync(async () => {
// 2. The value "first" is inserted into the test table and we wait 2
// seconds
await db.execAsync('INSERT INTO test (data) VALUES ("first")');
await sleep(2000);
// 4. Two seconds in, we read the latest data from the table
const row = await db.getFirstAsync<{ data: string }>('SELECT data FROM test');
// ❌ The data in the table will be "second" and this expectation will fail.
// Additionally, this expectation will throw an error and roll back the
// transaction, including the `UPDATE` query below since it ran within
// the transaction.
expect(row.data).toBe('first');
}),
// 3. One second in, the data in the test table is updated to be "second".
// This `UPDATE` query runs in the transaction even though its code is
// outside of it because the transaction happens to be active at the time
// this query runs.
sleep(1000).then(async () => db.execAsync('UPDATE test SET data = "second"')),
]);
withExclusiveTransactionAsync()
函数解决了这个问题。只有在传递给 withExclusiveTransactionAsync()
的范围函数内运行的查询才会在实际 SQL 事务中运行。
¥The withExclusiveTransactionAsync()
function addresses this. Only queries that run within the scope function passed to withExclusiveTransactionAsync()
will run within the actual SQL transaction.
¥Executing PRAGMA queries
const db = await SQLite.openDatabaseAsync('databaseName');
await db.execAsync('PRAGMA journal_mode = WAL');
await db.execAsync('PRAGMA foreign_keys = ON');
提示:创建新数据库时启用 WAL 日志模式 以提高总体性能。
¥Import an existing database
要使用你已有的现有 .db 文件打开新的 SQLite 数据库,你可以将 SQLiteProvider
与 assetSource
一起使用。
¥To open a new SQLite database using an existing .db file you already have, you can use the SQLiteProvider
with 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>
);
}
¥Passing binary data
使用 Uint8Array
将二进制数据传递到数据库:
¥Use Uint8Array
to pass binary data to the database:
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);
¥Browse an on-device database
你可以检查数据库,对其执行查询,并使用 drizzle-studio-expo 开发工具插件 探索数据。此插件使你能够直接从 Expo CLI 启动连接到应用中数据库的 Drizzle Studio。此插件可与任何 expo-sqlite
配置一起使用。它不需要你在应用中使用 毛毛雨 ORM。学习如何安装和使用插件。
¥You can inspect a database, execute queries against it, and explore data with the drizzle-studio-expo dev tools plugin. This plugin enables you to launch Drizzle Studio, connected to a database in your app, directly from Expo CLI. This plugin can be used with any expo-sqlite
configuration. It does not require that you use Drizzle ORM in your app. Learn how to install and use the plugin.
¥Third-party library integrations
expo-sqlite
库被设计为坚实的 SQLite 基础。它可以与第三方库进行更广泛的集成,以获得更高级的高级功能。以下是一些可以与 expo-sqlite
一起使用的库。
¥The expo-sqlite
library is designed to be a solid SQLite foundation. It enables broader integrations with third-party libraries for more advanced higher-level features. Here are some of the libraries that you can use with expo-sqlite
.
¥Drizzle ORM
细雨 是 "有头的无头 TypeScript ORM"。它运行在 Node.js、Bun、Deno 和 React Native 上。它还有一个名为 drizzle-kit
的 CLI 伴侣,用于生成 SQL 迁移。
¥Drizzle is a "headless TypeScript ORM with a head". It runs on Node.js, Bun, Deno, and React Native. It also has a CLI companion called drizzle-kit
for generating SQL migrations.
查看 细雨 ORM 文档 和 expo-sqlite
集成指南 了解更多详细信息。
¥Check out the Drizzle ORM documentation and the expo-sqlite
integration guide for more details.
Knex.js 是一个 SQL 查询构建器,"灵活、便携且使用起来充满乐趣!"
¥Knex.js is a SQL query builder that is "flexible, portable, and fun to use!"
查看 expo-sqlite
集成指南 了解更多详细信息。
¥Check out the expo-sqlite
integration guide for more details.
¥Cheatsheet for the common API
下表总结了 SQLiteDatabase
和 SQLiteStatement
类的通用 API:
¥The following table summarizes the common API for SQLiteDatabase
and SQLiteStatement
classes:
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() 相比,可能会减少内存使用量。 | 建议用于增量处理大型结果集,例如无限滚动实现。 |
SQLiteProvider
Type: React.Element<SQLiteProviderProps>
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.
assetSource
Optional • Type: SQLiteProviderAssetSource
Import a bundled database file from the specified asset module.
Example
assetSource={{ assetId: require('./assets/db.db') }}
onError
Optional • Type: (error: Error) => void
• Default: rethrow the error
Handle errors from SQLiteProvider.
onInit
Optional • Type: (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.
useSuspense
Optional • Type: boolean
• Default: false
Enable React.Suspense
integration.
Example
export default function App() {
return (
<Suspense fallback={<Text>Loading...</Text>}>
<SQLiteProvider databaseName="test.db" useSuspense={true}>
<Main />
</SQLiteProvider>
</Suspense>
);
}
useSQLiteContext()
A global hook for accessing the SQLite database across components.
This hook should only be used within a <SQLiteProvider>
component.
Example
export default function App() {
return (
<SQLiteProvider databaseName="test.db">
<Main />
</SQLiteProvider>
);
}
export function Main() {
const db = useSQLiteContext();
console.log('sqlite version', db.getSync('SELECT sqlite_version()'));
return <View />
}
SQLiteDatabase
A SQLite database.
SQLiteDatabase Properties
databaseName
Type: string
options
Type: SQLiteOpenOptions
SQLiteDatabase Methods
execAsync(source)
Name | 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>
execSync(source)
Name | 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
getAllAsync<T>(source, params)
Name | 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' });
getAllSync<T>(source, params)
Name | 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[]
getEachAsync<T>(source, params)
Name | 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()
.
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.
getEachSync<T>(source, params)
Name | 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.
This function returns an IterableIterator
. You can use for...of
to iterate over the rows from the SQLite query result.
getFirstAsync<T>(source, params)
Name | 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<null | T>
getFirstSync<T>(source, params)
Name | 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.
null | T
isInTransactionAsync()
Asynchronous call to return whether the database is currently in a transaction.
Promise<boolean>
isInTransactionSync()
Synchronous call to return whether the database is currently in a transaction.
boolean
prepareAsync(source)
Name | Type | Description |
---|---|---|
source | string | A string containing the SQL query. |
Create a prepared SQLite statement.
prepareSync(source)
Name | 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.
runAsync(source, params)
Name | 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()
.
runSync(source, params)
Name | 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.
serializeAsync(databaseName)
Name | 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>
serializeSync(databaseName)
Name | 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
withExclusiveTransactionAsync(task)
Name | 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.
Promise<void>
Example
db.withExclusiveTransactionAsync(async (txn) => {
await txn.execAsync('UPDATE test SET name = "aaa"');
});
withTransactionAsync(task)
Name | 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.getAsync<{ 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.
withTransactionSync(task)
Name | 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.
void
SQLiteStatement
A prepared statement returned by SQLiteDatabase.prepareAsync()
or SQLiteDatabase.prepareSync()
that can be binded with parameters and executed.
SQLiteStatement Methods
executeAsync<T>(params)
Name | 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.
executeSync<T>(params)
Name | 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.
finalizeAsync()
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-sqlite will 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 the
try...finally
statement to ensure that prepared statements are finalized even if an error occurs.
Promise<void>
finalizeSync()
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-sqlite will 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 the
try...finally
statement to ensure that prepared statements are finalized even if an error occurs.
void
SQLite.deleteDatabaseAsync(databaseName)
Name | Type | Description |
---|---|---|
databaseName | string | The name of the database file to delete. |
Delete a database file.
Promise<void>
SQLite.deleteDatabaseSync(databaseName)
Name | Type | Description |
---|---|---|
databaseName | string | The name of the database file to delete. |
Delete a database file.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
void
SQLite.deserializeDatabaseAsync(serializedData, options)
Name | Type | Description |
---|---|---|
serializedData | Uint8Array | The binary array to deserialize from |
options (optional) | SQLiteOpenOptions | Open options. |
Given a Uint8Array
data and deserialize to memory database.
SQLite.deserializeDatabaseSync(serializedData, options)
Name | 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.
SQLite.openDatabaseAsync(databaseName, options)
Name | Type | Description |
---|---|---|
databaseName | string | The name of the database file to open. |
options (optional) | SQLiteOpenOptions | Open options. |
Open a database.
SQLite.openDatabaseSync(databaseName, options)
Name | Type | Description |
---|---|---|
databaseName | string | The name of the database file to open. |
options (optional) | SQLiteOpenOptions | Open options. |
Open a database.
Note: Running heavy tasks with this function can block the JavaScript thread and affect performance.
SQLite.addDatabaseChangeListener(listener)
Name | 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
enableChangeListener
totrue
when opening the database.
A Subscription
object that you can call remove()
on when you would like to unsubscribe the listener.
SQLiteExecuteAsyncResult
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();
}
SQLiteExecuteAsyncResult Methods
getAllAsync()
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[]>
getFirstAsync()
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<null | T>
resetAsync()
Reset the prepared statement cursor. This will call the sqlite3_reset()
C function under the hood.
Promise<void>
SQLiteExecuteAsyncResult Properties
Name | Type | Description |
---|---|---|
changes | number | The number of rows affected. Returned from the |
lastInsertRowId | number | The last inserted row ID. Returned from the |
SQLiteExecuteSyncResult
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();
}
SQLiteExecuteSyncResult Methods
getAllSync()
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[]
getFirstSync()
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.
null | T
resetSync()
Reset the prepared statement cursor. This will call the sqlite3_reset()
C function under the hood.
void
SQLiteExecuteSyncResult Properties
Name | Type | Description |
---|---|---|
changes | number | The number of rows affected. Returned from the |
lastInsertRowId | number | The last inserted row ID. Returned from the |
SQLiteOpenOptions
Options for opening a database.
SQLiteOpenOptions Properties
Name | Type | Description |
---|---|---|
enableCRSQLite (optional) | boolean | Whether to enable the CR-SQLite extension. Default: false |
enableChangeListener (optional) | boolean | Whether to call the Default: false |
useNewConnection (optional) | boolean | Whether to create new connection even if connection with the same database name exists in cache. Default: false |
SQLiteProviderAssetSource
SQLiteProviderAssetSource Properties
Name | 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 |
SQLiteRunResult
A result returned by SQLiteDatabase.runAsync
or SQLiteDatabase.runSync
.
SQLiteRunResult Properties
Name | Type | Description |
---|---|---|
changes | number | The number of rows affected. Returned from the |
lastInsertRowId | number | The last inserted row ID. Returned from the |
DatabaseChangeEvent
The event payload for the listener of addDatabaseChangeListener
Name | 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. |
SQLiteBindValue
Literal Type: multiple types
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
| Uint8Array