-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transactions auto-close when queuing microtasks between executeSql() calls #46
Comments
Looking further into it when using promises alone things are okay. So I narrowed it down even further in that it is due to the |
Hmm, based on your repro, |
I am suspecting it could be in expo itself too. But Expo's implementation is pretty light in terms of code. However, it is running on top of React Native iOS and Android |
I have an mvce https://github.com/trajano/websql-mvce that proves that it does not work when doing the async/await style. I tweaked it around since the @types/websql does not work and I don't have Expo's typings. When the |
I think I might understand after looking at your repro. It sounds like basically you're saying that the code works when you use callbacks, but not async await. In particular, if you try to break up a single transaction into multiple operations across multiple promises (each handled using async/await), then the transaction automatically closes. This makes sense to me, because the WebSQL API was designed before Promises ever arrived in browsers. It wasn't really designed to work well with Promises. I guess the closest analog is how IndexedDB eventually allowed microtasks to execute without closing the transaction: w3c/IndexedDB#87. Based on this analog, I guess you could say that Here is the minimal repro of your issue, as I understand it: const openDatabase = require('websql')
const db = openDatabase(':memory:', '1.0', 'yolo', 100000);
async function main() {
const txn = await new Promise(resolve => {
db.transaction(resolve)
})
await new Promise(resolve => {
txn.executeSql('CREATE TABLE foo (bar text);', [], resolve)
})
await new Promise(resolve => {
txn.executeSql('INSERT INTO foo VALUES ("baz")', [], resolve)
})
const res = await new Promise(resolve => {
txn.executeSql('SELECT * FROM foo', [], (txn, res) => resolve(res))
})
console.log('res', res)
}
main() As I understand it, you would expect to be able to chain all these operations in the same transaction, but instead what actually happens is that the transaction closes after the |
Yup. I worked around it by creating a new The concept was to use
I still have a
The transactions are wrapped using
|
I'm glad you found a solution. I may never get around to solving this bug, especially since it's somewhat against the spirit of the library, as I said years ago that my goal was just to emulate the WebSQL API as designed (circa 2010!) and not "carry the flame" of WebSQL. I'll leave this issue open, though, as it seems potentially solvable without breaking backwards compatibility semantics. |
Added a failing test for this issue: aaf5c0f |
FWIW, we were able to make this work by patching in a way to disable the auto-commit mechanism and adding explicit |
@DerGuteMoritz would it work in Expo? |
@trajano Pretty sure, yes. IIRC the patch that Expo originally vendored |
Correct, I would prefer not to add new extensions to the WebSQL API. The goal of this project is to pretty narrowly just match the original WebSQL semantics and not invent new ones. Microtasks are kind of fuzzy, though, as the original WebSQL API predated promises. |
@DerGuteMoritz from the way your code looks, it appears that it requires |
I'm tracing through the code for a bug I opened in Expo and led me to this repo because they have a revendor of your code.
What I am trying to do is avoid doing chained callbacks and use async/await, for me to do that I wrapped some of the WebSQL code so that it uses the promise API to resolve the callbacks.
Almost everything goes well except when I chain two
executesql
in a single transaction where Iawait
. I am suspecting it may beimmediate
triggering the execution of the SQL tasks, but when it does it, it also completes the transaction since the queue is empty already.I've created a snack that shows this. But I am unsure how to fix it.
The text was updated successfully, but these errors were encountered: