expo-sqlite 58.0.8 → 58.0.9
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 +6 -0
- package/android/build.gradle +2 -2
- package/android/src/main/cpp/NativeDatabaseBinding.cpp +0 -22
- package/android/src/main/cpp/NativeDatabaseBinding.h +0 -1
- package/android/src/main/cpp/NativeStatementBinding.cpp +3 -1
- package/android/src/main/cpp/NativeStatementBinding.h +1 -1
- package/android/src/main/java/expo/modules/sqlite/NativeDatabase.kt +5 -0
- package/android/src/main/java/expo/modules/sqlite/NativeDatabaseBinding.kt +0 -1
- package/android/src/main/java/expo/modules/sqlite/NativeStatement.kt +9 -1
- package/android/src/main/java/expo/modules/sqlite/SQLiteModule.kt +78 -48
- package/dev-plugin-dist/+not-found.html +1 -1
- package/dev-plugin-dist/_expo/static/js/web/{__common-b5c30377ac28ec1a3c7472c7feddcab4.js → __common-9b94dd2fbdbb825a662f42cf8d2077ee.js} +36 -36
- package/dev-plugin-dist/_expo/static/js/web/{_layout-bdc15c267ba9298fc3df49fa915a8895.js → _layout-b2894030c1dfbd95b717a85901b6c271.js} +21 -21
- package/dev-plugin-dist/_expo/static/js/web/{entry-182fd72f164b90bb353bfd4ca3257c12.js → entry-04fdb7d857a65c0ed638ef2d774a4b6e.js} +547 -550
- package/dev-plugin-dist/_expo/static/js/web/{index-5d44464b52f351ee1a8d579d6ec31de6.js → index-4bf2da199f699eb47a42074d5e183c07.js} +1740 -1740
- package/dev-plugin-dist/_expo/static/js/web/{worker-634941622d077e92764ccbb4960edffc.js → worker-d51aa6be89e271e571111274ab8e7f5c.js} +17 -17
- package/dev-plugin-dist/_sitemap.html +1 -1
- package/dev-plugin-dist/index.html +1 -1
- package/ios/NativeDatabase.swift +14 -5
- package/ios/NativeStatement.swift +23 -15
- package/ios/SQLiteModule.swift +46 -45
- package/ios/Tests/test_StatementCleanup.swift +84 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.8/expo.modules.sqlite-58.0.8.module → 58.0.9/expo.modules.sqlite-58.0.9.module} +22 -22
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.8/expo.modules.sqlite-58.0.8.pom → 58.0.9/expo.modules.sqlite-58.0.9.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.sha512 +1 -0
- package/package.json +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 58.0.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [Android][iOS] Fixed database closing failure with FTS ([#38168](https://github.com/expo/expo/issues/38168)). ([#50121](https://github.com/expo/expo/pull/50121) by [@savv](https://github.com/savv))
|
|
8
|
+
|
|
3
9
|
## 58.0.8
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/android/build.gradle
CHANGED
|
@@ -47,13 +47,13 @@ def reactNativeArchitectures() {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
group = 'host.exp.exponent'
|
|
50
|
-
version = '58.0.
|
|
50
|
+
version = '58.0.9'
|
|
51
51
|
|
|
52
52
|
android {
|
|
53
53
|
namespace "expo.modules.sqlite"
|
|
54
54
|
defaultConfig {
|
|
55
55
|
versionCode 18
|
|
56
|
-
versionName "58.0.
|
|
56
|
+
versionName "58.0.9"
|
|
57
57
|
buildConfigField "boolean", "WITH_SQLITE_VEC", project.ext.WITH_SQLITE_VEC.toString()
|
|
58
58
|
|
|
59
59
|
externalNativeBuild {
|
|
@@ -8,20 +8,12 @@ namespace jni = facebook::jni;
|
|
|
8
8
|
|
|
9
9
|
namespace expo {
|
|
10
10
|
|
|
11
|
-
namespace {
|
|
12
|
-
|
|
13
|
-
constexpr char TAG[] = "expo-sqlite";
|
|
14
|
-
|
|
15
|
-
} // namespace
|
|
16
|
-
|
|
17
11
|
// static
|
|
18
12
|
void NativeDatabaseBinding::registerNatives() {
|
|
19
13
|
registerHybrid({
|
|
20
14
|
makeNativeMethod("initHybrid", NativeDatabaseBinding::initHybrid),
|
|
21
15
|
makeNativeMethod("sqlite3_changes",
|
|
22
16
|
NativeDatabaseBinding::sqlite3_changes),
|
|
23
|
-
makeNativeMethod("sqlite3_finalize_all_statement",
|
|
24
|
-
NativeDatabaseBinding::sqlite3_finalize_all_statement),
|
|
25
17
|
makeNativeMethod("sqlite3_close", NativeDatabaseBinding::sqlite3_close),
|
|
26
18
|
makeNativeMethod("sqlite3_interrupt", NativeDatabaseBinding::sqlite3_interrupt),
|
|
27
19
|
makeNativeMethod("sqlite3_db_filename",
|
|
@@ -52,20 +44,6 @@ void NativeDatabaseBinding::registerNatives() {
|
|
|
52
44
|
|
|
53
45
|
int NativeDatabaseBinding::sqlite3_changes() { return ::exsqlite3_changes(db); }
|
|
54
46
|
|
|
55
|
-
void NativeDatabaseBinding::sqlite3_finalize_all_statement() {
|
|
56
|
-
::exsqlite3_stmt *stmt = ::exsqlite3_next_stmt(db, nullptr);
|
|
57
|
-
while (stmt) {
|
|
58
|
-
::exsqlite3_stmt *nextStmt = ::exsqlite3_next_stmt(db, stmt);
|
|
59
|
-
int ret = ::exsqlite3_finalize(stmt);
|
|
60
|
-
if (ret != SQLITE_OK) {
|
|
61
|
-
std::string error = convertSqlLiteErrorToSTLString();
|
|
62
|
-
__android_log_print(ANDROID_LOG_WARN, TAG,
|
|
63
|
-
"exsqlite3_finalize failed: %s", error.c_str());
|
|
64
|
-
}
|
|
65
|
-
stmt = nextStmt;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
47
|
void NativeDatabaseBinding::sqlite3_interrupt() { ::exsqlite3_interrupt(db); }
|
|
70
48
|
|
|
71
49
|
int NativeDatabaseBinding::sqlite3_close() {
|
|
@@ -59,7 +59,9 @@ std::string NativeStatementBinding::sqlite3_column_name(int index) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
int NativeStatementBinding::sqlite3_finalize() {
|
|
62
|
-
|
|
62
|
+
int ret = ::exsqlite3_finalize(stmt);
|
|
63
|
+
stmt = nullptr;
|
|
64
|
+
return ret;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
int NativeStatementBinding::sqlite3_reset() { return ::exsqlite3_reset(stmt); }
|
|
@@ -9,6 +9,11 @@ import java.util.concurrent.locks.ReentrantLock
|
|
|
9
9
|
internal class NativeDatabase(val databasePath: String, val openOptions: OpenDatabaseOptions) : SharedRef<NativeDatabaseBinding>(NativeDatabaseBinding()) {
|
|
10
10
|
var isClosed = false
|
|
11
11
|
val closeLock = ReentrantLock()
|
|
12
|
+
|
|
13
|
+
// Protect statement registration and cleanup through the final close attempt.
|
|
14
|
+
// Running statements use their own locks, so interruption need not wait for them.
|
|
15
|
+
val statementLifecycleLock = Any()
|
|
16
|
+
val statements = mutableListOf<NativeStatement>()
|
|
12
17
|
private val refCount = AtomicInteger(1)
|
|
13
18
|
|
|
14
19
|
internal fun addRef(): Int {
|
|
@@ -44,7 +44,6 @@ internal class NativeDatabaseBinding : Closeable {
|
|
|
44
44
|
// region sqlite3 bindings
|
|
45
45
|
|
|
46
46
|
external fun sqlite3_changes(): Int
|
|
47
|
-
external fun sqlite3_finalize_all_statement()
|
|
48
47
|
external fun sqlite3_close(): Int
|
|
49
48
|
external fun sqlite3_interrupt()
|
|
50
49
|
external fun sqlite3_db_filename(databaseName: String): String
|
|
@@ -8,10 +8,18 @@ import java.nio.ByteBuffer
|
|
|
8
8
|
|
|
9
9
|
internal class NativeStatement : SharedRef<NativeStatementBinding>(NativeStatementBinding()) {
|
|
10
10
|
var isFinalized = false
|
|
11
|
+
var isPrepared = false
|
|
12
|
+
var releasedByJavaScript = false
|
|
11
13
|
|
|
12
14
|
override fun sharedObjectDidRelease() {
|
|
13
15
|
super.sharedObjectDidRelease()
|
|
14
|
-
this
|
|
16
|
+
synchronized(this) {
|
|
17
|
+
if (isFinalized || !isPrepared) {
|
|
18
|
+
ref.close()
|
|
19
|
+
} else {
|
|
20
|
+
releasedByJavaScript = true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
override fun equals(other: Any?): Boolean {
|
|
@@ -141,11 +141,7 @@ class SQLiteModule : Module() {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
AsyncFunction("closeAsync") { database: NativeDatabase ->
|
|
144
|
-
|
|
145
|
-
val db = removeCachedDatabase(database)
|
|
146
|
-
if (db != null) {
|
|
147
|
-
closeDatabase(db)
|
|
148
|
-
}
|
|
144
|
+
closeDatabaseIfNeeded(database)
|
|
149
145
|
}.runOnQueue(moduleCoroutineScope)
|
|
150
146
|
// Interrupt must reach SQLite immediately, without waiting for the running query's queue.
|
|
151
147
|
Function("interruptSync") { database: NativeDatabase ->
|
|
@@ -161,11 +157,7 @@ class SQLiteModule : Module() {
|
|
|
161
157
|
}
|
|
162
158
|
}
|
|
163
159
|
Function("closeSync") { database: NativeDatabase ->
|
|
164
|
-
|
|
165
|
-
val db = removeCachedDatabase(database)
|
|
166
|
-
if (db != null) {
|
|
167
|
-
closeDatabase(db)
|
|
168
|
-
}
|
|
160
|
+
closeDatabaseIfNeeded(database)
|
|
169
161
|
}
|
|
170
162
|
|
|
171
163
|
AsyncFunction("execAsync") { database: NativeDatabase, source: String ->
|
|
@@ -242,12 +234,16 @@ class SQLiteModule : Module() {
|
|
|
242
234
|
}
|
|
243
235
|
|
|
244
236
|
AsyncFunction("getColumnNamesAsync") { statement: NativeStatement ->
|
|
245
|
-
|
|
246
|
-
|
|
237
|
+
synchronized(statement) {
|
|
238
|
+
maybeThrowForFinalizedStatement(statement)
|
|
239
|
+
return@AsyncFunction statement.ref.getColumnNames()
|
|
240
|
+
}
|
|
247
241
|
}.runOnQueue(moduleCoroutineScope)
|
|
248
242
|
Function("getColumnNamesSync") { statement: NativeStatement ->
|
|
249
|
-
|
|
250
|
-
|
|
243
|
+
synchronized(statement) {
|
|
244
|
+
maybeThrowForFinalizedStatement(statement)
|
|
245
|
+
return@Function statement.ref.getColumnNames()
|
|
246
|
+
}
|
|
251
247
|
}
|
|
252
248
|
|
|
253
249
|
AsyncFunction("finalizeAsync") { statement: NativeStatement, database: NativeDatabase ->
|
|
@@ -371,21 +367,27 @@ class SQLiteModule : Module() {
|
|
|
371
367
|
|
|
372
368
|
@Throws(AccessClosedResourceException::class, SQLiteErrorException::class)
|
|
373
369
|
private fun prepareStatement(database: NativeDatabase, statement: NativeStatement, source: String) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
370
|
+
synchronized(database.statementLifecycleLock) {
|
|
371
|
+
synchronized(statement) {
|
|
372
|
+
maybeThrowForFinalizedStatement(statement)
|
|
373
|
+
maybeThrowForClosedDatabase(database)
|
|
374
|
+
if (database.ref.sqlite3_prepare_v2(source, statement.ref) != NativeDatabaseBinding.SQLITE_OK) {
|
|
375
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
376
|
+
}
|
|
377
|
+
statement.isPrepared = true
|
|
378
|
+
database.statements.add(statement)
|
|
379
|
+
}
|
|
378
380
|
}
|
|
379
381
|
}
|
|
380
382
|
|
|
381
383
|
@Throws(AccessClosedResourceException::class, SQLiteErrorException::class)
|
|
382
384
|
private fun run(statement: NativeStatement, database: NativeDatabase, bindParams: Map<String, Any?>, bindBlobParams: Map<String, ArrayBuffer>, shouldPassAsArray: Boolean): Map<String, Any> {
|
|
383
|
-
maybeThrowForClosedDatabase(database)
|
|
384
|
-
maybeThrowForFinalizedStatement(statement)
|
|
385
|
-
|
|
386
385
|
// The statement with parameter bindings is stateful,
|
|
387
386
|
// we have to guard with a critical section for thread safety.
|
|
388
387
|
synchronized(statement) {
|
|
388
|
+
maybeThrowForFinalizedStatement(statement)
|
|
389
|
+
maybeThrowForClosedDatabase(database)
|
|
390
|
+
|
|
389
391
|
statement.ref.sqlite3_reset()
|
|
390
392
|
statement.ref.sqlite3_clear_bindings()
|
|
391
393
|
for ((key, param) in bindParams) {
|
|
@@ -429,11 +431,11 @@ class SQLiteModule : Module() {
|
|
|
429
431
|
|
|
430
432
|
@Throws(AccessClosedResourceException::class, InvalidConvertibleException::class, SQLiteErrorException::class)
|
|
431
433
|
private fun step(statement: NativeStatement, database: NativeDatabase): SQLiteColumnValues? {
|
|
432
|
-
maybeThrowForClosedDatabase(database)
|
|
433
|
-
maybeThrowForFinalizedStatement(statement)
|
|
434
|
-
|
|
435
434
|
// Guard the stateful statement, see `run` above.
|
|
436
435
|
synchronized(statement) {
|
|
436
|
+
maybeThrowForFinalizedStatement(statement)
|
|
437
|
+
maybeThrowForClosedDatabase(database)
|
|
438
|
+
|
|
437
439
|
val ret = statement.ref.sqlite3_step()
|
|
438
440
|
if (ret == NativeDatabaseBinding.SQLITE_ROW) {
|
|
439
441
|
return statement.getTransformedColumnValues()
|
|
@@ -447,11 +449,11 @@ class SQLiteModule : Module() {
|
|
|
447
449
|
|
|
448
450
|
@Throws(AccessClosedResourceException::class, InvalidConvertibleException::class, SQLiteErrorException::class)
|
|
449
451
|
private fun getAll(statement: NativeStatement, database: NativeDatabase): List<SQLiteColumnValues> {
|
|
450
|
-
maybeThrowForClosedDatabase(database)
|
|
451
|
-
maybeThrowForFinalizedStatement(statement)
|
|
452
|
-
|
|
453
452
|
// Guard the stateful statement, see `run` above.
|
|
454
453
|
synchronized(statement) {
|
|
454
|
+
maybeThrowForFinalizedStatement(statement)
|
|
455
|
+
maybeThrowForClosedDatabase(database)
|
|
456
|
+
|
|
455
457
|
val columnValuesList = mutableListOf<SQLiteColumnValues>()
|
|
456
458
|
while (true) {
|
|
457
459
|
val ret = statement.ref.sqlite3_step()
|
|
@@ -469,11 +471,11 @@ class SQLiteModule : Module() {
|
|
|
469
471
|
|
|
470
472
|
@Throws(AccessClosedResourceException::class, SQLiteErrorException::class)
|
|
471
473
|
private fun reset(statement: NativeStatement, database: NativeDatabase) {
|
|
472
|
-
maybeThrowForClosedDatabase(database)
|
|
473
|
-
maybeThrowForFinalizedStatement(statement)
|
|
474
|
-
|
|
475
474
|
// Guard the stateful statement, see `run` above.
|
|
476
475
|
synchronized(statement) {
|
|
476
|
+
maybeThrowForFinalizedStatement(statement)
|
|
477
|
+
maybeThrowForClosedDatabase(database)
|
|
478
|
+
|
|
477
479
|
if (statement.ref.sqlite3_reset() != NativeDatabaseBinding.SQLITE_OK) {
|
|
478
480
|
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
479
481
|
}
|
|
@@ -482,15 +484,23 @@ class SQLiteModule : Module() {
|
|
|
482
484
|
|
|
483
485
|
@Throws(AccessClosedResourceException::class, SQLiteErrorException::class)
|
|
484
486
|
private fun finalize(statement: NativeStatement, database: NativeDatabase) {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
+
synchronized(database.statementLifecycleLock) {
|
|
488
|
+
// Guard the stateful statement, see `run` above.
|
|
489
|
+
synchronized(statement) {
|
|
490
|
+
maybeThrowForFinalizedStatement(statement)
|
|
491
|
+
maybeThrowForClosedDatabase(database)
|
|
487
492
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
493
|
+
val ret = statement.ref.sqlite3_finalize()
|
|
494
|
+
// SQLite destroys the statement even when returning an earlier execution error.
|
|
495
|
+
statement.isFinalized = true
|
|
496
|
+
database.statements.removeAll { it === statement }
|
|
497
|
+
if (statement.releasedByJavaScript) {
|
|
498
|
+
statement.ref.close()
|
|
499
|
+
}
|
|
500
|
+
if (ret != NativeDatabaseBinding.SQLITE_OK) {
|
|
501
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
502
|
+
}
|
|
492
503
|
}
|
|
493
|
-
statement.isFinalized = true
|
|
494
504
|
}
|
|
495
505
|
}
|
|
496
506
|
|
|
@@ -527,13 +537,15 @@ class SQLiteModule : Module() {
|
|
|
527
537
|
private fun closeDatabase(database: NativeDatabase) {
|
|
528
538
|
database.closeLock.lock()
|
|
529
539
|
try {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
540
|
+
synchronized(database.statementLifecycleLock) {
|
|
541
|
+
maybeThrowForClosedDatabase(database)
|
|
542
|
+
maybeFinalizeAllStatements(database)
|
|
543
|
+
val ret = database.ref.sqlite3_close()
|
|
544
|
+
if (ret != NativeDatabaseBinding.SQLITE_OK) {
|
|
545
|
+
throw SQLiteErrorException(database.ref.convertSqlLiteErrorToString())
|
|
546
|
+
}
|
|
547
|
+
database.isClosed = true
|
|
535
548
|
}
|
|
536
|
-
database.isClosed = true
|
|
537
549
|
} finally {
|
|
538
550
|
database.closeLock.unlock()
|
|
539
551
|
}
|
|
@@ -587,16 +599,22 @@ class SQLiteModule : Module() {
|
|
|
587
599
|
}
|
|
588
600
|
|
|
589
601
|
@Synchronized
|
|
590
|
-
private fun
|
|
602
|
+
private fun closeDatabaseIfNeeded(database: NativeDatabase) {
|
|
603
|
+
maybeThrowForClosedDatabase(database)
|
|
591
604
|
val index = cachedDatabases.indexOf(database)
|
|
592
605
|
if (index >= 0) {
|
|
593
606
|
val db = cachedDatabases[index]
|
|
594
607
|
if (db.release() == 0) {
|
|
608
|
+
try {
|
|
609
|
+
closeDatabase(db)
|
|
610
|
+
} catch (error: Exception) {
|
|
611
|
+
// Keep the connection cached and owned so callers can clean up and retry.
|
|
612
|
+
db.addRef()
|
|
613
|
+
throw error
|
|
614
|
+
}
|
|
595
615
|
cachedDatabases.removeAt(index)
|
|
596
|
-
return db
|
|
597
616
|
}
|
|
598
617
|
}
|
|
599
|
-
return null
|
|
600
618
|
}
|
|
601
619
|
|
|
602
620
|
@Synchronized
|
|
@@ -615,12 +633,24 @@ class SQLiteModule : Module() {
|
|
|
615
633
|
|
|
616
634
|
// region statements managements
|
|
617
635
|
|
|
618
|
-
@Synchronized
|
|
619
636
|
private fun maybeFinalizeAllStatements(database: NativeDatabase) {
|
|
620
637
|
if (!database.openOptions.finalizeUnusedStatementsBeforeClosing) {
|
|
621
638
|
return
|
|
622
639
|
}
|
|
623
|
-
|
|
640
|
+
// Finalize through the wrappers so even a failed close leaves them invalidated.
|
|
641
|
+
// Do not destroy SQLite-internal statements owned by concurrent exec/backup operations.
|
|
642
|
+
var firstError: Exception? = null
|
|
643
|
+
for (statement in database.statements.toList()) {
|
|
644
|
+
try {
|
|
645
|
+
finalize(statement, database)
|
|
646
|
+
} catch (error: SQLiteErrorException) {
|
|
647
|
+
android.util.Log.w("expo-sqlite", "Finalizing a statement during close failed", error)
|
|
648
|
+
} catch (error: Exception) {
|
|
649
|
+
// A broken wrapper must not prevent cleanup of the remaining statements.
|
|
650
|
+
firstError = firstError ?: error
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
firstError?.let { throw it }
|
|
624
654
|
}
|
|
625
655
|
|
|
626
656
|
// endregion
|
|
@@ -314,5 +314,5 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
|
|
|
314
314
|
@keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
|
|
315
315
|
@keyframes r-q67da2{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
|
|
316
316
|
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css" as="style">
|
|
317
|
-
<link rel="stylesheet" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css"></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-
|
|
317
|
+
<link rel="stylesheet" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css"></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-b2894030c1dfbd95b717a85901b6c271.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-9b94dd2fbdbb825a662f42cf8d2077ee.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-04fdb7d857a65c0ed638ef2d774a4b6e.js" defer></script>
|
|
318
318
|
</body></html>
|