I am trying to chain a sequence of executeSQL where I use the result set in some parts using the promise disposer pattern which I had implemented in the following class:
export class AsyncSQLTransaction implements SQLite.SQLTransaction {
constructor(private tx: SQLite.SQLTransaction) {}
/**
* fowards to the existing method
*/
executeSql(
sqlStatement: string,
args?: any[],
callback?: SQLite.SQLStatementCallback,
errorCallback?: SQLite.SQLStatementErrorCallback
): void {
this.tx.executeSql(sqlStatement, args, callback, errorCallback);
}
/**
* Executes an SQL statement as a promise
* @param sqlStatement
* @param args arguments
* @returns result set promise
*/
q(sqlStatement: string, ...args: any): Promise<SQLite.SQLResultSet> {
return new Promise((resolve, reject) => {
this.tx.executeSql(
sqlStatement,
args,
(tx, resultSet) => {
resolve(resultSet);
this.tx = tx;
},
(error) => {
console.error("q(e)", sqlStatement, args)
reject(error);
return true;
}
);
});
}
}
I used the it the following fashion.
console.log(tx); // says this.tx._complete is false
await tx.q("drop table if exists setup;");
console.log(tx); // says this.tx._complete is true
await tx.q("drop table if exists observation;");
console.log(tx); // never reaches here
I noticed this part of the code in expo-sqlite, from just reading it, it does some scheduling immediately. Which may be making the status of the transaction to complete when it does processing.
function executeSql(self, sql, args, sqlCallback, sqlErrorCallback) {
self._sqlQueue.push(new SQLTask(sql, args, sqlCallback, sqlErrorCallback));
if (self._runningTimeout) {
return;
}
self._runningTimeout = true;
immediate(function () {
self._runningTimeout = false;
runAllSql(self);
});
}
BTW if I don't do the the promise disposer pattern it works well.