I’m looking for some insights when using drift in multiple private packages.
We have a mono-repo with 3 apps and multiple private packages to share code amongst them. As more packages are starting to arise (these apps used to have a lot of copied code ), we’re facing some new challenges.
We have a few packages that would have to persist data, for which we’d like to use drift. Drift is already being used in our apps.
Should we go down the route of creating separate databases for each private package (we’re expecting 5 or 6 at the moment) or should we leave that responsibility to the host app and have multiple tables there?
I’ve been looking at the modular generation capabilities of drift, which might allow us to define the tables and DAOs in the package, but still have a single database in the app.
My main concern is performance but it’s hard to measure ahead of time so I’m hoping somebody can share their experiences on this topic
Thanks!
We went with the approach of having multiple databases first but in hindsight it might have been better with one database. We have 2 dbs to be accessed mainly by native code, and one db to be written to by the Flutter side. They were also accessed by the workmanager (i.e. background isolate Flutter).
Pros for multiple dbs:
for longer writes from the native side, we don’t have to worry about locking on the Flutter side
for sensitive data easier to analyze just a single file
we can basically avoid migrating databases when the schema is fixed
Cons:
a lot of back-and-forth to initialize and access various databases
locking still occurs occasionally
in the end we had to get access to the 3rd database on the native side, so we could’ve just done it in the very beginning anyway; so now all are accessed everywhere
necessary to run drift_dev multiple times
This is from the point of view of app, not package. Perhaps for packages it may be worth having isolated databases anyway. This is how a lot of the SDKs is approaching their data storage.
I’m currently using the modular generation, which allows me to keep create the package specific tables in the package and use them in the app’s generated database.
I’m still checking if it’s possible to create the DAO also in the package and use it in the @DriftDatabase annotation in the app. The app could then provide the instance of the package-specific DAO back to the package, allowing the package to only work on it’s own tables. Right now, I didn’t find a way to do this yet, since the DAO generation relies on the AppDatabase class.
As a workaround, I created a manual DAO which requires the instances of the generated tables in it’s constructor. I think it is basically the same. Just to summarize with a simplified example:
MyPackage:
has and exports MyPackageTable extends Table
exports a class MyPackageDao that requires a generated $MyPackageTable in it’s constructor.
Has an initialize method that requires an instance of MyPackageDao
MyApp:
has a database with @DriftDatabase(tables: [MyPackageTable, ...other])
calls my package’s initialize(MyPackageDao(database.myPackageTable))
Both have a build.yaml file that enables drift_dev:modular
Hopefully that makes sense.
I can follow up with a gist or github example later
That’s the price of code generation. The other alternative is to create the code that is generated in the DAOs and use’em as mixins or make them isolated, receiving the AppDatabase as an injected dependency? Oh boy, I miss introspection do much in Dart =(
I think the best shot is to expose your problem/thinking to Simon directly (drift author). He is a very nice guy and always listen to us. Maybe some kind of generic modularization is a good fit for Drift, and he can implement something in this regard.
Using contents of this forum for the purposes of training proprietary AI models is forbidden. Only if your AI model is free & open source, go ahead and scrape. Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.