-
Notifications
You must be signed in to change notification settings - Fork 438
Description
I'm developing a module that consists in a custom Migrator that any database can use to track metadata from its defined tables. This metadata will be stored inside the same database - to use triggers on the tracked tables -, so it has in itself another Drift Database with the metadata tables that will share the same executor. Although the shared executor architecture is supported, as stated on #488, the major concern is regarding migrations for two reasons: (1) if they run in parallel and (2) because the database only stores one schema version on the user_version PRAGMA.
The first problem is not a concern, since the database is inside the Migrator and it controls migrations execution. But the second problem is not currently possible to address otherwise than disabling migrations on this database - which translates into a lot more complexity if I ever need to evolve the schema of the metadata.
A solution that I came up for this problem would be if the versionDelegate parameter could be supplied or overriden on the database level - beside the already exposed enableMigrations parameter that controls which versionDelegate to use on the database.
drift/drift/lib/src/sqlite3/database.dart
Lines 106 to 108 in 5e4dfc8
| versionDelegate = enableMigrations | |
| ? _SqliteVersionDelegate(database) | |
| : const NoVersionDelegate(); |
Then, my hidden database could have a custom DynamicVersionDelegate subclass that would store the version anywhere (even out of the database if needed, like on a shared preferences) and apply it's migrations independently.
drift/drift/lib/src/sqlite3/database.dart
Lines 198 to 211 in 5e4dfc8
| class _SqliteVersionDelegate extends DynamicVersionDelegate { | |
| final CommonDatabase database; | |
| _SqliteVersionDelegate(this.database); | |
| @override | |
| Future<int> get schemaVersion => Future.value(database.userVersion); | |
| @override | |
| Future<void> setSchemaVersion(int version) { | |
| database.userVersion = version; | |
| return Future.value(); | |
| } | |
| } |
To give full flexibility to developers, the override of this parameter could be through a callback that receives the database and returns a VersionDelegate object. This would even allow storing the version on another table of the same database.
Does it make sense to expose such versionDelegate parameter? Or are there more implications to it than this simplistic approach?