You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying to write a transaction snippet which works both with sync and async drivers.
It took me a while to realize, that:
I can write async code and it'll seem to work with all drivers, no TS errors, no runtime errors.
It'll actually silently break sync drivers, as the COMMIT is inserted in the wrong place.
I mean this
await db.transaction(async (tx) => {
for (let i = 21; i <= 25; i++) {
const r = await tx
.insert(books)
.values({ id: i, title: `tx ${i}`, price: i })
.run()
}
})
Will result in this:
BEGIN DEFERRED
insert into "books" ("id", "title", "price") values (21.0, 'tx 21', 21.0)
COMMIT
insert into "books" ("id", "title", "price") values (22.0, 'tx 22', 22.0)
insert into "books" ("id", "title", "price") values (23.0, 'tx 23', 23.0)
insert into "books" ("id", "title", "price") values (24.0, 'tx 24', 24.0)
insert into "books" ("id", "title", "price") values (25.0, 'tx 25', 25.0)
The fact that this happens silently, without any error at runtime or TS time is quite bad I think. I mean, how much code might be out there in the wild, thinking that their transaction code is functioning correctly, while that COMMIT is actually silently inserted in the wrong place.
My questions:
Can you make this throw super big errors both at TS time and at runtime?
Can you give me some advice, how to write a universal snippet, which works both with sync and async drivers.
I'm kind of thinking something like this, but of course without 100% duplication and preferably, without using the private property db.resultKind.
if (db.resultKind === 'sync') {
;(db as BetterSQLite3Database).transaction((tx) => {
for (let i = 21; i <= 25; i++) {
const r = tx
.insert(books)
.values({ id: i, title: `tx ${i}`, price: i })
.run()
check(`tx insert ${i}`, r, { changes: 1, lastInsertRowid: i })
}
})
} else {
await (db as SqliteRemoteDatabase).transaction(async (tx) => {
for (let i = 21; i <= 25; i++) {
const r = await tx
.insert(books)
.values({ id: i, title: `tx ${i}`, price: i })
.run()
check(`tx insert ${i}`, r, { changes: 1, lastInsertRowid: i })
}
})
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm trying to write a transaction snippet which works both with sync and async drivers.
It took me a while to realize, that:
I mean this
Will result in this:
The fact that this happens silently, without any error at runtime or TS time is quite bad I think. I mean, how much code might be out there in the wild, thinking that their transaction code is functioning correctly, while that COMMIT is actually silently inserted in the wrong place.
My questions:
I'm kind of thinking something like this, but of course without 100% duplication and preferably, without using the private property
db.resultKind
.Beta Was this translation helpful? Give feedback.
All reactions