expo-sqlite 57.0.3 → 57.0.5
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 +13 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/sqlite/NativeDatabaseBinding.kt +1 -0
- package/android/src/main/java/expo/modules/sqlite/SQLiteModule.kt +47 -23
- 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 +37 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{57.0.3/expo.modules.sqlite-57.0.3.module → 57.0.5/expo.modules.sqlite-57.0.5.module} +22 -22
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{57.0.3/expo.modules.sqlite-57.0.3.pom → 57.0.5/expo.modules.sqlite-57.0.5.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.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/src/SQLiteStatement.ts +70 -16
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,19 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 57.0.5 — 2026-11-12
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- [iOS][Android] Fix every later transaction on a connection failing with `cannot commit transaction - SQL statements in progress` after a statement fails with `database is locked`, by resetting the statement when its run fails. ([#51413](https://github.com/expo/expo/pull/51413) by [@kudo](https://github.com/kudo))
|
|
18
|
+
- [iOS][Android] Fix `finalizeAsync()` and `finalizeSync()` not reporting the earlier error of a failed `run()`, by resetting the statement only when the run fails with `database is locked`. ([#53339](https://github.com/expo/expo/pull/53339) by [@kudo](https://github.com/kudo))
|
|
19
|
+
|
|
20
|
+
## 57.0.4 — 2026-10-06
|
|
21
|
+
|
|
22
|
+
### 🐛 Bug fixes
|
|
23
|
+
|
|
24
|
+
- 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))
|
|
25
|
+
|
|
13
26
|
## 57.0.3 — 2026-09-11
|
|
14
27
|
|
|
15
28
|
_This version does not introduce any user-facing changes._
|
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.5'
|
|
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.5"
|
|
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
|
|
|
@@ -417,7 +417,15 @@ class SQLiteModule : Module() {
|
|
|
417
417
|
|
|
418
418
|
val ret = statement.ref.sqlite3_step()
|
|
419
419
|
if (ret != NativeDatabaseBinding.SQLITE_ROW && ret != NativeDatabaseBinding.SQLITE_DONE) {
|
|
420
|
-
|
|
420
|
+
// A step that fails with SQLITE_BUSY leaves the statement running, so every later COMMIT
|
|
421
|
+
// on the connection fails until the statement is reset.
|
|
422
|
+
// Reset only for SQLITE_BUSY. A reset also clears other errors, which finalize() must still report.
|
|
423
|
+
// Read the message first. sqlite3_reset() replaces the error message.
|
|
424
|
+
val message = database.ref.convertSqlLiteErrorToString()
|
|
425
|
+
if ((ret and 0xff) == NativeDatabaseBinding.SQLITE_BUSY) {
|
|
426
|
+
statement.ref.sqlite3_reset()
|
|
427
|
+
}
|
|
428
|
+
throw SQLiteErrorException(message)
|
|
421
429
|
}
|
|
422
430
|
val firstRowValues: SQLiteColumnValues =
|
|
423
431
|
if (ret == NativeDatabaseBinding.SQLITE_ROW) {
|
|
@@ -437,40 +445,52 @@ class SQLiteModule : Module() {
|
|
|
437
445
|
private fun step(statement: NativeStatement, database: NativeDatabase): SQLiteColumnValues? {
|
|
438
446
|
maybeThrowForClosedDatabase(database)
|
|
439
447
|
maybeThrowForFinalizedStatement(statement)
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
448
|
+
|
|
449
|
+
// Guard the stateful statement, see `run` above.
|
|
450
|
+
synchronized(statement) {
|
|
451
|
+
val ret = statement.ref.sqlite3_step()
|
|
452
|
+
if (ret == NativeDatabaseBinding.SQLITE_ROW) {
|
|
453
|
+
return statement.getTransformedColumnValues()
|
|
454
|
+
}
|
|
455
|
+
if (ret != NativeDatabaseBinding.SQLITE_DONE) {
|
|
456
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
457
|
+
}
|
|
458
|
+
return null
|
|
446
459
|
}
|
|
447
|
-
return null
|
|
448
460
|
}
|
|
449
461
|
|
|
450
462
|
@Throws(AccessClosedResourceException::class, InvalidConvertibleException::class, SQLiteErrorException::class)
|
|
451
463
|
private fun getAll(statement: NativeStatement, database: NativeDatabase): List<SQLiteColumnValues> {
|
|
452
464
|
maybeThrowForClosedDatabase(database)
|
|
453
465
|
maybeThrowForFinalizedStatement(statement)
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
466
|
+
|
|
467
|
+
// Guard the stateful statement, see `run` above.
|
|
468
|
+
synchronized(statement) {
|
|
469
|
+
val columnValuesList = mutableListOf<SQLiteColumnValues>()
|
|
470
|
+
while (true) {
|
|
471
|
+
val ret = statement.ref.sqlite3_step()
|
|
472
|
+
if (ret == NativeDatabaseBinding.SQLITE_ROW) {
|
|
473
|
+
columnValuesList.add(statement.getTransformedColumnValues())
|
|
474
|
+
continue
|
|
475
|
+
} else if (ret == NativeDatabaseBinding.SQLITE_DONE) {
|
|
476
|
+
break
|
|
477
|
+
}
|
|
478
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
462
479
|
}
|
|
463
|
-
|
|
480
|
+
return columnValuesList
|
|
464
481
|
}
|
|
465
|
-
return columnValuesList
|
|
466
482
|
}
|
|
467
483
|
|
|
468
484
|
@Throws(AccessClosedResourceException::class, SQLiteErrorException::class)
|
|
469
485
|
private fun reset(statement: NativeStatement, database: NativeDatabase) {
|
|
470
486
|
maybeThrowForClosedDatabase(database)
|
|
471
487
|
maybeThrowForFinalizedStatement(statement)
|
|
472
|
-
|
|
473
|
-
|
|
488
|
+
|
|
489
|
+
// Guard the stateful statement, see `run` above.
|
|
490
|
+
synchronized(statement) {
|
|
491
|
+
if (statement.ref.sqlite3_reset() != NativeDatabaseBinding.SQLITE_OK) {
|
|
492
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
493
|
+
}
|
|
474
494
|
}
|
|
475
495
|
}
|
|
476
496
|
|
|
@@ -478,10 +498,14 @@ class SQLiteModule : Module() {
|
|
|
478
498
|
private fun finalize(statement: NativeStatement, database: NativeDatabase) {
|
|
479
499
|
maybeThrowForClosedDatabase(database)
|
|
480
500
|
maybeThrowForFinalizedStatement(statement)
|
|
481
|
-
|
|
482
|
-
|
|
501
|
+
|
|
502
|
+
// Guard the stateful statement, see `run` above.
|
|
503
|
+
synchronized(statement) {
|
|
504
|
+
if (statement.ref.sqlite3_finalize() != NativeDatabaseBinding.SQLITE_OK) {
|
|
505
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
506
|
+
}
|
|
507
|
+
statement.isFinalized = true
|
|
483
508
|
}
|
|
484
|
-
statement.isFinalized = true
|
|
485
509
|
}
|
|
486
510
|
|
|
487
511
|
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":"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","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":"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","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
|
@@ -413,7 +413,15 @@ public final class SQLiteModule: Module {
|
|
|
413
413
|
|
|
414
414
|
let ret = exsqlite3_step(statement.pointer)
|
|
415
415
|
if ret != SQLITE_ROW && ret != SQLITE_DONE {
|
|
416
|
-
|
|
416
|
+
// A step that fails with `SQLITE_BUSY` leaves the statement running, so every later `COMMIT`
|
|
417
|
+
// on the connection fails with "SQL statements in progress" until the statement is reset.
|
|
418
|
+
// Reset only for `SQLITE_BUSY`. A reset also clears other errors, which `finalize()` must still report.
|
|
419
|
+
// Read the message first. `sqlite3_reset` replaces the error message.
|
|
420
|
+
let message = convertSqlLiteErrorToString(database)
|
|
421
|
+
if ret & 0xff == SQLITE_BUSY {
|
|
422
|
+
exsqlite3_reset(statement.pointer)
|
|
423
|
+
}
|
|
424
|
+
throw SQLiteErrorException(message)
|
|
417
425
|
}
|
|
418
426
|
let firstRowValues: SQLiteColumnValues = (ret == SQLITE_ROW) ? try getColumnValues(statement: statement) : []
|
|
419
427
|
return [
|
|
@@ -428,6 +436,13 @@ public final class SQLiteModule: Module {
|
|
|
428
436
|
private func step(statement: NativeStatement, database: NativeDatabase) throws -> SQLiteColumnValues? {
|
|
429
437
|
try maybeThrowForClosedDatabase(database)
|
|
430
438
|
try maybeThrowForFinalizedStatement(statement)
|
|
439
|
+
|
|
440
|
+
// Guard the stateful statement, see `run` above.
|
|
441
|
+
statement.lock.wait()
|
|
442
|
+
defer {
|
|
443
|
+
statement.lock.signal()
|
|
444
|
+
}
|
|
445
|
+
|
|
431
446
|
let ret = exsqlite3_step(statement.pointer)
|
|
432
447
|
if ret == SQLITE_ROW {
|
|
433
448
|
return try getColumnValues(statement: statement)
|
|
@@ -441,6 +456,13 @@ public final class SQLiteModule: Module {
|
|
|
441
456
|
private func getAll(statement: NativeStatement, database: NativeDatabase) throws -> [SQLiteColumnValues] {
|
|
442
457
|
try maybeThrowForClosedDatabase(database)
|
|
443
458
|
try maybeThrowForFinalizedStatement(statement)
|
|
459
|
+
|
|
460
|
+
// Guard the stateful statement, see `run` above.
|
|
461
|
+
statement.lock.wait()
|
|
462
|
+
defer {
|
|
463
|
+
statement.lock.signal()
|
|
464
|
+
}
|
|
465
|
+
|
|
444
466
|
var columnValuesList: [SQLiteColumnValues] = []
|
|
445
467
|
while true {
|
|
446
468
|
let ret = exsqlite3_step(statement.pointer)
|
|
@@ -459,6 +481,13 @@ public final class SQLiteModule: Module {
|
|
|
459
481
|
private func reset(statement: NativeStatement, database: NativeDatabase) throws {
|
|
460
482
|
try maybeThrowForClosedDatabase(database)
|
|
461
483
|
try maybeThrowForFinalizedStatement(statement)
|
|
484
|
+
|
|
485
|
+
// Guard the stateful statement, see `run` above.
|
|
486
|
+
statement.lock.wait()
|
|
487
|
+
defer {
|
|
488
|
+
statement.lock.signal()
|
|
489
|
+
}
|
|
490
|
+
|
|
462
491
|
if exsqlite3_reset(statement.pointer) != SQLITE_OK {
|
|
463
492
|
throw SQLiteErrorException(convertSqlLiteErrorToString(database))
|
|
464
493
|
}
|
|
@@ -467,6 +496,13 @@ public final class SQLiteModule: Module {
|
|
|
467
496
|
private func finalize(statement: NativeStatement, database: NativeDatabase) throws {
|
|
468
497
|
try maybeThrowForClosedDatabase(database)
|
|
469
498
|
try maybeThrowForFinalizedStatement(statement)
|
|
499
|
+
|
|
500
|
+
// Guard the stateful statement, see `run` above.
|
|
501
|
+
statement.lock.wait()
|
|
502
|
+
defer {
|
|
503
|
+
statement.lock.signal()
|
|
504
|
+
}
|
|
505
|
+
|
|
470
506
|
if exsqlite3_finalize(statement.pointer) != SQLITE_OK {
|
|
471
507
|
throw SQLiteErrorException(convertSqlLiteErrorToString(database))
|
|
472
508
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
34e7fea693f36611af7d552e9c477a03
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
14aee4e10a29fa128eac15592d7d2615b925b4ba
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
246e4dc5d5ea9cec2e91193b6fe95946f29674d2a9762171daf01c60f8bdd7a9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d54e01c015f2c8f7ff965d4afe4a76b297b9bf4a63c60b173f904aad0ca11100ac6e50cc62f27066068fa28453b6305020c428568dedd94a61fbce8abfc4db24
|
package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.5/expo.modules.sqlite-57.0.5.aar
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d6631a5fb1bd6725a6b4cc14e11d853f
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
69de56b1948910c75d4c51ddea38ff3567706dc6
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
21dfa7a364f93fdac8f5dd3bbc73949d836079d79f900905ec0ced8034873759
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b4f071be26571e04e9451e10b9f27219b7b6719b54be9c3f8cea1550efe6f219d175171e325f91a80ee087df944a1e53c886af61afc7982c1cfd8c8604b4f60c
|
|
@@ -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.5",
|
|
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.5.aar",
|
|
28
|
+
"url": "expo.modules.sqlite-57.0.5.aar",
|
|
29
|
+
"size": 1147519,
|
|
30
|
+
"sha512": "b4f071be26571e04e9451e10b9f27219b7b6719b54be9c3f8cea1550efe6f219d175171e325f91a80ee087df944a1e53c886af61afc7982c1cfd8c8604b4f60c",
|
|
31
|
+
"sha256": "21dfa7a364f93fdac8f5dd3bbc73949d836079d79f900905ec0ced8034873759",
|
|
32
|
+
"sha1": "69de56b1948910c75d4c51ddea38ff3567706dc6",
|
|
33
|
+
"md5": "d6631a5fb1bd6725a6b4cc14e11d853f"
|
|
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.5.aar",
|
|
71
|
+
"url": "expo.modules.sqlite-57.0.5.aar",
|
|
72
|
+
"size": 1147519,
|
|
73
|
+
"sha512": "b4f071be26571e04e9451e10b9f27219b7b6719b54be9c3f8cea1550efe6f219d175171e325f91a80ee087df944a1e53c886af61afc7982c1cfd8c8604b4f60c",
|
|
74
|
+
"sha256": "21dfa7a364f93fdac8f5dd3bbc73949d836079d79f900905ec0ced8034873759",
|
|
75
|
+
"sha1": "69de56b1948910c75d4c51ddea38ff3567706dc6",
|
|
76
|
+
"md5": "d6631a5fb1bd6725a6b4cc14e11d853f"
|
|
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.5-sources.jar",
|
|
91
|
+
"url": "expo.modules.sqlite-57.0.5-sources.jar",
|
|
92
|
+
"size": 11795,
|
|
93
|
+
"sha512": "d54e01c015f2c8f7ff965d4afe4a76b297b9bf4a63c60b173f904aad0ca11100ac6e50cc62f27066068fa28453b6305020c428568dedd94a61fbce8abfc4db24",
|
|
94
|
+
"sha256": "246e4dc5d5ea9cec2e91193b6fe95946f29674d2a9762171daf01c60f8bdd7a9",
|
|
95
|
+
"sha1": "14aee4e10a29fa128eac15592d7d2615b925b4ba",
|
|
96
|
+
"md5": "34e7fea693f36611af7d552e9c477a03"
|
|
97
97
|
}
|
|
98
98
|
]
|
|
99
99
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
789d5209b0de78c55497751d50e4f4d4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bd5f32fc5cda40f2e4fc866fe18094567f9b2f84
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
09bfabf57d1e2fe9807bc15dcd5c2c82352618cda400a621dbdc913021434349
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c522663f3ea1aa4fa23869e41e6fdacd3e2b24a54c71ae928ffa9b3f064ac1d7a7fb54d25271d1c942f2a238b917a80e9c86f6d0f781f3f42e0977a94a67fd0b
|
|
@@ -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.5</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
|
+
feafc4af23bc4c7872bfd52d4f278260
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d7a49d1cbf0d7b3a2cdaf6bbc3ef7f834ca3b186
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
175b8d0b117dd21841ad39dcf829c54c8f71e11b0b4bb0662df25e422b25813c
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f4302aaa17f006f0e9b1f6ee231f6598fbc6f0c7d4cd7514326361d13067d1c2a287fc6fa54fbf911059e64e4aaef0b4ac766f3d7a0c879589aed2836e52da41
|
|
@@ -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.5</latest>
|
|
7
|
+
<release>57.0.5</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>57.0.
|
|
9
|
+
<version>57.0.5</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20261112131753</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
dccdb3d0f6e21b82da4026c5964c250f
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
f600d5787ea2bdfd0922dd260c30b940bc2fe248
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
039aeb06e7d3d367792bf461f21b1d5647d4b72d4bd1b191f14cd302530a3ccf
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
5b2af984e10d8f78bcd71adda7c3ff62500e17c682452f9d3469df91cdff1a6d440db6c3b6f0fdc58fc90e71a8ad71c707cfc24776d21bf15607c7395525112f
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-sqlite",
|
|
3
|
-
"version": "57.0.
|
|
3
|
+
"version": "57.0.5",
|
|
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",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@types/react": "~19.2.0",
|
|
56
56
|
"better-sqlite3": "^11.6.0",
|
|
57
57
|
"react-error-boundary": "^4.0.11",
|
|
58
|
-
"expo": "57.0.
|
|
58
|
+
"expo": "57.0.33",
|
|
59
59
|
"expo-module-scripts": "56.0.3"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"react": "*",
|
|
64
64
|
"react-native": "*"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "968a9dcec304789b2ccc1a41ef5d301938e91478",
|
|
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/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 {
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9b900a345245e67770016ae8154b63e1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
7c0a8d8193faac646dccacbe00982974ffb4f488
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b8f668275e3ec93cff367011da2b3ae7bd83f43a690ce56473395ba6284c8b7c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3b63d91aadb7a09514fc8fb158bb08caf92b6108cbc0876893b1a7a3fd33c1a4934c3b7912a858404f0a0eac7b854572fa90c90b8c93b9b52bde2204dcdab735
|
package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/57.0.3/expo.modules.sqlite-57.0.3.aar
DELETED
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
89190f5fa83aadb89346c061f9cb6c34
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
87f1f42b8d635fff98edf78cf7a123628dc369e0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
df1da5f5381b01deb84c69e946436e98f69fb7a3c3f55c03b01e88061fd88e4d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
97b9f3c849ecda169a14bd40502d11b42a7db55e98a1ac3a33391a720bdac4748fd4e7fe190c1ab77c37aada7d932f7b587efa141949d4f4f281959e5e1a2475
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9eb45591303ea8c621fc69e89826896d
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
08dc1316d88f40efbcfeb13c34d5f6d399c394d7
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ee3f075f3c6a0fd48956f50476ba6b9b2c53dfe35b19cce7f8e1976a1edb57a7
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
7072e77137d8d04d74c12cc050c55aad54854784349d7810b257b6cf8ea13dc94c885edd53532403ffa546d5f0d65623bb42340f7466e6f9b0442c6cc1b01d3a
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
d2aebcba7cf3dea8e355552107870cfb
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2d42be1f6cf0cb586196d93f920c8c780f4635d9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3af19f382afed8dd75aec53c44bf8e83edc810d919cb7603b9c70e055314bf85
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2ad35fe02f25b6a226941470aa67c2027318609b7ec156d61d77837bbdc8811de072fd24692a4577419b2fb1350e23377e031f82b9c835202b42ef14da542ca4
|