mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 12:07:09 +00:00
fix(folio-core): probe schema before create on wasmJs
Wasm SqlDriver doesn't auto-track user_version like the Android driver, so awaitCreate() ran on every page load and tripped over already-created tables. Read PRAGMA user_version, run awaitCreate/awaitMigrate based on it, and self-heal pre-existing tables with version 0 by stamping the current schema version.
This commit is contained in:
1 parent
afd92d461d
commit
8a3fa556d7
1 file changed
+51
-1
+51
-1
@@ -3,6 +3,7 @@
|
|||||||
package app.folio.core.data
|
package app.folio.core.data
|
||||||
|
|
||||||
import app.cash.sqldelight.async.coroutines.awaitCreate
|
import app.cash.sqldelight.async.coroutines.awaitCreate
|
||||||
|
import app.cash.sqldelight.async.coroutines.awaitMigrate
|
||||||
import app.cash.sqldelight.db.SqlDriver
|
import app.cash.sqldelight.db.SqlDriver
|
||||||
import app.cash.sqldelight.driver.worker.WebWorkerDriver
|
import app.cash.sqldelight.driver.worker.WebWorkerDriver
|
||||||
import app.folio.db.LedgerDatabase
|
import app.folio.db.LedgerDatabase
|
||||||
@@ -11,10 +12,59 @@ import org.w3c.dom.Worker
|
|||||||
actual class DriverFactory {
|
actual class DriverFactory {
|
||||||
actual suspend fun create(): SqlDriver {
|
actual suspend fun create(): SqlDriver {
|
||||||
val driver = WebWorkerDriver(createSqliteWorker())
|
val driver = WebWorkerDriver(createSqliteWorker())
|
||||||
LedgerDatabase.Schema.awaitCreate(driver)
|
val schema = LedgerDatabase.Schema
|
||||||
|
val current = readUserVersion(driver)
|
||||||
|
val target = schema.version
|
||||||
|
when {
|
||||||
|
current == 0L && !schemaExists(driver) -> {
|
||||||
|
schema.awaitCreate(driver)
|
||||||
|
writeUserVersion(driver, target)
|
||||||
|
}
|
||||||
|
current == 0L -> writeUserVersion(driver, target)
|
||||||
|
current < target -> {
|
||||||
|
schema.awaitMigrate(driver, current, target)
|
||||||
|
writeUserVersion(driver, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
return driver
|
return driver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun readUserVersion(driver: SqlDriver): Long {
|
||||||
|
var version = 0L
|
||||||
|
driver.executeQuery(
|
||||||
|
identifier = null,
|
||||||
|
sql = "PRAGMA user_version",
|
||||||
|
mapper = { cursor ->
|
||||||
|
app.cash.sqldelight.db.QueryResult.AsyncValue {
|
||||||
|
if (cursor.next().await()) version = cursor.getLong(0) ?: 0L
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parameters = 0,
|
||||||
|
).await()
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun writeUserVersion(driver: SqlDriver, version: Long) {
|
||||||
|
driver.execute(null, "PRAGMA user_version = $version", 0).await()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun schemaExists(driver: SqlDriver): Boolean {
|
||||||
|
var exists = false
|
||||||
|
driver.executeQuery(
|
||||||
|
identifier = null,
|
||||||
|
sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' LIMIT 1",
|
||||||
|
mapper = { cursor ->
|
||||||
|
app.cash.sqldelight.db.QueryResult.AsyncValue {
|
||||||
|
exists = cursor.next().await()
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parameters = 0,
|
||||||
|
).await()
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
private fun createSqliteWorker(): Worker =
|
private fun createSqliteWorker(): Worker =
|
||||||
js("""new Worker(new URL("./sqlite.worker.js", import.meta.url), { type: "module" })""")
|
js("""new Worker(new URL("./sqlite.worker.js", import.meta.url), { type: "module" })""")
|
||||||
Reference in new issue
Block a user