expo-sqlite 12.2.1 → 13.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/android/CMakeLists.txt +1 -1
- package/android/build.gradle +2 -2
- package/android/src/main/cpp/NativeDatabaseBinding.cpp +4 -4
- package/android/src/main/cpp/NativeDatabaseBinding.h +2 -2
- package/android/src/main/cpp/NativeStatementBinding.cpp +22 -15
- package/android/src/main/cpp/NativeStatementBinding.h +1 -0
- package/android/src/main/java/expo/modules/sqlite/NativeDatabase.kt +3 -1
- package/android/src/main/java/expo/modules/sqlite/NativeDatabaseBinding.kt +4 -4
- package/android/src/main/java/expo/modules/sqlite/NativeStatement.kt +2 -0
- package/android/src/main/java/expo/modules/sqlite/NativeStatementBinding.kt +5 -4
- package/android/src/main/java/expo/modules/sqlite/SQLExceptions.kt +6 -0
- package/android/src/main/java/expo/modules/sqlite/SQLiteModule.kt +21 -21
- package/android/src/main/java/expo/modules/sqlite/SQLiteModuleNext.kt +122 -132
- package/build/next/ExpoSQLiteNext.d.ts +4 -4
- package/build/next/ExpoSQLiteNext.d.ts.map +1 -1
- package/build/next/ExpoSQLiteNext.js +3 -3
- package/build/next/ExpoSQLiteNext.js.map +1 -1
- package/build/next/NativeDatabase.d.ts +3 -3
- package/build/next/NativeDatabase.d.ts.map +1 -1
- package/build/next/NativeDatabase.js.map +1 -1
- package/build/next/NativeStatement.d.ts +37 -35
- package/build/next/NativeStatement.d.ts.map +1 -1
- package/build/next/NativeStatement.js.map +1 -1
- package/build/next/SQLiteDatabase.d.ts +266 -0
- package/build/next/SQLiteDatabase.d.ts.map +1 -0
- package/build/next/{Database.js → SQLiteDatabase.js} +69 -59
- package/build/next/SQLiteDatabase.js.map +1 -0
- package/build/next/SQLiteStatement.d.ts +190 -0
- package/build/next/SQLiteStatement.d.ts.map +1 -0
- package/build/next/SQLiteStatement.js +275 -0
- package/build/next/SQLiteStatement.js.map +1 -0
- package/build/next/hooks.d.ts +26 -14
- package/build/next/hooks.d.ts.map +1 -1
- package/build/next/hooks.js +121 -33
- package/build/next/hooks.js.map +1 -1
- package/build/next/index.d.ts +2 -2
- package/build/next/index.d.ts.map +1 -1
- package/build/next/index.js +2 -2
- package/build/next/index.js.map +1 -1
- package/build/next/paramUtils.d.ts +18 -0
- package/build/next/paramUtils.d.ts.map +1 -0
- package/build/next/paramUtils.js +72 -0
- package/build/next/paramUtils.js.map +1 -0
- package/ios/Exceptions.swift +12 -0
- package/ios/NativeDatabase.swift +4 -3
- package/ios/NativeStatement.swift +1 -0
- package/ios/SQLiteModule.swift +20 -21
- package/ios/SQLiteModuleNext.swift +126 -131
- package/ios/crsqlite.xcframework/Info.plist +4 -0
- package/ios/crsqlite.xcframework/ios-arm64/crsqlite.framework/Info.plist +4 -0
- package/package.json +4 -3
- package/src/next/ExpoSQLiteNext.ts +4 -4
- package/src/next/NativeDatabase.ts +3 -3
- package/src/next/NativeStatement.ts +43 -48
- package/src/next/{Database.ts → SQLiteDatabase.ts} +134 -112
- package/src/next/SQLiteStatement.ts +528 -0
- package/src/next/hooks.tsx +202 -51
- package/src/next/index.ts +2 -2
- package/src/next/paramUtils.ts +94 -0
- package/build/next/Database.d.ts +0 -272
- package/build/next/Database.d.ts.map +0 -1
- package/build/next/Database.js.map +0 -1
- package/build/next/Statement.d.ts +0 -142
- package/build/next/Statement.d.ts.map +0 -1
- package/build/next/Statement.js +0 -184
- package/build/next/Statement.js.map +0 -1
- package/src/next/Statement.ts +0 -310
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SQLiteDatabase.js","sourceRoot":"","sources":["../../src/next/SQLiteDatabase.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter, Subscription } from 'expo-modules-core';\n\nimport ExpoSQLite from './ExpoSQLiteNext';\nimport { NativeDatabase, SQLiteOpenOptions } from './NativeDatabase';\nimport {\n SQLiteBindParams,\n SQLiteExecuteAsyncResult,\n SQLiteExecuteSyncResult,\n SQLiteRunResult,\n SQLiteStatement,\n SQLiteVariadicBindParams,\n} from './SQLiteStatement';\n\nexport { SQLiteOpenOptions };\n\nconst emitter = new EventEmitter(ExpoSQLite);\n\n/**\n * A SQLite database.\n */\nexport class SQLiteDatabase {\n constructor(\n public readonly databaseName: string,\n public readonly options: SQLiteOpenOptions,\n private readonly nativeDatabase: NativeDatabase\n ) {}\n\n /**\n * Asynchronous call to return whether the database is currently in a transaction.\n */\n public isInTransactionAsync(): Promise<boolean> {\n return this.nativeDatabase.isInTransactionAsync();\n }\n\n /**\n * Close the database.\n */\n public closeAsync(): Promise<void> {\n return this.nativeDatabase.closeAsync();\n }\n\n /**\n * Execute all SQL queries in the supplied string.\n * > Note: The queries are not escaped for you! Be careful when constructing your queries.\n *\n * @param source A string containing all the SQL queries.\n */\n public execAsync(source: string): Promise<void> {\n return this.nativeDatabase.execAsync(source);\n }\n\n /**\n * Create a [prepared SQLite statement](https://www.sqlite.org/c3ref/prepare.html).\n *\n * @param source A string containing the SQL query.\n */\n public async prepareAsync(source: string): Promise<SQLiteStatement> {\n const nativeStatement = new ExpoSQLite.NativeStatement();\n await this.nativeDatabase.prepareAsync(nativeStatement, source);\n return new SQLiteStatement(this.nativeDatabase, nativeStatement);\n }\n\n /**\n * Execute a transaction and automatically commit/rollback based on the `task` result.\n *\n * > **Note:** This transaction is not exclusive and can be interrupted by other async queries.\n * @example\n * ```ts\n * db.withTransactionAsync(async () => {\n * await db.execAsync('UPDATE test SET name = \"aaa\"');\n *\n * //\n * // We cannot control the order of async/await order, so order of execution is not guaranteed.\n * // The following UPDATE query out of transaction may be executed here and break the expectation.\n * //\n *\n * const result = await db.getAsync<{ name: string }>('SELECT name FROM Users');\n * expect(result?.name).toBe('aaa');\n * });\n * db.execAsync('UPDATE test SET name = \"bbb\"');\n * ```\n * If you worry about the order of execution, use `withExclusiveTransactionAsync` instead.\n *\n * @param task An async function to execute within a transaction.\n */\n public async withTransactionAsync(task: () => Promise<void>): Promise<void> {\n try {\n await this.execAsync('BEGIN');\n await task();\n await this.execAsync('COMMIT');\n } catch (e) {\n await this.execAsync('ROLLBACK');\n throw e;\n }\n }\n\n /**\n * Execute a transaction and automatically commit/rollback based on the `task` result.\n *\n * The transaction may be exclusive.\n * As long as the transaction is converted into a write transaction,\n * the other async write queries will abort with `database is locked` error.\n *\n * @param task An async function to execute within a transaction. Any queries inside the transaction must be executed on the `txn` object.\n * The `txn` object has the same interfaces as the [`SQLiteDatabase`](#sqlitedatabase) object. You can use `txn` like a [`SQLiteDatabase`](#sqlitedatabase) object.\n *\n * @example\n * ```ts\n * db.withExclusiveTransactionAsync(async (txn) => {\n * await txn.execAsync('UPDATE test SET name = \"aaa\"');\n * });\n * ```\n */\n public async withExclusiveTransactionAsync(\n task: (txn: Transaction) => Promise<void>\n ): Promise<void> {\n const transaction = await Transaction.createAsync(this);\n let error;\n try {\n await transaction.execAsync('BEGIN');\n await task(transaction);\n await transaction.execAsync('COMMIT');\n } catch (e) {\n await transaction.execAsync('ROLLBACK');\n error = e;\n } finally {\n await transaction.closeAsync();\n }\n if (error) {\n throw error;\n }\n }\n\n /**\n * Synchronous call to return whether the database is currently in a transaction.\n */\n public isInTransactionSync(): boolean {\n return this.nativeDatabase.isInTransactionSync();\n }\n\n /**\n * Close the database.\n */\n public closeSync(): void {\n return this.nativeDatabase.closeSync();\n }\n\n /**\n * Execute all SQL queries in the supplied string.\n *\n * > **Note:** The queries are not escaped for you! Be careful when constructing your queries.\n *\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n *\n * @param source A string containing all the SQL queries.\n */\n public execSync(source: string): void {\n return this.nativeDatabase.execSync(source);\n }\n\n /**\n * Create a [prepared SQLite statement](https://www.sqlite.org/c3ref/prepare.html).\n *\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n *\n * @param source A string containing the SQL query.\n */\n public prepareSync(source: string): SQLiteStatement {\n const nativeStatement = new ExpoSQLite.NativeStatement();\n this.nativeDatabase.prepareSync(nativeStatement, source);\n return new SQLiteStatement(this.nativeDatabase, nativeStatement);\n }\n\n /**\n * Execute a transaction and automatically commit/rollback based on the `task` result.\n *\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n *\n * @param task An async function to execute within a transaction.\n */\n public withTransactionSync(task: () => void): void {\n try {\n this.execSync('BEGIN');\n task();\n this.execSync('COMMIT');\n } catch (e) {\n this.execSync('ROLLBACK');\n throw e;\n }\n }\n\n //#region Statement API shorthands\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource), [`SQLiteStatement.executeAsync()`](#executeasyncparams), and [`SQLiteStatement.finalizeAsync()`](#finalizeasync).\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n */\n public runAsync(source: string, params: SQLiteBindParams): Promise<SQLiteRunResult>;\n\n /**\n * @hidden\n */\n public runAsync(source: string, ...params: SQLiteVariadicBindParams): Promise<SQLiteRunResult>;\n public async runAsync(source: string, ...params: any[]): Promise<SQLiteRunResult> {\n const statement = await this.prepareAsync(source);\n let result: SQLiteExecuteAsyncResult<unknown>;\n try {\n result = await statement.executeAsync(...params);\n } finally {\n await statement.finalizeAsync();\n }\n return result;\n }\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource), [`SQLiteStatement.executeAsync()`](#executeasyncparams), [`SQLiteExecuteAsyncResult.getFirstAsync()`](#getfirstasync), and [`SQLiteStatement.finalizeAsync()`](#finalizeasync).\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n */\n public getFirstAsync<T>(source: string, params: SQLiteBindParams): Promise<T | null>;\n /**\n * @hidden\n */\n public getFirstAsync<T>(source: string, ...params: SQLiteVariadicBindParams): Promise<T | null>;\n public async getFirstAsync<T>(source: string, ...params: any[]): Promise<T | null> {\n const statement = await this.prepareAsync(source);\n let firstRow: T | null;\n try {\n const result = await statement.executeAsync<T>(...params);\n firstRow = await result.getFirstAsync();\n } finally {\n await statement.finalizeAsync();\n }\n return firstRow;\n }\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource), [`SQLiteStatement.executeAsync()`](#executeasyncparams), [`SQLiteExecuteAsyncResult`](#sqliteexecuteasyncresult) `AsyncIterator`, and [`SQLiteStatement.finalizeAsync()`](#finalizeasync).\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n * @returns Rather than returning Promise, this function returns an [`AsyncIterableIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncIterator). You can use `for await...of` to iterate over the rows from the SQLite query result.\n */\n public getEachAsync<T>(source: string, params: SQLiteBindParams): AsyncIterableIterator<T>;\n /**\n * @hidden\n */\n public getEachAsync<T>(\n source: string,\n ...params: SQLiteVariadicBindParams\n ): AsyncIterableIterator<T>;\n public async *getEachAsync<T>(source: string, ...params: any[]): AsyncIterableIterator<T> {\n const statement = await this.prepareAsync(source);\n try {\n const result = await statement.executeAsync<T>(...params);\n for await (const row of result) {\n yield row;\n }\n } finally {\n await statement.finalizeAsync();\n }\n }\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource), [`SQLiteStatement.executeAsync()`](#executeasyncparams), [`SQLiteExecuteAsyncResult.getAllAsync()`](#getallasync), and [`SQLiteStatement.finalizeAsync()`](#finalizeasync).\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n * @example\n * ```ts\n * // For unnamed parameters, you pass values in an array.\n * db.getAllAsync('SELECT * FROM test WHERE intValue = ? AND name = ?', [1, 'Hello']);\n *\n * // For unnamed parameters, you pass values in variadic arguments.\n * db.getAllAsync('SELECT * FROM test WHERE intValue = ? AND name = ?', 1, 'Hello');\n *\n * // For named parameters, you should pass values in object.\n * db.getAllAsync('SELECT * FROM test WHERE intValue = $intValue AND name = $name', { $intValue: 1, $name: 'Hello' });\n * ```\n */\n public getAllAsync<T>(source: string, params: SQLiteBindParams): Promise<T[]>;\n /**\n * @hidden\n */\n public getAllAsync<T>(source: string, ...params: SQLiteVariadicBindParams): Promise<T[]>;\n public async getAllAsync<T>(source: string, ...params: any[]): Promise<T[]> {\n const statement = await this.prepareAsync(source);\n let allRows;\n try {\n const result = await statement.executeAsync<T>(...params);\n allRows = await result.getAllAsync();\n } finally {\n await statement.finalizeAsync();\n }\n return allRows;\n }\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareSync()`](#preparesyncsource), [`SQLiteStatement.executeSync()`](#executesyncparams), and [`SQLiteStatement.finalizeSync()`](#finalizesync).\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n */\n public runSync(source: string, params: SQLiteBindParams): SQLiteRunResult;\n /**\n * @hidden\n */\n public runSync(source: string, ...params: SQLiteVariadicBindParams): SQLiteRunResult;\n public runSync(source: string, ...params: any[]): SQLiteRunResult {\n const statement = this.prepareSync(source);\n let result: SQLiteExecuteSyncResult<unknown>;\n try {\n result = statement.executeSync(...params);\n } finally {\n statement.finalizeSync();\n }\n return result;\n }\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareSync()`](#preparesyncsource), [`SQLiteStatement.executeSync()`](#executesyncparams), [`SQLiteExecuteSyncResult.getFirstSync()`](#getfirstsync), and [`SQLiteStatement.finalizeSync()`](#finalizesync).\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n */\n public getFirstSync<T>(source: string, params: SQLiteBindParams): T | null;\n /**\n * @hidden\n */\n public getFirstSync<T>(source: string, ...params: SQLiteVariadicBindParams): T | null;\n public getFirstSync<T>(source: string, ...params: any[]): T | null {\n const statement = this.prepareSync(source);\n let firstRow: T | null;\n try {\n const result = statement.executeSync<T>(...params);\n firstRow = result.getFirstSync();\n } finally {\n statement.finalizeSync();\n }\n return firstRow;\n }\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareSync()`](#preparesyncsource), [`SQLiteStatement.executeSync()`](#executesyncparams), [`SQLiteExecuteSyncResult`](#sqliteexecutesyncresult) `Iterator`, and [`SQLiteStatement.finalizeSync()`](#finalizesync).\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n * @returns This function returns an [`IterableIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator). You can use `for...of` to iterate over the rows from the SQLite query result.\n */\n public getEachSync<T>(source: string, params: SQLiteBindParams): IterableIterator<T>;\n /**\n * @hidden\n */\n public getEachSync<T>(source: string, ...params: SQLiteVariadicBindParams): IterableIterator<T>;\n public *getEachSync<T>(source: string, ...params: any[]): IterableIterator<T> {\n const statement = this.prepareSync(source);\n try {\n const result = statement.executeSync<T>(...params);\n for (const row of result) {\n yield row;\n }\n } finally {\n statement.finalizeSync();\n }\n }\n\n /**\n * A convenience wrapper around [`SQLiteDatabase.prepareSync()`](#preparesyncsource), [`SQLiteStatement.executeSync()`](#executesyncparams), [`SQLiteExecuteSyncResult.getAllSync()`](#getallsync), and [`SQLiteStatement.finalizeSync()`](#finalizesync).\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n * @param source A string containing the SQL query.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n */\n public getAllSync<T>(source: string, params: SQLiteBindParams): T[];\n /**\n * @hidden\n */\n public getAllSync<T>(source: string, ...params: SQLiteVariadicBindParams): T[];\n public getAllSync<T>(source: string, ...params: any[]): T[] {\n const statement = this.prepareSync(source);\n let allRows;\n try {\n const result = statement.executeSync<T>(...params);\n allRows = result.getAllSync();\n } finally {\n statement.finalizeSync();\n }\n return allRows;\n }\n\n //#endregion\n}\n\n/**\n * Open a database.\n *\n * @param databaseName The name of the database file to open.\n * @param options Open options.\n */\nexport async function openDatabaseAsync(\n databaseName: string,\n options?: SQLiteOpenOptions\n): Promise<SQLiteDatabase> {\n const openOptions = options ?? {};\n const nativeDatabase = new ExpoSQLite.NativeDatabase(databaseName, openOptions);\n await nativeDatabase.initAsync();\n return new SQLiteDatabase(databaseName, openOptions, nativeDatabase);\n}\n\n/**\n * Open a database.\n *\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n *\n * @param databaseName The name of the database file to open.\n * @param options Open options.\n */\nexport function openDatabaseSync(\n databaseName: string,\n options?: SQLiteOpenOptions\n): SQLiteDatabase {\n const openOptions = options ?? {};\n const nativeDatabase = new ExpoSQLite.NativeDatabase(databaseName, openOptions);\n nativeDatabase.initSync();\n return new SQLiteDatabase(databaseName, openOptions, nativeDatabase);\n}\n\n/**\n * Delete a database file.\n *\n * @param databaseName The name of the database file to delete.\n */\nexport async function deleteDatabaseAsync(databaseName: string): Promise<void> {\n return await ExpoSQLite.deleteDatabaseAsync(databaseName);\n}\n\n/**\n * Delete a database file.\n *\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n *\n * @param databaseName The name of the database file to delete.\n */\nexport function deleteDatabaseSync(databaseName: string): void {\n return ExpoSQLite.deleteDatabaseSync(databaseName);\n}\n\n/**\n * The event payload for the listener of [`addDatabaseChangeListener`](#sqliteadddatabasechangelistenerlistener)\n */\nexport type DatabaseChangeEvent = {\n /** The database name. The value would be `main` by default and other database names if you use `ATTACH DATABASE` statement. */\n databaseName: string;\n\n /** The absolute file path to the database. */\n databaseFilePath: string;\n\n /** The table name. */\n tableName: string;\n\n /** The changed row ID. */\n rowId: number;\n};\n\n/**\n * Add a listener for database changes.\n * > Note: to enable this feature, you must set [`enableChangeListener` to `true`](#sqliteopenoptions) when opening the database.\n *\n * @param listener A function that receives the `databaseName`, `databaseFilePath`, `tableName` and `rowId` of the modified data.\n * @returns A `Subscription` object that you can call `remove()` on when you would like to unsubscribe the listener.\n */\nexport function addDatabaseChangeListener(\n listener: (event: DatabaseChangeEvent) => void\n): Subscription {\n return emitter.addListener('onDatabaseChange', listener);\n}\n\n/**\n * A new connection specific used for [`withExclusiveTransactionAsync`](#withexclusivetransactionasynctask).\n * @hidden not going to pull all the database methods to the document.\n */\nclass Transaction extends SQLiteDatabase {\n public static async createAsync(db: SQLiteDatabase): Promise<Transaction> {\n const options = { ...db.options, useNewConnection: true };\n const nativeDatabase = new ExpoSQLite.NativeDatabase(db.databaseName, options);\n await nativeDatabase.initAsync();\n return new Transaction(db.databaseName, options, nativeDatabase);\n }\n}\n"]}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { NativeDatabase } from './NativeDatabase';
|
|
2
|
+
import { SQLiteBindParams, SQLiteBindValue, NativeStatement, SQLiteVariadicBindParams, type SQLiteRunResult } from './NativeStatement';
|
|
3
|
+
export { SQLiteBindParams, SQLiteBindValue, SQLiteRunResult, SQLiteVariadicBindParams };
|
|
4
|
+
/**
|
|
5
|
+
* A prepared statement returned by [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource) or [`SQLiteDatabase.prepareSync()`](#preparesyncsource) that can be binded with parameters and executed.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SQLiteStatement {
|
|
8
|
+
private readonly nativeDatabase;
|
|
9
|
+
private readonly nativeStatement;
|
|
10
|
+
constructor(nativeDatabase: NativeDatabase, nativeStatement: NativeStatement);
|
|
11
|
+
/**
|
|
12
|
+
* Run the prepared statement and return the [`SQLiteExecuteAsyncResult`](#sqliteexecuteasyncresult) instance.
|
|
13
|
+
* @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.
|
|
14
|
+
*/
|
|
15
|
+
executeAsync<T>(params: SQLiteBindParams): Promise<SQLiteExecuteAsyncResult<T>>;
|
|
16
|
+
/**
|
|
17
|
+
* @hidden
|
|
18
|
+
*/
|
|
19
|
+
executeAsync<T>(...params: SQLiteVariadicBindParams): Promise<SQLiteExecuteAsyncResult<T>>;
|
|
20
|
+
/**
|
|
21
|
+
* Get the column names of the prepared statement.
|
|
22
|
+
*/
|
|
23
|
+
getColumnNamesAsync(): Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Finalize the prepared statement. This will call the [`sqlite3_finalize()`](https://www.sqlite.org/c3ref/finalize.html) C function under the hood.
|
|
26
|
+
*
|
|
27
|
+
* Attempting to access a finalized statement will result in an error.
|
|
28
|
+
* > **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.
|
|
29
|
+
*/
|
|
30
|
+
finalizeAsync(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Run the prepared statement and return the [`SQLiteExecuteSyncResult`](#sqliteexecutesyncresult) instance.
|
|
33
|
+
* > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.
|
|
34
|
+
* @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.
|
|
35
|
+
*/
|
|
36
|
+
executeSync<T>(params: SQLiteBindParams): SQLiteExecuteSyncResult<T>;
|
|
37
|
+
/**
|
|
38
|
+
* @hidden
|
|
39
|
+
*/
|
|
40
|
+
executeSync<T>(...params: SQLiteVariadicBindParams): SQLiteExecuteSyncResult<T>;
|
|
41
|
+
/**
|
|
42
|
+
* Get the column names of the prepared statement.
|
|
43
|
+
*/
|
|
44
|
+
getColumnNamesSync(): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Finalize the prepared statement. This will call the [`sqlite3_finalize()`](https://www.sqlite.org/c3ref/finalize.html) C function under the hood.
|
|
47
|
+
*
|
|
48
|
+
* Attempting to access a finalized statement will result in an error.
|
|
49
|
+
* > **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.
|
|
50
|
+
*/
|
|
51
|
+
finalizeSync(): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A result returned by [`SQLiteStatement.executeAsync()`](#executeasyncparams).
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* The result includes the [`lastInsertRowId`](https://www.sqlite.org/c3ref/last_insert_rowid.html) and [`changes`](https://www.sqlite.org/c3ref/changes.html) properties. You can get the information from the write operations.
|
|
58
|
+
* ```ts
|
|
59
|
+
* const statement = await db.prepareAsync('INSERT INTO test (value) VALUES (?)');
|
|
60
|
+
* try {
|
|
61
|
+
* const result = await statement.executeAsync(101);
|
|
62
|
+
* console.log('lastInsertRowId:', result.lastInsertRowId);
|
|
63
|
+
* console.log('changes:', result.changes);
|
|
64
|
+
* } finally {
|
|
65
|
+
* await statement.finalizeAsync();
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* The result implements the [`AsyncIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) interface, so you can use it in `for await...of` loops.
|
|
71
|
+
* ```ts
|
|
72
|
+
* const statement = await db.prepareAsync('SELECT value FROM test WHERE value > ?');
|
|
73
|
+
* try {
|
|
74
|
+
* const result = await statement.executeAsync<{ value: number }>(100);
|
|
75
|
+
* for await (const row of result) {
|
|
76
|
+
* console.log('row value:', row.value);
|
|
77
|
+
* }
|
|
78
|
+
* } finally {
|
|
79
|
+
* await statement.finalizeAsync();
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* If your write operations also return values, you can mix all of them together.
|
|
85
|
+
* ```ts
|
|
86
|
+
* const statement = await db.prepareAsync('INSERT INTO test (name, value) VALUES (?, ?) RETURNING name');
|
|
87
|
+
* try {
|
|
88
|
+
* const result = await statement.executeAsync<{ name: string }>('John Doe', 101);
|
|
89
|
+
* console.log('lastInsertRowId:', result.lastInsertRowId);
|
|
90
|
+
* console.log('changes:', result.changes);
|
|
91
|
+
* for await (const row of result) {
|
|
92
|
+
* console.log('name:', row.name);
|
|
93
|
+
* }
|
|
94
|
+
* } finally {
|
|
95
|
+
* await statement.finalizeAsync();
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export interface SQLiteExecuteAsyncResult<T> extends AsyncIterableIterator<T> {
|
|
100
|
+
/**
|
|
101
|
+
* The last inserted row ID. Returned from the [`sqlite3_last_insert_rowid()`](https://www.sqlite.org/c3ref/last_insert_rowid.html) function.
|
|
102
|
+
*/
|
|
103
|
+
readonly lastInsertRowId: number;
|
|
104
|
+
/**
|
|
105
|
+
* The number of rows affected. Returned from the [`sqlite3_changes()`](https://www.sqlite.org/c3ref/changes.html) function.
|
|
106
|
+
*/
|
|
107
|
+
readonly changes: number;
|
|
108
|
+
/**
|
|
109
|
+
* 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()`](#resetasync). Otherwise, an error will be thrown.
|
|
110
|
+
*/
|
|
111
|
+
getFirstAsync(): Promise<T | null>;
|
|
112
|
+
/**
|
|
113
|
+
* 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()`](#resetasync). Otherwise, an error will be thrown.
|
|
114
|
+
*/
|
|
115
|
+
getAllAsync(): Promise<T[]>;
|
|
116
|
+
/**
|
|
117
|
+
* Reset the prepared statement cursor. This will call the [`sqlite3_reset()`](https://www.sqlite.org/c3ref/reset.html) C function under the hood.
|
|
118
|
+
*/
|
|
119
|
+
resetAsync(): Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A result returned by [`SQLiteStatement.executeSync()`](#executesyncparams).
|
|
123
|
+
* > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.
|
|
124
|
+
|
|
125
|
+
* @example
|
|
126
|
+
* The result includes the [`lastInsertRowId`](https://www.sqlite.org/c3ref/last_insert_rowid.html) and [`changes`](https://www.sqlite.org/c3ref/changes.html) properties. You can get the information from the write operations.
|
|
127
|
+
* ```ts
|
|
128
|
+
* const statement = db.prepareSync('INSERT INTO test (value) VALUES (?)');
|
|
129
|
+
* try {
|
|
130
|
+
* const result = statement.executeSync(101);
|
|
131
|
+
* console.log('lastInsertRowId:', result.lastInsertRowId);
|
|
132
|
+
* console.log('changes:', result.changes);
|
|
133
|
+
* } finally {
|
|
134
|
+
* statement.finalizeSync();
|
|
135
|
+
* }
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* The result implements the [`Iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator) interface, so you can use it in `for...of` loops.
|
|
140
|
+
* ```ts
|
|
141
|
+
* const statement = db.prepareSync('SELECT value FROM test WHERE value > ?');
|
|
142
|
+
* try {
|
|
143
|
+
* const result = statement.executeSync<{ value: number }>(100);
|
|
144
|
+
* for (const row of result) {
|
|
145
|
+
* console.log('row value:', row.value);
|
|
146
|
+
* }
|
|
147
|
+
* } finally {
|
|
148
|
+
* statement.finalizeSync();
|
|
149
|
+
* }
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* If your write operations also return values, you can mix all of them together.
|
|
154
|
+
* ```ts
|
|
155
|
+
* const statement = db.prepareSync('INSERT INTO test (name, value) VALUES (?, ?) RETURNING name');
|
|
156
|
+
* try {
|
|
157
|
+
* const result = statement.executeSync<{ name: string }>('John Doe', 101);
|
|
158
|
+
* console.log('lastInsertRowId:', result.lastInsertRowId);
|
|
159
|
+
* console.log('changes:', result.changes);
|
|
160
|
+
* for (const row of result) {
|
|
161
|
+
* console.log('name:', row.name);
|
|
162
|
+
* }
|
|
163
|
+
* } finally {
|
|
164
|
+
* statement.finalizeSync();
|
|
165
|
+
* }
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export interface SQLiteExecuteSyncResult<T> extends IterableIterator<T> {
|
|
169
|
+
/**
|
|
170
|
+
* The last inserted row ID. Returned from the [`sqlite3_last_insert_rowid()`](https://www.sqlite.org/c3ref/last_insert_rowid.html) function.
|
|
171
|
+
*/
|
|
172
|
+
readonly lastInsertRowId: number;
|
|
173
|
+
/**
|
|
174
|
+
* The number of rows affected. Returned from the [`sqlite3_changes()`](https://www.sqlite.org/c3ref/changes.html) function.
|
|
175
|
+
*/
|
|
176
|
+
readonly changes: number;
|
|
177
|
+
/**
|
|
178
|
+
* 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()`](#resetsync). Otherwise, an error will be thrown.
|
|
179
|
+
*/
|
|
180
|
+
getFirstSync(): T | null;
|
|
181
|
+
/**
|
|
182
|
+
* 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()`](#resetsync). Otherwise, an error will be thrown.
|
|
183
|
+
*/
|
|
184
|
+
getAllSync(): T[];
|
|
185
|
+
/**
|
|
186
|
+
* Reset the prepared statement cursor. This will call the [`sqlite3_reset()`](https://www.sqlite.org/c3ref/reset.html) C function under the hood.
|
|
187
|
+
*/
|
|
188
|
+
resetSync(): void;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=SQLiteStatement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SQLiteStatement.d.ts","sourceRoot":"","sources":["../../src/next/SQLiteStatement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,wBAAwB,EAExB,KAAK,eAAe,EAErB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,wBAAwB,EAAE,CAAC;AAExF;;GAEG;AACH,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADf,cAAc,EAAE,cAAc,EAC9B,eAAe,EAAE,eAAe;IAKnD;;;OAGG;IACI,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACtF;;OAEG;IACI,YAAY,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;IAejG;;OAEG;IACI,mBAAmB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/C;;;;;OAKG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3C;;;;OAIG;IACI,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,GAAG,uBAAuB,CAAC,CAAC,CAAC;IAC3E;;OAEG;IACI,WAAW,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,wBAAwB,GAAG,uBAAuB,CAAC,CAAC,CAAC;IAetF;;OAEG;IACI,kBAAkB,IAAI,MAAM,EAAE;IAIrC;;;;;OAKG;IACI,YAAY,IAAI,IAAI;CAK5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,MAAM,WAAW,wBAAwB,CAAC,CAAC,CAAE,SAAQ,qBAAqB,CAAC,CAAC,CAAC;IAC3E;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAE5B;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACrE;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,YAAY,IAAI,CAAC,GAAG,IAAI,CAAC;IAEzB;;OAEG;IACH,UAAU,IAAI,CAAC,EAAE,CAAC;IAElB;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;CACnB"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { composeRow, composeRows, normalizeParams } from './paramUtils';
|
|
2
|
+
/**
|
|
3
|
+
* A prepared statement returned by [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource) or [`SQLiteDatabase.prepareSync()`](#preparesyncsource) that can be binded with parameters and executed.
|
|
4
|
+
*/
|
|
5
|
+
export class SQLiteStatement {
|
|
6
|
+
nativeDatabase;
|
|
7
|
+
nativeStatement;
|
|
8
|
+
constructor(nativeDatabase, nativeStatement) {
|
|
9
|
+
this.nativeDatabase = nativeDatabase;
|
|
10
|
+
this.nativeStatement = nativeStatement;
|
|
11
|
+
}
|
|
12
|
+
async executeAsync(...params) {
|
|
13
|
+
const { lastInsertRowId, changes, firstRowValues } = await this.nativeStatement.runAsync(this.nativeDatabase, ...normalizeParams(...params));
|
|
14
|
+
return createSQLiteExecuteAsyncResult(this.nativeDatabase, this.nativeStatement, lastInsertRowId, changes, firstRowValues);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the column names of the prepared statement.
|
|
18
|
+
*/
|
|
19
|
+
getColumnNamesAsync() {
|
|
20
|
+
return this.nativeStatement.getColumnNamesAsync();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Finalize the prepared statement. This will call the [`sqlite3_finalize()`](https://www.sqlite.org/c3ref/finalize.html) C function under the hood.
|
|
24
|
+
*
|
|
25
|
+
* Attempting to access a finalized statement will result in an error.
|
|
26
|
+
* > **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.
|
|
27
|
+
*/
|
|
28
|
+
async finalizeAsync() {
|
|
29
|
+
await this.nativeStatement.finalizeAsync(this.nativeDatabase);
|
|
30
|
+
}
|
|
31
|
+
executeSync(...params) {
|
|
32
|
+
const { lastInsertRowId, changes, firstRowValues } = this.nativeStatement.runSync(this.nativeDatabase, ...normalizeParams(...params));
|
|
33
|
+
return createSQLiteExecuteSyncResult(this.nativeDatabase, this.nativeStatement, lastInsertRowId, changes, firstRowValues);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the column names of the prepared statement.
|
|
37
|
+
*/
|
|
38
|
+
getColumnNamesSync() {
|
|
39
|
+
return this.nativeStatement.getColumnNamesSync();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Finalize the prepared statement. This will call the [`sqlite3_finalize()`](https://www.sqlite.org/c3ref/finalize.html) C function under the hood.
|
|
43
|
+
*
|
|
44
|
+
* Attempting to access a finalized statement will result in an error.
|
|
45
|
+
* > **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.
|
|
46
|
+
*/
|
|
47
|
+
finalizeSync() {
|
|
48
|
+
this.nativeStatement.finalizeSync(this.nativeDatabase);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//#region Internals for SQLiteExecuteAsyncResult and SQLiteExecuteSyncResult
|
|
52
|
+
/**
|
|
53
|
+
* Create the `SQLiteExecuteAsyncResult` instance.
|
|
54
|
+
*
|
|
55
|
+
* NOTE: Since Hermes does not support the `Symbol.asyncIterator` feature, we have to use an AsyncGenerator to implement the `AsyncIterableIterator` interface.
|
|
56
|
+
* This is done by `Object.defineProperties` to add the properties to the AsyncGenerator.
|
|
57
|
+
*/
|
|
58
|
+
async function createSQLiteExecuteAsyncResult(database, statement, lastInsertRowId, changes, firstRowValues) {
|
|
59
|
+
const instance = new SQLiteExecuteAsyncResultImpl(database, statement, lastInsertRowId, changes, firstRowValues);
|
|
60
|
+
const generator = instance.generatorAsync();
|
|
61
|
+
Object.defineProperties(generator, {
|
|
62
|
+
lastInsertRowId: {
|
|
63
|
+
value: lastInsertRowId,
|
|
64
|
+
enumerable: true,
|
|
65
|
+
writable: false,
|
|
66
|
+
configurable: true,
|
|
67
|
+
},
|
|
68
|
+
changes: { value: changes, enumerable: true, writable: false, configurable: true },
|
|
69
|
+
getFirstAsync: {
|
|
70
|
+
value: instance.getFirstAsync.bind(instance),
|
|
71
|
+
enumerable: true,
|
|
72
|
+
writable: false,
|
|
73
|
+
configurable: true,
|
|
74
|
+
},
|
|
75
|
+
getAllAsync: {
|
|
76
|
+
value: instance.getAllAsync.bind(instance),
|
|
77
|
+
enumerable: true,
|
|
78
|
+
writable: false,
|
|
79
|
+
configurable: true,
|
|
80
|
+
},
|
|
81
|
+
resetAsync: {
|
|
82
|
+
value: instance.resetAsync.bind(instance),
|
|
83
|
+
enumerable: true,
|
|
84
|
+
writable: false,
|
|
85
|
+
configurable: true,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
return generator;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create the `SQLiteExecuteSyncResult` instance.
|
|
92
|
+
*/
|
|
93
|
+
function createSQLiteExecuteSyncResult(database, statement, lastInsertRowId, changes, firstRowValues) {
|
|
94
|
+
const instance = new SQLiteExecuteSyncResultImpl(database, statement, lastInsertRowId, changes, firstRowValues);
|
|
95
|
+
const generator = instance.generatorSync();
|
|
96
|
+
Object.defineProperties(generator, {
|
|
97
|
+
lastInsertRowId: {
|
|
98
|
+
value: lastInsertRowId,
|
|
99
|
+
enumerable: true,
|
|
100
|
+
writable: false,
|
|
101
|
+
configurable: true,
|
|
102
|
+
},
|
|
103
|
+
changes: { value: changes, enumerable: true, writable: false, configurable: true },
|
|
104
|
+
getFirstSync: {
|
|
105
|
+
value: instance.getFirstSync.bind(instance),
|
|
106
|
+
enumerable: true,
|
|
107
|
+
writable: false,
|
|
108
|
+
configurable: true,
|
|
109
|
+
},
|
|
110
|
+
getAllSync: {
|
|
111
|
+
value: instance.getAllSync.bind(instance),
|
|
112
|
+
enumerable: true,
|
|
113
|
+
writable: false,
|
|
114
|
+
configurable: true,
|
|
115
|
+
},
|
|
116
|
+
resetSync: {
|
|
117
|
+
value: instance.resetSync.bind(instance),
|
|
118
|
+
enumerable: true,
|
|
119
|
+
writable: false,
|
|
120
|
+
configurable: true,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
return generator;
|
|
124
|
+
}
|
|
125
|
+
class SQLiteExecuteAsyncResultImpl {
|
|
126
|
+
database;
|
|
127
|
+
statement;
|
|
128
|
+
lastInsertRowId;
|
|
129
|
+
changes;
|
|
130
|
+
firstRowValues;
|
|
131
|
+
columnNames = null;
|
|
132
|
+
isStepCalled = false;
|
|
133
|
+
constructor(database, statement, lastInsertRowId, changes, firstRowValues) {
|
|
134
|
+
this.database = database;
|
|
135
|
+
this.statement = statement;
|
|
136
|
+
this.lastInsertRowId = lastInsertRowId;
|
|
137
|
+
this.changes = changes;
|
|
138
|
+
this.firstRowValues = firstRowValues;
|
|
139
|
+
}
|
|
140
|
+
async getFirstAsync() {
|
|
141
|
+
if (this.isStepCalled) {
|
|
142
|
+
throw new Error('The SQLite cursor has been shifted and is unable to retrieve the first row without being reset. Invoke `resetAsync()` to reset the cursor first if you want to retrieve the first row.');
|
|
143
|
+
}
|
|
144
|
+
this.isStepCalled = true;
|
|
145
|
+
const columnNames = await this.getColumnNamesAsync();
|
|
146
|
+
const firstRowValues = this.popFirstRowValues();
|
|
147
|
+
if (firstRowValues != null) {
|
|
148
|
+
return composeRow(columnNames, firstRowValues);
|
|
149
|
+
}
|
|
150
|
+
const firstRow = await this.statement.stepAsync(this.database);
|
|
151
|
+
return firstRow != null ? composeRow(columnNames, firstRow) : null;
|
|
152
|
+
}
|
|
153
|
+
async getAllAsync() {
|
|
154
|
+
if (this.isStepCalled) {
|
|
155
|
+
throw new Error('The SQLite cursor has been shifted and is unable to retrieve all rows without being reset. Invoke `resetAsync()` to reset the cursor first if you want to retrieve all rows.');
|
|
156
|
+
}
|
|
157
|
+
this.isStepCalled = true;
|
|
158
|
+
const columnNames = await this.getColumnNamesAsync();
|
|
159
|
+
const allRows = await this.statement.getAllAsync(this.database);
|
|
160
|
+
const firstRowValues = this.popFirstRowValues();
|
|
161
|
+
if (firstRowValues != null && firstRowValues.length > 0) {
|
|
162
|
+
return composeRows(columnNames, [firstRowValues, ...allRows]);
|
|
163
|
+
}
|
|
164
|
+
return composeRows(columnNames, allRows);
|
|
165
|
+
}
|
|
166
|
+
async *generatorAsync() {
|
|
167
|
+
this.isStepCalled = true;
|
|
168
|
+
const columnNames = await this.getColumnNamesAsync();
|
|
169
|
+
const firstRowValues = this.popFirstRowValues();
|
|
170
|
+
if (firstRowValues != null) {
|
|
171
|
+
yield composeRow(columnNames, firstRowValues);
|
|
172
|
+
}
|
|
173
|
+
let result;
|
|
174
|
+
do {
|
|
175
|
+
result = await this.statement.stepAsync(this.database);
|
|
176
|
+
if (result != null) {
|
|
177
|
+
yield composeRow(columnNames, result);
|
|
178
|
+
}
|
|
179
|
+
} while (result != null);
|
|
180
|
+
}
|
|
181
|
+
resetAsync() {
|
|
182
|
+
const result = this.statement.resetAsync(this.database);
|
|
183
|
+
this.isStepCalled = false;
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
popFirstRowValues() {
|
|
187
|
+
if (this.firstRowValues != null) {
|
|
188
|
+
const firstRowValues = this.firstRowValues;
|
|
189
|
+
this.firstRowValues = null;
|
|
190
|
+
return firstRowValues.length > 0 ? firstRowValues : null;
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
async getColumnNamesAsync() {
|
|
195
|
+
if (this.columnNames == null) {
|
|
196
|
+
this.columnNames = await this.statement.getColumnNamesAsync();
|
|
197
|
+
}
|
|
198
|
+
return this.columnNames;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
class SQLiteExecuteSyncResultImpl {
|
|
202
|
+
database;
|
|
203
|
+
statement;
|
|
204
|
+
lastInsertRowId;
|
|
205
|
+
changes;
|
|
206
|
+
firstRowValues;
|
|
207
|
+
columnNames = null;
|
|
208
|
+
isStepCalled = false;
|
|
209
|
+
constructor(database, statement, lastInsertRowId, changes, firstRowValues) {
|
|
210
|
+
this.database = database;
|
|
211
|
+
this.statement = statement;
|
|
212
|
+
this.lastInsertRowId = lastInsertRowId;
|
|
213
|
+
this.changes = changes;
|
|
214
|
+
this.firstRowValues = firstRowValues;
|
|
215
|
+
}
|
|
216
|
+
getFirstSync() {
|
|
217
|
+
if (this.isStepCalled) {
|
|
218
|
+
throw new Error('The SQLite cursor has been shifted and is unable to retrieve the first row without being reset. Invoke `resetSync()` to reset the cursor first if you want to retrieve the first row.');
|
|
219
|
+
}
|
|
220
|
+
const columnNames = this.getColumnNamesSync();
|
|
221
|
+
const firstRowValues = this.popFirstRowValues();
|
|
222
|
+
if (firstRowValues != null) {
|
|
223
|
+
return composeRow(columnNames, firstRowValues);
|
|
224
|
+
}
|
|
225
|
+
const firstRow = this.statement.stepSync(this.database);
|
|
226
|
+
return firstRow != null ? composeRow(columnNames, firstRow) : null;
|
|
227
|
+
}
|
|
228
|
+
getAllSync() {
|
|
229
|
+
if (this.isStepCalled) {
|
|
230
|
+
throw new Error('The SQLite cursor has been shifted and is unable to retrieve all rows without being reset. Invoke `resetSync()` to reset the cursor first if you want to retrieve all rows.');
|
|
231
|
+
}
|
|
232
|
+
const columnNames = this.getColumnNamesSync();
|
|
233
|
+
const allRows = this.statement.getAllSync(this.database);
|
|
234
|
+
const firstRowValues = this.popFirstRowValues();
|
|
235
|
+
if (firstRowValues != null && firstRowValues.length > 0) {
|
|
236
|
+
return composeRows(columnNames, [firstRowValues, ...allRows]);
|
|
237
|
+
}
|
|
238
|
+
return composeRows(columnNames, allRows);
|
|
239
|
+
}
|
|
240
|
+
*generatorSync() {
|
|
241
|
+
const columnNames = this.getColumnNamesSync();
|
|
242
|
+
const firstRowValues = this.popFirstRowValues();
|
|
243
|
+
if (firstRowValues != null) {
|
|
244
|
+
yield composeRow(columnNames, firstRowValues);
|
|
245
|
+
}
|
|
246
|
+
let result;
|
|
247
|
+
do {
|
|
248
|
+
result = this.statement.stepSync(this.database);
|
|
249
|
+
if (result != null) {
|
|
250
|
+
yield composeRow(columnNames, result);
|
|
251
|
+
}
|
|
252
|
+
} while (result != null);
|
|
253
|
+
}
|
|
254
|
+
resetSync() {
|
|
255
|
+
const result = this.statement.resetSync(this.database);
|
|
256
|
+
this.isStepCalled = false;
|
|
257
|
+
return result;
|
|
258
|
+
}
|
|
259
|
+
popFirstRowValues() {
|
|
260
|
+
if (this.firstRowValues != null) {
|
|
261
|
+
const firstRowValues = this.firstRowValues;
|
|
262
|
+
this.firstRowValues = null;
|
|
263
|
+
return firstRowValues.length > 0 ? firstRowValues : null;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
getColumnNamesSync() {
|
|
268
|
+
if (this.columnNames == null) {
|
|
269
|
+
this.columnNames = this.statement.getColumnNamesSync();
|
|
270
|
+
}
|
|
271
|
+
return this.columnNames;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
//#endregion
|
|
275
|
+
//# sourceMappingURL=SQLiteStatement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SQLiteStatement.js","sourceRoot":"","sources":["../../src/next/SQLiteStatement.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAIxE;;GAEG;AACH,MAAM,OAAO,eAAe;IAEP;IACA;IAFnB,YACmB,cAA8B,EAC9B,eAAgC;QADhC,mBAAc,GAAd,cAAc,CAAgB;QAC9B,oBAAe,GAAf,eAAe,CAAiB;IAChD,CAAC;IAaG,KAAK,CAAC,YAAY,CAAI,GAAG,MAAiB;QAC/C,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CACtF,IAAI,CAAC,cAAc,EACnB,GAAG,eAAe,CAAC,GAAG,MAAM,CAAC,CAC9B,CAAC;QACF,OAAO,8BAA8B,CACnC,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,eAAe,EACpB,eAAe,EACf,OAAO,EACP,cAAc,CACf,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,mBAAmB;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC;IACpD,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,aAAa;QACxB,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAChE,CAAC;IAgBM,WAAW,CAAI,GAAG,MAAiB;QACxC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAC/E,IAAI,CAAC,cAAc,EACnB,GAAG,eAAe,CAAC,GAAG,MAAM,CAAC,CAC9B,CAAC;QACF,OAAO,6BAA6B,CAClC,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,eAAe,EACpB,eAAe,EACf,OAAO,EACP,cAAc,CACf,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,kBAAkB;QACvB,OAAO,IAAI,CAAC,eAAe,CAAC,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED;;;;;OAKG;IACI,YAAY;QACjB,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzD,CAAC;CAGF;AAqJD,4EAA4E;AAE5E;;;;;GAKG;AACH,KAAK,UAAU,8BAA8B,CAC3C,QAA2B,EAC3B,SAA0B,EAC1B,eAAuB,EACvB,OAAe,EACf,cAAyC;IAEzC,MAAM,QAAQ,GAAG,IAAI,4BAA4B,CAC/C,QAAQ,EACR,SAAS,EACT,eAAe,EACf,OAAO,EACP,cAAc,CACf,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC5C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE;QACjC,eAAe,EAAE;YACf,KAAK,EAAE,eAAe;YACtB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;QAClF,aAAa,EAAE;YACb,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC5C,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,WAAW,EAAE;YACX,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC1C,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,UAAU,EAAE;YACV,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;YACzC,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;KACF,CAAC,CAAC;IAEH,OAAO,SAAwC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,SAAS,6BAA6B,CACpC,QAA2B,EAC3B,SAA0B,EAC1B,eAAuB,EACvB,OAAe,EACf,cAAyC;IAEzC,MAAM,QAAQ,GAAG,IAAI,2BAA2B,CAC9C,QAAQ,EACR,SAAS,EACT,eAAe,EACf,OAAO,EACP,cAAc,CACf,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC3C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE;QACjC,eAAe,EAAE;YACf,KAAK,EAAE,eAAe;YACtB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;QAClF,YAAY,EAAE;YACZ,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC3C,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,UAAU,EAAE;YACV,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;YACzC,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,SAAS,EAAE;YACT,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;YACxC,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;KACF,CAAC,CAAC;IAEH,OAAO,SAAuC,CAAC;AACjD,CAAC;AAED,MAAM,4BAA4B;IAKb;IACA;IACD;IACA;IACR;IARF,WAAW,GAAoB,IAAI,CAAC;IACpC,YAAY,GAAG,KAAK,CAAC;IAE7B,YACmB,QAA2B,EAC3B,SAA0B,EAC3B,eAAuB,EACvB,OAAe,EACvB,cAAyC;QAJhC,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,cAAS,GAAT,SAAS,CAAiB;QAC3B,oBAAe,GAAf,eAAe,CAAQ;QACvB,YAAO,GAAP,OAAO,CAAQ;QACvB,mBAAc,GAAd,cAAc,CAA2B;IAChD,CAAC;IAEJ,KAAK,CAAC,aAAa;QACjB,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,MAAM,IAAI,KAAK,CACb,wLAAwL,CACzL,CAAC;SACH;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrD,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE;YAC1B,OAAO,UAAU,CAAI,WAAW,EAAE,cAAc,CAAC,CAAC;SACnD;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/D,OAAO,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAI,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,MAAM,IAAI,KAAK,CACb,8KAA8K,CAC/K,CAAC;SACH;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChE,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YACvD,OAAO,WAAW,CAAI,WAAW,EAAE,CAAC,cAAc,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;SAClE;QACD,OAAO,WAAW,CAAI,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,CAAC,cAAc;QACnB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrD,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE;YAC1B,MAAM,UAAU,CAAI,WAAW,EAAE,cAAc,CAAC,CAAC;SAClD;QAED,IAAI,MAAM,CAAC;QACX,GAAG;YACD,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvD,IAAI,MAAM,IAAI,IAAI,EAAE;gBAClB,MAAM,UAAU,CAAI,WAAW,EAAE,MAAM,CAAC,CAAC;aAC1C;SACF,QAAQ,MAAM,IAAI,IAAI,EAAE;IAC3B,CAAC;IAED,UAAU;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE;YAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;YAC3C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,OAAO,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;SAC1D;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,mBAAmB;QAC/B,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE;YAC5B,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;SAC/D;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,2BAA2B;IAKZ;IACA;IACD;IACA;IACR;IARF,WAAW,GAAoB,IAAI,CAAC;IACpC,YAAY,GAAG,KAAK,CAAC;IAE7B,YACmB,QAA2B,EAC3B,SAA0B,EAC3B,eAAuB,EACvB,OAAe,EACvB,cAAyC;QAJhC,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,cAAS,GAAT,SAAS,CAAiB;QAC3B,oBAAe,GAAf,eAAe,CAAQ;QACvB,YAAO,GAAP,OAAO,CAAQ;QACvB,mBAAc,GAAd,cAAc,CAA2B;IAChD,CAAC;IAEJ,YAAY;QACV,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,MAAM,IAAI,KAAK,CACb,uLAAuL,CACxL,CAAC;SACH;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE;YAC1B,OAAO,UAAU,CAAI,WAAW,EAAE,cAAc,CAAC,CAAC;SACnD;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,OAAO,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAI,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,MAAM,IAAI,KAAK,CACb,6KAA6K,CAC9K,CAAC;SACH;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YACvD,OAAO,WAAW,CAAI,WAAW,EAAE,CAAC,cAAc,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;SAClE;QACD,OAAO,WAAW,CAAI,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,CAAC,aAAa;QACZ,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE;YAC1B,MAAM,UAAU,CAAI,WAAW,EAAE,cAAc,CAAC,CAAC;SAClD;QACD,IAAI,MAAM,CAAC;QACX,GAAG;YACD,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,MAAM,IAAI,IAAI,EAAE;gBAClB,MAAM,UAAU,CAAI,WAAW,EAAE,MAAM,CAAC,CAAC;aAC1C;SACF,QAAQ,MAAM,IAAI,IAAI,EAAE;IAC3B,CAAC;IAED,SAAS;QACP,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE;YAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;YAC3C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,OAAO,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;SAC1D;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,kBAAkB;QACxB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE;YAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;SACxD;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,YAAY","sourcesContent":["import { NativeDatabase } from './NativeDatabase';\nimport {\n SQLiteBindParams,\n SQLiteBindValue,\n NativeStatement,\n SQLiteVariadicBindParams,\n type SQLiteAnyDatabase,\n type SQLiteRunResult,\n SQLiteColumnValues,\n} from './NativeStatement';\nimport { composeRow, composeRows, normalizeParams } from './paramUtils';\n\nexport { SQLiteBindParams, SQLiteBindValue, SQLiteRunResult, SQLiteVariadicBindParams };\n\n/**\n * A prepared statement returned by [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource) or [`SQLiteDatabase.prepareSync()`](#preparesyncsource) that can be binded with parameters and executed.\n */\nexport class SQLiteStatement {\n constructor(\n private readonly nativeDatabase: NativeDatabase,\n private readonly nativeStatement: NativeStatement\n ) {}\n\n //#region Asynchronous API\n\n /**\n * Run the prepared statement and return the [`SQLiteExecuteAsyncResult`](#sqliteexecuteasyncresult) instance.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n */\n public executeAsync<T>(params: SQLiteBindParams): Promise<SQLiteExecuteAsyncResult<T>>;\n /**\n * @hidden\n */\n public executeAsync<T>(...params: SQLiteVariadicBindParams): Promise<SQLiteExecuteAsyncResult<T>>;\n public async executeAsync<T>(...params: unknown[]): Promise<SQLiteExecuteAsyncResult<T>> {\n const { lastInsertRowId, changes, firstRowValues } = await this.nativeStatement.runAsync(\n this.nativeDatabase,\n ...normalizeParams(...params)\n );\n return createSQLiteExecuteAsyncResult<T>(\n this.nativeDatabase,\n this.nativeStatement,\n lastInsertRowId,\n changes,\n firstRowValues\n );\n }\n\n /**\n * Get the column names of the prepared statement.\n */\n public getColumnNamesAsync(): Promise<string[]> {\n return this.nativeStatement.getColumnNamesAsync();\n }\n\n /**\n * Finalize the prepared statement. This will call the [`sqlite3_finalize()`](https://www.sqlite.org/c3ref/finalize.html) C function under the hood.\n *\n * Attempting to access a finalized statement will result in an error.\n * > **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.\n */\n public async finalizeAsync(): Promise<void> {\n await this.nativeStatement.finalizeAsync(this.nativeDatabase);\n }\n\n //#endregion\n\n //#region Synchronous API\n\n /**\n * Run the prepared statement and return the [`SQLiteExecuteSyncResult`](#sqliteexecutesyncresult) instance.\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n * @param params The parameters to bind to the prepared statement. You can pass values in array, object, or variadic arguments. See [`SQLiteBindValue`](#sqlitebindvalue) for more information about binding values.\n */\n public executeSync<T>(params: SQLiteBindParams): SQLiteExecuteSyncResult<T>;\n /**\n * @hidden\n */\n public executeSync<T>(...params: SQLiteVariadicBindParams): SQLiteExecuteSyncResult<T>;\n public executeSync<T>(...params: unknown[]): SQLiteExecuteSyncResult<T> {\n const { lastInsertRowId, changes, firstRowValues } = this.nativeStatement.runSync(\n this.nativeDatabase,\n ...normalizeParams(...params)\n );\n return createSQLiteExecuteSyncResult<T>(\n this.nativeDatabase,\n this.nativeStatement,\n lastInsertRowId,\n changes,\n firstRowValues\n );\n }\n\n /**\n * Get the column names of the prepared statement.\n */\n public getColumnNamesSync(): string[] {\n return this.nativeStatement.getColumnNamesSync();\n }\n\n /**\n * Finalize the prepared statement. This will call the [`sqlite3_finalize()`](https://www.sqlite.org/c3ref/finalize.html) C function under the hood.\n *\n * Attempting to access a finalized statement will result in an error.\n * > **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.\n */\n public finalizeSync(): void {\n this.nativeStatement.finalizeSync(this.nativeDatabase);\n }\n\n //#endregion\n}\n\n/**\n * A result returned by [`SQLiteStatement.executeAsync()`](#executeasyncparams).\n *\n * @example\n * The result includes the [`lastInsertRowId`](https://www.sqlite.org/c3ref/last_insert_rowid.html) and [`changes`](https://www.sqlite.org/c3ref/changes.html) properties. You can get the information from the write operations.\n * ```ts\n * const statement = await db.prepareAsync('INSERT INTO test (value) VALUES (?)');\n * try {\n * const result = await statement.executeAsync(101);\n * console.log('lastInsertRowId:', result.lastInsertRowId);\n * console.log('changes:', result.changes);\n * } finally {\n * await statement.finalizeAsync();\n * }\n * ```\n *\n * @example\n * The result implements the [`AsyncIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) interface, so you can use it in `for await...of` loops.\n * ```ts\n * const statement = await db.prepareAsync('SELECT value FROM test WHERE value > ?');\n * try {\n * const result = await statement.executeAsync<{ value: number }>(100);\n * for await (const row of result) {\n * console.log('row value:', row.value);\n * }\n * } finally {\n * await statement.finalizeAsync();\n * }\n * ```\n *\n * @example\n * If your write operations also return values, you can mix all of them together.\n * ```ts\n * const statement = await db.prepareAsync('INSERT INTO test (name, value) VALUES (?, ?) RETURNING name');\n * try {\n * const result = await statement.executeAsync<{ name: string }>('John Doe', 101);\n * console.log('lastInsertRowId:', result.lastInsertRowId);\n * console.log('changes:', result.changes);\n * for await (const row of result) {\n * console.log('name:', row.name);\n * }\n * } finally {\n * await statement.finalizeAsync();\n * }\n * ```\n */\nexport interface SQLiteExecuteAsyncResult<T> extends AsyncIterableIterator<T> {\n /**\n * The last inserted row ID. Returned from the [`sqlite3_last_insert_rowid()`](https://www.sqlite.org/c3ref/last_insert_rowid.html) function.\n */\n readonly lastInsertRowId: number;\n\n /**\n * The number of rows affected. Returned from the [`sqlite3_changes()`](https://www.sqlite.org/c3ref/changes.html) function.\n */\n readonly changes: number;\n\n /**\n * 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()`](#resetasync). Otherwise, an error will be thrown.\n */\n getFirstAsync(): Promise<T | null>;\n\n /**\n * 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()`](#resetasync). Otherwise, an error will be thrown.\n */\n getAllAsync(): Promise<T[]>;\n\n /**\n * Reset the prepared statement cursor. This will call the [`sqlite3_reset()`](https://www.sqlite.org/c3ref/reset.html) C function under the hood.\n */\n resetAsync(): Promise<void>;\n}\n\n/**\n * A result returned by [`SQLiteStatement.executeSync()`](#executesyncparams).\n * > **Note:** Running heavy tasks with this function can block the JavaScript thread and affect performance.\n\n * @example\n * The result includes the [`lastInsertRowId`](https://www.sqlite.org/c3ref/last_insert_rowid.html) and [`changes`](https://www.sqlite.org/c3ref/changes.html) properties. You can get the information from the write operations.\n * ```ts\n * const statement = db.prepareSync('INSERT INTO test (value) VALUES (?)');\n * try {\n * const result = statement.executeSync(101);\n * console.log('lastInsertRowId:', result.lastInsertRowId);\n * console.log('changes:', result.changes);\n * } finally {\n * statement.finalizeSync();\n * }\n * ```\n *\n * @example\n * The result implements the [`Iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator) interface, so you can use it in `for...of` loops.\n * ```ts\n * const statement = db.prepareSync('SELECT value FROM test WHERE value > ?');\n * try {\n * const result = statement.executeSync<{ value: number }>(100);\n * for (const row of result) {\n * console.log('row value:', row.value);\n * }\n * } finally {\n * statement.finalizeSync();\n * }\n * ```\n *\n * @example\n * If your write operations also return values, you can mix all of them together.\n * ```ts\n * const statement = db.prepareSync('INSERT INTO test (name, value) VALUES (?, ?) RETURNING name');\n * try {\n * const result = statement.executeSync<{ name: string }>('John Doe', 101);\n * console.log('lastInsertRowId:', result.lastInsertRowId);\n * console.log('changes:', result.changes);\n * for (const row of result) {\n * console.log('name:', row.name);\n * }\n * } finally {\n * statement.finalizeSync();\n * }\n * ```\n */\nexport interface SQLiteExecuteSyncResult<T> extends IterableIterator<T> {\n /**\n * The last inserted row ID. Returned from the [`sqlite3_last_insert_rowid()`](https://www.sqlite.org/c3ref/last_insert_rowid.html) function.\n */\n readonly lastInsertRowId: number;\n\n /**\n * The number of rows affected. Returned from the [`sqlite3_changes()`](https://www.sqlite.org/c3ref/changes.html) function.\n */\n readonly changes: number;\n\n /**\n * 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()`](#resetsync). Otherwise, an error will be thrown.\n */\n getFirstSync(): T | null;\n\n /**\n * 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()`](#resetsync). Otherwise, an error will be thrown.\n */\n getAllSync(): T[];\n\n /**\n * Reset the prepared statement cursor. This will call the [`sqlite3_reset()`](https://www.sqlite.org/c3ref/reset.html) C function under the hood.\n */\n resetSync(): void;\n}\n\n//#region Internals for SQLiteExecuteAsyncResult and SQLiteExecuteSyncResult\n\n/**\n * Create the `SQLiteExecuteAsyncResult` instance.\n *\n * NOTE: Since Hermes does not support the `Symbol.asyncIterator` feature, we have to use an AsyncGenerator to implement the `AsyncIterableIterator` interface.\n * This is done by `Object.defineProperties` to add the properties to the AsyncGenerator.\n */\nasync function createSQLiteExecuteAsyncResult<T>(\n database: SQLiteAnyDatabase,\n statement: NativeStatement,\n lastInsertRowId: number,\n changes: number,\n firstRowValues: SQLiteColumnValues | null\n): Promise<SQLiteExecuteAsyncResult<T>> {\n const instance = new SQLiteExecuteAsyncResultImpl<T>(\n database,\n statement,\n lastInsertRowId,\n changes,\n firstRowValues\n );\n const generator = instance.generatorAsync();\n Object.defineProperties(generator, {\n lastInsertRowId: {\n value: lastInsertRowId,\n enumerable: true,\n writable: false,\n configurable: true,\n },\n changes: { value: changes, enumerable: true, writable: false, configurable: true },\n getFirstAsync: {\n value: instance.getFirstAsync.bind(instance),\n enumerable: true,\n writable: false,\n configurable: true,\n },\n getAllAsync: {\n value: instance.getAllAsync.bind(instance),\n enumerable: true,\n writable: false,\n configurable: true,\n },\n resetAsync: {\n value: instance.resetAsync.bind(instance),\n enumerable: true,\n writable: false,\n configurable: true,\n },\n });\n\n return generator as SQLiteExecuteAsyncResult<T>;\n}\n\n/**\n * Create the `SQLiteExecuteSyncResult` instance.\n */\nfunction createSQLiteExecuteSyncResult<T>(\n database: SQLiteAnyDatabase,\n statement: NativeStatement,\n lastInsertRowId: number,\n changes: number,\n firstRowValues: SQLiteColumnValues | null\n): SQLiteExecuteSyncResult<T> {\n const instance = new SQLiteExecuteSyncResultImpl<T>(\n database,\n statement,\n lastInsertRowId,\n changes,\n firstRowValues\n );\n const generator = instance.generatorSync();\n Object.defineProperties(generator, {\n lastInsertRowId: {\n value: lastInsertRowId,\n enumerable: true,\n writable: false,\n configurable: true,\n },\n changes: { value: changes, enumerable: true, writable: false, configurable: true },\n getFirstSync: {\n value: instance.getFirstSync.bind(instance),\n enumerable: true,\n writable: false,\n configurable: true,\n },\n getAllSync: {\n value: instance.getAllSync.bind(instance),\n enumerable: true,\n writable: false,\n configurable: true,\n },\n resetSync: {\n value: instance.resetSync.bind(instance),\n enumerable: true,\n writable: false,\n configurable: true,\n },\n });\n\n return generator as SQLiteExecuteSyncResult<T>;\n}\n\nclass SQLiteExecuteAsyncResultImpl<T> {\n private columnNames: string[] | null = null;\n private isStepCalled = false;\n\n constructor(\n private readonly database: SQLiteAnyDatabase,\n private readonly statement: NativeStatement,\n public readonly lastInsertRowId: number,\n public readonly changes: number,\n private firstRowValues: SQLiteColumnValues | null\n ) {}\n\n async getFirstAsync(): Promise<T | null> {\n if (this.isStepCalled) {\n throw new Error(\n 'The SQLite cursor has been shifted and is unable to retrieve the first row without being reset. Invoke `resetAsync()` to reset the cursor first if you want to retrieve the first row.'\n );\n }\n this.isStepCalled = true;\n const columnNames = await this.getColumnNamesAsync();\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null) {\n return composeRow<T>(columnNames, firstRowValues);\n }\n const firstRow = await this.statement.stepAsync(this.database);\n return firstRow != null ? composeRow<T>(columnNames, firstRow) : null;\n }\n\n async getAllAsync(): Promise<T[]> {\n if (this.isStepCalled) {\n throw new Error(\n 'The SQLite cursor has been shifted and is unable to retrieve all rows without being reset. Invoke `resetAsync()` to reset the cursor first if you want to retrieve all rows.'\n );\n }\n this.isStepCalled = true;\n const columnNames = await this.getColumnNamesAsync();\n const allRows = await this.statement.getAllAsync(this.database);\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null && firstRowValues.length > 0) {\n return composeRows<T>(columnNames, [firstRowValues, ...allRows]);\n }\n return composeRows<T>(columnNames, allRows);\n }\n\n async *generatorAsync(): AsyncIterableIterator<T> {\n this.isStepCalled = true;\n const columnNames = await this.getColumnNamesAsync();\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null) {\n yield composeRow<T>(columnNames, firstRowValues);\n }\n\n let result;\n do {\n result = await this.statement.stepAsync(this.database);\n if (result != null) {\n yield composeRow<T>(columnNames, result);\n }\n } while (result != null);\n }\n\n resetAsync(): Promise<void> {\n const result = this.statement.resetAsync(this.database);\n this.isStepCalled = false;\n return result;\n }\n\n private popFirstRowValues(): SQLiteColumnValues | null {\n if (this.firstRowValues != null) {\n const firstRowValues = this.firstRowValues;\n this.firstRowValues = null;\n return firstRowValues.length > 0 ? firstRowValues : null;\n }\n return null;\n }\n\n private async getColumnNamesAsync(): Promise<string[]> {\n if (this.columnNames == null) {\n this.columnNames = await this.statement.getColumnNamesAsync();\n }\n return this.columnNames;\n }\n}\n\nclass SQLiteExecuteSyncResultImpl<T> {\n private columnNames: string[] | null = null;\n private isStepCalled = false;\n\n constructor(\n private readonly database: SQLiteAnyDatabase,\n private readonly statement: NativeStatement,\n public readonly lastInsertRowId: number,\n public readonly changes: number,\n private firstRowValues: SQLiteColumnValues | null\n ) {}\n\n getFirstSync(): T | null {\n if (this.isStepCalled) {\n throw new Error(\n 'The SQLite cursor has been shifted and is unable to retrieve the first row without being reset. Invoke `resetSync()` to reset the cursor first if you want to retrieve the first row.'\n );\n }\n const columnNames = this.getColumnNamesSync();\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null) {\n return composeRow<T>(columnNames, firstRowValues);\n }\n const firstRow = this.statement.stepSync(this.database);\n return firstRow != null ? composeRow<T>(columnNames, firstRow) : null;\n }\n\n getAllSync(): T[] {\n if (this.isStepCalled) {\n throw new Error(\n 'The SQLite cursor has been shifted and is unable to retrieve all rows without being reset. Invoke `resetSync()` to reset the cursor first if you want to retrieve all rows.'\n );\n }\n const columnNames = this.getColumnNamesSync();\n const allRows = this.statement.getAllSync(this.database);\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null && firstRowValues.length > 0) {\n return composeRows<T>(columnNames, [firstRowValues, ...allRows]);\n }\n return composeRows<T>(columnNames, allRows);\n }\n\n *generatorSync(): IterableIterator<T> {\n const columnNames = this.getColumnNamesSync();\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null) {\n yield composeRow<T>(columnNames, firstRowValues);\n }\n let result;\n do {\n result = this.statement.stepSync(this.database);\n if (result != null) {\n yield composeRow<T>(columnNames, result);\n }\n } while (result != null);\n }\n\n resetSync(): void {\n const result = this.statement.resetSync(this.database);\n this.isStepCalled = false;\n return result;\n }\n\n private popFirstRowValues(): SQLiteColumnValues | null {\n if (this.firstRowValues != null) {\n const firstRowValues = this.firstRowValues;\n this.firstRowValues = null;\n return firstRowValues.length > 0 ? firstRowValues : null;\n }\n return null;\n }\n\n private getColumnNamesSync(): string[] {\n if (this.columnNames == null) {\n this.columnNames = this.statement.getColumnNamesSync();\n }\n return this.columnNames;\n }\n}\n\n//#endregion\n"]}
|