-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
trigger update table callbacks only if changes are commited inside tr…
…ansactions
- Loading branch information
1 parent
7262d47
commit 8e6d64a
Showing
7 changed files
with
330 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@journeyapps/react-native-quick-sqlite': minor | ||
--- | ||
|
||
Fixed table change updates to only trigger change updates for changes made in `writeTransaction` and `writeLock`s which have been commited. Added ability to listen to all table change events as they occur. Added listeners for when a transaction has started, been commited or rolled back. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import _ from 'lodash'; | ||
import { registerUpdateHook } from './table-updates'; | ||
import { UpdateCallback, UpdateNotification } from './types'; | ||
import { BaseListener, BaseObserver } from './utils/BaseObserver'; | ||
|
||
export interface DBListenerManagerOptions { | ||
dbName: string; | ||
} | ||
|
||
export enum WriteTransactionEventType { | ||
STARTED = 'started', | ||
COMMIT = 'commit', | ||
ROLLBACK = 'rollback' | ||
} | ||
|
||
export interface WriteTransactionEvent { | ||
type: WriteTransactionEventType; | ||
} | ||
|
||
export interface DBListener extends BaseListener { | ||
/** | ||
* Register a listener to be fired for any table change. | ||
* Changes inside write transactions are reported immediately. | ||
*/ | ||
rawTableChange: UpdateCallback; | ||
|
||
/** | ||
* Register a listener for when table changes are persisted | ||
* into the DB. Changes during write transactions which are | ||
* rolled back are not reported. | ||
* Any changes during write transactions are buffered and reported | ||
* after commit. | ||
* Table changes are reported individually for now in order to maintain | ||
* API compatibility. These can be batched in future. | ||
*/ | ||
tableUpdated: UpdateCallback; | ||
|
||
/** | ||
* Listener event triggered whenever a write transaction | ||
* is started, committed or rolled back. | ||
*/ | ||
writeTransaction: (event: WriteTransactionEvent) => void; | ||
} | ||
|
||
export class DBListenerManager extends BaseObserver<DBListener> {} | ||
|
||
export class DBListenerManagerInternal extends DBListenerManager { | ||
private _writeTransactionActive: boolean; | ||
private updateBuffer: UpdateNotification[]; | ||
|
||
get writeTransactionActive() { | ||
return this._writeTransactionActive; | ||
} | ||
|
||
constructor(protected options: DBListenerManagerOptions) { | ||
super(); | ||
this._writeTransactionActive = false; | ||
this.updateBuffer = []; | ||
registerUpdateHook(this.options.dbName, (update) => this.handleTableUpdates(update)); | ||
} | ||
|
||
transactionStarted() { | ||
this._writeTransactionActive = true; | ||
this.iterateListeners((l) => l?.writeTransaction?.({ type: WriteTransactionEventType.STARTED })); | ||
} | ||
|
||
transactionCommitted() { | ||
this._writeTransactionActive = false; | ||
// flush updates | ||
const uniqueUpdates = _.uniq(this.updateBuffer); | ||
this.updateBuffer = []; | ||
this.iterateListeners((l) => { | ||
l.writeTransaction?.({ type: WriteTransactionEventType.COMMIT }); | ||
uniqueUpdates.forEach((update) => l.tableUpdated?.(update)); | ||
}); | ||
} | ||
|
||
transactionReverted() { | ||
this._writeTransactionActive = false; | ||
// clear updates | ||
this.updateBuffer = []; | ||
this.iterateListeners((l) => l?.writeTransaction?.({ type: WriteTransactionEventType.ROLLBACK })); | ||
} | ||
|
||
handleTableUpdates(notification: UpdateNotification) { | ||
// Fire updates for any change | ||
this.iterateListeners((l) => l.rawTableChange?.({ ...notification, pendingCommit: this._writeTransactionActive })); | ||
|
||
if (this.writeTransactionActive) { | ||
this.updateBuffer.push(notification); | ||
return; | ||
} | ||
|
||
this.iterateListeners((l) => l.tableUpdated?.(notification)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/** | ||
* Hooks which can be triggered during the execution of read/write locks | ||
*/ | ||
export interface LockHooks { | ||
/** | ||
* Executed after a SQL statement has been executed | ||
*/ | ||
execute?: (sql: string, args?: any[]) => Promise<void>; | ||
lockAcquired?: () => Promise<void>; | ||
lockReleased?: () => Promise<void>; | ||
} | ||
|
||
export interface TransactionHooks extends LockHooks { | ||
begin?: () => Promise<void>; | ||
commit?: () => Promise<void>; | ||
rollback?: () => Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.