expo-sqlite 57.0.2 → 57.0.4
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 +10 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/sqlite/SQLiteModule.kt +38 -22
- package/build/SQLiteStatement.d.ts +10 -0
- package/build/SQLiteStatement.d.ts.map +1 -1
- package/build/SQLiteStatement.js +58 -16
- package/build/SQLiteStatement.js.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/SQLiteModule.swift +28 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{57.0.2/expo.modules.sqlite-57.0.2-sources.jar → 57.0.4/expo.modules.sqlite-57.0.4-sources.jar} +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{57.0.2/expo.modules.sqlite-57.0.2.aar → 57.0.4/expo.modules.sqlite-57.0.4.aar} +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{57.0.2/expo.modules.sqlite-57.0.2.module → 57.0.4/expo.modules.sqlite-57.0.4.module} +22 -22
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{57.0.2/expo.modules.sqlite-57.0.2.pom → 57.0.4/expo.modules.sqlite-57.0.4.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.4/expo.modules.sqlite-57.0.4.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.sha512 +1 -1
- package/package.json +3 -3
- package/spm.config.json +1 -1
- package/src/SQLiteStatement.ts +70 -16
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.2/expo.modules.sqlite-57.0.2.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 57.0.4 — 2026-10-06
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fixed reading a prepared statement result after the same statement ran again returning the later run's rows instead of throwing. Also guarded `step`, `getAll`, `reset` and `finalize` with the same per-statement lock that `run` takes. ([#49796](https://github.com/expo/expo/pull/49796) by [@tsapeta](https://github.com/tsapeta))
|
|
18
|
+
|
|
19
|
+
## 57.0.3 — 2026-09-11
|
|
20
|
+
|
|
21
|
+
_This version does not introduce any user-facing changes._
|
|
22
|
+
|
|
13
23
|
## 57.0.2 — 2026-08-26
|
|
14
24
|
|
|
15
25
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -47,13 +47,13 @@ def reactNativeArchitectures() {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
group = 'host.exp.exponent'
|
|
50
|
-
version = '57.0.
|
|
50
|
+
version = '57.0.4'
|
|
51
51
|
|
|
52
52
|
android {
|
|
53
53
|
namespace "expo.modules.sqlite"
|
|
54
54
|
defaultConfig {
|
|
55
55
|
versionCode 18
|
|
56
|
-
versionName "57.0.
|
|
56
|
+
versionName "57.0.4"
|
|
57
57
|
buildConfigField "boolean", "USE_LIBSQL", project.ext.USE_LIBSQL.toString()
|
|
58
58
|
buildConfigField "boolean", "WITH_SQLITE_VEC", project.ext.WITH_SQLITE_VEC.toString()
|
|
59
59
|
|
|
@@ -437,40 +437,52 @@ class SQLiteModule : Module() {
|
|
|
437
437
|
private fun step(statement: NativeStatement, database: NativeDatabase): SQLiteColumnValues? {
|
|
438
438
|
maybeThrowForClosedDatabase(database)
|
|
439
439
|
maybeThrowForFinalizedStatement(statement)
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
440
|
+
|
|
441
|
+
// Guard the stateful statement, see `run` above.
|
|
442
|
+
synchronized(statement) {
|
|
443
|
+
val ret = statement.ref.sqlite3_step()
|
|
444
|
+
if (ret == NativeDatabaseBinding.SQLITE_ROW) {
|
|
445
|
+
return statement.getTransformedColumnValues()
|
|
446
|
+
}
|
|
447
|
+
if (ret != NativeDatabaseBinding.SQLITE_DONE) {
|
|
448
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
449
|
+
}
|
|
450
|
+
return null
|
|
446
451
|
}
|
|
447
|
-
return null
|
|
448
452
|
}
|
|
449
453
|
|
|
450
454
|
@Throws(AccessClosedResourceException::class, InvalidConvertibleException::class, SQLiteErrorException::class)
|
|
451
455
|
private fun getAll(statement: NativeStatement, database: NativeDatabase): List<SQLiteColumnValues> {
|
|
452
456
|
maybeThrowForClosedDatabase(database)
|
|
453
457
|
maybeThrowForFinalizedStatement(statement)
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
458
|
+
|
|
459
|
+
// Guard the stateful statement, see `run` above.
|
|
460
|
+
synchronized(statement) {
|
|
461
|
+
val columnValuesList = mutableListOf<SQLiteColumnValues>()
|
|
462
|
+
while (true) {
|
|
463
|
+
val ret = statement.ref.sqlite3_step()
|
|
464
|
+
if (ret == NativeDatabaseBinding.SQLITE_ROW) {
|
|
465
|
+
columnValuesList.add(statement.getTransformedColumnValues())
|
|
466
|
+
continue
|
|
467
|
+
} else if (ret == NativeDatabaseBinding.SQLITE_DONE) {
|
|
468
|
+
break
|
|
469
|
+
}
|
|
470
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
462
471
|
}
|
|
463
|
-
|
|
472
|
+
return columnValuesList
|
|
464
473
|
}
|
|
465
|
-
return columnValuesList
|
|
466
474
|
}
|
|
467
475
|
|
|
468
476
|
@Throws(AccessClosedResourceException::class, SQLiteErrorException::class)
|
|
469
477
|
private fun reset(statement: NativeStatement, database: NativeDatabase) {
|
|
470
478
|
maybeThrowForClosedDatabase(database)
|
|
471
479
|
maybeThrowForFinalizedStatement(statement)
|
|
472
|
-
|
|
473
|
-
|
|
480
|
+
|
|
481
|
+
// Guard the stateful statement, see `run` above.
|
|
482
|
+
synchronized(statement) {
|
|
483
|
+
if (statement.ref.sqlite3_reset() != NativeDatabaseBinding.SQLITE_OK) {
|
|
484
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
485
|
+
}
|
|
474
486
|
}
|
|
475
487
|
}
|
|
476
488
|
|
|
@@ -478,10 +490,14 @@ class SQLiteModule : Module() {
|
|
|
478
490
|
private fun finalize(statement: NativeStatement, database: NativeDatabase) {
|
|
479
491
|
maybeThrowForClosedDatabase(database)
|
|
480
492
|
maybeThrowForFinalizedStatement(statement)
|
|
481
|
-
|
|
482
|
-
|
|
493
|
+
|
|
494
|
+
// Guard the stateful statement, see `run` above.
|
|
495
|
+
synchronized(statement) {
|
|
496
|
+
if (statement.ref.sqlite3_finalize() != NativeDatabaseBinding.SQLITE_OK) {
|
|
497
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
498
|
+
}
|
|
499
|
+
statement.isFinalized = true
|
|
483
500
|
}
|
|
484
|
-
statement.isFinalized = true
|
|
485
501
|
}
|
|
486
502
|
|
|
487
503
|
private fun addUpdateHook(database: NativeDatabase) {
|
|
@@ -8,7 +8,17 @@ type ValuesOf<T extends object> = T[keyof T][];
|
|
|
8
8
|
export declare class SQLiteStatement {
|
|
9
9
|
private readonly nativeDatabase;
|
|
10
10
|
private readonly nativeStatement;
|
|
11
|
+
/**
|
|
12
|
+
* The cursor that currently owns the underlying `sqlite3_stmt`. A prepared statement has exactly
|
|
13
|
+
* one cursor, so running the statement again invalidates the cursor of every earlier run.
|
|
14
|
+
*/
|
|
15
|
+
private currentCursor;
|
|
11
16
|
constructor(nativeDatabase: NativeDatabase, nativeStatement: NativeStatement);
|
|
17
|
+
/**
|
|
18
|
+
* Make the run that just finished the owner of the statement cursor, and return a predicate
|
|
19
|
+
* that tells whether it still is.
|
|
20
|
+
*/
|
|
21
|
+
private claimCursor;
|
|
12
22
|
/**
|
|
13
23
|
* Run the prepared statement and return the [`SQLiteExecuteAsyncResult`](#sqliteexecuteasyncresult) instance.
|
|
14
24
|
* @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.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SQLiteStatement.d.ts","sourceRoot":"","sources":["../src/SQLiteStatement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EAIzB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,KAAK,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;AAE/C;;GAEG;AACH,qBAAa,eAAe;
|
|
1
|
+
{"version":3,"file":"SQLiteStatement.d.ts","sourceRoot":"","sources":["../src/SQLiteStatement.ts"],"names":[],"mappings":"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"}
|
package/build/SQLiteStatement.js
CHANGED
|
@@ -5,17 +5,31 @@ import { composeRow, composeRows, normalizeParams } from './paramUtils';
|
|
|
5
5
|
export class SQLiteStatement {
|
|
6
6
|
nativeDatabase;
|
|
7
7
|
nativeStatement;
|
|
8
|
+
/**
|
|
9
|
+
* The cursor that currently owns the underlying `sqlite3_stmt`. A prepared statement has exactly
|
|
10
|
+
* one cursor, so running the statement again invalidates the cursor of every earlier run.
|
|
11
|
+
*/
|
|
12
|
+
currentCursor = null;
|
|
8
13
|
constructor(nativeDatabase, nativeStatement) {
|
|
9
14
|
this.nativeDatabase = nativeDatabase;
|
|
10
15
|
this.nativeStatement = nativeStatement;
|
|
11
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Make the run that just finished the owner of the statement cursor, and return a predicate
|
|
19
|
+
* that tells whether it still is.
|
|
20
|
+
*/
|
|
21
|
+
claimCursor() {
|
|
22
|
+
const cursor = {};
|
|
23
|
+
this.currentCursor = cursor;
|
|
24
|
+
return () => this.currentCursor === cursor;
|
|
25
|
+
}
|
|
12
26
|
async executeAsync(...params) {
|
|
13
27
|
const { lastInsertRowId, changes, firstRowValues } = await this.nativeStatement.runAsync(this.nativeDatabase, ...normalizeParams(...params));
|
|
14
28
|
return createSQLiteExecuteAsyncResult(this.nativeDatabase, this.nativeStatement, firstRowValues, {
|
|
15
29
|
rawResult: false,
|
|
16
30
|
lastInsertRowId,
|
|
17
31
|
changes,
|
|
18
|
-
});
|
|
32
|
+
}, this.claimCursor());
|
|
19
33
|
}
|
|
20
34
|
async executeForRawResultAsync(...params) {
|
|
21
35
|
const { lastInsertRowId, changes, firstRowValues } = await this.nativeStatement.runAsync(this.nativeDatabase, ...normalizeParams(...params));
|
|
@@ -23,7 +37,7 @@ export class SQLiteStatement {
|
|
|
23
37
|
rawResult: true,
|
|
24
38
|
lastInsertRowId,
|
|
25
39
|
changes,
|
|
26
|
-
});
|
|
40
|
+
}, this.claimCursor());
|
|
27
41
|
}
|
|
28
42
|
/**
|
|
29
43
|
* Get the column names of the prepared statement.
|
|
@@ -48,7 +62,7 @@ export class SQLiteStatement {
|
|
|
48
62
|
rawResult: false,
|
|
49
63
|
lastInsertRowId,
|
|
50
64
|
changes,
|
|
51
|
-
});
|
|
65
|
+
}, this.claimCursor());
|
|
52
66
|
}
|
|
53
67
|
executeForRawResultSync(...params) {
|
|
54
68
|
const { lastInsertRowId, changes, firstRowValues } = this.nativeStatement.runSync(this.nativeDatabase, ...normalizeParams(...params));
|
|
@@ -56,7 +70,7 @@ export class SQLiteStatement {
|
|
|
56
70
|
rawResult: true,
|
|
57
71
|
lastInsertRowId,
|
|
58
72
|
changes,
|
|
59
|
-
});
|
|
73
|
+
}, this.claimCursor());
|
|
60
74
|
}
|
|
61
75
|
/**
|
|
62
76
|
* Get the column names of the prepared statement.
|
|
@@ -77,14 +91,18 @@ export class SQLiteStatement {
|
|
|
77
91
|
this.nativeStatement.finalizeSync(this.nativeDatabase);
|
|
78
92
|
}
|
|
79
93
|
}
|
|
94
|
+
const SUPERSEDED_CURSOR_MESSAGE = 'This result is no longer readable because the prepared statement ran again. ' +
|
|
95
|
+
'A prepared statement holds a single SQLite cursor, so a later run rebinds the parameters and moves that cursor, ' +
|
|
96
|
+
'and this result would return the rows of the later run. ' +
|
|
97
|
+
'Read a result to the end before you run the same statement again, or prepare a separate statement for each reader.';
|
|
80
98
|
/**
|
|
81
99
|
* Create the `SQLiteExecuteAsyncResult` instance.
|
|
82
100
|
*
|
|
83
101
|
* NOTE: Since Hermes does not support the `Symbol.asyncIterator` feature, we have to use an AsyncGenerator to implement the `AsyncIterableIterator` interface.
|
|
84
102
|
* This is done by `Object.defineProperties` to add the properties to the AsyncGenerator.
|
|
85
103
|
*/
|
|
86
|
-
async function createSQLiteExecuteAsyncResult(database, statement, firstRowValues, options) {
|
|
87
|
-
const instance = new SQLiteExecuteAsyncResultImpl(database, statement, firstRowValues ? processNativeRow(firstRowValues) : null, options);
|
|
104
|
+
async function createSQLiteExecuteAsyncResult(database, statement, firstRowValues, options, isCursorOwner) {
|
|
105
|
+
const instance = new SQLiteExecuteAsyncResultImpl(database, statement, firstRowValues ? processNativeRow(firstRowValues) : null, options, isCursorOwner);
|
|
88
106
|
const generator = instance.generatorAsync();
|
|
89
107
|
Object.defineProperties(generator, {
|
|
90
108
|
lastInsertRowId: {
|
|
@@ -118,8 +136,8 @@ async function createSQLiteExecuteAsyncResult(database, statement, firstRowValue
|
|
|
118
136
|
/**
|
|
119
137
|
* Create the `SQLiteExecuteSyncResult` instance.
|
|
120
138
|
*/
|
|
121
|
-
function createSQLiteExecuteSyncResult(database, statement, firstRowValues, options) {
|
|
122
|
-
const instance = new SQLiteExecuteSyncResultImpl(database, statement, firstRowValues ? processNativeRow(firstRowValues) : firstRowValues, options);
|
|
139
|
+
function createSQLiteExecuteSyncResult(database, statement, firstRowValues, options, isCursorOwner) {
|
|
140
|
+
const instance = new SQLiteExecuteSyncResultImpl(database, statement, firstRowValues ? processNativeRow(firstRowValues) : firstRowValues, options, isCursorOwner);
|
|
123
141
|
const generator = instance.generatorSync();
|
|
124
142
|
Object.defineProperties(generator, {
|
|
125
143
|
lastInsertRowId: {
|
|
@@ -155,13 +173,21 @@ class SQLiteExecuteAsyncResultImpl {
|
|
|
155
173
|
statement;
|
|
156
174
|
firstRowValues;
|
|
157
175
|
options;
|
|
176
|
+
isCursorOwner;
|
|
158
177
|
columnNames = null;
|
|
159
178
|
isStepCalled = false;
|
|
160
|
-
constructor(database, statement, firstRowValues, options) {
|
|
179
|
+
constructor(database, statement, firstRowValues, options, isCursorOwner) {
|
|
161
180
|
this.database = database;
|
|
162
181
|
this.statement = statement;
|
|
163
182
|
this.firstRowValues = firstRowValues;
|
|
164
183
|
this.options = options;
|
|
184
|
+
this.isCursorOwner = isCursorOwner;
|
|
185
|
+
}
|
|
186
|
+
/** Throw rather than step a cursor that a later run of the same statement has taken over. */
|
|
187
|
+
assertCursorOwner() {
|
|
188
|
+
if (!this.isCursorOwner()) {
|
|
189
|
+
throw new Error(SUPERSEDED_CURSOR_MESSAGE);
|
|
190
|
+
}
|
|
165
191
|
}
|
|
166
192
|
async getFirstAsync() {
|
|
167
193
|
if (this.isStepCalled) {
|
|
@@ -173,6 +199,7 @@ class SQLiteExecuteAsyncResultImpl {
|
|
|
173
199
|
if (firstRowValues != null) {
|
|
174
200
|
return composeRowIfNeeded(this.options.rawResult, columnNames, firstRowValues);
|
|
175
201
|
}
|
|
202
|
+
this.assertCursorOwner();
|
|
176
203
|
const firstRow = await this.statement.stepAsync(this.database);
|
|
177
204
|
return firstRow != null
|
|
178
205
|
? composeRowIfNeeded(this.options.rawResult, columnNames, processNativeRow(firstRow))
|
|
@@ -189,9 +216,10 @@ class SQLiteExecuteAsyncResultImpl {
|
|
|
189
216
|
return [];
|
|
190
217
|
}
|
|
191
218
|
const columnNames = await this.getColumnNamesAsync();
|
|
219
|
+
this.assertCursorOwner();
|
|
192
220
|
const nativeRows = await this.statement.getAllAsync(this.database);
|
|
193
221
|
const allRows = processNativeRows(nativeRows);
|
|
194
|
-
if (firstRowValues
|
|
222
|
+
if (firstRowValues.length > 0) {
|
|
195
223
|
return composeRowsIfNeeded(this.options.rawResult, columnNames, [
|
|
196
224
|
firstRowValues,
|
|
197
225
|
...allRows,
|
|
@@ -208,16 +236,18 @@ class SQLiteExecuteAsyncResultImpl {
|
|
|
208
236
|
}
|
|
209
237
|
let result;
|
|
210
238
|
do {
|
|
239
|
+
this.assertCursorOwner();
|
|
211
240
|
result = await this.statement.stepAsync(this.database);
|
|
212
241
|
if (result != null) {
|
|
213
242
|
yield composeRowIfNeeded(this.options.rawResult, columnNames, processNativeRow(result));
|
|
214
243
|
}
|
|
215
244
|
} while (result != null);
|
|
216
245
|
}
|
|
217
|
-
resetAsync() {
|
|
218
|
-
|
|
246
|
+
async resetAsync() {
|
|
247
|
+
// Resetting a superseded result would rewind the cursor of the run that owns it now.
|
|
248
|
+
this.assertCursorOwner();
|
|
249
|
+
await this.statement.resetAsync(this.database);
|
|
219
250
|
this.isStepCalled = false;
|
|
220
|
-
return result;
|
|
221
251
|
}
|
|
222
252
|
popFirstRowValues() {
|
|
223
253
|
if (this.firstRowValues != null) {
|
|
@@ -239,13 +269,21 @@ class SQLiteExecuteSyncResultImpl {
|
|
|
239
269
|
statement;
|
|
240
270
|
firstRowValues;
|
|
241
271
|
options;
|
|
272
|
+
isCursorOwner;
|
|
242
273
|
columnNames = null;
|
|
243
274
|
isStepCalled = false;
|
|
244
|
-
constructor(database, statement, firstRowValues, options) {
|
|
275
|
+
constructor(database, statement, firstRowValues, options, isCursorOwner) {
|
|
245
276
|
this.database = database;
|
|
246
277
|
this.statement = statement;
|
|
247
278
|
this.firstRowValues = firstRowValues;
|
|
248
279
|
this.options = options;
|
|
280
|
+
this.isCursorOwner = isCursorOwner;
|
|
281
|
+
}
|
|
282
|
+
/** Throw rather than step a cursor that a later run of the same statement has taken over. */
|
|
283
|
+
assertCursorOwner() {
|
|
284
|
+
if (!this.isCursorOwner()) {
|
|
285
|
+
throw new Error(SUPERSEDED_CURSOR_MESSAGE);
|
|
286
|
+
}
|
|
249
287
|
}
|
|
250
288
|
getFirstSync() {
|
|
251
289
|
if (this.isStepCalled) {
|
|
@@ -256,6 +294,7 @@ class SQLiteExecuteSyncResultImpl {
|
|
|
256
294
|
if (firstRowValues != null) {
|
|
257
295
|
return composeRowIfNeeded(this.options.rawResult, columnNames, firstRowValues);
|
|
258
296
|
}
|
|
297
|
+
this.assertCursorOwner();
|
|
259
298
|
const firstRow = this.statement.stepSync(this.database);
|
|
260
299
|
return firstRow != null
|
|
261
300
|
? composeRowIfNeeded(this.options.rawResult, columnNames, processNativeRow(firstRow))
|
|
@@ -271,6 +310,7 @@ class SQLiteExecuteSyncResultImpl {
|
|
|
271
310
|
return [];
|
|
272
311
|
}
|
|
273
312
|
const columnNames = this.getColumnNamesSync();
|
|
313
|
+
this.assertCursorOwner();
|
|
274
314
|
const nativeRows = this.statement.getAllSync(this.database);
|
|
275
315
|
const allRows = processNativeRows(nativeRows);
|
|
276
316
|
if (firstRowValues != null && firstRowValues.length > 0) {
|
|
@@ -289,6 +329,7 @@ class SQLiteExecuteSyncResultImpl {
|
|
|
289
329
|
}
|
|
290
330
|
let result;
|
|
291
331
|
do {
|
|
332
|
+
this.assertCursorOwner();
|
|
292
333
|
result = this.statement.stepSync(this.database);
|
|
293
334
|
if (result != null) {
|
|
294
335
|
yield composeRowIfNeeded(this.options.rawResult, columnNames, processNativeRow(result));
|
|
@@ -296,9 +337,10 @@ class SQLiteExecuteSyncResultImpl {
|
|
|
296
337
|
} while (result != null);
|
|
297
338
|
}
|
|
298
339
|
resetSync() {
|
|
299
|
-
|
|
340
|
+
// Resetting a superseded result would rewind the cursor of the run that owns it now.
|
|
341
|
+
this.assertCursorOwner();
|
|
342
|
+
this.statement.resetSync(this.database);
|
|
300
343
|
this.isStepCalled = false;
|
|
301
|
-
return result;
|
|
302
344
|
}
|
|
303
345
|
popFirstRowValues() {
|
|
304
346
|
if (this.firstRowValues != null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SQLiteStatement.js","sourceRoot":"","sources":["../src/SQLiteStatement.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWxE;;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,cAAc,EACd;YACE,SAAS,EAAE,KAAK;YAChB,eAAe;YACf,OAAO;SACR,CACF,CAAC;IACJ,CAAC;IAeM,KAAK,CAAC,wBAAwB,CACnC,GAAG,MAAiB;QAEpB,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,cAAc,EACd;YACE,SAAS,EAAE,IAAI;YACf,eAAe;YACf,OAAO;SACR,CACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,mBAAmB;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;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,cAAc,EACd;YACE,SAAS,EAAE,KAAK;YAChB,eAAe;YACf,OAAO;SACR,CACF,CAAC;IACJ,CAAC;IAeM,uBAAuB,CAC5B,GAAG,MAAiB;QAEpB,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,cAAc,EACd;YACE,SAAS,EAAE,IAAI;YACf,eAAe;YACf,OAAO;SACR,CACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,kBAAkB;QACvB,OAAO,IAAI,CAAC,eAAe,CAAC,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED;;;;;;;;OAQG;IACI,YAAY;QACjB,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzD,CAAC;CAGF;AA6JD;;;;;GAKG;AACH,KAAK,UAAU,8BAA8B,CAC3C,QAA2B,EAC3B,SAA0B,EAC1B,cAAyC,EACzC,OAAmC;IAEnC,MAAM,QAAQ,GAAG,IAAI,4BAA4B,CAC/C,QAAQ,EACR,SAAS,EACT,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,EACxD,OAAO,CACR,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC5C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE;QACjC,eAAe,EAAE;YACf,KAAK,EAAE,OAAO,CAAC,eAAe;YAC9B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;QAC1F,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,cAAyC,EACzC,OAAmC;IAEnC,MAAM,QAAQ,GAAG,IAAI,2BAA2B,CAC9C,QAAQ,EACR,SAAS,EACT,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,EAClE,OAAO,CACR,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC3C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE;QACjC,eAAe,EAAE;YACf,KAAK,EAAE,OAAO,CAAC,eAAe;YAC9B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;QAC1F,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;IACT;IACQ;IAPV,WAAW,GAAoB,IAAI,CAAC;IACpC,YAAY,GAAG,KAAK,CAAC;IAE7B,YACmB,QAA2B,EAC3B,SAA0B,EACnC,cAAyC,EACjC,OAAmC;QAHlC,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,cAAS,GAAT,SAAS,CAAiB;QACnC,mBAAc,GAAd,cAAc,CAA2B;QACjC,YAAO,GAAP,OAAO,CAA4B;IAClD,CAAC;IAEJ,KAAK,CAAC,aAAa;QACjB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,wLAAwL,CACzL,CAAC;QACJ,CAAC;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,CAAC;YAC3B,OAAO,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/D,OAAO,QAAQ,IAAI,IAAI;YACrB,CAAC,CAAC,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YACxF,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,8KAA8K,CAC/K,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,mIAAmI;YACnI,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,cAAc,IAAI,IAAI,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE;gBACjE,cAAc;gBACd,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QACD,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9E,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,CAAC;YAC3B,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACnF,CAAC;QAED,IAAI,MAAM,CAAC;QACX,GAAG,CAAC;YACF,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC,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,CAAC;YAChC,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;QAC3D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,mBAAmB;QAC/B,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;QAChE,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,2BAA2B;IAKZ;IACA;IACT;IACQ;IAPV,WAAW,GAAoB,IAAI,CAAC;IACpC,YAAY,GAAG,KAAK,CAAC;IAE7B,YACmB,QAA2B,EAC3B,SAA0B,EACnC,cAAyC,EACjC,OAAmC;QAHlC,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,cAAS,GAAT,SAAS,CAAiB;QACnC,mBAAc,GAAd,cAAc,CAA2B;QACjC,YAAO,GAAP,OAAO,CAA4B;IAClD,CAAC;IAEJ,YAAY;QACV,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,uLAAuL,CACxL,CAAC;QACJ,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,OAAO,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,OAAO,QAAQ,IAAI,IAAI;YACrB,CAAC,CAAC,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YACxF,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,6KAA6K,CAC9K,CAAC;QACJ,CAAC;QACD,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,mIAAmI;YACnI,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,cAAc,IAAI,IAAI,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE;gBACjE,cAAc;gBACd,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QACD,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9E,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,CAAC;YAC3B,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,MAAM,CAAC;QACX,GAAG,CAAC;YACF,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC,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,CAAC;YAChC,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;QAC3D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,kBAAkB;QACxB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;QACzD,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,SAAS,kBAAkB,CACzB,SAAkB,EAClB,WAA8B,EAC9B,YAAgC;IAEhC,OAAO,SAAS;QACd,CAAC,CAAE,YAAkB,CAAC,sCAAsC;QAC5D,CAAC,CAAC,UAAU,CAAI,WAAW,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,mBAAmB,CAC1B,SAAkB,EAClB,WAA8B,EAC9B,gBAAsC;IAEtC,OAAO,SAAS;QACd,CAAC,CAAE,gBAAwB,CAAC,0CAA0C;QACtE,CAAC,CAAC,WAAW,CAAI,WAAW,EAAE,gBAAgB,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,gBAAgB,CAAC,SAA6B;IACrD,OAAO,SAAS,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAC/B,MAAM,YAAY,WAAW,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAChE,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,UAAgC;IACzD,OAAO,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAC1C,CAAC;AAED,YAAY","sourcesContent":["import type { NativeDatabase } from './NativeDatabase';\nimport type {\n NativeStatement,\n SQLiteBindParams,\n SQLiteVariadicBindParams,\n SQLiteAnyDatabase,\n SQLiteColumnNames,\n SQLiteColumnValues,\n} from './NativeStatement';\nimport { composeRow, composeRows, normalizeParams } from './paramUtils';\n\nexport type {\n SQLiteBindParams,\n SQLiteBindValue,\n SQLiteRunResult,\n SQLiteVariadicBindParams,\n} from './NativeStatement';\n\ntype ValuesOf<T extends object> = T[keyof T][];\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 firstRowValues,\n {\n rawResult: false,\n lastInsertRowId,\n changes,\n }\n );\n }\n\n /**\n * Similar to [`executeAsync()`](#executeasyncparams) but returns the raw value array result instead of the row objects.\n * @hidden Advanced use only.\n */\n public executeForRawResultAsync<T extends object>(\n params: SQLiteBindParams\n ): Promise<SQLiteExecuteAsyncResult<ValuesOf<T>>>;\n /**\n * @hidden\n */\n public executeForRawResultAsync<T extends object>(\n ...params: SQLiteVariadicBindParams\n ): Promise<SQLiteExecuteAsyncResult<ValuesOf<T>>>;\n public async executeForRawResultAsync<T extends object>(\n ...params: unknown[]\n ): Promise<SQLiteExecuteAsyncResult<ValuesOf<T>>> {\n const { lastInsertRowId, changes, firstRowValues } = await this.nativeStatement.runAsync(\n this.nativeDatabase,\n ...normalizeParams(...params)\n );\n return createSQLiteExecuteAsyncResult<ValuesOf<T>>(\n this.nativeDatabase,\n this.nativeStatement,\n firstRowValues,\n {\n rawResult: true,\n lastInsertRowId,\n changes,\n }\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\n * > to manually finalize prepared statements as soon as they are no longer needed. This helps to prevent resource leaks.\n * > 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 firstRowValues,\n {\n rawResult: false,\n lastInsertRowId,\n changes,\n }\n );\n }\n\n /**\n * Similar to [`executeSync()`](#executesyncparams) but returns the raw value array result instead of the row objects.\n * @hidden Advanced use only.\n */\n public executeForRawResultSync<T extends object>(\n params: SQLiteBindParams\n ): SQLiteExecuteSyncResult<ValuesOf<T>>;\n /**\n * @hidden\n */\n public executeForRawResultSync<T extends object>(\n ...params: SQLiteVariadicBindParams\n ): SQLiteExecuteSyncResult<ValuesOf<T>>;\n public executeForRawResultSync<T extends object>(\n ...params: unknown[]\n ): SQLiteExecuteSyncResult<ValuesOf<T>> {\n const { lastInsertRowId, changes, firstRowValues } = this.nativeStatement.runSync(\n this.nativeDatabase,\n ...normalizeParams(...params)\n );\n return createSQLiteExecuteSyncResult<ValuesOf<T>>(\n this.nativeDatabase,\n this.nativeStatement,\n firstRowValues,\n {\n rawResult: true,\n lastInsertRowId,\n changes,\n }\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 *\n * > **Note:** While `expo-sqlite` will automatically finalize any orphaned prepared statements upon closing the database, it is considered best practice\n * > to manually finalize prepared statements as soon as they are no longer needed. This helps to prevent resource leaks.\n * > 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\ninterface SQLiteExecuteResultOptions {\n rawResult: boolean;\n lastInsertRowId: number;\n changes: number;\n}\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 firstRowValues: SQLiteColumnValues | null,\n options: SQLiteExecuteResultOptions\n): Promise<SQLiteExecuteAsyncResult<T>> {\n const instance = new SQLiteExecuteAsyncResultImpl<T>(\n database,\n statement,\n firstRowValues ? processNativeRow(firstRowValues) : null,\n options\n );\n const generator = instance.generatorAsync();\n Object.defineProperties(generator, {\n lastInsertRowId: {\n value: options.lastInsertRowId,\n enumerable: true,\n writable: false,\n configurable: true,\n },\n changes: { value: options.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 firstRowValues: SQLiteColumnValues | null,\n options: SQLiteExecuteResultOptions\n): SQLiteExecuteSyncResult<T> {\n const instance = new SQLiteExecuteSyncResultImpl<T>(\n database,\n statement,\n firstRowValues ? processNativeRow(firstRowValues) : firstRowValues,\n options\n );\n const generator = instance.generatorSync();\n Object.defineProperties(generator, {\n lastInsertRowId: {\n value: options.lastInsertRowId,\n enumerable: true,\n writable: false,\n configurable: true,\n },\n changes: { value: options.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 private firstRowValues: SQLiteColumnValues | null,\n public readonly options: SQLiteExecuteResultOptions\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 composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n const firstRow = await this.statement.stepAsync(this.database);\n return firstRow != null\n ? composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(firstRow))\n : 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 firstRowValues = this.popFirstRowValues();\n if (firstRowValues == null) {\n // If the first row is empty, this SQL query may be a write operation. We should not call `statement.getAllAsync()` to write again.\n return [];\n }\n const columnNames = await this.getColumnNamesAsync();\n const nativeRows = await this.statement.getAllAsync(this.database);\n const allRows = processNativeRows(nativeRows);\n if (firstRowValues != null && firstRowValues.length > 0) {\n return composeRowsIfNeeded<T>(this.options.rawResult, columnNames, [\n firstRowValues,\n ...allRows,\n ]);\n }\n return composeRowsIfNeeded<T>(this.options.rawResult, 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 composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n\n let result;\n do {\n result = await this.statement.stepAsync(this.database);\n if (result != null) {\n yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(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 private firstRowValues: SQLiteColumnValues | null,\n public readonly options: SQLiteExecuteResultOptions\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 composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n const firstRow = this.statement.stepSync(this.database);\n return firstRow != null\n ? composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(firstRow))\n : 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 firstRowValues = this.popFirstRowValues();\n if (firstRowValues == null) {\n // If the first row is empty, this SQL query may be a write operation. We should not call `statement.getAllAsync()` to write again.\n return [];\n }\n const columnNames = this.getColumnNamesSync();\n const nativeRows = this.statement.getAllSync(this.database);\n const allRows = processNativeRows(nativeRows);\n if (firstRowValues != null && firstRowValues.length > 0) {\n return composeRowsIfNeeded<T>(this.options.rawResult, columnNames, [\n firstRowValues,\n ...allRows,\n ]);\n }\n return composeRowsIfNeeded<T>(this.options.rawResult, columnNames, allRows);\n }\n\n *generatorSync(): IterableIterator<T> {\n const columnNames = this.getColumnNamesSync();\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null) {\n yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n let result;\n do {\n result = this.statement.stepSync(this.database);\n if (result != null) {\n yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(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\nfunction composeRowIfNeeded<T>(\n rawResult: boolean,\n columnNames: SQLiteColumnNames,\n columnValues: SQLiteColumnValues\n): T {\n return rawResult\n ? (columnValues as T) // T would be a ValuesOf<> from caller\n : composeRow<T>(columnNames, columnValues);\n}\n\nfunction composeRowsIfNeeded<T>(\n rawResult: boolean,\n columnNames: SQLiteColumnNames,\n columnValuesList: SQLiteColumnValues[]\n): T[] {\n return rawResult\n ? (columnValuesList as T[]) // T[] would be a ValuesOf<>[] from caller\n : composeRows<T>(columnNames, columnValuesList);\n}\n\nfunction processNativeRow(nativeRow: SQLiteColumnValues): SQLiteColumnValues {\n return nativeRow?.map((column) =>\n column instanceof ArrayBuffer ? new Uint8Array(column) : column\n );\n}\n\nfunction processNativeRows(nativeRows: SQLiteColumnValues[]): SQLiteColumnValues[] {\n return nativeRows.map(processNativeRow);\n}\n\n//#endregion\n"]}
|
|
1
|
+
{"version":3,"file":"SQLiteStatement.js","sourceRoot":"","sources":["../src/SQLiteStatement.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWxE;;GAEG;AACH,MAAM,OAAO,eAAe;IAQP;IACA;IARnB;;;OAGG;IACK,aAAa,GAAkB,IAAI,CAAC;IAE5C,YACmB,cAA8B,EAC9B,eAAgC;QADhC,mBAAc,GAAd,cAAc,CAAgB;QAC9B,oBAAe,GAAf,eAAe,CAAiB;IAChD,CAAC;IAEJ;;;OAGG;IACK,WAAW;QACjB,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;QAC5B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,KAAK,MAAM,CAAC;IAC7C,CAAC;IAaM,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,cAAc,EACd;YACE,SAAS,EAAE,KAAK;YAChB,eAAe;YACf,OAAO;SACR,EACD,IAAI,CAAC,WAAW,EAAE,CACnB,CAAC;IACJ,CAAC;IAeM,KAAK,CAAC,wBAAwB,CACnC,GAAG,MAAiB;QAEpB,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,cAAc,EACd;YACE,SAAS,EAAE,IAAI;YACf,eAAe;YACf,OAAO;SACR,EACD,IAAI,CAAC,WAAW,EAAE,CACnB,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,mBAAmB;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC,mBAAmB,EAAE,CAAC;IACpD,CAAC;IAED;;;;;;;OAOG;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,cAAc,EACd;YACE,SAAS,EAAE,KAAK;YAChB,eAAe;YACf,OAAO;SACR,EACD,IAAI,CAAC,WAAW,EAAE,CACnB,CAAC;IACJ,CAAC;IAeM,uBAAuB,CAC5B,GAAG,MAAiB;QAEpB,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,cAAc,EACd;YACE,SAAS,EAAE,IAAI;YACf,eAAe;YACf,OAAO;SACR,EACD,IAAI,CAAC,WAAW,EAAE,CACnB,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,kBAAkB;QACvB,OAAO,IAAI,CAAC,eAAe,CAAC,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED;;;;;;;;OAQG;IACI,YAAY;QACjB,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzD,CAAC;CAGF;AA6JD,MAAM,yBAAyB,GAC7B,8EAA8E;IAC9E,kHAAkH;IAClH,0DAA0D;IAC1D,oHAAoH,CAAC;AAEvH;;;;;GAKG;AACH,KAAK,UAAU,8BAA8B,CAC3C,QAA2B,EAC3B,SAA0B,EAC1B,cAAyC,EACzC,OAAmC,EACnC,aAA4B;IAE5B,MAAM,QAAQ,GAAG,IAAI,4BAA4B,CAC/C,QAAQ,EACR,SAAS,EACT,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,EACxD,OAAO,EACP,aAAa,CACd,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC5C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE;QACjC,eAAe,EAAE;YACf,KAAK,EAAE,OAAO,CAAC,eAAe;YAC9B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;QAC1F,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,cAAyC,EACzC,OAAmC,EACnC,aAA4B;IAE5B,MAAM,QAAQ,GAAG,IAAI,2BAA2B,CAC9C,QAAQ,EACR,SAAS,EACT,cAAc,CAAC,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,EAClE,OAAO,EACP,aAAa,CACd,CAAC;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC3C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE;QACjC,eAAe,EAAE;YACf,KAAK,EAAE,OAAO,CAAC,eAAe;YAC9B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB;QACD,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;QAC1F,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;IACT;IACQ;IACC;IARX,WAAW,GAAoB,IAAI,CAAC;IACpC,YAAY,GAAG,KAAK,CAAC;IAE7B,YACmB,QAA2B,EAC3B,SAA0B,EACnC,cAAyC,EACjC,OAAmC,EAClC,aAA4B;QAJ5B,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,cAAS,GAAT,SAAS,CAAiB;QACnC,mBAAc,GAAd,cAAc,CAA2B;QACjC,YAAO,GAAP,OAAO,CAA4B;QAClC,kBAAa,GAAb,aAAa,CAAe;IAC5C,CAAC;IAEJ,6FAA6F;IACrF,iBAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,wLAAwL,CACzL,CAAC;QACJ,CAAC;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,CAAC;YAC3B,OAAO,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/D,OAAO,QAAQ,IAAI,IAAI;YACrB,CAAC,CAAC,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YACxF,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,8KAA8K,CAC/K,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,mIAAmI;YACnI,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE;gBACjE,cAAc;gBACd,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QACD,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9E,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,CAAC;YAC3B,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACnF,CAAC;QAED,IAAI,MAAM,CAAC;QACX,GAAG,CAAC;YACF,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC,QAAQ,MAAM,IAAI,IAAI,EAAE;IAC3B,CAAC;IAED,KAAK,CAAC,UAAU;QACd,qFAAqF;QACrF,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;YAChC,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;QAC3D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,mBAAmB;QAC/B,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;QAChE,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,2BAA2B;IAKZ;IACA;IACT;IACQ;IACC;IARX,WAAW,GAAoB,IAAI,CAAC;IACpC,YAAY,GAAG,KAAK,CAAC;IAE7B,YACmB,QAA2B,EAC3B,SAA0B,EACnC,cAAyC,EACjC,OAAmC,EAClC,aAA4B;QAJ5B,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,cAAS,GAAT,SAAS,CAAiB;QACnC,mBAAc,GAAd,cAAc,CAA2B;QACjC,YAAO,GAAP,OAAO,CAA4B;QAClC,kBAAa,GAAb,aAAa,CAAe;IAC5C,CAAC;IAEJ,6FAA6F;IACrF,iBAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,uLAAuL,CACxL,CAAC;QACJ,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,OAAO,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,OAAO,QAAQ,IAAI,IAAI;YACrB,CAAC,CAAC,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YACxF,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,6KAA6K,CAC9K,CAAC;QACJ,CAAC;QACD,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,mIAAmI;YACnI,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,cAAc,IAAI,IAAI,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE;gBACjE,cAAc;gBACd,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QACD,OAAO,mBAAmB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC9E,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,CAAC;YAC3B,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,MAAM,CAAC;QACX,GAAG,CAAC;YACF,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,kBAAkB,CAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC,QAAQ,MAAM,IAAI,IAAI,EAAE;IAC3B,CAAC;IAED,SAAS;QACP,qFAAqF;QACrF,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;YAChC,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;QAC3D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,kBAAkB;QACxB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;QACzD,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,SAAS,kBAAkB,CACzB,SAAkB,EAClB,WAA8B,EAC9B,YAAgC;IAEhC,OAAO,SAAS;QACd,CAAC,CAAE,YAAkB,CAAC,sCAAsC;QAC5D,CAAC,CAAC,UAAU,CAAI,WAAW,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,mBAAmB,CAC1B,SAAkB,EAClB,WAA8B,EAC9B,gBAAsC;IAEtC,OAAO,SAAS;QACd,CAAC,CAAE,gBAAwB,CAAC,0CAA0C;QACtE,CAAC,CAAC,WAAW,CAAI,WAAW,EAAE,gBAAgB,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,gBAAgB,CAAC,SAA6B;IACrD,OAAO,SAAS,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAC/B,MAAM,YAAY,WAAW,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAChE,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,UAAgC;IACzD,OAAO,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAC1C,CAAC;AAED,YAAY","sourcesContent":["import type { NativeDatabase } from './NativeDatabase';\nimport type {\n NativeStatement,\n SQLiteBindParams,\n SQLiteVariadicBindParams,\n SQLiteAnyDatabase,\n SQLiteColumnNames,\n SQLiteColumnValues,\n} from './NativeStatement';\nimport { composeRow, composeRows, normalizeParams } from './paramUtils';\n\nexport type {\n SQLiteBindParams,\n SQLiteBindValue,\n SQLiteRunResult,\n SQLiteVariadicBindParams,\n} from './NativeStatement';\n\ntype ValuesOf<T extends object> = T[keyof T][];\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 /**\n * The cursor that currently owns the underlying `sqlite3_stmt`. A prepared statement has exactly\n * one cursor, so running the statement again invalidates the cursor of every earlier run.\n */\n private currentCursor: object | null = null;\n\n constructor(\n private readonly nativeDatabase: NativeDatabase,\n private readonly nativeStatement: NativeStatement\n ) {}\n\n /**\n * Make the run that just finished the owner of the statement cursor, and return a predicate\n * that tells whether it still is.\n */\n private claimCursor(): () => boolean {\n const cursor = {};\n this.currentCursor = cursor;\n return () => this.currentCursor === cursor;\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 firstRowValues,\n {\n rawResult: false,\n lastInsertRowId,\n changes,\n },\n this.claimCursor()\n );\n }\n\n /**\n * Similar to [`executeAsync()`](#executeasyncparams) but returns the raw value array result instead of the row objects.\n * @hidden Advanced use only.\n */\n public executeForRawResultAsync<T extends object>(\n params: SQLiteBindParams\n ): Promise<SQLiteExecuteAsyncResult<ValuesOf<T>>>;\n /**\n * @hidden\n */\n public executeForRawResultAsync<T extends object>(\n ...params: SQLiteVariadicBindParams\n ): Promise<SQLiteExecuteAsyncResult<ValuesOf<T>>>;\n public async executeForRawResultAsync<T extends object>(\n ...params: unknown[]\n ): Promise<SQLiteExecuteAsyncResult<ValuesOf<T>>> {\n const { lastInsertRowId, changes, firstRowValues } = await this.nativeStatement.runAsync(\n this.nativeDatabase,\n ...normalizeParams(...params)\n );\n return createSQLiteExecuteAsyncResult<ValuesOf<T>>(\n this.nativeDatabase,\n this.nativeStatement,\n firstRowValues,\n {\n rawResult: true,\n lastInsertRowId,\n changes,\n },\n this.claimCursor()\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\n * > to manually finalize prepared statements as soon as they are no longer needed. This helps to prevent resource leaks.\n * > 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 firstRowValues,\n {\n rawResult: false,\n lastInsertRowId,\n changes,\n },\n this.claimCursor()\n );\n }\n\n /**\n * Similar to [`executeSync()`](#executesyncparams) but returns the raw value array result instead of the row objects.\n * @hidden Advanced use only.\n */\n public executeForRawResultSync<T extends object>(\n params: SQLiteBindParams\n ): SQLiteExecuteSyncResult<ValuesOf<T>>;\n /**\n * @hidden\n */\n public executeForRawResultSync<T extends object>(\n ...params: SQLiteVariadicBindParams\n ): SQLiteExecuteSyncResult<ValuesOf<T>>;\n public executeForRawResultSync<T extends object>(\n ...params: unknown[]\n ): SQLiteExecuteSyncResult<ValuesOf<T>> {\n const { lastInsertRowId, changes, firstRowValues } = this.nativeStatement.runSync(\n this.nativeDatabase,\n ...normalizeParams(...params)\n );\n return createSQLiteExecuteSyncResult<ValuesOf<T>>(\n this.nativeDatabase,\n this.nativeStatement,\n firstRowValues,\n {\n rawResult: true,\n lastInsertRowId,\n changes,\n },\n this.claimCursor()\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 *\n * > **Note:** While `expo-sqlite` will automatically finalize any orphaned prepared statements upon closing the database, it is considered best practice\n * > to manually finalize prepared statements as soon as they are no longer needed. This helps to prevent resource leaks.\n * > 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\ninterface SQLiteExecuteResultOptions {\n rawResult: boolean;\n lastInsertRowId: number;\n changes: number;\n}\n\nconst SUPERSEDED_CURSOR_MESSAGE =\n 'This result is no longer readable because the prepared statement ran again. ' +\n 'A prepared statement holds a single SQLite cursor, so a later run rebinds the parameters and moves that cursor, ' +\n 'and this result would return the rows of the later run. ' +\n 'Read a result to the end before you run the same statement again, or prepare a separate statement for each reader.';\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 firstRowValues: SQLiteColumnValues | null,\n options: SQLiteExecuteResultOptions,\n isCursorOwner: () => boolean\n): Promise<SQLiteExecuteAsyncResult<T>> {\n const instance = new SQLiteExecuteAsyncResultImpl<T>(\n database,\n statement,\n firstRowValues ? processNativeRow(firstRowValues) : null,\n options,\n isCursorOwner\n );\n const generator = instance.generatorAsync();\n Object.defineProperties(generator, {\n lastInsertRowId: {\n value: options.lastInsertRowId,\n enumerable: true,\n writable: false,\n configurable: true,\n },\n changes: { value: options.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 firstRowValues: SQLiteColumnValues | null,\n options: SQLiteExecuteResultOptions,\n isCursorOwner: () => boolean\n): SQLiteExecuteSyncResult<T> {\n const instance = new SQLiteExecuteSyncResultImpl<T>(\n database,\n statement,\n firstRowValues ? processNativeRow(firstRowValues) : firstRowValues,\n options,\n isCursorOwner\n );\n const generator = instance.generatorSync();\n Object.defineProperties(generator, {\n lastInsertRowId: {\n value: options.lastInsertRowId,\n enumerable: true,\n writable: false,\n configurable: true,\n },\n changes: { value: options.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 private firstRowValues: SQLiteColumnValues | null,\n public readonly options: SQLiteExecuteResultOptions,\n private readonly isCursorOwner: () => boolean\n ) {}\n\n /** Throw rather than step a cursor that a later run of the same statement has taken over. */\n private assertCursorOwner() {\n if (!this.isCursorOwner()) {\n throw new Error(SUPERSEDED_CURSOR_MESSAGE);\n }\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 composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n this.assertCursorOwner();\n const firstRow = await this.statement.stepAsync(this.database);\n return firstRow != null\n ? composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(firstRow))\n : 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 firstRowValues = this.popFirstRowValues();\n if (firstRowValues == null) {\n // If the first row is empty, this SQL query may be a write operation. We should not call `statement.getAllAsync()` to write again.\n return [];\n }\n const columnNames = await this.getColumnNamesAsync();\n this.assertCursorOwner();\n const nativeRows = await this.statement.getAllAsync(this.database);\n const allRows = processNativeRows(nativeRows);\n if (firstRowValues.length > 0) {\n return composeRowsIfNeeded<T>(this.options.rawResult, columnNames, [\n firstRowValues,\n ...allRows,\n ]);\n }\n return composeRowsIfNeeded<T>(this.options.rawResult, 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 composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n\n let result;\n do {\n this.assertCursorOwner();\n result = await this.statement.stepAsync(this.database);\n if (result != null) {\n yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(result));\n }\n } while (result != null);\n }\n\n async resetAsync(): Promise<void> {\n // Resetting a superseded result would rewind the cursor of the run that owns it now.\n this.assertCursorOwner();\n await this.statement.resetAsync(this.database);\n this.isStepCalled = false;\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 private firstRowValues: SQLiteColumnValues | null,\n public readonly options: SQLiteExecuteResultOptions,\n private readonly isCursorOwner: () => boolean\n ) {}\n\n /** Throw rather than step a cursor that a later run of the same statement has taken over. */\n private assertCursorOwner() {\n if (!this.isCursorOwner()) {\n throw new Error(SUPERSEDED_CURSOR_MESSAGE);\n }\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 composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n this.assertCursorOwner();\n const firstRow = this.statement.stepSync(this.database);\n return firstRow != null\n ? composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(firstRow))\n : 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 firstRowValues = this.popFirstRowValues();\n if (firstRowValues == null) {\n // If the first row is empty, this SQL query may be a write operation. We should not call `statement.getAllAsync()` to write again.\n return [];\n }\n const columnNames = this.getColumnNamesSync();\n this.assertCursorOwner();\n const nativeRows = this.statement.getAllSync(this.database);\n const allRows = processNativeRows(nativeRows);\n if (firstRowValues != null && firstRowValues.length > 0) {\n return composeRowsIfNeeded<T>(this.options.rawResult, columnNames, [\n firstRowValues,\n ...allRows,\n ]);\n }\n return composeRowsIfNeeded<T>(this.options.rawResult, columnNames, allRows);\n }\n\n *generatorSync(): IterableIterator<T> {\n const columnNames = this.getColumnNamesSync();\n const firstRowValues = this.popFirstRowValues();\n if (firstRowValues != null) {\n yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);\n }\n let result;\n do {\n this.assertCursorOwner();\n result = this.statement.stepSync(this.database);\n if (result != null) {\n yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(result));\n }\n } while (result != null);\n }\n\n resetSync(): void {\n // Resetting a superseded result would rewind the cursor of the run that owns it now.\n this.assertCursorOwner();\n this.statement.resetSync(this.database);\n this.isStepCalled = false;\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\nfunction composeRowIfNeeded<T>(\n rawResult: boolean,\n columnNames: SQLiteColumnNames,\n columnValues: SQLiteColumnValues\n): T {\n return rawResult\n ? (columnValues as T) // T would be a ValuesOf<> from caller\n : composeRow<T>(columnNames, columnValues);\n}\n\nfunction composeRowsIfNeeded<T>(\n rawResult: boolean,\n columnNames: SQLiteColumnNames,\n columnValuesList: SQLiteColumnValues[]\n): T[] {\n return rawResult\n ? (columnValuesList as T[]) // T[] would be a ValuesOf<>[] from caller\n : composeRows<T>(columnNames, columnValuesList);\n}\n\nfunction processNativeRow(nativeRow: SQLiteColumnValues): SQLiteColumnValues {\n return nativeRow?.map((column) =>\n column instanceof ArrayBuffer ? new Uint8Array(column) : column\n );\n}\n\nfunction processNativeRows(nativeRows: SQLiteColumnValues[]): SQLiteColumnValues[] {\n return nativeRows.map(processNativeRow);\n}\n\n//#endregion\n"]}
|
package/expo-module.config.json
CHANGED
package/ios/SQLiteModule.swift
CHANGED
|
@@ -428,6 +428,13 @@ public final class SQLiteModule: Module {
|
|
|
428
428
|
private func step(statement: NativeStatement, database: NativeDatabase) throws -> SQLiteColumnValues? {
|
|
429
429
|
try maybeThrowForClosedDatabase(database)
|
|
430
430
|
try maybeThrowForFinalizedStatement(statement)
|
|
431
|
+
|
|
432
|
+
// Guard the stateful statement, see `run` above.
|
|
433
|
+
statement.lock.wait()
|
|
434
|
+
defer {
|
|
435
|
+
statement.lock.signal()
|
|
436
|
+
}
|
|
437
|
+
|
|
431
438
|
let ret = exsqlite3_step(statement.pointer)
|
|
432
439
|
if ret == SQLITE_ROW {
|
|
433
440
|
return try getColumnValues(statement: statement)
|
|
@@ -441,6 +448,13 @@ public final class SQLiteModule: Module {
|
|
|
441
448
|
private func getAll(statement: NativeStatement, database: NativeDatabase) throws -> [SQLiteColumnValues] {
|
|
442
449
|
try maybeThrowForClosedDatabase(database)
|
|
443
450
|
try maybeThrowForFinalizedStatement(statement)
|
|
451
|
+
|
|
452
|
+
// Guard the stateful statement, see `run` above.
|
|
453
|
+
statement.lock.wait()
|
|
454
|
+
defer {
|
|
455
|
+
statement.lock.signal()
|
|
456
|
+
}
|
|
457
|
+
|
|
444
458
|
var columnValuesList: [SQLiteColumnValues] = []
|
|
445
459
|
while true {
|
|
446
460
|
let ret = exsqlite3_step(statement.pointer)
|
|
@@ -459,6 +473,13 @@ public final class SQLiteModule: Module {
|
|
|
459
473
|
private func reset(statement: NativeStatement, database: NativeDatabase) throws {
|
|
460
474
|
try maybeThrowForClosedDatabase(database)
|
|
461
475
|
try maybeThrowForFinalizedStatement(statement)
|
|
476
|
+
|
|
477
|
+
// Guard the stateful statement, see `run` above.
|
|
478
|
+
statement.lock.wait()
|
|
479
|
+
defer {
|
|
480
|
+
statement.lock.signal()
|
|
481
|
+
}
|
|
482
|
+
|
|
462
483
|
if exsqlite3_reset(statement.pointer) != SQLITE_OK {
|
|
463
484
|
throw SQLiteErrorException(convertSqlLiteErrorToString(database))
|
|
464
485
|
}
|
|
@@ -467,6 +488,13 @@ public final class SQLiteModule: Module {
|
|
|
467
488
|
private func finalize(statement: NativeStatement, database: NativeDatabase) throws {
|
|
468
489
|
try maybeThrowForClosedDatabase(database)
|
|
469
490
|
try maybeThrowForFinalizedStatement(statement)
|
|
491
|
+
|
|
492
|
+
// Guard the stateful statement, see `run` above.
|
|
493
|
+
statement.lock.wait()
|
|
494
|
+
defer {
|
|
495
|
+
statement.lock.signal()
|
|
496
|
+
}
|
|
497
|
+
|
|
470
498
|
if exsqlite3_finalize(statement.pointer) != SQLITE_OK {
|
|
471
499
|
throw SQLiteErrorException(convertSqlLiteErrorToString(database))
|
|
472
500
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2a2a61f4c3d0acedc5a7bcb4b9e57d6b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c386518214d8885ee76a3a74d1fe9f1d3b4cbd26
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
02bdb019cd014cbe43cff391ee53f9eed49ff6c78e425113af3a892390822f29
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
37442b363d616ef7fd204893efb02ac15d4829aa5e2a3fe91be4b3cb17d9826f1d0abfdc9b3017b7618dfd85aa8156c234f39bc3ac7abd676072783d25e93125
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8a8943ce1632fc9989a6d5276e673c06
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
7324fa7559653d19ad9e9997f8e9bf98308e805c
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fafd65cc002c5173fe1935d4db3a860f7fb248e1252a18cd45374fd951183125
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9125c2a3ff328bf8a1491d7e235a9b77e842b01ff3b02013eba7769fcca0f486a3d56e08da83757b9ea429667fca726d92de122440b2b0e9df1d9711a379bab9
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "host.exp.exponent",
|
|
5
5
|
"module": "expo.modules.sqlite",
|
|
6
|
-
"version": "57.0.
|
|
6
|
+
"version": "57.0.4",
|
|
7
7
|
"attributes": {
|
|
8
8
|
"org.gradle.status": "release"
|
|
9
9
|
}
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
{
|
|
27
|
-
"name": "expo.modules.sqlite-57.0.
|
|
28
|
-
"url": "expo.modules.sqlite-57.0.
|
|
29
|
-
"size":
|
|
30
|
-
"sha512": "
|
|
31
|
-
"sha256": "
|
|
32
|
-
"sha1": "
|
|
33
|
-
"md5": "
|
|
27
|
+
"name": "expo.modules.sqlite-57.0.4.aar",
|
|
28
|
+
"url": "expo.modules.sqlite-57.0.4.aar",
|
|
29
|
+
"size": 3823428,
|
|
30
|
+
"sha512": "9125c2a3ff328bf8a1491d7e235a9b77e842b01ff3b02013eba7769fcca0f486a3d56e08da83757b9ea429667fca726d92de122440b2b0e9df1d9711a379bab9",
|
|
31
|
+
"sha256": "fafd65cc002c5173fe1935d4db3a860f7fb248e1252a18cd45374fd951183125",
|
|
32
|
+
"sha1": "7324fa7559653d19ad9e9997f8e9bf98308e805c",
|
|
33
|
+
"md5": "8a8943ce1632fc9989a6d5276e673c06"
|
|
34
34
|
}
|
|
35
35
|
]
|
|
36
36
|
},
|
|
@@ -67,13 +67,13 @@
|
|
|
67
67
|
],
|
|
68
68
|
"files": [
|
|
69
69
|
{
|
|
70
|
-
"name": "expo.modules.sqlite-57.0.
|
|
71
|
-
"url": "expo.modules.sqlite-57.0.
|
|
72
|
-
"size":
|
|
73
|
-
"sha512": "
|
|
74
|
-
"sha256": "
|
|
75
|
-
"sha1": "
|
|
76
|
-
"md5": "
|
|
70
|
+
"name": "expo.modules.sqlite-57.0.4.aar",
|
|
71
|
+
"url": "expo.modules.sqlite-57.0.4.aar",
|
|
72
|
+
"size": 3823428,
|
|
73
|
+
"sha512": "9125c2a3ff328bf8a1491d7e235a9b77e842b01ff3b02013eba7769fcca0f486a3d56e08da83757b9ea429667fca726d92de122440b2b0e9df1d9711a379bab9",
|
|
74
|
+
"sha256": "fafd65cc002c5173fe1935d4db3a860f7fb248e1252a18cd45374fd951183125",
|
|
75
|
+
"sha1": "7324fa7559653d19ad9e9997f8e9bf98308e805c",
|
|
76
|
+
"md5": "8a8943ce1632fc9989a6d5276e673c06"
|
|
77
77
|
}
|
|
78
78
|
]
|
|
79
79
|
},
|
|
@@ -87,13 +87,13 @@
|
|
|
87
87
|
},
|
|
88
88
|
"files": [
|
|
89
89
|
{
|
|
90
|
-
"name": "expo.modules.sqlite-57.0.
|
|
91
|
-
"url": "expo.modules.sqlite-57.0.
|
|
92
|
-
"size":
|
|
93
|
-
"sha512": "
|
|
94
|
-
"sha256": "
|
|
95
|
-
"sha1": "
|
|
96
|
-
"md5": "
|
|
90
|
+
"name": "expo.modules.sqlite-57.0.4-sources.jar",
|
|
91
|
+
"url": "expo.modules.sqlite-57.0.4-sources.jar",
|
|
92
|
+
"size": 11596,
|
|
93
|
+
"sha512": "37442b363d616ef7fd204893efb02ac15d4829aa5e2a3fe91be4b3cb17d9826f1d0abfdc9b3017b7618dfd85aa8156c234f39bc3ac7abd676072783d25e93125",
|
|
94
|
+
"sha256": "02bdb019cd014cbe43cff391ee53f9eed49ff6c78e425113af3a892390822f29",
|
|
95
|
+
"sha1": "c386518214d8885ee76a3a74d1fe9f1d3b4cbd26",
|
|
96
|
+
"md5": "2a2a61f4c3d0acedc5a7bcb4b9e57d6b"
|
|
97
97
|
}
|
|
98
98
|
]
|
|
99
99
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ac8d273739d99f58a075fcf6be9e9465
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
978eaf7830a814e3d16d0f5f12e96ddb5d68c856
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
32006cd7b6db719b0d1128927fb263d3fd32c3603ba2d693d136f8164c28d396
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
50966a95d994aa5fd02e79b140949ad4b67107454db1ee207f18e4ee3d3834c9ffadef7e4dc388bcbd926e8471118f1acb55f17d5ecbdb5f84d8171bf4f79c17
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<modelVersion>4.0.0</modelVersion>
|
|
10
10
|
<groupId>host.exp.exponent</groupId>
|
|
11
11
|
<artifactId>expo.modules.sqlite</artifactId>
|
|
12
|
-
<version>57.0.
|
|
12
|
+
<version>57.0.4</version>
|
|
13
13
|
<packaging>aar</packaging>
|
|
14
14
|
<name>expo.modules.sqlite</name>
|
|
15
15
|
<url>https://github.com/expo/expo</url>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1bc3c4f8fc789f118bea650404368a8b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ad5c7092249e91005b5bb98a0039f0067f5bdc74
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
62d81beab910b4ef587a515c384b64afe2ad0be9dbe55dd2a0104cd0b053f4cc
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c27968915e38ad2bb3a17d96c0fd73d651a4153d72b41b1f728836ec1d31460db2a5181c61301cf812f17c7af1fe0e3fd8bebb6ac3c4b37754b297e2522eb175
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>host.exp.exponent</groupId>
|
|
4
4
|
<artifactId>expo.modules.sqlite</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>57.0.
|
|
7
|
-
<release>57.0.
|
|
6
|
+
<latest>57.0.4</latest>
|
|
7
|
+
<release>57.0.4</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>57.0.
|
|
9
|
+
<version>57.0.4</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20261006120125</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d4a2192c71378c23486cb4d637c45b26
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
6385eb786defeadab4c7efc41b425bd8940c4162
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
14c9e125a492e31b4f9e6767f02b6cac50a969754bf68978c7ad7bc6dff7cd23
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d5d1d62ea565ab63307ca35a0dd0c23d5a5a332214ed02980dbb236d81be9f108e200b6d0214123236de38591f0c26f6cb5cee17362230aa83f71643810336e9
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-sqlite",
|
|
3
|
-
"version": "57.0.
|
|
3
|
+
"version": "57.0.4",
|
|
4
4
|
"description": "Provides access to a database using SQLite (https://www.sqlite.org/). The database is persisted across restarts of your app.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
"better-sqlite3": "^11.6.0",
|
|
57
57
|
"react-error-boundary": "^4.0.11",
|
|
58
58
|
"expo-module-scripts": "56.0.3",
|
|
59
|
-
"expo": "57.0.
|
|
59
|
+
"expo": "57.0.27"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"expo": "*",
|
|
63
63
|
"react": "*",
|
|
64
64
|
"react-native": "*"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "50ac74f1ab5682c8e32b24da6e5e97dd4dbbb80f",
|
|
67
67
|
"scripts": {
|
|
68
68
|
"build": "expo-module build",
|
|
69
69
|
"bundle:webui": "pushd dev-plugin-webui && bun run build && popd && rm -rf dev-plugin-dist && mv dev-plugin-webui/dist dev-plugin-dist",
|
package/spm.config.json
CHANGED
package/src/SQLiteStatement.ts
CHANGED
|
@@ -22,11 +22,27 @@ type ValuesOf<T extends object> = T[keyof T][];
|
|
|
22
22
|
* A prepared statement returned by [`SQLiteDatabase.prepareAsync()`](#prepareasyncsource) or [`SQLiteDatabase.prepareSync()`](#preparesyncsource) that can be binded with parameters and executed.
|
|
23
23
|
*/
|
|
24
24
|
export class SQLiteStatement {
|
|
25
|
+
/**
|
|
26
|
+
* The cursor that currently owns the underlying `sqlite3_stmt`. A prepared statement has exactly
|
|
27
|
+
* one cursor, so running the statement again invalidates the cursor of every earlier run.
|
|
28
|
+
*/
|
|
29
|
+
private currentCursor: object | null = null;
|
|
30
|
+
|
|
25
31
|
constructor(
|
|
26
32
|
private readonly nativeDatabase: NativeDatabase,
|
|
27
33
|
private readonly nativeStatement: NativeStatement
|
|
28
34
|
) {}
|
|
29
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Make the run that just finished the owner of the statement cursor, and return a predicate
|
|
38
|
+
* that tells whether it still is.
|
|
39
|
+
*/
|
|
40
|
+
private claimCursor(): () => boolean {
|
|
41
|
+
const cursor = {};
|
|
42
|
+
this.currentCursor = cursor;
|
|
43
|
+
return () => this.currentCursor === cursor;
|
|
44
|
+
}
|
|
45
|
+
|
|
30
46
|
//#region Asynchronous API
|
|
31
47
|
|
|
32
48
|
/**
|
|
@@ -51,7 +67,8 @@ export class SQLiteStatement {
|
|
|
51
67
|
rawResult: false,
|
|
52
68
|
lastInsertRowId,
|
|
53
69
|
changes,
|
|
54
|
-
}
|
|
70
|
+
},
|
|
71
|
+
this.claimCursor()
|
|
55
72
|
);
|
|
56
73
|
}
|
|
57
74
|
|
|
@@ -83,7 +100,8 @@ export class SQLiteStatement {
|
|
|
83
100
|
rawResult: true,
|
|
84
101
|
lastInsertRowId,
|
|
85
102
|
changes,
|
|
86
|
-
}
|
|
103
|
+
},
|
|
104
|
+
this.claimCursor()
|
|
87
105
|
);
|
|
88
106
|
}
|
|
89
107
|
|
|
@@ -133,7 +151,8 @@ export class SQLiteStatement {
|
|
|
133
151
|
rawResult: false,
|
|
134
152
|
lastInsertRowId,
|
|
135
153
|
changes,
|
|
136
|
-
}
|
|
154
|
+
},
|
|
155
|
+
this.claimCursor()
|
|
137
156
|
);
|
|
138
157
|
}
|
|
139
158
|
|
|
@@ -165,7 +184,8 @@ export class SQLiteStatement {
|
|
|
165
184
|
rawResult: true,
|
|
166
185
|
lastInsertRowId,
|
|
167
186
|
changes,
|
|
168
|
-
}
|
|
187
|
+
},
|
|
188
|
+
this.claimCursor()
|
|
169
189
|
);
|
|
170
190
|
}
|
|
171
191
|
|
|
@@ -347,6 +367,12 @@ interface SQLiteExecuteResultOptions {
|
|
|
347
367
|
changes: number;
|
|
348
368
|
}
|
|
349
369
|
|
|
370
|
+
const SUPERSEDED_CURSOR_MESSAGE =
|
|
371
|
+
'This result is no longer readable because the prepared statement ran again. ' +
|
|
372
|
+
'A prepared statement holds a single SQLite cursor, so a later run rebinds the parameters and moves that cursor, ' +
|
|
373
|
+
'and this result would return the rows of the later run. ' +
|
|
374
|
+
'Read a result to the end before you run the same statement again, or prepare a separate statement for each reader.';
|
|
375
|
+
|
|
350
376
|
/**
|
|
351
377
|
* Create the `SQLiteExecuteAsyncResult` instance.
|
|
352
378
|
*
|
|
@@ -357,13 +383,15 @@ async function createSQLiteExecuteAsyncResult<T>(
|
|
|
357
383
|
database: SQLiteAnyDatabase,
|
|
358
384
|
statement: NativeStatement,
|
|
359
385
|
firstRowValues: SQLiteColumnValues | null,
|
|
360
|
-
options: SQLiteExecuteResultOptions
|
|
386
|
+
options: SQLiteExecuteResultOptions,
|
|
387
|
+
isCursorOwner: () => boolean
|
|
361
388
|
): Promise<SQLiteExecuteAsyncResult<T>> {
|
|
362
389
|
const instance = new SQLiteExecuteAsyncResultImpl<T>(
|
|
363
390
|
database,
|
|
364
391
|
statement,
|
|
365
392
|
firstRowValues ? processNativeRow(firstRowValues) : null,
|
|
366
|
-
options
|
|
393
|
+
options,
|
|
394
|
+
isCursorOwner
|
|
367
395
|
);
|
|
368
396
|
const generator = instance.generatorAsync();
|
|
369
397
|
Object.defineProperties(generator, {
|
|
@@ -404,13 +432,15 @@ function createSQLiteExecuteSyncResult<T>(
|
|
|
404
432
|
database: SQLiteAnyDatabase,
|
|
405
433
|
statement: NativeStatement,
|
|
406
434
|
firstRowValues: SQLiteColumnValues | null,
|
|
407
|
-
options: SQLiteExecuteResultOptions
|
|
435
|
+
options: SQLiteExecuteResultOptions,
|
|
436
|
+
isCursorOwner: () => boolean
|
|
408
437
|
): SQLiteExecuteSyncResult<T> {
|
|
409
438
|
const instance = new SQLiteExecuteSyncResultImpl<T>(
|
|
410
439
|
database,
|
|
411
440
|
statement,
|
|
412
441
|
firstRowValues ? processNativeRow(firstRowValues) : firstRowValues,
|
|
413
|
-
options
|
|
442
|
+
options,
|
|
443
|
+
isCursorOwner
|
|
414
444
|
);
|
|
415
445
|
const generator = instance.generatorSync();
|
|
416
446
|
Object.defineProperties(generator, {
|
|
@@ -452,9 +482,17 @@ class SQLiteExecuteAsyncResultImpl<T> {
|
|
|
452
482
|
private readonly database: SQLiteAnyDatabase,
|
|
453
483
|
private readonly statement: NativeStatement,
|
|
454
484
|
private firstRowValues: SQLiteColumnValues | null,
|
|
455
|
-
public readonly options: SQLiteExecuteResultOptions
|
|
485
|
+
public readonly options: SQLiteExecuteResultOptions,
|
|
486
|
+
private readonly isCursorOwner: () => boolean
|
|
456
487
|
) {}
|
|
457
488
|
|
|
489
|
+
/** Throw rather than step a cursor that a later run of the same statement has taken over. */
|
|
490
|
+
private assertCursorOwner() {
|
|
491
|
+
if (!this.isCursorOwner()) {
|
|
492
|
+
throw new Error(SUPERSEDED_CURSOR_MESSAGE);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
458
496
|
async getFirstAsync(): Promise<T | null> {
|
|
459
497
|
if (this.isStepCalled) {
|
|
460
498
|
throw new Error(
|
|
@@ -467,6 +505,7 @@ class SQLiteExecuteAsyncResultImpl<T> {
|
|
|
467
505
|
if (firstRowValues != null) {
|
|
468
506
|
return composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);
|
|
469
507
|
}
|
|
508
|
+
this.assertCursorOwner();
|
|
470
509
|
const firstRow = await this.statement.stepAsync(this.database);
|
|
471
510
|
return firstRow != null
|
|
472
511
|
? composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(firstRow))
|
|
@@ -486,9 +525,10 @@ class SQLiteExecuteAsyncResultImpl<T> {
|
|
|
486
525
|
return [];
|
|
487
526
|
}
|
|
488
527
|
const columnNames = await this.getColumnNamesAsync();
|
|
528
|
+
this.assertCursorOwner();
|
|
489
529
|
const nativeRows = await this.statement.getAllAsync(this.database);
|
|
490
530
|
const allRows = processNativeRows(nativeRows);
|
|
491
|
-
if (firstRowValues
|
|
531
|
+
if (firstRowValues.length > 0) {
|
|
492
532
|
return composeRowsIfNeeded<T>(this.options.rawResult, columnNames, [
|
|
493
533
|
firstRowValues,
|
|
494
534
|
...allRows,
|
|
@@ -507,6 +547,7 @@ class SQLiteExecuteAsyncResultImpl<T> {
|
|
|
507
547
|
|
|
508
548
|
let result;
|
|
509
549
|
do {
|
|
550
|
+
this.assertCursorOwner();
|
|
510
551
|
result = await this.statement.stepAsync(this.database);
|
|
511
552
|
if (result != null) {
|
|
512
553
|
yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(result));
|
|
@@ -514,10 +555,11 @@ class SQLiteExecuteAsyncResultImpl<T> {
|
|
|
514
555
|
} while (result != null);
|
|
515
556
|
}
|
|
516
557
|
|
|
517
|
-
resetAsync(): Promise<void> {
|
|
518
|
-
|
|
558
|
+
async resetAsync(): Promise<void> {
|
|
559
|
+
// Resetting a superseded result would rewind the cursor of the run that owns it now.
|
|
560
|
+
this.assertCursorOwner();
|
|
561
|
+
await this.statement.resetAsync(this.database);
|
|
519
562
|
this.isStepCalled = false;
|
|
520
|
-
return result;
|
|
521
563
|
}
|
|
522
564
|
|
|
523
565
|
private popFirstRowValues(): SQLiteColumnValues | null {
|
|
@@ -545,9 +587,17 @@ class SQLiteExecuteSyncResultImpl<T> {
|
|
|
545
587
|
private readonly database: SQLiteAnyDatabase,
|
|
546
588
|
private readonly statement: NativeStatement,
|
|
547
589
|
private firstRowValues: SQLiteColumnValues | null,
|
|
548
|
-
public readonly options: SQLiteExecuteResultOptions
|
|
590
|
+
public readonly options: SQLiteExecuteResultOptions,
|
|
591
|
+
private readonly isCursorOwner: () => boolean
|
|
549
592
|
) {}
|
|
550
593
|
|
|
594
|
+
/** Throw rather than step a cursor that a later run of the same statement has taken over. */
|
|
595
|
+
private assertCursorOwner() {
|
|
596
|
+
if (!this.isCursorOwner()) {
|
|
597
|
+
throw new Error(SUPERSEDED_CURSOR_MESSAGE);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
551
601
|
getFirstSync(): T | null {
|
|
552
602
|
if (this.isStepCalled) {
|
|
553
603
|
throw new Error(
|
|
@@ -559,6 +609,7 @@ class SQLiteExecuteSyncResultImpl<T> {
|
|
|
559
609
|
if (firstRowValues != null) {
|
|
560
610
|
return composeRowIfNeeded<T>(this.options.rawResult, columnNames, firstRowValues);
|
|
561
611
|
}
|
|
612
|
+
this.assertCursorOwner();
|
|
562
613
|
const firstRow = this.statement.stepSync(this.database);
|
|
563
614
|
return firstRow != null
|
|
564
615
|
? composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(firstRow))
|
|
@@ -577,6 +628,7 @@ class SQLiteExecuteSyncResultImpl<T> {
|
|
|
577
628
|
return [];
|
|
578
629
|
}
|
|
579
630
|
const columnNames = this.getColumnNamesSync();
|
|
631
|
+
this.assertCursorOwner();
|
|
580
632
|
const nativeRows = this.statement.getAllSync(this.database);
|
|
581
633
|
const allRows = processNativeRows(nativeRows);
|
|
582
634
|
if (firstRowValues != null && firstRowValues.length > 0) {
|
|
@@ -596,6 +648,7 @@ class SQLiteExecuteSyncResultImpl<T> {
|
|
|
596
648
|
}
|
|
597
649
|
let result;
|
|
598
650
|
do {
|
|
651
|
+
this.assertCursorOwner();
|
|
599
652
|
result = this.statement.stepSync(this.database);
|
|
600
653
|
if (result != null) {
|
|
601
654
|
yield composeRowIfNeeded<T>(this.options.rawResult, columnNames, processNativeRow(result));
|
|
@@ -604,9 +657,10 @@ class SQLiteExecuteSyncResultImpl<T> {
|
|
|
604
657
|
}
|
|
605
658
|
|
|
606
659
|
resetSync(): void {
|
|
607
|
-
|
|
660
|
+
// Resetting a superseded result would rewind the cursor of the run that owns it now.
|
|
661
|
+
this.assertCursorOwner();
|
|
662
|
+
this.statement.resetSync(this.database);
|
|
608
663
|
this.isStepCalled = false;
|
|
609
|
-
return result;
|
|
610
664
|
}
|
|
611
665
|
|
|
612
666
|
private popFirstRowValues(): SQLiteColumnValues | null {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9b900a345245e67770016ae8154b63e1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
7c0a8d8193faac646dccacbe00982974ffb4f488
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b8f668275e3ec93cff367011da2b3ae7bd83f43a690ce56473395ba6284c8b7c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3b63d91aadb7a09514fc8fb158bb08caf92b6108cbc0876893b1a7a3fd33c1a4934c3b7912a858404f0a0eac7b854572fa90c90b8c93b9b52bde2204dcdab735
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
89190f5fa83aadb89346c061f9cb6c34
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
87f1f42b8d635fff98edf78cf7a123628dc369e0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
df1da5f5381b01deb84c69e946436e98f69fb7a3c3f55c03b01e88061fd88e4d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
97b9f3c849ecda169a14bd40502d11b42a7db55e98a1ac3a33391a720bdac4748fd4e7fe190c1ab77c37aada7d932f7b587efa141949d4f4f281959e5e1a2475
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
59486bb962ec51c4a505928b3887b0bf
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4f11c5f9c07691398777238a4fada628234ddd7f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c93569dd661c1229cf4dd11f95777d1393298b14594803957f8fc6ca6ec31c4f
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
f2b4ce5c245f0db1c269e117fcd5331790142445f2671d4d44affa3d5ea867247094d3a24304f938e7956a1596779854a5345d323d558b03a423ac3d37e4cddb
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4f32159f8a3733fd4e0029736ec8a7c2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
70c6c5fb5efdd7025199538ee165b02fe8bb13fe
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
94cafda0638ad1c46827badb1c67105c365a281ba54c504a42d6bc776502ef7a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bc7961c892e2d30f9cf5f01d24f004f3db07c1771e3c36601051297d3ea2eb3f201483444a1ff471b0e354a7d7e1d22b6beb2cf82b4d3ad3df5e293db52b479e
|