An extension to sqflite for adding hooks to database actions.
In your flutter project add the dependency:
dependencies:
...
sqflite_hooks: ^1.0.0
sqflite is included as part of this package but if you require a specific version, make sure this is added to your pubspec.yaml
.
For help getting started with Flutter, view the online documentation.
The usage is no different to sqflite. Just be sure to import sqflite_hooks
instead of sqflite
:
import 'package:sqflite_hooks/sqflite_hooks.dart';
Then you can open and create your database like so:
var databasesPath = await getDatabasesPath();
var path = join(databasesPath, 'demo.db');
var database = await openDatabase(path, version: 1,
onCreate: (database, version) async {
await database.execute(
'''CREATE TABLE Users (Id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL);''');
});
The main difference when using sqflite_hooks
is that you can add hooks to a database object. This allows you to easily run Dart code when actions occur on your database.
database.addHook(
(event) => event.table == 'Users' && event.operation == DatabaseOperation.insert,
(event) {
// do something when a new record is inserted on the Users table
},
'NewUserHook');
The addHook
method is as follows:
void addHook(bool Function(DatabaseEvent) predicate, Function(DatabaseEvent) hook, String key)
- The
predicate
parameter is aFunction
which should returntrue
if thehook
should run. Apredicate
should not be marked asasync
. - The
hook
parameter is aFunction
which will run should thepredicate
return true. Ahook
can beasync
. - The
key
parameter is aString
used for keeping track of hooks and removing them later.
The DatabaseEvent
class contains the following properties:
final DatabaseOperation operation;
final String table;
final Map<String, dynamic> values;
final String where;
final List whereArgs;
The operation
property is a DatabaseOperation
enum which has the following values:
enum DatabaseOperation { insert, update, delete }
Hooks can be removed like so:
database.removeHook('NewUserHook');
Please note: all hooks for a predicate
returning true
will run and be await
-ed before the database operation completes.
Hooks on a HookedDatabase
will also be fired when using a HookedTransaction
. You can get a HookedTransaction
object as you would usually get a Transaction
:
await database.transaction((transaction) async {
// this gives you a HookedTransaction object but the type exposed is a Transaction
// use the transaction object as normal
});
Hooks get fired for each operation
performed on a HookedTransaction
If a transaction fails and hooks have already fired, you can provide a function to the named parameter onRollBack
when creating a hooked transaction. onRollBack
expects a Function(List<DatabaseEvent>)
argument:
await database.transaction((transaction) async {
...
}, onRollBack: (events) {
for (var event in events) {
// undo anything that might have happened from fired hooks before the transaction failed
}
});
Hooks on a HookedDatabase
will also be fired when using a HookedBatch
. You can get a HookedBatch
object as you would usually get a Batch
:
var batch = database.batch(); // this returns a HookedBatch object but the type exposed is a Batch
Hooks get fired once the commit
method has been called on the HookedBatch
, but after all database operations for the batch has completed.
A HookedBatch
is also provided when using transaction.batch()
and has its hooks fired once the commit
method is called.