Make `generate_connect_constructor` the default

This commit is contained in:
Simon Binder 2023-01-28 16:14:27 +01:00
parent bff8d6c6a1
commit 83fad8426e
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
12 changed files with 41 additions and 49 deletions

View File

@ -53,8 +53,10 @@ At the moment, drift supports these options:
(so a column named `user_name` would also use `user_name` as a json key instead of `userName`). (so a column named `user_name` would also use `user_name` as a json key instead of `userName`).
You can always override the json key by using a `JSON KEY` column constraint You can always override the json key by using a `JSON KEY` column constraint
(e.g. `user_name VARCHAR NOT NULL JSON KEY userName`). (e.g. `user_name VARCHAR NOT NULL JSON KEY userName`).
* `generate_connect_constructor`: Generate necessary code to support the [isolate runtime]({{ "isolates.md" | pageUrl }}). * `generate_connect_constructor`: Generates a named `connect()` constructor on database classes
This is a build option because isolates are still experimental. This will be the default option eventually. that takes a `DatabaseConnection` instead of a `QueryExecutor` - this allows sharing stream queries
between two drift database instances, which can be helpful for some [isolate setups]({{ "isolates.md" | pageUrl }}).
The option is enabled by default.
* `data_class_to_companions` (defaults to `true`): Controls whether drift will write the `toCompanion` method in generated * `data_class_to_companions` (defaults to `true`): Controls whether drift will write the `toCompanion` method in generated
data classes. data classes.
* `mutable_classes` (defaults to `false`): The fields generated in generated data, companion and result set classes are final * `mutable_classes` (defaults to `false`): The fields generated in generated data, companion and result set classes are final

View File

@ -45,7 +45,7 @@ replacement for the `NativeDatabase` you've been using before:
{% include "blocks/snippet" snippets = snippets name = 'simple' %} {% include "blocks/snippet" snippets = snippets name = 'simple' %}
In the common case where you only need a isolate for performance reasons, this In the common case where you only need a isolate for performance reasons, this
is as simple as it gets. is everything you need to do to run queries in a background isolate.
The rest of this article explains a more complex setup giving you full control The rest of this article explains a more complex setup giving you full control
over the internal components making up a drift isolate. This is useful for over the internal components making up a drift isolate. This is useful for
advanced use cases, including: advanced use cases, including:
@ -60,29 +60,26 @@ the complicated bits are hidden behind a simple method.
## Preparations ## Preparations
To use the isolate api, first enable the appropriate [build option]({{ "builder_options.md" | pageUrl }}) by When a drift database is opened multiple times, the two instances need to
creating a file called `build.yaml` in your project root, next to your `pubspec.yaml`. It should have the following synchronize query streams, so that updates made in one instance are reflected
content: in queries watched by the other.
```yaml
targets:
$default:
builders:
drift_dev:
options:
generate_connect_constructor: true
```
Next, re-run the build. You can now add another constructor to the generated database class: By default, drift databases are created from a `QueryExecutor` - an interface
responsible for running the SQL statements generated by higher-level drift APIs.
To share both the underlying database and a drift-specific mechanism for
streams, you can instead use a `DatabaseConnection` instance. For that, you need
to use the generated `connect()` constructor in your database class:
{% include "blocks/snippet" snippets = snippets name = 'database' %} {% include "blocks/snippet" snippets = snippets name = 'database' %}
This setup is unfortunately necessary for backwards compatibility. A Having a second constructor taking a `DatabaseConnection` is necessary for
`DatabaseConnection` and the `connect` constructor make it possible to share backwards compatibility since the default constructor only takes a
query streams between isolates, the default constructor can't do this. In a `QueryExecutor` which is insufficient to synchronize streams.
future drift reelase, this option will no longer be necessary. If you only want to open your database with a `DatabaseConnection`, you can
remove the default constructor though.
After adding the `connect` constructor, you can launch a drift isolate to After adding the new constructor, you can create instances of your database
connect to: that will transparently run queries on a background isolate:
## Using drift in a background isolate {#using-moor-in-a-background-isolate} ## Using drift in a background isolate {#using-moor-in-a-background-isolate}
@ -102,11 +99,12 @@ Internally, drift will connect when the first query is sent to the database.
### Initialization on the main thread ### Initialization on the main thread
At the moment, Flutter's platform channels are [not available on background isolates](https://github.com/flutter/flutter/issues/13937). Before Flutter 3.7, platforms channels weren't [available on background isolates](https://github.com/flutter/flutter/issues/13937).
If you want to use functions like `getApplicationDocumentsDirectory` from `path_provider` to So, if functions like `getApplicationDocumentsDirectory` from `path_provider`
construct the database's path, we'll have to use some tricks to avoid using platforms channels. are used to construct the path to the database, some tricks were necessary.
Here, we're going to start the isolate running the database manually. This allows us to pass additional This section describes a workaround to start the isolate running the database
data that we calculated on the main thread. manually. This allows passing additional data that can be computed on the main
isolate, using platform channels.
{% include "blocks/snippet" snippets = snippets name = 'initialization' %} {% include "blocks/snippet" snippets = snippets name = 'initialization' %}

View File

@ -369,12 +369,12 @@ void main() {
In general, a test looks like this: In general, a test looks like this:
- Use `verifier.startAt()` to obtain a [connection](https://pub.dev/documentation/moor/latest/moor/DatabaseConnection-class.html) 1. Use `verifier.startAt()` to obtain a [connection](https://drift.simonbinder.eu/api/drift/databaseconnection-class)
to a database with an initial schema. to a database with an initial schema.
This database contains all your tables, indices and triggers from that version, created by using `Migrator.createAll`. This database contains all your tables, indices and triggers from that version, created by using `Migrator.createAll`.
- Create your application database (you can enable the [`generate_connect_constructor`]({{ "builder_options.md" | pageUrl }}) to use 2. Create your application database with that connection - you can forward the `DatabaseConnection` to the
a `DatabaseConnection` directly) `GeneratedDatabase.connect()` constructor on the parent class for this.
- Call `verifier.migrateAndValidate(db, version)`. This will initiate a migration towards the target version (here, `2`). 3. Call `verifier.migrateAndValidate(db, version)`. This will initiate a migration towards the target version (here, `2`).
Unlike the database created by `startAt`, this uses the migration logic you wrote for your database. Unlike the database created by `startAt`, this uses the migration logic you wrote for your database.
`migrateAndValidate` will extract all `CREATE` statement from the `sqlite_schema` table and semantically compare them. `migrateAndValidate` will extract all `CREATE` statement from the `sqlite_schema` table and semantically compare them.

View File

@ -194,8 +194,7 @@ DatabaseConnection connectToWorker() {
} }
``` ```
You can pass that `DatabaseConnection` to your database by enabling the You can then open a drift database with that connection.
`generate_connect_constructor` build option.
For more information on the `DatabaseConnection` class, see the documentation on For more information on the `DatabaseConnection` class, see the documentation on
[isolates]({{ "../Advanced Features/isolates.md" | pageUrl }}). [isolates]({{ "../Advanced Features/isolates.md" | pageUrl }}).

View File

@ -15,7 +15,6 @@ targets:
options: options:
override_hash_and_equals_in_result_sets: true override_hash_and_equals_in_result_sets: true
use_column_name_as_json_key_when_defined_in_moor_file: true use_column_name_as_json_key_when_defined_in_moor_file: true
generate_connect_constructor: true
write_from_json_string_constructor: true write_from_json_string_constructor: true
raw_result_set_data: true raw_result_set_data: true
named_parameters: true named_parameters: true
@ -38,7 +37,6 @@ targets:
# Dart doesn't support YAML merge tags yet, https://github.com/dart-lang/yaml/issues/121 # Dart doesn't support YAML merge tags yet, https://github.com/dart-lang/yaml/issues/121
override_hash_and_equals_in_result_sets: true override_hash_and_equals_in_result_sets: true
use_column_name_as_json_key_when_defined_in_moor_file: true use_column_name_as_json_key_when_defined_in_moor_file: true
generate_connect_constructor: true
write_from_json_string_constructor: true write_from_json_string_constructor: true
raw_result_set_data: true raw_result_set_data: true
named_parameters: true named_parameters: true

View File

@ -4,6 +4,7 @@
- Support `MAPPED BY` for individual columns in queries or in views defined with SQL. - Support `MAPPED BY` for individual columns in queries or in views defined with SQL.
- Consistently interpret `CAST (x AS DATETIME)` and `CAST(x AS TEXT)` in drift files. - Consistently interpret `CAST (x AS DATETIME)` and `CAST(x AS TEXT)` in drift files.
- Support a `CAST` to an enum type in drift types. - Support a `CAST` to an enum type in drift types.
- The `generate_connect_constructor` option is now enabled by default.
- Support two different queries using `LIST()` columns having the same result class name. - Support two different queries using `LIST()` columns having the same result class name.
- Fix table classes not extending defining Dart classes with modular generation. - Fix table classes not extending defining Dart classes with modular generation.
- Fix `@UseDataClass` with `extending` not working with modular generation. - Fix `@UseDataClass` with `extending` not working with modular generation.

View File

@ -45,9 +45,12 @@ class DriftOptions {
defaultValue: true) defaultValue: true)
final bool useColumnNameAsJsonKeyWhenDefinedInMoorFile; final bool useColumnNameAsJsonKeyWhenDefinedInMoorFile;
/// Generate a `connect` constructor in database superclasses. This is /// Generate a `connect` constructor in database superclasses.
/// required to run databases in a background isolate. ///
@JsonKey(name: 'generate_connect_constructor', defaultValue: false) /// This makes drift generate a constructor for database classes that takes a
/// `DatabaseConnection` instead of just a `QueryExecutor` - meaning that
/// stream queries can also be shared across multiple database instances.
@JsonKey(name: 'generate_connect_constructor', defaultValue: true)
final bool generateConnectConstructor; final bool generateConnectConstructor;
@JsonKey(name: 'sqlite_modules', defaultValue: []) @JsonKey(name: 'sqlite_modules', defaultValue: [])
@ -104,7 +107,7 @@ class DriftOptions {
this.skipVerificationCode = false, this.skipVerificationCode = false,
this.useDataClassNameForCompanions = false, this.useDataClassNameForCompanions = false,
this.useColumnNameAsJsonKeyWhenDefinedInMoorFile = true, this.useColumnNameAsJsonKeyWhenDefinedInMoorFile = true,
this.generateConnectConstructor = false, this.generateConnectConstructor = true,
this.dataClassToCompanions = true, this.dataClassToCompanions = true,
this.generateMutableClasses = false, this.generateMutableClasses = false,
this.rawResultSetData = false, this.rawResultSetData = false,
@ -180,9 +183,6 @@ class DriftOptions {
bool hasModule(SqlModule module) => effectiveModules.contains(module); bool hasModule(SqlModule module) => effectiveModules.contains(module);
/// Checks whether a deprecated option is enabled. /// Checks whether a deprecated option is enabled.
///
/// At this time, all deprecated options have been removed, meaning that this
/// getter always returns `false`.
bool get enabledDeprecatedOption => false; bool get enabledDeprecatedOption => false;
SqlDialect get effectiveDialect => dialect?.dialect ?? SqlDialect.sqlite; SqlDialect get effectiveDialect => dialect?.dialect ?? SqlDialect.sqlite;

View File

@ -49,7 +49,7 @@ DriftOptions _$DriftOptionsFromJson(Map json) => $checkedCreate(
'use_column_name_as_json_key_when_defined_in_moor_file', 'use_column_name_as_json_key_when_defined_in_moor_file',
(v) => v as bool? ?? true), (v) => v as bool? ?? true),
generateConnectConstructor: $checkedConvert( generateConnectConstructor: $checkedConvert(
'generate_connect_constructor', (v) => v as bool? ?? false), 'generate_connect_constructor', (v) => v as bool? ?? true),
dataClassToCompanions: $checkedConvert( dataClassToCompanions: $checkedConvert(
'data_class_to_companions', (v) => v as bool? ?? true), 'data_class_to_companions', (v) => v as bool? ?? true),
generateMutableClasses: generateMutableClasses:

View File

@ -25,9 +25,6 @@ targets:
version: "3.38" version: "3.38"
modules: [fts5] modules: [fts5]
# This allows us to share a drift database across isolates (or different tabs on the web)
generate_connect_constructor: true
# Configuring this builder isn't required for most apps. In our case, we # Configuring this builder isn't required for most apps. In our case, we
# want to compile the web worker in `web/worker.dart` to JS and we use the # want to compile the web worker in `web/worker.dart` to JS and we use the
# build system for that. # build system for that.

View File

@ -3,7 +3,6 @@ targets:
builders: builders:
drift_dev: drift_dev:
options: options:
generate_connect_constructor: true
store_date_time_values_as_text: true store_date_time_values_as_text: true
sql: sql:
dialect: sqlite dialect: sqlite

View File

@ -31,7 +31,6 @@ targets:
builders: builders:
drift_dev: drift_dev:
options: options:
generate_connect_constructor: true
named_parameters: true named_parameters: true
build_web_compilers:entrypoint: build_web_compilers:entrypoint:
generate_for: generate_for:

View File

@ -5,7 +5,6 @@ targets:
options: options:
override_hash_and_equals_in_result_sets: true override_hash_and_equals_in_result_sets: true
use_column_name_as_json_key_when_defined_in_moor_file: true use_column_name_as_json_key_when_defined_in_moor_file: true
generate_connect_constructor: true
write_from_json_string_constructor: true write_from_json_string_constructor: true
raw_result_set_data: false raw_result_set_data: false
named_parameters: false named_parameters: false