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
|
@@ -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>
|
|
@@ -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 class="flex min-h-screen items-center justify-center bg-linear-to-br from-slate-50 to-slate-100 p-4"><div class="rounded-xl border bg-card text-card-foreground shadow w-full max-w-2xl"><div class="flex flex-col space-y-1.5 p-6 text-center"><div class="font-semibold tracking-tight text-3xl">SQLite Database Inspector</div><div class="text-muted-foreground text-base">Upload a database file or connect to your app</div></div><div class="p-6 pt-0"><div dir="ltr" data-orientation="horizontal" class="w-full"><div role="tablist" aria-orientation="horizontal" class="h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground grid w-full grid-cols-2" tabindex="-1" data-orientation="horizontal" style="outline:none"><button type="button" role="tab" aria-selected="true" aria-controls="radix-_R_jer3_-content-devtools" data-state="active" data-disabled="" disabled="" id="radix-_R_jer3_-trigger-devtools" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">From App </button><button type="button" role="tab" aria-selected="false" aria-controls="radix-_R_jer3_-content-upload" data-state="inactive" id="radix-_R_jer3_-trigger-upload" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">Upload File</button></div><div data-state="inactive" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-upload" hidden="" id="radix-_R_jer3_-content-upload" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"></div><div data-state="active" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-devtools" id="radix-_R_jer3_-content-devtools" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" style="animation-duration:0s"><div class="space-y-4"><div class="flex items-center justify-between"><h3 class="text-sm font-medium">Available Databases</h3><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 text-xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-4 w-4 mr-2" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>Refresh</button></div><div class="text-center p-12 rounded-lg border-2 border-dashed border-muted-foreground/25"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-database h-12 w-12 text-muted-foreground mx-auto mb-4" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5V19A9 3 0 0 0 21 19V5"></path><path d="M3 12A9 3 0 0 0 21 12"></path></svg><p class="text-sm text-muted-foreground">No databases found. Make sure your app is using useSQLiteDevTool.</p></div></div></div></div></div></div></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><!--/$--><!--/$--></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 class="flex min-h-screen items-center justify-center bg-linear-to-br from-slate-50 to-slate-100 p-4"><div class="rounded-xl border bg-card text-card-foreground shadow w-full max-w-2xl"><div class="flex flex-col space-y-1.5 p-6 text-center"><div class="font-semibold tracking-tight text-3xl">SQLite Database Inspector</div><div class="text-muted-foreground text-base">Upload a database file or connect to your app</div></div><div class="p-6 pt-0"><div dir="ltr" data-orientation="horizontal" class="w-full"><div role="tablist" aria-orientation="horizontal" class="h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground grid w-full grid-cols-2" tabindex="-1" data-orientation="horizontal" style="outline:none"><button type="button" role="tab" aria-selected="true" aria-controls="radix-_R_jer3_-content-devtools" data-state="active" data-disabled="" disabled="" id="radix-_R_jer3_-trigger-devtools" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">From App </button><button type="button" role="tab" aria-selected="false" aria-controls="radix-_R_jer3_-content-upload" data-state="inactive" id="radix-_R_jer3_-trigger-upload" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">Upload File</button></div><div data-state="inactive" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-upload" hidden="" id="radix-_R_jer3_-content-upload" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"></div><div data-state="active" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-devtools" id="radix-_R_jer3_-content-devtools" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" style="animation-duration:0s"><div class="space-y-4"><div class="flex items-center justify-between"><h3 class="text-sm font-medium">Available Databases</h3><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 text-xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-4 w-4 mr-2" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>Refresh</button></div><div class="text-center p-12 rounded-lg border-2 border-dashed border-muted-foreground/25"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-database h-12 w-12 text-muted-foreground mx-auto mb-4" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5V19A9 3 0 0 0 21 19V5"></path><path d="M3 12A9 3 0 0 0 21 12"></path></svg><p class="text-sm text-muted-foreground">No databases found. Make sure your app is using useSQLiteDevTool.</p></div></div></div></div></div></div></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><!--/$--><!--/$--></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/index-4bf2da199f699eb47a42074d5e183c07.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>
|
package/ios/NativeDatabase.swift
CHANGED
|
@@ -11,6 +11,10 @@ final class NativeDatabase: SharedObject, @unchecked Sendable {
|
|
|
11
11
|
let openOptions: OpenDatabaseOptions
|
|
12
12
|
var isClosed = false
|
|
13
13
|
let closeLock = NSLock()
|
|
14
|
+
// Protect statement registration and cleanup through the final close attempt.
|
|
15
|
+
// Running statements use their own locks, so interruption need not wait for them.
|
|
16
|
+
let statementLifecycleLock = NSRecursiveLock()
|
|
17
|
+
var statements: [NativeStatement] = []
|
|
14
18
|
var extraPointer: OpaquePointer?
|
|
15
19
|
private var refCount = AtomicInteger(1)
|
|
16
20
|
|
|
@@ -134,11 +138,16 @@ final class NativeDatabase: SharedObject, @unchecked Sendable {
|
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
private func prepare(statement: NativeStatement, source: String) throws {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
statementLifecycleLock.lock()
|
|
142
|
+
defer { statementLifecycleLock.unlock() }
|
|
143
|
+
try statement.lock.withLock { _ in
|
|
144
|
+
try statement.ensureNotFinalized()
|
|
145
|
+
try ensureOpen()
|
|
146
|
+
let sourceString = source.cString(using: .utf8)
|
|
147
|
+
if exsqlite3_prepare_v2(pointer, sourceString, -1, &statement.pointer, nil) != SQLITE_OK {
|
|
148
|
+
throw SQLiteErrorException(lastErrorMessage())
|
|
149
|
+
}
|
|
150
|
+
statements.append(statement)
|
|
142
151
|
}
|
|
143
152
|
}
|
|
144
153
|
|
|
@@ -60,10 +60,10 @@ final class NativeStatement: SharedObject, @unchecked Sendable {
|
|
|
60
60
|
// MARK: - Implementation shared by the sync and async members
|
|
61
61
|
|
|
62
62
|
private func reset(database: NativeDatabase) throws {
|
|
63
|
-
try database.ensureOpen()
|
|
64
|
-
try ensureNotFinalized()
|
|
65
|
-
|
|
66
63
|
try lock.withLock { _ in
|
|
64
|
+
try ensureNotFinalized()
|
|
65
|
+
try database.ensureOpen()
|
|
66
|
+
|
|
67
67
|
if exsqlite3_reset(pointer) != SQLITE_OK {
|
|
68
68
|
throw SQLiteErrorException(database.lastErrorMessage())
|
|
69
69
|
}
|
|
@@ -71,24 +71,32 @@ final class NativeStatement: SharedObject, @unchecked Sendable {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
private func getColumnNames() throws -> [String] {
|
|
74
|
-
try
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
return try lock.withLock { _ in
|
|
75
|
+
try ensureNotFinalized()
|
|
76
|
+
let columnCount = Int(exsqlite3_column_count(pointer))
|
|
77
|
+
var columnNames: [String] = Array(repeating: "", count: columnCount)
|
|
78
|
+
for i in 0..<columnCount {
|
|
79
|
+
columnNames[i] = String(cString: exsqlite3_column_name(pointer, Int32(i)))
|
|
80
|
+
}
|
|
81
|
+
return columnNames
|
|
79
82
|
}
|
|
80
|
-
return columnNames
|
|
81
83
|
}
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
func finalize(database: NativeDatabase) throws {
|
|
86
|
+
database.statementLifecycleLock.lock()
|
|
87
|
+
defer { database.statementLifecycleLock.unlock() }
|
|
87
88
|
try lock.withLock { _ in
|
|
88
|
-
|
|
89
|
+
try ensureNotFinalized()
|
|
90
|
+
try database.ensureOpen()
|
|
91
|
+
|
|
92
|
+
let ret = exsqlite3_finalize(pointer)
|
|
93
|
+
// SQLite destroys the statement even when returning an earlier execution error.
|
|
94
|
+
isFinalized = true
|
|
95
|
+
pointer = nil
|
|
96
|
+
database.statements.removeAll { $0 === self }
|
|
97
|
+
if ret != SQLITE_OK {
|
|
89
98
|
throw SQLiteErrorException(database.lastErrorMessage())
|
|
90
99
|
}
|
|
91
|
-
isFinalized = true
|
|
92
100
|
}
|
|
93
101
|
}
|
|
94
102
|
}
|
package/ios/SQLiteModule.swift
CHANGED
|
@@ -9,7 +9,7 @@ private let MEMORY_DB_NAME = ":memory:"
|
|
|
9
9
|
private let moduleQueue = DispatchQueue(label: "expo.module.sqlite.AsyncQueue", qos: .userInitiated, attributes: .concurrent)
|
|
10
10
|
|
|
11
11
|
// `@unchecked Sendable`: the `@JS(.concurrent)` members send the module off the JavaScript thread, which
|
|
12
|
-
// Swift 6 mode allows only for a `Sendable` module. The mutable state is either guarded by `
|
|
12
|
+
// Swift 6 mode allows only for a `Sendable` module. The mutable state is either guarded by `cacheLock` or
|
|
13
13
|
// only read off the JavaScript thread (`hasListeners`).
|
|
14
14
|
@ExpoModule("ExpoSQLite")
|
|
15
15
|
public final class SQLiteModule: Module, @unchecked Sendable {
|
|
@@ -17,7 +17,8 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
17
17
|
// will release the pair when `closeDatabase` is called.
|
|
18
18
|
private var contextPairs = [Unmanaged<AnyObject>]()
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// Closing a cached connection also releases its update-hook context under this lock.
|
|
21
|
+
private static let cacheLock = NSRecursiveLock()
|
|
21
22
|
private var cachedDatabases = [NativeDatabase]()
|
|
22
23
|
private(set) var hasListeners = false
|
|
23
24
|
|
|
@@ -154,10 +155,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
AsyncFunction("closeAsync") { (database: NativeDatabase) in
|
|
157
|
-
try
|
|
158
|
-
if let db = removeCachedDatabase(of: database) {
|
|
159
|
-
try closeDatabase(db)
|
|
160
|
-
}
|
|
158
|
+
try closeDatabaseIfNeeded(database)
|
|
161
159
|
}.runOnQueue(moduleQueue)
|
|
162
160
|
// Interrupt must reach SQLite immediately, without waiting for the running query's queue.
|
|
163
161
|
Function("interruptSync") { (database: NativeDatabase) in
|
|
@@ -170,10 +168,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
170
168
|
exsqlite3_interrupt(database.pointer)
|
|
171
169
|
}
|
|
172
170
|
Function("closeSync") { (database: NativeDatabase) in
|
|
173
|
-
try
|
|
174
|
-
if let db = removeCachedDatabase(of: database) {
|
|
175
|
-
try closeDatabase(db)
|
|
176
|
-
}
|
|
171
|
+
try closeDatabaseIfNeeded(database)
|
|
177
172
|
}
|
|
178
173
|
}
|
|
179
174
|
|
|
@@ -264,12 +259,12 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
264
259
|
// swiftlint:disable line_length
|
|
265
260
|
|
|
266
261
|
private func run(statement: NativeStatement, database: NativeDatabase, bindParams: [String: Any], bindBlobParams: [String: any AnyArrayBuffer], shouldPassAsArray: Bool) throws -> [String: Any] {
|
|
267
|
-
try maybeThrowForClosedDatabase(database)
|
|
268
|
-
try maybeThrowForFinalizedStatement(statement)
|
|
269
|
-
|
|
270
262
|
// The statement with parameter bindings is stateful,
|
|
271
263
|
// we have to guard with a critical section for thread safety.
|
|
272
264
|
return try statement.lock.withLock { _ -> [String: Any] in
|
|
265
|
+
try maybeThrowForFinalizedStatement(statement)
|
|
266
|
+
try maybeThrowForClosedDatabase(database)
|
|
267
|
+
|
|
273
268
|
exsqlite3_reset(statement.pointer)
|
|
274
269
|
exsqlite3_clear_bindings(statement.pointer)
|
|
275
270
|
for (key, param) in bindParams {
|
|
@@ -301,11 +296,11 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
301
296
|
// swiftlint:enable line_length
|
|
302
297
|
|
|
303
298
|
private func step(statement: NativeStatement, database: NativeDatabase) throws -> SQLiteColumnValues? {
|
|
304
|
-
try maybeThrowForClosedDatabase(database)
|
|
305
|
-
try maybeThrowForFinalizedStatement(statement)
|
|
306
|
-
|
|
307
299
|
// Guard the stateful statement, see `run` above.
|
|
308
300
|
return try statement.lock.withLock { _ -> SQLiteColumnValues? in
|
|
301
|
+
try maybeThrowForFinalizedStatement(statement)
|
|
302
|
+
try maybeThrowForClosedDatabase(database)
|
|
303
|
+
|
|
309
304
|
let ret = exsqlite3_step(statement.pointer)
|
|
310
305
|
if ret == SQLITE_ROW {
|
|
311
306
|
return try getColumnValues(statement: statement)
|
|
@@ -318,11 +313,11 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
318
313
|
}
|
|
319
314
|
|
|
320
315
|
private func getAll(statement: NativeStatement, database: NativeDatabase) throws -> [SQLiteColumnValues] {
|
|
321
|
-
try maybeThrowForClosedDatabase(database)
|
|
322
|
-
try maybeThrowForFinalizedStatement(statement)
|
|
323
|
-
|
|
324
316
|
// Guard the stateful statement, see `run` above.
|
|
325
317
|
return try statement.lock.withLock { _ -> [SQLiteColumnValues] in
|
|
318
|
+
try maybeThrowForFinalizedStatement(statement)
|
|
319
|
+
try maybeThrowForClosedDatabase(database)
|
|
320
|
+
|
|
326
321
|
var columnValuesList: [SQLiteColumnValues] = []
|
|
327
322
|
while true {
|
|
328
323
|
let ret = exsqlite3_step(statement.pointer)
|
|
@@ -343,16 +338,24 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
343
338
|
return db.lastErrorMessage()
|
|
344
339
|
}
|
|
345
340
|
|
|
346
|
-
|
|
341
|
+
func closeDatabase(_ db: NativeDatabase) throws {
|
|
342
|
+
Self.cacheLock.lock()
|
|
343
|
+
defer { Self.cacheLock.unlock() }
|
|
347
344
|
db.closeLock.lock()
|
|
348
345
|
defer { db.closeLock.unlock() }
|
|
349
|
-
|
|
346
|
+
db.statementLifecycleLock.lock()
|
|
347
|
+
defer { db.statementLifecycleLock.unlock() }
|
|
348
|
+
try db.ensureOpen()
|
|
350
349
|
try maybeFinalizeAllStatements(db)
|
|
351
350
|
|
|
352
351
|
let ret = exsqlite3_close(db.pointer)
|
|
352
|
+
// SQLITE_BUSY leaves the connection open, including its update hook.
|
|
353
|
+
if ret != SQLITE_OK {
|
|
354
|
+
throw SQLiteErrorException(convertSqlLiteErrorToString(db))
|
|
355
|
+
}
|
|
353
356
|
db.isClosed = true
|
|
354
357
|
|
|
355
|
-
Self.
|
|
358
|
+
Self.cacheLock.withLock {
|
|
356
359
|
if let index = contextPairs.firstIndex(where: {
|
|
357
360
|
guard let pair = $0.takeUnretainedValue() as? (SQLiteModule, NativeDatabase) else {
|
|
358
361
|
return false
|
|
@@ -366,10 +369,6 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
366
369
|
contextPairs.remove(at: index)
|
|
367
370
|
}
|
|
368
371
|
}
|
|
369
|
-
|
|
370
|
-
if ret != SQLITE_OK {
|
|
371
|
-
throw SQLiteErrorException(convertSqlLiteErrorToString(db))
|
|
372
|
-
}
|
|
373
372
|
}
|
|
374
373
|
|
|
375
374
|
private func deleteDatabase(databasePath: String) throws {
|
|
@@ -412,7 +411,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
412
411
|
|
|
413
412
|
private func addUpdateHook(_ database: NativeDatabase) {
|
|
414
413
|
let contextPair = Unmanaged.passRetained(((self, database) as AnyObject))
|
|
415
|
-
Self.
|
|
414
|
+
Self.cacheLock.withLock {
|
|
416
415
|
contextPairs.append(contextPair)
|
|
417
416
|
}
|
|
418
417
|
// swiftlint:disable:next multiline_arguments
|
|
@@ -525,27 +524,32 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
525
524
|
// MARK: - cachedDatabases managements
|
|
526
525
|
|
|
527
526
|
private func addCachedDatabase(_ database: NativeDatabase) {
|
|
528
|
-
Self.
|
|
527
|
+
Self.cacheLock.withLock {
|
|
529
528
|
cachedDatabases.append(database)
|
|
530
529
|
}
|
|
531
530
|
}
|
|
532
531
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
532
|
+
private func closeDatabaseIfNeeded(_ database: NativeDatabase) throws {
|
|
533
|
+
try Self.cacheLock.withLock {
|
|
534
|
+
try maybeThrowForClosedDatabase(database)
|
|
536
535
|
if let index = cachedDatabases.firstIndex(of: database) {
|
|
537
536
|
let db = cachedDatabases[index]
|
|
538
537
|
if db.release() == 0 {
|
|
538
|
+
do {
|
|
539
|
+
try closeDatabase(db)
|
|
540
|
+
} catch {
|
|
541
|
+
// Keep the connection cached and owned so callers can clean up and retry.
|
|
542
|
+
db.addRef()
|
|
543
|
+
throw error
|
|
544
|
+
}
|
|
539
545
|
cachedDatabases.remove(at: index)
|
|
540
|
-
return db
|
|
541
546
|
}
|
|
542
547
|
}
|
|
543
|
-
return nil
|
|
544
548
|
}
|
|
545
549
|
}
|
|
546
550
|
|
|
547
551
|
private func findCachedDatabase(where predicate: (NativeDatabase) -> Bool) -> NativeDatabase? {
|
|
548
|
-
return Self.
|
|
552
|
+
return Self.cacheLock.withLock {
|
|
549
553
|
if let database = cachedDatabases.first(where: predicate) {
|
|
550
554
|
return database
|
|
551
555
|
}
|
|
@@ -554,7 +558,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
554
558
|
}
|
|
555
559
|
|
|
556
560
|
private func removeAllCachedDatabases() -> [NativeDatabase] {
|
|
557
|
-
return Self.
|
|
561
|
+
return Self.cacheLock.withLock {
|
|
558
562
|
let databases = cachedDatabases
|
|
559
563
|
cachedDatabases.removeAll()
|
|
560
564
|
return databases
|
|
@@ -566,17 +570,14 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
566
570
|
guard database.openOptions.finalizeUnusedStatementsBeforeClosing else {
|
|
567
571
|
return
|
|
568
572
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if ret != SQLITE_OK {
|
|
577
|
-
ExpoModulesCore.log.warn("exsqlite3_finalize failed: \(convertSqlLiteErrorToString(database))")
|
|
573
|
+
// Finalize through the wrappers so even a failed close leaves them invalidated.
|
|
574
|
+
// Do not destroy SQLite-internal statements owned by concurrent exec/backup operations.
|
|
575
|
+
for statement in database.statements {
|
|
576
|
+
do {
|
|
577
|
+
try statement.finalize(database: database)
|
|
578
|
+
} catch {
|
|
579
|
+
ExpoModulesCore.log.warn("Finalizing a statement during close failed: \(error)")
|
|
578
580
|
}
|
|
579
|
-
stmt = nextStmt
|
|
580
581
|
}
|
|
581
582
|
}
|
|
582
583
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Copyright 2026-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import Testing
|
|
4
|
+
|
|
5
|
+
@testable import ExpoModulesCore
|
|
6
|
+
@testable import ExpoSQLite
|
|
7
|
+
|
|
8
|
+
@Suite("Statement cleanup")
|
|
9
|
+
struct StatementCleanupTests {
|
|
10
|
+
@Test
|
|
11
|
+
@JavaScriptActor
|
|
12
|
+
func `failed close invalidates cleaned up statements and permits retry`() throws {
|
|
13
|
+
let appContext = AppContext.create()
|
|
14
|
+
let module = SQLiteModule(appContext: appContext)
|
|
15
|
+
var pointer: OpaquePointer?
|
|
16
|
+
var destination: OpaquePointer?
|
|
17
|
+
#expect(exsqlite3_open(":memory:", &pointer) == SQLITE_OK)
|
|
18
|
+
#expect(exsqlite3_open(":memory:", &destination) == SQLITE_OK)
|
|
19
|
+
let database = NativeDatabase(pointer, databasePath: ":memory:", openOptions: OpenDatabaseOptions())
|
|
20
|
+
defer {
|
|
21
|
+
if !database.isClosed { try? module.closeDatabase(database) }
|
|
22
|
+
exsqlite3_close(destination)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let statement = NativeStatement()
|
|
26
|
+
try database.prepareSync(statement: statement, source: "SELECT 42 AS value")
|
|
27
|
+
|
|
28
|
+
// A pending backup keeps the source connection busy even after every statement is finalized.
|
|
29
|
+
// This reproduces a failed close after cleanup without depending on a thread race.
|
|
30
|
+
let backup = try #require(exsqlite3_backup_init(destination, "main", pointer, "main"))
|
|
31
|
+
do {
|
|
32
|
+
defer { exsqlite3_backup_finish(backup) }
|
|
33
|
+
#expect(throws: SQLiteErrorException.self) { try module.closeDatabase(database) }
|
|
34
|
+
#expect(!database.isClosed)
|
|
35
|
+
try #require(statement.isFinalized)
|
|
36
|
+
#expect(throws: AccessClosedResourceException.self) { try statement.getColumnNamesSync() }
|
|
37
|
+
#expect(throws: AccessClosedResourceException.self) {
|
|
38
|
+
try statement.finalizeSync(database: database)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let fresh = NativeStatement()
|
|
42
|
+
try database.prepareSync(statement: fresh, source: "SELECT 1 AS fresh")
|
|
43
|
+
#expect(try fresh.getColumnNamesSync() == ["fresh"])
|
|
44
|
+
try fresh.finalizeSync(database: database)
|
|
45
|
+
}
|
|
46
|
+
try module.closeDatabase(database)
|
|
47
|
+
#expect(database.isClosed)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Test
|
|
51
|
+
func `preparing during close either gets cleaned up or rejects the closed database`() async throws {
|
|
52
|
+
let appContext = AppContext.create()
|
|
53
|
+
let module = SQLiteModule(appContext: appContext)
|
|
54
|
+
for _ in 0..<50 {
|
|
55
|
+
var pointer: OpaquePointer?
|
|
56
|
+
#expect(exsqlite3_open(":memory:", &pointer) == SQLITE_OK)
|
|
57
|
+
let database = NativeDatabase(pointer, databasePath: ":memory:", openOptions: OpenDatabaseOptions())
|
|
58
|
+
defer {
|
|
59
|
+
if !database.isClosed { try? module.closeDatabase(database) }
|
|
60
|
+
}
|
|
61
|
+
let statement = NativeStatement()
|
|
62
|
+
await withTaskGroup(of: Void.self) { group in
|
|
63
|
+
for index in 0..<2 {
|
|
64
|
+
group.addTask {
|
|
65
|
+
do {
|
|
66
|
+
if index == 0 {
|
|
67
|
+
try await database.prepareAsync(statement: statement, source: "SELECT 1")
|
|
68
|
+
} else {
|
|
69
|
+
try module.closeDatabase(database)
|
|
70
|
+
}
|
|
71
|
+
} catch is AccessClosedResourceException {
|
|
72
|
+
#expect(index == 0)
|
|
73
|
+
} catch {
|
|
74
|
+
Issue.record(error)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
#expect(database.isClosed)
|
|
80
|
+
// A prepared statement must have been invalidated by cleanup.
|
|
81
|
+
#expect(statement.pointer == nil)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f9c01cec01c62d6a619fdc69f237e033
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
afa88d36ec945ad0442cc3582e05eb84b07cb9f1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
67dbdc88a1d7fc60c31092ad150a98a30d93d8ca82bbf869609890965425524d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
47d6b003042ef32b80e19b64fd015ffcfa159bb8f08971459211cd6ab971304da58dee6236c2be5319f606f9062d023530dcaa5c2e530bb17e42ab1465d5b95f
|
package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0c582335d4a9a710a780e9e636dbc73a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3ef893dc3f6aec4bda329646065115814fd42d0a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
96b87814356fa93bcc9eb091c5b2f96f243fa661bd70740c352dae65cca23d8f
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d3fbb6aad5541429fc0b0c3edb30d9e71f12636e9215617d2cb19750aecb36c4df1efc1bc5f84fb75f816d9db01c4ad9a0f08457d67ae892e2ebb59d3bd26246
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "host.exp.exponent",
|
|
5
5
|
"module": "expo.modules.sqlite",
|
|
6
|
-
"version": "58.0.
|
|
6
|
+
"version": "58.0.9",
|
|
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-58.0.
|
|
28
|
-
"url": "expo.modules.sqlite-58.0.
|
|
29
|
-
"size":
|
|
30
|
-
"sha512": "
|
|
31
|
-
"sha256": "
|
|
32
|
-
"sha1": "
|
|
33
|
-
"md5": "
|
|
27
|
+
"name": "expo.modules.sqlite-58.0.9.aar",
|
|
28
|
+
"url": "expo.modules.sqlite-58.0.9.aar",
|
|
29
|
+
"size": 3958907,
|
|
30
|
+
"sha512": "d3fbb6aad5541429fc0b0c3edb30d9e71f12636e9215617d2cb19750aecb36c4df1efc1bc5f84fb75f816d9db01c4ad9a0f08457d67ae892e2ebb59d3bd26246",
|
|
31
|
+
"sha256": "96b87814356fa93bcc9eb091c5b2f96f243fa661bd70740c352dae65cca23d8f",
|
|
32
|
+
"sha1": "3ef893dc3f6aec4bda329646065115814fd42d0a",
|
|
33
|
+
"md5": "0c582335d4a9a710a780e9e636dbc73a"
|
|
34
34
|
}
|
|
35
35
|
]
|
|
36
36
|
},
|
|
@@ -67,13 +67,13 @@
|
|
|
67
67
|
],
|
|
68
68
|
"files": [
|
|
69
69
|
{
|
|
70
|
-
"name": "expo.modules.sqlite-58.0.
|
|
71
|
-
"url": "expo.modules.sqlite-58.0.
|
|
72
|
-
"size":
|
|
73
|
-
"sha512": "
|
|
74
|
-
"sha256": "
|
|
75
|
-
"sha1": "
|
|
76
|
-
"md5": "
|
|
70
|
+
"name": "expo.modules.sqlite-58.0.9.aar",
|
|
71
|
+
"url": "expo.modules.sqlite-58.0.9.aar",
|
|
72
|
+
"size": 3958907,
|
|
73
|
+
"sha512": "d3fbb6aad5541429fc0b0c3edb30d9e71f12636e9215617d2cb19750aecb36c4df1efc1bc5f84fb75f816d9db01c4ad9a0f08457d67ae892e2ebb59d3bd26246",
|
|
74
|
+
"sha256": "96b87814356fa93bcc9eb091c5b2f96f243fa661bd70740c352dae65cca23d8f",
|
|
75
|
+
"sha1": "3ef893dc3f6aec4bda329646065115814fd42d0a",
|
|
76
|
+
"md5": "0c582335d4a9a710a780e9e636dbc73a"
|
|
77
77
|
}
|
|
78
78
|
]
|
|
79
79
|
},
|
|
@@ -87,13 +87,13 @@
|
|
|
87
87
|
},
|
|
88
88
|
"files": [
|
|
89
89
|
{
|
|
90
|
-
"name": "expo.modules.sqlite-58.0.
|
|
91
|
-
"url": "expo.modules.sqlite-58.0.
|
|
92
|
-
"size":
|
|
93
|
-
"sha512": "
|
|
94
|
-
"sha256": "
|
|
95
|
-
"sha1": "
|
|
96
|
-
"md5": "
|
|
90
|
+
"name": "expo.modules.sqlite-58.0.9-sources.jar",
|
|
91
|
+
"url": "expo.modules.sqlite-58.0.9-sources.jar",
|
|
92
|
+
"size": 12434,
|
|
93
|
+
"sha512": "47d6b003042ef32b80e19b64fd015ffcfa159bb8f08971459211cd6ab971304da58dee6236c2be5319f606f9062d023530dcaa5c2e530bb17e42ab1465d5b95f",
|
|
94
|
+
"sha256": "67dbdc88a1d7fc60c31092ad150a98a30d93d8ca82bbf869609890965425524d",
|
|
95
|
+
"sha1": "afa88d36ec945ad0442cc3582e05eb84b07cb9f1",
|
|
96
|
+
"md5": "f9c01cec01c62d6a619fdc69f237e033"
|
|
97
97
|
}
|
|
98
98
|
]
|
|
99
99
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
027bb16e5aa93ebd85e027ee2f46126a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
214b155b65fff08267e3c51f3c305d0a60393fcd
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a1a758d13d8bfa0a508a0e8e76d619145bf6e9fed21e2793b4c3250c747ab0e2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
edceb164c582da1e7acbb0d0e0b64074ef17bb2af5a95a63f0d37e2272b93e8be9802bae030c92050f7dc7b357aa14ccbfa864c78d3818301aec13fecb0b04b0
|
|
@@ -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>58.0.
|
|
12
|
+
<version>58.0.9</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
|
+
b2d62f1ac9414101b72082d1f7184972
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4966c5a227bb7b1cd816624a1c7490c2214b26fd
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2835028ead37c42578edaaa5b9c5f7610643bd86b825c6e099c90cbfdc764bd7
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f3a422c4b7869c9b5bc74f3d85670925330e84ea0af7dbc1366e13122238618d5615159ab2db6d2e5d1b6a489ea69c2eee6051a395a64d4b4f6c841dc4c4bc23
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-sqlite",
|
|
3
|
-
"version": "58.0.
|
|
3
|
+
"version": "58.0.9",
|
|
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
|
"keywords": [
|
|
6
6
|
"async-storage",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@expo/spawn-async": "^1.8.0",
|
|
54
54
|
"@testing-library/react-native": "^14.0.1",
|
|
55
|
-
"@types/jest": "^
|
|
55
|
+
"@types/jest": "^30.0.0",
|
|
56
56
|
"@types/node": "^22.14.0",
|
|
57
57
|
"@types/react": "~19.3.0",
|
|
58
|
-
"expo": "58.0.
|
|
59
|
-
"expo-module-scripts": "56.0.
|
|
58
|
+
"expo": "58.0.3",
|
|
59
|
+
"expo-module-scripts": "56.0.6",
|
|
60
60
|
"react-error-boundary": "^4.0.11",
|
|
61
61
|
"tar": "^7.5.22"
|
|
62
62
|
},
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
5d7041a309f5d84f10ac82d07da84fd0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bfd1fcd029fde1a4a79827d383f8169dc4bfcba1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
652bb0d50e54573ff702a6a612c59a12dbb248176cfcb22a37ac7664f8df2ff8
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ffd5436b47527a99c40ad5552caf847eeb4a71a02f1d6adaaaa0a902bd56776239f76c8f0000eced2dd25824aacd7c0cbc5bf4390ff19f641f057fd5b7e64a59
|
package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.8/expo.modules.sqlite-58.0.8.aar
DELETED
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
b09d51c468f67c9f68bbe38ffacfcc9b
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9459af5726cbb1217327c3756f748c20b1abf2bc
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4db1f3cfc70e5178eb3fef1520de0b499cdca0c662c0fce6bbdfe806599b92d6
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
464a9e78fbec5af84d2f2957395aea245a089e145ffa4649074c9193d6b1a2b7b7bc0ee6cbc216a8b0b22bb9dd2f22b0b68ff7e2b9f601fa38d01bdd9e6d4cb0
|