1- /* eslint-disable no-shadow */
2- /* eslint-disable no-undef */
31import { NativeModules } from 'react-native' ;
42
53declare global {
@@ -129,6 +127,19 @@ export interface Transaction {
129127 executeSql : ( query : string , params ?: any [ ] ) => QueryResult ;
130128}
131129
130+ export interface AsyncTransaction {
131+ executeSql : ( query : string , params ?: any [ ] ) => QueryResult ;
132+ asyncExecuteSql : (
133+ query : string ,
134+ params : any [ ] | undefined ,
135+ cb : ( res : QueryResult ) => void
136+ ) => void ;
137+ promiseExecuteSql : (
138+ query : string ,
139+ params : any [ ] | undefined
140+ ) => Promise < QueryResult > ;
141+ }
142+
132143export interface PendingTransaction {
133144 start : ( ) => void ;
134145}
@@ -141,9 +152,7 @@ interface ISQLite {
141152 status : 0 | 1 ;
142153 message ?: string ;
143154 } ;
144- close : (
145- dbName : string
146- ) => {
155+ close : ( dbName : string ) => {
147156 status : 0 | 1 ;
148157 message ?: string ;
149158 } ;
@@ -156,6 +165,10 @@ interface ISQLite {
156165 ) => StatementResult ;
157166 detach : ( mainDbName : string , alias : string ) => StatementResult ;
158167 transaction : ( dbName : string , fn : ( tx : Transaction ) => boolean ) => void ;
168+ asyncTransaction : (
169+ dbName : string ,
170+ fn : ( tx : AsyncTransaction ) => Promise < boolean >
171+ ) => void ;
159172 executeSql : (
160173 dbName : string ,
161174 query : string ,
@@ -298,6 +311,70 @@ QuickSQLite.transaction = (
298311 startNextTransaction ( dbName ) ;
299312} ;
300313
314+ QuickSQLite . asyncTransaction = (
315+ dbName : string ,
316+ callback : ( tx : AsyncTransaction ) => Promise < boolean >
317+ ) => {
318+ if ( ! locks [ dbName ] ) {
319+ throw Error ( `Quick SQLite Error: No lock found on db: ${ dbName } ` ) ;
320+ }
321+
322+ // Local transaction context object implementation
323+ const executeSql = ( query : string , params ?: any [ ] ) : QueryResult => {
324+ return QuickSQLite . executeSql ( dbName , query , params ) ;
325+ } ;
326+
327+ const asyncExecuteSql = (
328+ query : string ,
329+ params : any [ ] | undefined ,
330+ cb : ( res : QueryResult ) => void
331+ ) => {
332+ return QuickSQLite . asyncExecuteSql ( dbName , query , params , cb ) ;
333+ } ;
334+
335+ const promiseExecuteSql = (
336+ query : string ,
337+ params : any [ ] | undefined
338+ ) : Promise < QueryResult > => {
339+ return new Promise ( ( resolve , reject ) => {
340+ QuickSQLite . asyncExecuteSql ( dbName , query , params , ( res ) => {
341+ if ( res . status ) {
342+ reject ( res ) ;
343+ } else {
344+ resolve ( res ) ;
345+ }
346+ } ) ;
347+ } ) ;
348+ } ;
349+
350+ const tx : PendingTransaction = {
351+ start : async ( ) => {
352+ try {
353+ QuickSQLite . executeSql ( dbName , 'BEGIN TRANSACTION' , null ) ;
354+ const result = await callback ( {
355+ executeSql,
356+ asyncExecuteSql,
357+ promiseExecuteSql,
358+ } ) ;
359+ if ( result === true ) {
360+ QuickSQLite . executeSql ( dbName , 'COMMIT' , null ) ;
361+ } else {
362+ QuickSQLite . executeSql ( dbName , 'ROLLBACK' , null ) ;
363+ }
364+ } catch ( e : any ) {
365+ QuickSQLite . executeSql ( dbName , 'ROLLBACK' , null ) ;
366+ throw e ;
367+ } finally {
368+ locks [ dbName ] . inProgress = false ;
369+ startNextTransaction ( dbName ) ;
370+ }
371+ } ,
372+ } ;
373+
374+ locks [ dbName ] . queue . push ( tx ) ;
375+ startNextTransaction ( dbName ) ;
376+ } ;
377+
301378const startNextTransaction = ( dbName : string ) => {
302379 if ( locks [ dbName ] . inProgress ) {
303380 // Transaction is already in process bail out
@@ -358,6 +435,7 @@ interface IDBConnection {
358435 ) => void ;
359436 detach : ( alias : string , callback : ( result : StatementResult ) => void ) => void ;
360437 transaction : ( fn : ( tx : Transaction ) => boolean ) => void ;
438+ asyncTransaction : ( fn : ( tx : AsyncTransaction ) => Promise < boolean > ) => void
361439 loadSqlFile : (
362440 location : string ,
363441 callback : ( result : FileLoadResult ) => void
@@ -430,6 +508,9 @@ export const openDatabase = (
430508 transaction : ( fn : ( tx : Transaction ) => boolean ) : void => {
431509 QuickSQLite . transaction ( options . name , fn ) ;
432510 } ,
511+ asyncTransaction : ( fn : ( tx : AsyncTransaction ) => Promise < boolean > ) : void => {
512+ return QuickSQLite . asyncTransaction ( options . name , fn ) ;
513+ } ,
433514 close : ( ok : any , fail : any ) => {
434515 try {
435516 QuickSQLite . close ( options . name ) ;
0 commit comments