Migrate rest of documentation to drift

This commit is contained in:
Simon Binder 2021-10-10 16:01:50 +02:00
parent e91207e9e4
commit 3157d687e5
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
34 changed files with 549 additions and 564 deletions

View File

@ -8,10 +8,10 @@ aliases:
- "options/" - "options/"
--- ---
The `moor_generator` package supports a range of options that control how code The `drift_dev` package supports a range of options that control how code
is generated. is generated.
In most cases, the default settings should be sufficient. But if you want to In most cases, the default settings should be sufficient. But if you want to
try out new features faster or configure how moor-generated code looks like, try out new features faster or configure how drift-generated code looks like,
you can use the available options listed below. you can use the available options listed below.
You can also see the section on [recommended options](#recommended-options) for You can also see the section on [recommended options](#recommended-options) for
advice on which options to use. advice on which options to use.
@ -24,28 +24,28 @@ to your `pubspec.yaml`):
targets: targets:
$default: $default:
builders: builders:
moor_generator: drift_dev:
options: options:
compact_query_methods: true compact_query_methods: true
``` ```
## Available options ## Available options
At the moment, moor supports these options: At the moment, drift supports these options:
* `write_from_json_string_constructor`: boolean. Adds a `.fromJsonString` factory * `write_from_json_string_constructor`: boolean. Adds a `.fromJsonString` factory
constructor to generated data classes. By default, we only write a `.fromJson` constructor to generated data classes. By default, we only write a `.fromJson`
constructor that takes a `Map<String, dynamic>`. constructor that takes a `Map<String, dynamic>`.
* `override_hash_and_equals_in_result_sets`: boolean. When moor generates another class * `override_hash_and_equals_in_result_sets`: boolean. When drift generates another class
to hold the result of generated select queries, this flag controls whether moor should to hold the result of generated select queries, this flag controls whether drift should
override `operator ==` and `hashCode` in those classes. In recent versions, it will also override `operator ==` and `hashCode` in those classes. In recent versions, it will also
override `toString` if this option is enabled. override `toString` if this option is enabled.
* `compact_query_methods` (defaults to `true`): * `compact_query_methods` (defaults to `true`):
For queries declared on a `@UseMoor` or `@UseDao` annotation, moor used to generate three methods: For queries declared on a `@DriftDatabase` or `@DriftAccessor` annotation, drift used to generate three methods:
A base method returning a `Selectable` and then two helper methods returning a `Stream` or a `Future`. A base method returning a `Selectable` and then two helper methods returning a `Stream` or a `Future`.
As the `Selectable` class contains its own methods to convert it to a `Stream` and `Future`, the two As the `Selectable` class contains its own methods to convert it to a `Stream` and `Future`, the two
later methods only exist for backwards compatibility. When this flag is enabled, moor won't write them at all. later methods only exist for backwards compatibility. When this flag is enabled, drift won't write them at all.
This flag is enabled by default in moor 3.0, but it can still be disabled. This flag is enabled by default in moor 3.0 and drift, but it can still be disabled.
* `skip_verification_code`: Generated tables contain a significant chunk of code to verify integrity * `skip_verification_code`: Generated tables contain a significant chunk of code to verify integrity
of inserted data and report detailed errors when the integrity is violated. If you're only using of inserted data and report detailed errors when the integrity is violated. If you're only using
inserts with SQL, or don't need this functionality, enabling this flag can help to reduce the amount inserts with SQL, or don't need this functionality, enabling this flag can help to reduce the amount
@ -55,7 +55,7 @@ At the moment, moor supports these options:
a `UsersTableCompanion`). With this option, the name is based on the data class (so `UsersCompanion` in a `UsersTableCompanion`). With this option, the name is based on the data class (so `UsersCompanion` in
this case). this case).
* `use_column_name_as_json_key_when_defined_in_moor_file` (defaults to `true`): When serializing columns declared inside a * `use_column_name_as_json_key_when_defined_in_moor_file` (defaults to `true`): When serializing columns declared inside a
`.moor` file from and to json, use their sql name instead of the generated Dart getter name `.moor` (or `.drift`) file from and to json, use their sql name instead of the generated Dart getter name
(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`)
@ -64,9 +64,9 @@ At the moment, moor supports these options:
* `sqlite_modules`: This list can be used to enable sqlite extensions, like those for json or full-text search. * `sqlite_modules`: This list can be used to enable sqlite extensions, like those for json or full-text search.
Modules have to be enabled explicitly because they're not supported on all platforms. See the following section for Modules have to be enabled explicitly because they're not supported on all platforms. See the following section for
details. details.
* `eagerly_load_dart_ast`: Moor's builder will load the resolved AST whenever it encounters a Dart file, * `eagerly_load_dart_ast`: Drift's builder will load the resolved AST whenever it encounters a Dart file,
instead of lazily when it reads a table. This is used to investigate rare builder crashes. instead of lazily when it reads a table. This is used to investigate rare builder crashes.
* `data_class_to_companions` (defaults to `true`): Controls whether moor 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
by default. You can make them mutable by setting `mutable_classes: true`. by default. You can make them mutable by setting `mutable_classes: true`.
@ -97,7 +97,7 @@ version:
targets: targets:
$default: $default:
builders: builders:
moor_generator: drift_dev:
options: options:
sqlite: sqlite:
version: "3.34" version: "3.34"
@ -112,15 +112,15 @@ minimum version needed in options.
### Available extensions ### Available extensions
__Note__: This enables extensions in the analyzer for custom queries only. For instance, when the `json1` extension is __Note__: This enables extensions in the analyzer for custom queries only. For instance, when the `json1` extension is
enabled, the [`json`](https://www.sqlite.org/json1.html) functions can be used in moor files. This doesn't necessarily enabled, the [`json`](https://www.sqlite.org/json1.html) functions can be used in drift files. This doesn't necessarily
mean that those functions are supported at runtime! Both extensions are available on iOS 11 or later. On Android, they're mean that those functions are supported at runtime! Both extensions are available on iOS 11 or later. On Android, they're
only available when using `moor_ffi`. only available when using a `NativeDatabase`.
```yaml ```yaml
targets: targets:
$default: $default:
builders: builders:
moor_generator: drift_dev:
options: options:
sqlite: sqlite:
modules: modules:
@ -134,14 +134,14 @@ We currently support the following extensions:
- [json1](https://www.sqlite.org/json1.html): Support static analysis for `json_` functions in moor files - [json1](https://www.sqlite.org/json1.html): Support static analysis for `json_` functions in moor files
- [fts5](https://www.sqlite.org/fts5.html): Support `CREATE VIRTUAL TABLE` statements for `fts5` tables and the `MATCH` operator. - [fts5](https://www.sqlite.org/fts5.html): Support `CREATE VIRTUAL TABLE` statements for `fts5` tables and the `MATCH` operator.
Functions like `highlight` or `bm25` are available as well. Functions like `highlight` or `bm25` are available as well.
- `moor_ffi`: Enables support for functions that are only available when using `moor_ffi`. This contains `pow`, `sqrt` and a variety - `moor_ffi`: Enables support for functions that are only available when using a `NativeDatabase`. This contains `pow`, `sqrt` and a variety
of trigonometric functions. Details on those functions are available [here]({{ "../Other engines/vm.md#moor-only-functions" | pageUrl }}). of trigonometric functions. Details on those functions are available [here]({{ "../Other engines/vm.md#moor-only-functions" | pageUrl }}).
- `math`: Assumes that sqlite3 was compiled with [math functions](https://www.sqlite.org/lang_mathfunc.html). - `math`: Assumes that sqlite3 was compiled with [math functions](https://www.sqlite.org/lang_mathfunc.html).
This module is largely incompatible with the `moor_ffi` module. This module is largely incompatible with the `moor_ffi` module.
## Recommended options ## Recommended options
In general, we recommend using the default options. However, some options will be enabled by default in a future moor release. In general, we recommend using the default options. However, some options will be enabled by default in a future drift release.
At the moment, they're opt-in to not break existing users. These options are: At the moment, they're opt-in to not break existing users. These options are:
- `apply_converters_on_variables` - `apply_converters_on_variables`
@ -151,71 +151,68 @@ At the moment, they're opt-in to not break existing users. These options are:
We recommend enabling these options. We recommend enabling these options.
You can disable some default moor features and reduce the amount of generated code with the following options: You can disable some default drift features and reduce the amount of generated code with the following options:
- `skip_verification_code: true`: You can remove a significant portion of generated code with this option. The - `skip_verification_code: true`: You can remove a significant portion of generated code with this option. The
downside is that error messages when inserting invalid data will be less specific. downside is that error messages when inserting invalid data will be less specific.
- `data_class_to_companions: false`: Don't generate the `toCompanion` method on data classes. If you don't need that - `data_class_to_companions: false`: Don't generate the `toCompanion` method on data classes. If you don't need that
method, you can disable this option. method, you can disable this option.
## Using moor classes in other builders ## Using drift classes in other builders
Starting with moor 2.4, it's possible to use classes generated by moor in other builders.
It is possible to use classes generated by drift in other builders.
Due to technicalities related to Dart's build system and `source_gen`, this approach requires a custom configuration Due to technicalities related to Dart's build system and `source_gen`, this approach requires a custom configuration
and minor code changes. Put this content in a file called `build.yaml` next to your `pubspec.yaml`: and minor code changes. Put this content in a file called `build.yaml` next to your `pubspec.yaml`:
```yaml ```yaml
targets: targets:
$default: $default:
# disable the default generators, we'll only use the non-shared moor generator here # disable the default generators, we'll only use the non-shared drift generator here
auto_apply_builders: false auto_apply_builders: false
builders: builders:
moor_generator|moor_generator_not_shared: drift_dev|not_shared:
enabled: true enabled: true
# If needed, you can configure the builder like this: # If needed, you can configure the builder like this:
# options: # options:
# skip_verification_code: true # skip_verification_code: true
# use_experimental_inference: true # use_experimental_inference: true
# This builder is necessary for moor-file preprocessing. You can disable it if you're not # This builder is necessary for drift-file preprocessing. You can disable it if you're not
# using .moor files with type converters. # using .drift files with type converters.
moor_generator|preparing_builder: drift_dev|preparing_builder:
enabled: true enabled: true
run_built_value: run_built_value:
dependencies: ['your_package_name'] dependencies: ['your_package_name']
builders: builders:
# Disable moor builders. By default, those would run on each target # Disable drift builders. By default, those would run on each target
moor_generator: drift_dev:
enabled: false enabled: false
moor_generator|preparing_builder: drift_dev|preparing_builder:
enabled: false enabled: false
# we don't need to disable moor_generator_not_shared, because it's disabled by default # we don't need to disable drift|not_shared, because it's disabled by default
``` ```
In all files that use generated moor code, you'll have to replace `part 'filename.g.dart'` with `part 'filename.moor.dart'`. In all files that use generated drift code, you'll have to replace `part 'filename.g.dart'` with `part 'filename.drift.dart'`.
If you use moor _and_ another builder in the same file, you'll need both `.g.dart` and `.moor.dart` as part-files. If you use drift _and_ another builder in the same file, you'll need both `.g.dart` and `.drift.dart` as part-files.
A full example is available as part of [the moor repo](https://github.com/simolus3/moor/tree/develop/extras/with_built_value). A full example is available as part of [the drift repo](https://github.com/simolus3/moor/tree/develop/extras/with_built_value).
If you run into any problems with this approach, feel free to open an issue on moor. At the moment, a known issue is that If you run into any problems with this approach, feel free to open an issue on drift.
other builders can emit a warning about missing `part` statements in the `.moor.dart` file generated by moor. This shouldn't
affect the generated code and has been reported [here](https://github.com/dart-lang/source_gen/issues/447).
### The technicalities, explained ### The technicalities, explained
Almost all code generation packages use a so called "shared part file" approach provided by `source_gen`. Almost all code generation packages use a so called "shared part file" approach provided by `source_gen`.
It's a common protocol that allows unrelated builders to write into the same `.g.dart` file. It's a common protocol that allows unrelated builders to write into the same `.g.dart` file.
For this to work, each builder first writes a `.part` file with its name. For instance, if you used `moor` For this to work, each builder first writes a `.part` file with its name. For instance, if you used `drift`
and `built_value` in the same project, those part files could be called `.moor.part` and `.built_value.part`. and `built_value` in the same project, those part files could be called `.drift.part` and `.built_value.part`.
Later, the common `source_gen` package would merge the part files into a single `.g.dart` file. Later, the common `source_gen` package would merge the part files into a single `.g.dart` file.
This works great for most use cases, but a downside is that each builder can't see the final `.g.dart` This works great for most use cases, but a downside is that each builder can't see the final `.g.dart`
file, or use any classes or methods defined in it. To fix that, moor offers an optional builder - file, or use any classes or methods defined in it. To fix that, drift offers an optional builder -
`moor_generator|moor_generator_not_shared` - that will generate a separate part file only containing `drift_dev|not_shared` - that will generate a separate part file only containing
code generated by moor. So most of the work resolves around disabling the default generator of moor code generated by drift. So most of the work resolves around disabling the default generator of drift
and use the non-shared generator instead. and use the non-shared generator instead.
Finally, we need to the build system to run moor first, and all the other builders otherwise. This is Finally, we need to the build system to run drift first, and all the other builders otherwise. This is
why we split the builders up into multiple targets. The first target will only run moor, the second why we split the builders up into multiple targets. The first target will only run drift, the second
target has a dependency on the first one and will run all the other builders. target has a dependency on the first one and will run all the other builders.

View File

@ -2,18 +2,18 @@
data: data:
title: "Custom row classes" title: "Custom row classes"
description: >- description: >-
Use your own classes as data classes for moor tables Use your own classes as data classes for drift tables
template: layouts/docs/single template: layouts/docs/single
--- ---
For each table declared in Dart or in a moor file, `moor_generator` generates a row class (sometimes also referred to as _data class_) For each table declared in Dart or in a drift file, `drift_dev` generates a row class (sometimes also referred to as _data class_)
to hold a full row and a companion class for updates and inserts. to hold a full row and a companion class for updates and inserts.
This works well for most cases: Moor knows what columns your table has, and it can generate a simple class for all of that. This works well for most cases: Drift knows what columns your table has, and it can generate a simple class for all of that.
In some cases, you might want to customize the generated classes though. In some cases, you might want to customize the generated classes though.
For instance, you might want to add a mixin, let it extend another class or interface, or use other builders like For instance, you might want to add a mixin, let it extend another class or interface, or use other builders like
`json_serializable` to customize how it gets serialized to json. `json_serializable` to customize how it gets serialized to json.
Starting from moor version 4.3, it is possible to use your own classes as data classes. Starting from moor version 4.3 (and in drift), it is possible to use your own classes as data classes.
## Using custom classes ## Using custom classes
@ -39,7 +39,7 @@ class User {
A row class must adhere to the following requirements: A row class must adhere to the following requirements:
- It must have an unnamed constructor - It must have an unnamed constructor
- Each constructor argument must have the name of a moor column - Each constructor argument must have the name of a drift column
(matching the getter name in the table definition) (matching the getter name in the table definition)
- The type of a constructor argument must be equal to the type of a column, - The type of a constructor argument must be equal to the type of a column,
including nullability and applied type converters. including nullability and applied type converters.
@ -47,14 +47,14 @@ A row class must adhere to the following requirements:
On the other hand, note that: On the other hand, note that:
- A custom row class can have additional fields and constructor arguments, as - A custom row class can have additional fields and constructor arguments, as
long as they're not required. Moor will ignore those parameters when mapping long as they're not required. Drift will ignore those parameters when mapping
a database row. a database row.
- A table can have additional columns not reflected in a custom data class. - A table can have additional columns not reflected in a custom data class.
Moor will simply not load those columns when mapping a row. Drift will simply not load those columns when mapping a row.
### Using another constructor ### Using another constructor
By default, moor will use the default, unnamed constructor to map a row to the class. By default, drift will use the default, unnamed constructor to map a row to the class.
If you want to use another constructor, set the `constructor` parameter on the If you want to use another constructor, set the `constructor` parameter on the
`@UseRowClass` annotation: `@UseRowClass` annotation:
@ -73,11 +73,11 @@ class User {
} }
``` ```
### Existing row classes in moor files ### Existing row classes in drift files
To use existing row classes in moor files, use the `WITH` keyword at the end of the To use existing row classes in drift files, use the `WITH` keyword at the end of the
table declaration. Also, don't forget to import the Dart file declaring the row table declaration. Also, don't forget to import the Dart file declaring the row
class into the moor file. class into the drift file.
```sql ```sql
import 'user.dart'; -- or what the Dart file is called import 'user.dart'; -- or what the Dart file is called
@ -117,10 +117,10 @@ class User implements Insertable<User> {
## When custom classes make sense ## When custom classes make sense
The default moor-generated classes are a good default for most applications. The default drift-generated classes are a good default for most applications.
In some advanced use-cases, custom classes can be a better alternative though: In some advanced use-cases, custom classes can be a better alternative though:
- Reduce generated code size: Due to historical reasons and backwards-compatibility, moor's classes - Reduce generated code size: Due to historical reasons and backwards-compatibility, drift's classes
contain a number of methods for json serialization and `copyWith` that might not be necessary contain a number of methods for json serialization and `copyWith` that might not be necessary
for all users. for all users.
Custom row classes can reduce bloat here. Custom row classes can reduce bloat here.
@ -131,10 +131,10 @@ In some advanced use-cases, custom classes can be a better alternative though:
## Limitations ## Limitations
These restrictions will be gradually lifted in upcoming moor versions. Follow [#1134](https://github.com/simolus3/moor/issues/1134) for details. These restrictions will be gradually lifted in upcoming drift versions. Follow [#1134](https://github.com/simolus3/moor/issues/1134) for details.
For now, this feature is subject to the following limitations: For now, this feature is subject to the following limitations:
- In moor files, you can only use the default unnamed constructor - In drift files, you can only use the default unnamed constructor
- Custom row classes can only be used for tables, not for custom result sets of compiled queries - Custom row classes can only be used for tables, not for custom result sets of compiled queries

View File

@ -13,10 +13,10 @@ available from your main database class. Consider the following code:
```dart ```dart
part 'todos_dao.g.dart'; part 'todos_dao.g.dart';
// the _TodosDaoMixin will be created by moor. It contains all the necessary // the _TodosDaoMixin will be created by drift. It contains all the necessary
// fields for the tables. The <MyDatabase> type annotation is the database class // fields for the tables. The <MyDatabase> type annotation is the database class
// that should use this dao. // that should use this dao.
@UseDao(tables: [Todos]) @DriftAccessor(tables: [Todos])
class TodosDao extends DatabaseAccessor<MyDatabase> with _$TodosDaoMixin { class TodosDao extends DatabaseAccessor<MyDatabase> with _$TodosDaoMixin {
// this constructor is required so that the main database can create an instance // this constructor is required so that the main database can create an instance
// of this object. // of this object.
@ -32,5 +32,5 @@ class TodosDao extends DatabaseAccessor<MyDatabase> with _$TodosDaoMixin {
} }
} }
``` ```
If we now change the annotation on the `MyDatabase` class to `@UseMoor(tables: [Todos, Categories], daos: [TodosDao])` If we now change the annotation on the `MyDatabase` class to `@DriftDatabase(tables: [Todos, Categories], daos: [TodosDao])`
and re-run the code generation, a generated getter `todosDao` can be used to access the instance of that dao. and re-run the code generation, a generated getter `todosDao` can be used to access the instance of that dao.

View File

@ -10,7 +10,7 @@ template: layouts/docs/single
--- ---
Expressions are pieces of sql that return a value when the database interprets them. Expressions are pieces of sql that return a value when the database interprets them.
The Dart API from moor allows you to write most expressions in Dart and then convert The Dart API from drift allows you to write most expressions in Dart and then convert
them to sql. Expressions are used in all kinds of situations. For instance, `where` them to sql. Expressions are used in all kinds of situations. For instance, `where`
expects an expression that returns a boolean. expects an expression that returns a boolean.
@ -37,7 +37,7 @@ Future<List<Animal>> findAnimalsByLegs(int legCount) {
## Boolean algebra ## Boolean algebra
You can nest boolean expressions by using the `&`, `|` operators and the `not` method You can nest boolean expressions by using the `&`, `|` operators and the `not` method
exposed by moor: exposed by drift:
```dart ```dart
// find all animals that aren't mammals and have 4 legs // find all animals that aren't mammals and have 4 legs
@ -93,7 +93,7 @@ select(users)..where((u) => u.birthDate.year.isLessThan(1950))
The individual fields like `year`, `month` and so on are expressions themselves. This means The individual fields like `year`, `month` and so on are expressions themselves. This means
that you can use operators and comparisons on them. that you can use operators and comparisons on them.
To obtain the current date or the current time as an expression, use the `currentDate` To obtain the current date or the current time as an expression, use the `currentDate`
and `currentDateAndTime` constants provided by moor. and `currentDateAndTime` constants provided by drift.
You can also use the `+` and `-` operators to add or subtract a duration from a time column: You can also use the `+` and `-` operators to add or subtract a duration from a time column:
@ -113,7 +113,7 @@ Again, the `isNotIn` function works the other way around.
## Aggregate functions (like count and sum) {#aggregate} ## Aggregate functions (like count and sum) {#aggregate}
Since moor 2.4, [aggregate functions](https://www.sqlite.org/lang_aggfunc.html) are available [Aggregate functions](https://www.sqlite.org/lang_aggfunc.html) are available
from the Dart api. Unlike regular functions, aggregate functions operate on multiple rows at from the Dart api. Unlike regular functions, aggregate functions operate on multiple rows at
once. once.
By default, they combine all rows that would be returned by the select statement into a single value. By default, they combine all rows that would be returned by the select statement into a single value.
@ -171,7 +171,7 @@ use the `filter` parameter on `count`.
To count all rows (instead of a single value), you can use the top-level `countAll()` To count all rows (instead of a single value), you can use the top-level `countAll()`
function. function.
More information on how to write aggregate queries with moor's Dart api is available More information on how to write aggregate queries with drift's Dart api is available
[here]({{ "joins.md#group-by" | pageUrl }}) [here]({{ "joins.md#group-by" | pageUrl }})
### group_concat ### group_concat
@ -198,7 +198,7 @@ For more information, see the [list of functions]({{ "../Other engines/vm.md#moo
## Subqueries ## Subqueries
Starting from version 4.1, moor has basic support for subqueries in expressions. Drift has basic support for subqueries in expressions.
### Scalar subqueries ### Scalar subqueries
@ -215,7 +215,7 @@ Future<List<Todo>> findTodosInCategory(String description) async {
} }
``` ```
Here, `groupId` is a regular select statement. By default moor would select all columns, so we use Here, `groupId` is a regular select statement. By default drift would select all columns, so we use
`selectOnly` to only load the id of the category we care about. `selectOnly` to only load the id of the category we care about.
Then, we can use `subqueryExpression` to embed that query into an expression that we're using as Then, we can use `subqueryExpression` to embed that query into an expression that we're using as
a filter. a filter.
@ -250,6 +250,6 @@ select(users)..where((u) => inactive);
``` ```
_Note_: It's easy to write invalid queries by using `CustomExpressions` too much. If you feel like _Note_: It's easy to write invalid queries by using `CustomExpressions` too much. If you feel like
you need to use them because a feature you use is not available in moor, consider creating an issue you need to use them because a feature you use is not available in drift, consider creating an issue
to let us know. If you just prefer sql, you could also take a look at to let us know. If you just prefer sql, you could also take a look at
[compiled sql]({{ "../Using SQL/custom_queries.md" | pageUrl }}) which is typesafe to use. [compiled sql]({{ "../Using SQL/custom_queries.md" | pageUrl }}) which is typesafe to use.

View File

@ -2,6 +2,6 @@
data: data:
title: Advanced Features title: Advanced Features
weight: 20 weight: 20
description: Learn about some advanced features of moor description: Learn about some advanced features of drift
template: layouts/docs/list template: layouts/docs/list
--- ---

View File

@ -1,16 +1,10 @@
--- ---
data: data:
title: Isolates title: Isolates
description: Using moor databases on a background isolate description: Using drift databases on a background isolate
template: layouts/docs/single template: layouts/docs/single
--- ---
{% block "blocks/alert" title="New feature" color="primary" %}
The api for background isolates only works with moor version 2.1.0 or newer. Due to
platform limitations, using [moor_ffi]({{ "../Other engines/vm.md" | pageUrl }}) is required when
using a background isolate. Using `moor_flutter` is not supported.
{% endblock %}
## Preparations ## Preparations
To use the isolate api, first enable the appropriate [build option]({{ "builder_options.md" | pageUrl }}) by To use the isolate api, first enable the appropriate [build option]({{ "builder_options.md" | pageUrl }}) by
@ -20,13 +14,13 @@ content:
targets: targets:
$default: $default:
builders: builders:
moor_generator: drift_dev:
options: options:
generate_connect_constructor: true generate_connect_constructor: true
``` ```
Next, re-run the build. You can now add another constructor to the generated database class: Next, re-run the build. You can now add another constructor to the generated database class:
```dart ```dart
@UseMoor(...) @DriftDatabase(...)
class TodoDb extends _$TodoDb { class TodoDb extends _$TodoDb {
TodoDb() : super(VmDatabase.memory()); TodoDb() : super(VmDatabase.memory());
@ -35,11 +29,11 @@ class TodoDb extends _$TodoDb {
} }
``` ```
## Using moor in a background isolate ## Using drift in a background isolate {#using-moor-in-a-background-isolate}
With the database class ready, let's open it on a background isolate With the database class ready, let's open it on a background isolate
```dart ```dart
import 'package:moor/isolate.dart'; import 'package:drift/isolate.dart';
// This needs to be a top-level method because it's run on a background isolate // This needs to be a top-level method because it's run on a background isolate
DatabaseConnection _backgroundConnection() { DatabaseConnection _backgroundConnection() {
@ -53,12 +47,12 @@ DatabaseConnection _backgroundConnection() {
} }
void main() async { void main() async {
// create a moor executor in a new background isolate. If you want to start the isolate yourself, you // create a drift executor in a new background isolate. If you want to start the isolate yourself, you
// can also call MoorIsolate.inCurrent() from the background isolate // can also call DriftIsolate.inCurrent() from the background isolate
MoorIsolate isolate = await MoorIsolate.spawn(_backgroundConnection); DriftIsolate isolate = await DriftIsolate.spawn(_backgroundConnection);
// we can now create a database connection that will use the isolate internally. This is NOT what's // we can now create a database connection that will use the isolate internally. This is NOT what's
// returned from _backgroundConnection, moor uses an internal proxy class for isolate communication. // returned from _backgroundConnection, drift uses an internal proxy class for isolate communication.
DatabaseConnection connection = await isolate.connect(); DatabaseConnection connection = await isolate.connect();
final db = TodoDb.connect(connection); final db = TodoDb.connect(connection);
@ -68,13 +62,13 @@ void main() async {
} }
``` ```
If you need to construct the database outside of an `async` context, you can use the new If you need to construct the database outside of an `async` context, you can use the
`DatabaseConnection.delayed` constructor introduced in moor 3.4. In the example above, you `DatabaseConnection.delayed` constructor. In the example above, you
could synchronously obtain a `TodoDb` by using: could synchronously obtain a `TodoDb` by using:
```dart ```dart
Future<DatabaseConnection> _connectAsync() async { Future<DatabaseConnection> _connectAsync() async {
MoorIsolate isolate = await MoorIsolate.spawn(_backgroundConnection); DriftIsolate isolate = await DriftIsolate.spawn(_backgroundConnection);
return isolate.connect(); return isolate.connect();
} }
@ -83,8 +77,8 @@ void main() {
} }
``` ```
This can be helpful when using moor in DI frameworks, since you have the database available This can be helpful when using drift in DI frameworks, since you have the database available
immediately. Internally, moor will connect when the first query is sent to the database. immediately. Internally, drift will connect when the first query is sent to the database.
### Initialization on the main thread ### Initialization on the main thread
@ -96,7 +90,7 @@ We're going to start the isolate running the database manually. This allows us t
data that we calculated on the main thread. data that we calculated on the main thread.
```dart ```dart
Future<MoorIsolate> _createMoorIsolate() async { Future<DriftIsolate> _createDriftIsolate() async {
// this method is called from the main isolate. Since we can't use // this method is called from the main isolate. Since we can't use
// getApplicationDocumentsDirectory on a background isolate, we calculate // getApplicationDocumentsDirectory on a background isolate, we calculate
// the database path in the foreground isolate and then inform the // the database path in the foreground isolate and then inform the
@ -110,31 +104,31 @@ Future<MoorIsolate> _createMoorIsolate() async {
_IsolateStartRequest(receivePort.sendPort, path), _IsolateStartRequest(receivePort.sendPort, path),
); );
// _startBackground will send the MoorIsolate to this ReceivePort // _startBackground will send the DriftIsolate to this ReceivePort
return await receivePort.first as MoorIsolate; return await receivePort.first as DriftIsolate;
} }
void _startBackground(_IsolateStartRequest request) { void _startBackground(_IsolateStartRequest request) {
// this is the entry point from the background isolate! Let's create // this is the entry point from the background isolate! Let's create
// the database from the path we received // the database from the path we received
final executor = VmDatabase(File(request.targetPath)); final executor = NativeDatabase(File(request.targetPath));
// we're using MoorIsolate.inCurrent here as this method already runs on a // we're using DriftIsolate.inCurrent here as this method already runs on a
// background isolate. If we used MoorIsolate.spawn, a third isolate would be // background isolate. If we used DriftIsolate.spawn, a third isolate would be
// started which is not what we want! // started which is not what we want!
final moorIsolate = MoorIsolate.inCurrent( final driftIsolate = DriftIsolate.inCurrent(
() => DatabaseConnection.fromExecutor(executor), () => DatabaseConnection.fromExecutor(executor),
); );
// inform the starting isolate about this, so that it can call .connect() // inform the starting isolate about this, so that it can call .connect()
request.sendMoorIsolate.send(moorIsolate); request.sendDriftIsolate.send(driftIsolate);
} }
// used to bundle the SendPort and the target path, since isolate entry point // used to bundle the SendPort and the target path, since isolate entry point
// functions can only take one parameter. // functions can only take one parameter.
class _IsolateStartRequest { class _IsolateStartRequest {
final SendPort sendMoorIsolate; final SendPort sendDriftIsolate;
final String targetPath; final String targetPath;
_IsolateStartRequest(this.sendMoorIsolate, this.targetPath); _IsolateStartRequest(this.sendDriftIsolate, this.targetPath);
} }
``` ```
@ -142,9 +136,9 @@ Once again, you can use a `DatabaseConnection.delayed()` to obtain a database
connection for your database class: connection for your database class:
```dart ```dart
DatabaseConnection _createMoorIsolateAndConnect() { DatabaseConnection _createDriftIsolateAndConnect() {
return DatabaseConnection.delayed(() async { return DatabaseConnection.delayed(() async {
final isolate = await _createMoorIsolate(); final isolate = await _createDriftIsolate();
return await isolate.connect(); return await isolate.connect();
}()); }());
} }
@ -157,7 +151,7 @@ and values accessible in one isolate may not be visible in a background isolate.
For instance, if you're using `open.overrideFor` from `package:sqlite3`, you need to do that For instance, if you're using `open.overrideFor` from `package:sqlite3`, you need to do that
on the isolate where you're actually opening the database! on the isolate where you're actually opening the database!
With a background isolate as shown here, the right place to call `open.overrideFor` is in the With a background isolate as shown here, the right place to call `open.overrideFor` is in the
`_startBackground` function, before you're using `MoorIsolate.inCurrent`. `_startBackground` function, before you're using `DriftIsolate.inCurrent`.
Other global fields that you might be relying on when constructing the database (service Other global fields that you might be relying on when constructing the database (service
locators like `get_it` come to mind) may also need to be initialized seperately on the background locators like `get_it` come to mind) may also need to be initialized seperately on the background
isolate. isolate.
@ -165,54 +159,54 @@ isolate.
### Shutting down the isolate ### Shutting down the isolate
Since multiple `DatabaseConnection`s can exist to a specific `MoorIsolate`, simply calling Since multiple `DatabaseConnection`s can exist to a specific `DriftIsolate`, simply calling
`Database.close` won't stop the isolate. You can use the `MoorIsolate.shutdownAll()` for that. `Database.close` won't stop the isolate. You can use the `DriftIsolate.shutdownAll()` for that.
It will disconnect all databases and then close the background isolate, releasing all resources. It will disconnect all databases and then close the background isolate, releasing all resources.
## Common operation modes ## Common operation modes
You can use a `MoorIsolate` across multiple isolates you control and connect from any of them. You can use a `DriftIsolate` across multiple isolates you control and connect from any of them.
__One executor isolate, one foreground isolate__: This is the most common usage mode. You would call __One executor isolate, one foreground isolate__: This is the most common usage mode. You would call
`MoorIsolate.spawn` from the `main` method in your Flutter or Dart app. Similar to the example above, `DriftIsolate.spawn` from the `main` method in your Flutter or Dart app. Similar to the example above,
you could then use moor from the main isolate by connecting with `MoorIsolate.connect` and passing that you could then use drift from the main isolate by connecting with `DriftIsolate.connect` and passing that
connection to a generated database class. connection to a generated database class.
__One executor isolate, multiple client isolates__: The `MoorIsolate` can be sent across multiple __One executor isolate, multiple client isolates__: The `DriftIsolate` can be sent across multiple
isolates, each of which can use `MoorIsolate.connect` on their own. This is useful to implement isolates, each of which can use `DriftIsolate.connect` on their own. This is useful to implement
a setup where you have three or more threads: a setup where you have three or more threads:
- The moor executor isolate - The drift executor isolate
- A foreground isolate, probably for Flutter - A foreground isolate, probably for Flutter
- Another background isolate, which could be used for networking. - Another background isolate, which could be used for networking.
You can then read data from the foreground isolate or start query streams, similar to the example You can then read data from the foreground isolate or start query streams, similar to the example
above. The background isolate would _also_ call `MoorIsolate.connect` and create its own instance above. The background isolate would _also_ call `DriftIsolate.connect` and create its own instance
of the generated database class. Writes to one database will be visible to the other isolate and of the generated database class. Writes to one database will be visible to the other isolate and
also update query streams. also update query streams.
To safely send a `MoorIsolate` instance across a `SendPort`, it's recommended to instead send the To safely send a `DriftIsolate` instance across a `SendPort`, it's recommended to instead send the
underlying `SendPort` used internally by `MoorIsolate`: underlying `SendPort` used internally by `DriftIsolate`:
```dart ```dart
// Don't do this, it doesn't work in all circumstances // Don't do this, it doesn't work in all circumstances
void shareMoorIsolate(MoorIsolate isolate, SendPort sendPort) { void shareDriftIsolate(DriftIsolate isolate, SendPort sendPort) {
sendPort.send(isolate); sendPort.send(isolate);
} }
// Instead, send the underlying SendPort: // Instead, send the underlying SendPort:
void shareMoorIsolate(MoorIsolate isolate, SendPort sendPort) { void shareDriftIsolate(DriftIsolate isolate, SendPort sendPort) {
sendPort.send(isolate.connectPort); sendPort.send(isolate.connectPort);
} }
``` ```
The receiving end can reconstruct a `MoorIsolate` from a `SendPort` by using the The receiving end can reconstruct a `DriftIsolate` from a `SendPort` by using the
`MoorIsolate.fromConnectPort` constructor. That `MoorIsolate` behaves exactly like the original `DriftIsolate.fromConnectPort` constructor. That `DriftIsolate` behaves exactly like the original
one, but we only had to send a primitive `SendPort` and not a complex Dart object. one, but we only had to send a primitive `SendPort` and not a complex Dart object.
## How does this work? Are there any limitations? ## How does this work? Are there any limitations?
All moor features are supported on background isolates and work out of the box. This includes All drift features are supported on background isolates and work out of the box. This includes
- Transactions - Transactions
- Auto-updating queries (even if the table was updated from another isolate) - Auto-updating queries (even if the table was updated from another isolate)
@ -221,20 +215,20 @@ All moor features are supported on background isolates and work out of the box.
Please note that, while using a background isolate can reduce lag on the UI thread, the overall Please note that, while using a background isolate can reduce lag on the UI thread, the overall
database is going to be slower! There's a overhead involved in sending data between database is going to be slower! There's a overhead involved in sending data between
isolates, and that's exactly what moor has to do internally. If you're not running into dropped isolates, and that's exactly what drift has to do internally. If you're not running into dropped
frames because of moor, using a background isolate is probably not necessary for your app. frames because of drift, using a background isolate is probably not necessary for your app.
Internally, moor uses the following model to implement this api: Internally, drift uses the following model to implement this api:
- __A server isolate__: A single isolate that executes all queries and broadcasts tables updates. - __A server isolate__: A single isolate that executes all queries and broadcasts tables updates.
This is the isolate created by `MoorIsolate.spawn`. It supports any number of clients via an This is the isolate created by `DriftIsolate.spawn`. It supports any number of clients via an
rpc-like connection model. Connections are established via `SendPort`s and `ReceivePort`s. rpc-like connection model. Connections are established via `SendPort`s and `ReceivePort`s.
Internally, the `MoorIsolate` class only contains a reference to a `SendPort` that can be used to Internally, the `DriftIsolate` class only contains a reference to a `SendPort` that can be used to
establish a connection to the background isolate. This lets users share the `MoorIsolate` establish a connection to the background isolate. This lets users share the `DriftIsolate`
object across many isolates and connect multiple times. The actual server logic that listens on object across many isolates and connect multiple times. The actual server logic that listens on
the port is in a private `_MoorServer` class. the port is in a private `RunningDriftServer` class.
- __Client isolates__: Any number of clients in any number of isolates can connect to a `MoorIsolate`. - __Client isolates__: Any number of clients in any number of isolates can connect to a `DriftIsolate`.
The client acts as a moor backend, which means that all queries are built on the client isolate. The The client acts as a drift backend, which means that all queries are built on the client isolate. The
raw sql string and parameters are then sent to the server isolate, which will enqueue the operation raw sql string and parameters are then sent to the server isolate, which will enqueue the operation
and execute it eventually. Implementing the isolate commands at a low level allows users to re-use and execute it eventually. Implementing the isolate commands at a low level allows users to re-use
all their code used without the isolate api. all their code used without the isolate api.
@ -242,20 +236,20 @@ Internally, moor uses the following model to implement this api:
## Independent isolates ## Independent isolates
All setups mentioned here assume that there will be one main isolate responsible for spawning a All setups mentioned here assume that there will be one main isolate responsible for spawning a
`MoorIsolate` that it (and other isolates) can then connect to. `DriftIsolate` that it (and other isolates) can then connect to.
In Flutter apps, this model may not always fit your use case. In Flutter apps, this model may not always fit your use case.
For instance, your app may use background tasks or receive FCM notifications while closed. For instance, your app may use background tasks or receive FCM notifications while closed.
These tasks will run in a background `FlutterEngine` managed by native platform code, so there's These tasks will run in a background `FlutterEngine` managed by native platform code, so there's
no clear communication scheme between isolates. no clear communication scheme between isolates.
Still, you may want to share a live moor database between your UI engine and potential background engines, Still, you may want to share a live drift database between your UI engine and potential background engines,
even without them directly knowing about each other. even without them directly knowing about each other.
An [IsolateNameServer](https://api.flutter.dev/flutter/dart-ui/IsolateNameServer-class.html) from `dart:ui` can An [IsolateNameServer](https://api.flutter.dev/flutter/dart-ui/IsolateNameServer-class.html) from `dart:ui` can
be used to transparently share a moor isolate between such workers. be used to transparently share a drift isolate between such workers.
You can store the [`connectPort`](https://moor.simonbinder.eu/api/isolate/moorisolate/connectport) of a `MoorIsolate` You can store the [`connectPort`](https://drift.simonbinder.eu/api/isolate/driftisolate/connectport) of a `DriftIsolate`
under a specific name to look it up later. under a specific name to look it up later.
Other clients can use `MoorIsolate.fromConnectPort` to obtain a `MoorIsolate` from the name server, if one has been Other clients can use `DriftIsolate.fromConnectPort` to obtain a `DriftIsolate` from the name server, if one has been
registered. registered.
Please note that, at the moment, Flutter still has some inherent problems with spawning isolates from background engines Please note that, at the moment, Flutter still has some inherent problems with spawning isolates from background engines

View File

@ -10,7 +10,7 @@ template: layouts/docs/single
## Joins ## Joins
Moor supports sql joins to write queries that operate on more than one table. To use that feature, start Drift supports sql joins to write queries that operate on more than one table. To use that feature, start
a select regular select statement with `select(table)` and then add a list of joins using `.join()`. For a select regular select statement with `select(table)` and then add a list of joins using `.join()`. For
inner and left outer joins, a `ON` expression needs to be specified. Here's an example using the tables inner and left outer joins, a `ON` expression needs to be specified. Here's an example using the tables
defined in the [example]({{ "../Getting started/index.md" | pageUrl }}). defined in the [example]({{ "../Getting started/index.md" | pageUrl }}).
@ -182,7 +182,7 @@ comes from multiple rows. Common questions include
- what's the average length of a todo entry? - what's the average length of a todo entry?
What these queries have in common is that data from multiple rows needs to be combined into a single What these queries have in common is that data from multiple rows needs to be combined into a single
row. In sql, this can be achieved with "aggregate functions", for which moor has row. In sql, this can be achieved with "aggregate functions", for which drift has
[builtin support]({{ "expressions.md#aggregate" | pageUrl }}). [builtin support]({{ "expressions.md#aggregate" | pageUrl }}).
_Additional info_: A good tutorial for group by in sql is available [here](https://www.sqlitetutorial.net/sqlite-group-by/). _Additional info_: A good tutorial for group by in sql is available [here](https://www.sqlitetutorial.net/sqlite-group-by/).
@ -190,7 +190,7 @@ _Additional info_: A good tutorial for group by in sql is available [here](https
To write a query that answers the first question for us, we can use the `count` function. To write a query that answers the first question for us, we can use the `count` function.
We're going to select all categories and join each todo entry for each category. What's special is that we set We're going to select all categories and join each todo entry for each category. What's special is that we set
`useColumns: false` on the join. We do that because we're not interested in the columns of the todo item. `useColumns: false` on the join. We do that because we're not interested in the columns of the todo item.
We only care about how many there are. By default, moor would attempt to read each todo item when it appears We only care about how many there are. By default, drift would attempt to read each todo item when it appears
in a join. in a join.
```dart ```dart
@ -219,8 +219,8 @@ a `join` since all the data comes from a single table (todos).
That's a problem though - in the join, we used `useColumns: false` because we weren't interested That's a problem though - in the join, we used `useColumns: false` because we weren't interested
in the columns of each todo item. Here we don't care about an individual item either, but there's in the columns of each todo item. Here we don't care about an individual item either, but there's
no join where we could set that flag. no join where we could set that flag.
Moor provides a special method for this case - instead of using `select`, we use `selectOnly`. Drift provides a special method for this case - instead of using `select`, we use `selectOnly`.
The "only" means that moor will only report columns we added via "addColumns". In a regular select, The "only" means that drift will only report columns we added via "addColumns". In a regular select,
all columns from the table would be selected, which is what you'd usually need. all columns from the table would be selected, which is what you'd usually need.
```dart ```dart

View File

@ -8,7 +8,7 @@ aliases:
template: layouts/docs/single template: layouts/docs/single
--- ---
Moor provides a migration API that can be used to gradually apply schema changes after bumping Drift provides a migration API that can be used to gradually apply schema changes after bumping
the `schemaVersion` getter inside the `Database` class. To use it, override the `migration` the `schemaVersion` getter inside the `Database` class. To use it, override the `migration`
getter. Here's an example: Let's say you wanted to add a due date to your todo entries: getter. Here's an example: Let's say you wanted to add a due date to your todo entries:
@ -44,7 +44,7 @@ We can now change the `database` class like this:
// rest of class can stay the same // rest of class can stay the same
``` ```
You can also add individual tables or drop them - see the reference of [Migrator](https://pub.dev/documentation/moor/latest/moor/Migrator-class.html) You can also add individual tables or drop them - see the reference of [Migrator](https://pub.dev/documentation/drift/latest/drift/Migrator-class.html)
for all the available options. You can't use the high-level query API in migrations - calling `select` or similar for all the available options. You can't use the high-level query API in migrations - calling `select` or similar
methods will throw. methods will throw.
@ -57,9 +57,9 @@ can be used together with `customStatement` to run the statements.
Sqlite has builtin statements for simple changes, like adding columns or dropping entire tables. Sqlite has builtin statements for simple changes, like adding columns or dropping entire tables.
More complex migrations require a [12-step procedure](https://www.sqlite.org/lang_altertable.html#otheralter) that More complex migrations require a [12-step procedure](https://www.sqlite.org/lang_altertable.html#otheralter) that
involes creating a copy of the table and copying over data from the old table. involes creating a copy of the table and copying over data from the old table.
Moor 3.4 introduced the `TableMigration` api to automate most of this procedure, making it easier and safer to use. Drift 3.4 introduced the `TableMigration` api to automate most of this procedure, making it easier and safer to use.
To start the migration, moor will create a new instance of the table with the current schema. Next, it will copy over To start the migration, drift will create a new instance of the table with the current schema. Next, it will copy over
rows from the old table. rows from the old table.
In most cases, for instance when changing column types, we can't just copy over each row without changing its content. In most cases, for instance when changing column types, we can't just copy over each row without changing its content.
Here, you can use a `columnTransformer` to apply a per-row transformation. Here, you can use a `columnTransformer` to apply a per-row transformation.
@ -73,13 +73,13 @@ columnTransformer: {
} }
``` ```
Internally, moor will use a `INSERT INTO SELECT` statement to copy old data. In this case, it would look like Internally, drift will use a `INSERT INTO SELECT` statement to copy old data. In this case, it would look like
`INSERT INTO temporary_todos_copy SELECT id, title, content, CAST(category AS INT) FROM todos`. `INSERT INTO temporary_todos_copy SELECT id, title, content, CAST(category AS INT) FROM todos`.
As you can see, moor will use the expression from the `columnTransformer` map and fall back to just copying the column As you can see, drift will use the expression from the `columnTransformer` map and fall back to just copying the column
otherwise. otherwise.
If you're introducing new columns in a table migration, be sure to include them in the `newColumns` parameter of If you're introducing new columns in a table migration, be sure to include them in the `newColumns` parameter of
`TableMigration`. Moor will ensure that those columns have a default value or a transformation in `columnTransformer`. `TableMigration`. Drift will ensure that those columns have a default value or a transformation in `columnTransformer`.
Of course, moor won't attempt to copy `newColumns` from the old table either. Of course, drift won't attempt to copy `newColumns` from the old table either.
Regardless of whether you're implementing complex migrations with `TableMigration` or by running a custom sequence Regardless of whether you're implementing complex migrations with `TableMigration` or by running a custom sequence
of statements, we strongly recommend to write integration tests covering your migrations. This helps to avoid data of statements, we strongly recommend to write integration tests covering your migrations. This helps to avoid data
@ -225,24 +225,24 @@ on how that can be achieved.
## Verifying migrations ## Verifying migrations
Since version 3.4, moor contains **experimental** support to verify the integrity of your migrations in unit tests. Drift contains **experimental** support to verify the integrity of your migrations in unit tests.
To support this feature, moor can help you generate To support this feature, drift can help you generate
- a json represenation of your database schema - a json represenation of your database schema
- test databases operating on an older schema version - test databases operating on an older schema version
By using those test databases, moor can help you test migrations from and to any schema version. By using those test databases, drift can help you test migrations from and to any schema version.
{% block "blocks/alert" title="Complex topic ahead" %} {% block "blocks/alert" title="Complex topic ahead" %}
> Writing schema tests is an advanced topic that requires a fairly complex setup described here. > Writing schema tests is an advanced topic that requires a fairly complex setup described here.
If you get stuck along the way, don't hesitate to [open a discussion about it](https://github.com/simolus3/moor/discussions). If you get stuck along the way, don't hesitate to [open a discussion about it](https://github.com/simolus3/moor/discussions).
Also, there's a working example [in the moor repository](https://github.com/simolus3/moor/tree/master/extras/migrations_example). Also, there's a working example [in the drift repository](https://github.com/simolus3/moor/tree/master/extras/migrations_example).
{% endblock %} {% endblock %}
### Setup ### Setup
To use this feature, moor needs to know all schemas of your database. A schema is the set of all tables, triggers To use this feature, drift needs to know all schemas of your database. A schema is the set of all tables, triggers
and indices that you use in your database. and indices that you use in your database.
You can use the [CLI tools]({{ "../CLI.md" | pageUrl }}) to export a json representation of your schema. You can use the [CLI tools]({{ "../CLI.md" | pageUrl }}) to export a json representation of your schema.
@ -260,14 +260,14 @@ my_app
schema.dart schema.dart
schema_v1.dart schema_v1.dart
schema_v2.dart schema_v2.dart
moor_schemas/ drift_schemas/
moor_schema_v1.json drift_schema_v1.json
moor_schema_v2.json drift_schema_v2.json
pubspec.yaml pubspec.yaml
``` ```
The generated migrations implementation and the schema jsons will be generated by moor. The generated migrations implementation and the schema jsons will be generated by drift.
To start writing schemas, create an empty folder named `moor_schemas` in your project. To start writing schemas, create an empty folder named `drift_schemas` in your project.
Of course, you can also choose a different name or use a nested subfolder if you want to. Of course, you can also choose a different name or use a nested subfolder if you want to.
#### Exporting the schema #### Exporting the schema
@ -275,8 +275,8 @@ Of course, you can also choose a different name or use a nested subfolder if you
To begin, let's create the first schema representation: To begin, let's create the first schema representation:
``` ```
$ mkdir moor_schemas $ mkdir drift_schemas
$ dart pub run moor_generator schema dump lib/database/database.dart moor_schemas/moor_schema_v1.json $ dart run drift_dev schema dump lib/database/database.dart drift_schemas/drift_schema_v1.json
``` ```
This instructs the generator to look at the database defined in `lib/database/database.dart` and extract This instructs the generator to look at the database defined in `lib/database/database.dart` and extract
@ -286,24 +286,24 @@ After making a change to your database schema, you can run the command again. Fo
made a change to our tables and increased the `schemaVersion` to `2`. We would then run: made a change to our tables and increased the `schemaVersion` to `2`. We would then run:
``` ```
$ dart pub run moor_generator schema dump lib/database/database.dart moor_schemas/moor_schema_v2.json $ dart run drift_dev schema dump lib/database/database.dart drift_schemas/drift_schema_v2.json
``` ```
You'll need to run this command everytime you change the schema of your database and increment the `schemaVersion`. You'll need to run this command everytime you change the schema of your database and increment the `schemaVersion`.
Remember to name the files `moor_schema_vX.json`, where `X` is the current `schemaVersion` of your database. Remember to name the files `drift_schema_vX.json`, where `X` is the current `schemaVersion` of your database.
#### Generating test code #### Generating test code
After you exported the database schema into a folder, you can generate old versions of your database class After you exported the database schema into a folder, you can generate old versions of your database class
based on those schema files. based on those schema files.
For verifications, moor will generate a much smaller database implementation that can only be used to For verifications, drift will generate a much smaller database implementation that can only be used to
test migrations. test migrations.
You can put this test code whereever you want, but it makes sense to put it in a subfolder of `test/`. You can put this test code whereever you want, but it makes sense to put it in a subfolder of `test/`.
If we wanted to write them to `test/generated_migrations/`, we could use If we wanted to write them to `test/generated_migrations/`, we could use
``` ```
$ dart pub run moor_generator schema generate moor_schemas/ test/generated/ $ dart run drift_dev schema generate drift_schemas/ test/generated/
``` ```
### Writing tests ### Writing tests
@ -314,7 +314,7 @@ After that setup, it's finally time to write some tests! For instance, a test co
import 'package:my_app/database/database.dart'; import 'package:my_app/database/database.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:moor_generator/api/migrations.dart'; import 'package:drift_dev/api/migrations.dart';
// The generated directory from before. // The generated directory from before.
import 'generated/schema.dart'; import 'generated/schema.dart';
@ -323,8 +323,8 @@ void main() {
SchemaVerifier verifier; SchemaVerifier verifier;
setUpAll(() { setUpAll(() {
// GeneratedHelper() was generated by moor, the verifier is an api // GeneratedHelper() was generated by drift, the verifier is an api
// provided by moor_generator. // provided by drift_generator.
verifier = SchemaVerifier(GeneratedHelper()); verifier = SchemaVerifier(GeneratedHelper());
}); });
@ -368,8 +368,8 @@ You can use `schemaAt` to obtain a raw `Database` from the `sqlite3` package in
This can be used to insert data before a migration. After the migration ran, you can then check that the data is still there. This can be used to insert data before a migration. After the migration ran, you can then check that the data is still there.
Note that you can't use the regular database class from you app for this, since its data classes always expect the latest Note that you can't use the regular database class from you app for this, since its data classes always expect the latest
schema. However, you can instruct moor to generate older snapshots of your data classes and companions for this purpose. schema. However, you can instruct drift to generate older snapshots of your data classes and companions for this purpose.
To enable this feature, pass the `--data-classes` and `--companions` command-line arguments to the `moor_generator schema generate` To enable this feature, pass the `--data-classes` and `--companions` command-line arguments to the `drift_dev schema generate`
command. command.
Then, you can import the generated classes with an alias: Then, you can import the generated classes with an alias:

View File

@ -7,10 +7,10 @@ aliases:
template: layouts/docs/single template: layouts/docs/single
--- ---
Moor supports a variety of types out of the box, but sometimes you need to store more complex data. Drift supports a variety of types out of the box, but sometimes you need to store more complex data.
You can achieve this by using `TypeConverters`. In this example, we'll use the the You can achieve this by using `TypeConverters`. In this example, we'll use the the
[json_serializable](https://pub.dev/packages/json_annotation) package to store a custom object in a [json_serializable](https://pub.dev/packages/json_annotation) package to store a custom object in a
text column. Moor supports any Dart type for which you provide a `TypeConverter`, we're using that text column. Drift supports any Dart type for which you provide a `TypeConverter`, we're using that
package here to make the example simpler. package here to make the example simpler.
## Using converters in Dart ## Using converters in Dart
@ -19,7 +19,7 @@ package here to make the example simpler.
import 'dart:convert'; import 'dart:convert';
import 'package:json_annotation/json_annotation.dart' as j; import 'package:json_annotation/json_annotation.dart' as j;
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
part 'database.g.dart'; part 'database.g.dart';
@ -37,7 +37,7 @@ class Preferences {
} }
``` ```
Next, we have to tell moor how to store a `Preferences` object in the database. We write Next, we have to tell drift how to store a `Preferences` object in the database. We write
a `TypeConverter` for that: a `TypeConverter` for that:
```dart ```dart
// stores preferences as strings // stores preferences as strings
@ -74,7 +74,7 @@ class Users extends Table {
``` ```
The generated `User` class will then have a `preferences` column of type The generated `User` class will then have a `preferences` column of type
`Preferences`. Moor will automatically take care of storing and loading `Preferences`. Drift will automatically take care of storing and loading
the object in `select`, `update` and `insert` statements. This feature the object in `select`, `update` and `insert` statements. This feature
also works with [compiled custom queries]({{ "/queries/custom" | absUrl }}). also works with [compiled custom queries]({{ "/queries/custom" | absUrl }}).
@ -86,7 +86,7 @@ also works with [compiled custom queries]({{ "/queries/custom" | absUrl }}).
### Implicit enum converters ### Implicit enum converters
A common scenario for type converters is to map between enums and integers by representing enums A common scenario for type converters is to map between enums and integers by representing enums
as their index. Since this is so common, moor has the integrated `intEnum` column type to make this as their index. Since this is so common, drift has the integrated `intEnum` column type to make this
easier. easier.
```dart ```dart
@ -125,11 +125,11 @@ class Tasks extends Table {
Also note that you can't apply another type converter on a column declared with an enum converter. Also note that you can't apply another type converter on a column declared with an enum converter.
## Using converters in moor ## Using converters in drift {#using-converters-in-moor}
Since moor 2.4, type converters can also be used inside moor files. Type converters can also be used inside drift files.
Assuming that the `Preferences` and `PreferenceConverter` are contained in Assuming that the `Preferences` and `PreferenceConverter` are contained in
`preferences.dart`, that file can imported into moor for the type converter to `preferences.dart`, that file can imported into drift for the type converter to
be available. be available.
```sql ```sql
@ -142,11 +142,11 @@ CREATE TABLE users (
); );
``` ```
When using type converters in moor files, we recommend the [`apply_converters_on_variables`]({{ "builder_options.md" | pageUrl }}) When using type converters in drift files, we recommend the [`apply_converters_on_variables`]({{ "builder_options.md" | pageUrl }})
build option. This will also apply the converter from Dart to SQL, for instance if used on variables: `SELECT * FROM users WHERE preferences = ?`. build option. This will also apply the converter from Dart to SQL, for instance if used on variables: `SELECT * FROM users WHERE preferences = ?`.
With that option, the variable will be inferred to `Preferences` instead of `String`. With that option, the variable will be inferred to `Preferences` instead of `String`.
Moor files also have special support for implicit enum converters: Drift files also have special support for implicit enum converters:
```sql ```sql
import 'status.dart'; import 'status.dart';
@ -157,4 +157,4 @@ CREATE TABLE tasks (
); );
``` ```
Of course, the warning about automatic enum converters also applies to moor files. Of course, the warning about automatic enum converters also applies to drift files.

View File

@ -1,18 +1,18 @@
--- ---
data: data:
title: "Command line tools for moor" title: "Command line tools for drift"
description: A set of CLI tools to interact with moor files description: A set of CLI tools to interact with drift projects
path: /cli/ path: /cli/
template: layouts/docs/single template: layouts/docs/single
--- ---
{% block "blocks/alert" title="Experimental" %} {% block "blocks/alert" title="Experimental" %}
The moor cli tool is experimental at the moment. Please report all issues you can find. The drift cli tool is experimental at the moment. Please report all issues you can find.
{% endblock %} {% endblock %}
## Usage ## Usage
If your app depends on `moor_generator`, you're ready to use the CLI tool. If your app depends on `drift_dev`, you're ready to use the CLI tool.
In this article, we'll use `pub run ...` to start the tool. In this article, we'll use `pub run ...` to start the tool.
If you're using Flutter, you need to run `flutter pub run ...`. If you're using Flutter, you need to run `flutter pub run ...`.
In either case, the tool should be run from the same folder where you keep your In either case, the tool should be run from the same folder where you keep your
@ -20,12 +20,12 @@ In either case, the tool should be run from the same folder where you keep your
## Analyze ## Analyze
Runs moor's analyzer and linter across all `.moor` files in your project. Runs drift's analyzer and linter across all `.drift` files in your project.
``` ```
$ pub run moor_generator analyze $ dart run drift_dev analyze
WARNING: For file test/data/tables/tables.moor: WARNING: For file test/data/tables/tables.drift:
WARNING: line 38, column 28: This table has columns without default values, so defaults can't be used for insert. WARNING: line 38, column 28: This table has columns without default values, so defaults can't be used for insert.
38 │ defaultConfig: INSERT INTO config DEFAULT VALUES; 38 │ defaultConfig: INSERT INTO config DEFAULT VALUES;
@ -38,16 +38,16 @@ Exits with error code `1` if any error was found.
## Identify databases ## Identify databases
This is more of a test command to verify that moor's analyzer is working correctly. This is more of a test command to verify that drift's analyzer is working correctly.
It will identify all databases or daos defined in your project. It will identify all databases or daos defined in your project.
``` ```
$ pub run moor_generator identify-databases $ dart run drift_dev identify-databases
Starting to scan in /home/simon/IdeaProjects/moor/moor... Starting to scan in /tmp/example/ ...
INFO: example/example.dart has moor databases or daos: Database INFO: example/example.dart has drift databases or daos: Database
INFO: lib/src/data/database.dart has moor databases or daos: AppDatabase INFO: lib/src/data/database.dart has drift databases or daos: AppDatabase
INFO: test/fake_db.dart has moor databases or daos: TodoDb, SomeDao INFO: test/fake_db.dart has drift databases or daos: TodoDb, SomeDao
``` ```
## Schema tools ## Schema tools
@ -55,11 +55,11 @@ INFO: test/fake_db.dart has moor databases or daos: TodoDb, SomeDao
### Export ### Export
This subcommand expects two paths, a Dart file and a target. The Dart file should contain This subcommand expects two paths, a Dart file and a target. The Dart file should contain
exactly one class annotated with `@UseMoor`. Running the following command will export exactly one class annotated with `@DriftDatabase`. Running the following command will export
the database schema to json. the database schema to json.
``` ```
$ pub run moor_generator schema dump path/to/databases.dart schema.json $ dart run drift_dev schema dump path/to/databases.dart schema.json
``` ```
The generated file (`schema.json` in this case) contains information about all The generated file (`schema.json` in this case) contains information about all
@ -67,7 +67,7 @@ The generated file (`schema.json` in this case) contains information about all
- tables, including detailed information about columns - tables, including detailed information about columns
- triggers - triggers
- indices - indices
- `@create`-queries from included moor files - `@create`-queries from included drift files
- dependecies thereof - dependecies thereof
Exporting a schema can be used to generate test code for your schema migrations. For details, Exporting a schema can be used to generate test code for your schema migrations. For details,

View File

@ -1,11 +1,11 @@
--- ---
data: data:
title: "Existing databases" title: "Existing databases"
description: Using moor with an existing database description: Using drift with an existing database
template: layouts/docs/single template: layouts/docs/single
--- ---
You can use moor with a pre-propulated database that you ship with your app. You can use drift with a pre-propulated database that you ship with your app.
## Including the database ## Including the database
@ -13,7 +13,7 @@ First, create the sqlite3 database you want to ship with your app.
You can create a database with the [sqlite3 CLI tool](https://sqlite.org/cli.html) You can create a database with the [sqlite3 CLI tool](https://sqlite.org/cli.html)
on your development machine. on your development machine.
Of course, you can also create the database programmatically by using a library Of course, you can also create the database programmatically by using a library
like [sqlite3](https://pub.dev/packages/sqlite3) (or even moor itself). like [sqlite3](https://pub.dev/packages/sqlite3) (or even drift itself).
To ship that database to users, you can include it as a [flutter asset](https://flutter.dev/docs/development/ui/assets-and-images). To ship that database to users, you can include it as a [flutter asset](https://flutter.dev/docs/development/ui/assets-and-images).
Simply include it in your pubspec: Simply include it in your pubspec:
@ -26,13 +26,13 @@ flutter:
## Extracting the database ## Extracting the database
To initialize the database before using moor, you need to extract the asset from your To initialize the database before using drift, you need to extract the asset from your
app onto the device. app onto the device.
In moor, you can use a [LazyDatabase](https://pub.dev/documentation/moor/latest/moor/LazyDatabase-class.html) In drift, you can use a [LazyDatabase](https://pub.dev/documentation/drift/latest/drift/LazyDatabase-class.html)
to perform that work just before your moor database is opened: to perform that work just before your drift database is opened:
```dart ```dart
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
import 'package:flutter/services.dart' show rootBundle; import 'package:flutter/services.dart' show rootBundle;
LazyDatabase _openConnection() { LazyDatabase _openConnection() {
@ -56,7 +56,7 @@ LazyDatabase _openConnection() {
Finally, use that method to open your database: Finally, use that method to open your database:
```dart ```dart
@UseMoor(tables: [Todos, Categories]) @DriftDatabase(tables: [Todos, Categories])
class MyDatabase extends _$MyDatabase { class MyDatabase extends _$MyDatabase {
MyDatabase() : super(_openConnection()); MyDatabase() : super(_openConnection());

View File

@ -2,13 +2,13 @@
data: data:
title: "Examples" title: "Examples"
weight: 3 weight: 3
description: Example apps using moor description: Example apps using drift
template: layouts/docs/list template: layouts/docs/list
--- ---
We have an [example in the repo](https://github.com/simolus3/moor/tree/master/moor_flutter/example), it's a simple todo list app, We have an [example in the repo](https://github.com/simolus3/moor/tree/master/moor_flutter/example), it's a simple todo list app,
written with moor. [Rody Davis](https://github.com/rodydavis) has built a cleaner version of the example that works on all written with drift. [Rody Davis](https://github.com/rodydavis) has built a cleaner version of the example that works on all
Flutter platforms - including Web and Desktop! You can check it out [here](https://github.com/rodydavis/moor_shared). Flutter platforms - including Web and Desktop! You can check it out [here](https://github.com/rodydavis/drift_shared).
The [HackerNews reader app](https://github.com/filiph/hn_app) from the [Boring Flutter Show](https://www.youtube.com/playlist?list=PLjxrf2q8roU3ahJVrSgAnPjzkpGmL9Czl) also uses moor to keep a list of favorite articles. The [HackerNews reader app](https://github.com/filiph/hn_app) from the [Boring Flutter Show](https://www.youtube.com/playlist?list=PLjxrf2q8roU3ahJVrSgAnPjzkpGmL9Czl) also uses moor to keep a list of favorite articles.

View File

@ -1,14 +1,14 @@
--- ---
data: data:
title: "Many to many relationships" title: "Many to many relationships"
description: An example that models a shopping cart system with moor. description: An example that models a shopping cart system with drift.
template: layouts/docs/single template: layouts/docs/single
--- ---
## Defining the model ## Defining the model
In this example, we're going to model a shopping system and some of its In this example, we're going to model a shopping system and some of its
queries in moor. First, we need to store some items that can be bought: queries in drift. First, we need to store some items that can be bought:
```dart ```dart
class BuyableItems extends Table { class BuyableItems extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
@ -39,7 +39,7 @@ class ShoppingCartEntries extends Table {
} }
``` ```
Moor will generate matching classes for the three tables. But having to use Drift will generate matching classes for the three tables. But having to use
three different classes to model a shopping cart in our application would be three different classes to model a shopping cart in our application would be
quite annoying. Let's write a single class to represent an entire shopping quite annoying. Let's write a single class to represent an entire shopping
cart that: cart that:

View File

@ -8,7 +8,7 @@ template: layouts/docs/single
{% block "blocks/pageinfo" %} {% block "blocks/pageinfo" %}
__Prefer sql?__ If you prefer, you can also declare tables via `CREATE TABLE` statements. __Prefer sql?__ If you prefer, you can also declare tables via `CREATE TABLE` statements.
Moor's sql analyzer will generate matching Dart code. [Details]({{ "starting_with_sql.md" | pageUrl }}). Drift's sql analyzer will generate matching Dart code. [Details]({{ "starting_with_sql.md" | pageUrl }}).
{% endblock %} {% endblock %}
As shown in the [getting started guide]({{ "index.md" | pageUrl }}), sql tables can be written in Dart: As shown in the [getting started guide]({{ "index.md" | pageUrl }}), sql tables can be written in Dart:
@ -25,7 +25,7 @@ In this article, we'll cover some advanced features of this syntax.
## Names ## Names
By default, moor uses the `snake_case` name of the Dart getter in the database. For instance, the By default, drift uses the `snake_case` name of the Dart getter in the database. For instance, the
table table
```dart ```dart
class EnabledCategories extends Table { class EnabledCategories extends Table {
@ -49,18 +49,18 @@ class EnabledCategories extends Table {
The updated class would be generated as `CREATE TABLE categories (parent INTEGER NOT NULL)`. The updated class would be generated as `CREATE TABLE categories (parent INTEGER NOT NULL)`.
To update the name of a column when serializing data to json, annotate the getter with To update the name of a column when serializing data to json, annotate the getter with
[`@JsonKey`](https://pub.dev/documentation/moor/latest/moor/JsonKey-class.html). [`@JsonKey`](https://pub.dev/documentation/drift/latest/drift/JsonKey-class.html).
You can change the name of the generated data class too. By default, moor will stip a trailing You can change the name of the generated data class too. By default, drift will stip a trailing
`s` from the table name (so a `Users` table would have a `User` data class). `s` from the table name (so a `Users` table would have a `User` data class).
That doesn't work in all cases though. With the `EnabledCategories` class from above, we'd get That doesn't work in all cases though. With the `EnabledCategories` class from above, we'd get
a `EnabledCategorie` data class. In those cases, you can use the [`@DataClassName`](https://pub.dev/documentation/moor/latest/moor/DataClassName-class.html) a `EnabledCategorie` data class. In those cases, you can use the [`@DataClassName`](https://pub.dev/documentation/drift/latest/drift/DataClassName-class.html)
annotation to set the desired name. annotation to set the desired name.
## Nullability ## Nullability
By default, columns may not contain null values. When you forgot to set a value in an insert, By default, columns may not contain null values. When you forgot to set a value in an insert,
an exception will be thrown. When using sql, moor also warns about that at compile time. an exception will be thrown. When using sql, drift also warns about that at compile time.
If you do want to make a column nullable, just use `nullable()`: If you do want to make a column nullable, just use `nullable()`:
```dart ```dart
@ -109,7 +109,7 @@ can be more efficient, but doesn't support dynamic values.
## Primary keys ## Primary keys
If your table has an `IntColumn` with an `autoIncrement()` constraint, moor recognizes that as the default If your table has an `IntColumn` with an `autoIncrement()` constraint, drift recognizes that as the default
primary key. If you want to specify a custom primary key for your table, you can override the `primaryKey` primary key. If you want to specify a custom primary key for your table, you can override the `primaryKey`
getter in your table: getter in your table:
@ -130,7 +130,7 @@ Note that the primary key must essentially be constant so that the generator can
## Supported column types ## Supported column types
Moor supports a variety of column types out of the box. You can store custom classes in columns by using Drift supports a variety of column types out of the box. You can store custom classes in columns by using
[type converters]({{ "../Advanced Features/type_converters.md" | pageUrl }}). [type converters]({{ "../Advanced Features/type_converters.md" | pageUrl }}).
| Dart type | Column | Corresponding SQLite type | | Dart type | Column | Corresponding SQLite type |
@ -146,11 +146,11 @@ Note that the mapping for `boolean`, `dateTime` and type converters only applies
the database. the database.
They don't affect JSON serialization at all. For instance, `boolean` values are expected as `true` or `false` They don't affect JSON serialization at all. For instance, `boolean` values are expected as `true` or `false`
in the `fromJson` factory, even though they would be saved as `0` or `1` in the database. in the `fromJson` factory, even though they would be saved as `0` or `1` in the database.
If you want a custom mapping for JSON, you need to provide your own [`ValueSerializer`](https://pub.dev/documentation/moor/latest/moor/ValueSerializer-class.html). If you want a custom mapping for JSON, you need to provide your own [`ValueSerializer`](https://pub.dev/documentation/drift/latest/drift/ValueSerializer-class.html).
## Custom constraints ## Custom constraints
Some column and table constraints aren't supported through moor's Dart api. This includes `REFERENCES` clauses on columns, which you can set Some column and table constraints aren't supported through drift's Dart api. This includes `REFERENCES` clauses on columns, which you can set
through `customConstraint`: through `customConstraint`:
```dart ```dart

View File

@ -1,7 +1,7 @@
--- ---
data: data:
title: Getting started title: Getting started
description: Simple guide to get a moor project up and running description: Simple guide to get a drift project up and running
weight: 1 weight: 1
template: layouts/docs/list template: layouts/docs/list
aliases: aliases:
@ -12,42 +12,42 @@ _Note:_ If you prefer a tutorial video, Reso Coder has made a detailed video exp
how to get started. You can watch it [here](https://youtu.be/zpWsedYMczM). how to get started. You can watch it [here](https://youtu.be/zpWsedYMczM).
## Adding the dependency ## Adding the dependency
First, lets add moor to your project's `pubspec.yaml`. First, lets add drift to your project's `pubspec.yaml`.
At the moment, the current version of `moor` is [![Moor version](https://img.shields.io/pub/v/moor.svg)](https://pub.dev/packages/moor) At the moment, the current version of `drift` is [![Drift version](https://img.shields.io/pub/v/drift.svg)](https://pub.dev/packages/drift)
and the latest version of `moor_generator` is [![Generator version](https://img.shields.io/pub/v/moor_generator.svg)](https://pub.dev/packages/moor_generator). and the latest version of `drift_dev` is [![Generator version](https://img.shields.io/pub/v/drift_dev.svg)](https://pub.dev/packages/drift_dev).
{% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %} {% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %}
```yaml ```yaml
dependencies: dependencies:
moor: ^{{ versions.moor }} drift: ^{{ versions.drift }}
sqlite3_flutter_libs: ^0.5.0 sqlite3_flutter_libs: ^0.5.0
path_provider: ^2.0.0 path_provider: ^2.0.0
path: ^{{ versions.path }} path: ^{{ versions.path }}
dev_dependencies: dev_dependencies:
moor_generator: ^{{ versions.moor_generator }} drift_dev: ^{{ versions.drift_dev }}
build_runner: ^{{ versions.build_runner }} build_runner: ^{{ versions.build_runner }}
``` ```
If you're wondering why so many packages are necessary, here's a quick overview over what each package does: If you're wondering why so many packages are necessary, here's a quick overview over what each package does:
- `moor`: This is the core package defining most apis - `drift`: This is the core package defining most apis
- `sqlite3_flutter_libs`: Ships the latest `sqlite3` version with your Android or iOS app. This is not required when you're _not_ using Flutter, - `sqlite3_flutter_libs`: Ships the latest `sqlite3` version with your Android or iOS app. This is not required when you're _not_ using Flutter,
but then you need to take care of including `sqlite3` yourself. but then you need to take care of including `sqlite3` yourself.
- `path_provider` and `path`: Used to find a suitable location to store the database. Maintained by the Flutter and Dart team - `path_provider` and `path`: Used to find a suitable location to store the database. Maintained by the Flutter and Dart team
- `moor_generator`: Generates query code based on your tables - `drift_dev`: This development-only dependency generates query code based on your tables. It will not be included in your final app.
- `build_runner`: Common tool for code-generation, maintained by the Dart team - `build_runner`: Common tool for code-generation, maintained by the Dart team
{% include "partials/changed_to_ffi" %} {% include "partials/changed_to_ffi" %}
### Declaring tables ### Declaring tables
Using moor, you can model the structure of your tables with simple dart code: Using drift, you can model the structure of your tables with simple dart code:
```dart ```dart
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
// assuming that your file is called filename.dart. This will give an error at first, // assuming that your file is called filename.dart. This will give an error at first,
// but it's needed for moor to know about the generated code // but it's needed for drift to know about the generated code
part 'filename.g.dart'; part 'filename.g.dart';
// this will generate a table called "todos" for us. The rows of that table will // this will generate a table called "todos" for us. The rows of that table will
@ -59,7 +59,7 @@ class Todos extends Table {
IntColumn get category => integer().nullable()(); IntColumn get category => integer().nullable()();
} }
// This will make moor generate a class called "Category" to represent a row in this table. // This will make drift generate a class called "Category" to represent a row in this table.
// By default, "Categorie" would have been used because it only strips away the trailing "s" // By default, "Categorie" would have been used because it only strips away the trailing "s"
// in the table name. // in the table name.
@DataClassName("Category") @DataClassName("Category")
@ -69,9 +69,9 @@ class Categories extends Table {
TextColumn get description => text()(); TextColumn get description => text()();
} }
// this annotation tells moor to prepare a database class that uses both of the // this annotation tells drift to prepare a database class that uses both of the
// tables we just defined. We'll see how to use that database class in a moment. // tables we just defined. We'll see how to use that database class in a moment.
@UseMoor(tables: [Todos, Categories]) @DriftDatabase(tables: [Todos, Categories])
class MyDatabase { class MyDatabase {
} }
@ -83,18 +83,18 @@ operator and can't contain anything more than what's included in the documentati
examples. Otherwise, the generator won't be able to know what's going on. examples. Otherwise, the generator won't be able to know what's going on.
## Generating the code ## Generating the code
Moor integrates with Dart's `build` system, so you can generate all the code needed with Drift integrates with Dart's `build` system, so you can generate all the code needed with
`flutter packages pub run build_runner build`. If you want to continuously rebuild the generated code `flutter packages pub run build_runner build`. If you want to continuously rebuild the generated code
where you change your code, run `flutter packages pub run build_runner watch` instead. where you change your code, run `flutter packages pub run build_runner watch` instead.
After running either command once, the moor generator will have created a class for your After running either command once, the drift generator will have created a class for your
database and data classes for your entities. To use it, change the `MyDatabase` class as database and data classes for your entities. To use it, change the `MyDatabase` class as
follows: follows:
```dart ```dart
// These imports are only needed to open the database // These imports are only needed to open the database
import 'package:moor/ffi.dart'; import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
import 'dart:io'; import 'dart:io';
LazyDatabase _openConnection() { LazyDatabase _openConnection() {
@ -104,11 +104,11 @@ LazyDatabase _openConnection() {
// for your app. // for your app.
final dbFolder = await getApplicationDocumentsDirectory(); final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite')); final file = File(p.join(dbFolder.path, 'db.sqlite'));
return VmDatabase(file); return NativeDatabase(file);
}); });
} }
@UseMoor(tables: [Todos, Categories]) @DriftDatabase(tables: [Todos, Categories])
class MyDatabase extends _$MyDatabase { class MyDatabase extends _$MyDatabase {
// we tell the database where to store the data with this constructor // we tell the database where to store the data with this constructor
MyDatabase() : super(_openConnection()); MyDatabase() : super(_openConnection());
@ -120,6 +120,6 @@ class MyDatabase extends _$MyDatabase {
} }
``` ```
Congratulations! You're now ready to use all of moor. See the articles below for further reading. Congratulations! You're now ready to use all of drift. See the articles below for further reading.
The ["Writing queries"]({{ "writing_queries.md" | pageUrl }}) article contains everything you need The ["Writing queries"]({{ "writing_queries.md" | pageUrl }}) article contains everything you need
to know to write selects, updates and inserts in moor! to know to write selects, updates and inserts in drift!

View File

@ -2,54 +2,54 @@
data: data:
title: "Getting started with sql" title: "Getting started with sql"
weight: 5 weight: 5
description: Learn how to get started with the SQL version of moor, or how to migrate an existing project to moor. description: Learn how to get started with the SQL version of drift, or how to migrate an existing project to drift.
template: layouts/docs/single template: layouts/docs/single
--- ---
The regular [getting started guide]({{ "index.md" | pageUrl }}) explains how to get started with moor by The regular [getting started guide]({{ "index.md" | pageUrl }}) explains how to get started with drift by
declaring both tables and queries in Dart. This version will focus on how to use moor with SQL instead. declaring both tables and queries in Dart. This version will focus on how to use drift with SQL instead.
## Adding the dependency ## Adding the dependency
First, lets add moor to your project's `pubspec.yaml`. First, lets add drift to your project's `pubspec.yaml`.
At the moment, the current version of `moor` is [![Moor version](https://img.shields.io/pub/v/moor.svg)](https://pub.dev/packages/moor) At the moment, the current version of `drift` is [![Drift version](https://img.shields.io/pub/v/drift.svg)](https://pub.dev/packages/drift)
and the latest version of `moor_generator` is [![Generator version](https://img.shields.io/pub/v/moor_generator.svg)](https://pub.dev/packages/moor_generator) and the latest version of `drift_dev` is [![Generator version](https://img.shields.io/pub/v/drift_dev.svg)](https://pub.dev/packages/drift_dev).
{% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %} {% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %}
```yaml ```yaml
dependencies: dependencies:
moor: ^{{ versions.moor }} drift: ^{{ versions.drift }}
sqlite3_flutter_libs: ^0.5.0 sqlite3_flutter_libs: ^0.5.0
path_provider: ^2.0.0 path_provider: ^2.0.0
path: ^{{ versions.path }} path: ^{{ versions.path }}
dev_dependencies: dev_dependencies:
moor_generator: ^{{ versions.moor_generator }} drift_dev: ^{{ versions.drift_dev }}
build_runner: ^{{ versions.build_runner }} build_runner: ^{{ versions.build_runner }}
``` ```
If you're wondering why so many packages are necessary, here's a quick overview over what each package does: If you're wondering why so many packages are necessary, here's a quick overview over what each package does:
- `moor`: This is the core package defining most apis - `drift`: This is the core package defining most apis
- `sqlite3_flutter_libs`: Ships the latest `sqlite3` version with your Android or iOS app. This is not required when you're _not_ using Flutter, - `sqlite3_flutter_libs`: Ships the latest `sqlite3` version with your Android or iOS app. This is not required when you're _not_ using Flutter,
but then you need to take care of including `sqlite3` yourself. but then you need to take care of including `sqlite3` yourself.
- `path_provider` and `path`: Used to find a suitable location to store the database. Maintained by the Flutter and Dart team - `path_provider` and `path`: Used to find a suitable location to store the database. Maintained by the Flutter and Dart team
- `moor_generator`: Generates query code based on your tables - `drift_dev`: This development-only dependency generates query code based on your tables. It will not be included in your final app.
- `build_runner`: Common tool for code-generation, maintained by the Dart team - `build_runner`: Common tool for code-generation, maintained by the Dart team
{% include "partials/changed_to_ffi" %} {% include "partials/changed_to_ffi" %}
## Declaring tables and queries ## Declaring tables and queries
To declare tables and queries in sql, create a file called `tables.moor` To declare tables and queries in sql, create a file called `tables.drift`
next to your Dart files (for instance in `lib/database/tables.moor`). next to your Dart files (for instance in `lib/database/tables.drift`).
You can put `CREATE TABLE` statements for your queries in there. You can put `CREATE TABLE` statements for your queries in there.
The following example creates two tables to model a todo-app. If you're The following example creates two tables to model a todo-app. If you're
migrating an existing project to moor, you can just copy the `CREATE TABLE` migrating an existing project to drift, you can just copy the `CREATE TABLE`
statements you've already written into this file. statements you've already written into this file.
```sql ```sql
-- this is the tables.moor file -- this is the tables.drift file
CREATE TABLE todos ( CREATE TABLE todos (
id INT NOT NULL PRIMARY KEY AUTOINCREMENT, id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
title TEXT, title TEXT,
@ -78,37 +78,37 @@ countEntries:
``` ```
{% block "blocks/alert" title="On that AS Category" %} {% block "blocks/alert" title="On that AS Category" %}
Moor will generate Dart classes for your tables, and the name of those Drift will generate Dart classes for your tables, and the name of those
classes is based on the table name. By default, moor just strips away classes is based on the table name. By default, drift just strips away
the trailing `s` from your table. That works for most cases, but in some the trailing `s` from your table. That works for most cases, but in some
(like the `categories` table above), it doesn't. We'd like to have a (like the `categories` table above), it doesn't. We'd like to have a
`Category` class (and not `Categorie`) generated, so we tell moor to `Category` class (and not `Categorie`) generated, so we tell drift to
generate a different name with the `AS <name>` declaration at the end. generate a different name with the `AS <name>` declaration at the end.
{% endblock %} {% endblock %}
## Generating matching code ## Generating matching code
After you declared the tables, lets generate some Dart code to actually After you declared the tables, lets generate some Dart code to actually
run them. Moor needs to know which tables are used in a database, so we run them. Drift needs to know which tables are used in a database, so we
have to write a small Dart class that moor will then read. Lets create have to write a small Dart class that drift will then read. Lets create
a file called `database.dart` next to the `tables.moor` file you wrote a file called `database.dart` next to the `tables.drift` file you wrote
in the previous step. in the previous step.
```dart ```dart
import 'dart:io'; import 'dart:io';
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
// These imports are only needed to open the database // These imports are only needed to open the database
import 'package:moor/ffi.dart'; import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
part 'database.g.dart'; part 'database.g.dart';
@UseMoor( @DriftDatabase(
// relative import for the moor file. Moor also supports `package:` // relative import for the drift file. Drift also supports `package:`
// imports // imports
include: {'tables.moor'}, include: {'tables.drift'},
) )
class AppDb extends _$AppDb { class AppDb extends _$AppDb {
AppDb() : super(_openConnection()); AppDb() : super(_openConnection());
@ -133,21 +133,21 @@ To generate the `database.g.dart` file which contains the `_$AppDb`
superclass, run `flutter pub run build_runner build` on the command superclass, run `flutter pub run build_runner build` on the command
line. line.
## What moor generates ## What drift generates
Let's take a look at what moor generated during the build: Let's take a look at what drift generated during the build:
- Generated data classes (`Todo` and `Category`) - these hold a single - Generated data classes (`Todo` and `Category`) - these hold a single
row from the respective table. row from the respective table.
- Companion versions of these classes. Those are only relevant when - Companion versions of these classes. Those are only relevant when
using the Dart apis of moor, you can [learn more here]({{ "writing_queries.md#inserts" | pageUrl }}). using the Dart apis of drift, you can [learn more here]({{ "writing_queries.md#inserts" | pageUrl }}).
- A `CountEntriesResult` class, it holds the result rows when running the - A `CountEntriesResult` class, it holds the result rows when running the
`countEntries` query. `countEntries` query.
- A `_$AppDb` superclass. It takes care of creating the tables when - A `_$AppDb` superclass. It takes care of creating the tables when
the database file is first opened. It also contains typesafe methods the database file is first opened. It also contains typesafe methods
for the queries declared in the `tables.moor` file: for the queries declared in the `tables.drift` file:
- a `Selectable<Todo> todosInCategory(int)` method, which runs the - a `Selectable<Todo> todosInCategory(int)` method, which runs the
`todosInCategory` query declared above. Moor has determined that the `todosInCategory` query declared above. Drift has determined that the
type of the variable in that query is `int`, because that's the type type of the variable in that query is `int`, because that's the type
of the `category` column we're comparing it to. of the `category` column we're comparing it to.
The method returns a `Selectable` to indicate that it can both be The method returns a `Selectable` to indicate that it can both be
@ -157,11 +157,11 @@ Let's take a look at what moor generated during the build:
the other query when used. the other query when used.
By the way, you can also put insert, update and delete statements in By the way, you can also put insert, update and delete statements in
a `.moor` file - moor will generate matching code for them as well. a `.drift` file - drift will generate matching code for them as well.
## Learning more ## Learning more
Now that you know how to use moor together with sql, here are some Now that you know how to use drift together with sql, here are some
further guides to help you learn more: further guides to help you learn more:
- The [SQL IDE]({{ "../Using SQL/sql_ide.md" | pageUrl }}) that provides feedback on sql queries right in your editor. - The [SQL IDE]({{ "../Using SQL/sql_ide.md" | pageUrl }}) that provides feedback on sql queries right in your editor.
@ -170,4 +170,4 @@ further guides to help you learn more:
- Writing [queries]({{ "writing_queries.md" | pageUrl }}) and - Writing [queries]({{ "writing_queries.md" | pageUrl }}) and
[expressions]({{ "../Advanced Features/expressions.md" | pageUrl }}) in Dart [expressions]({{ "../Advanced Features/expressions.md" | pageUrl }}) in Dart
- A more [in-depth guide]({{ "../Using SQL/moor_files.md" | pageUrl }}) - A more [in-depth guide]({{ "../Using SQL/moor_files.md" | pageUrl }})
on `moor` files, which explains `import` statements and the Dart-SQL interop. on `drift` files, which explains `import` statements and the Dart-SQL interop.

View File

@ -2,7 +2,7 @@
data: data:
title: "Writing queries" title: "Writing queries"
linkTitle: "Writing queries" linkTitle: "Writing queries"
description: Learn how to write database queries in pure Dart with moor description: Learn how to write database queries in pure Dart with drift
weight: 100 weight: 100
aliases: aliases:
- /queries/ - /queries/
@ -13,12 +13,12 @@ template: layouts/docs/single
__Note__: This assumes that you've already completed [the setup]({{ "index.md" | pageUrl }}). __Note__: This assumes that you've already completed [the setup]({{ "index.md" | pageUrl }}).
{% endblock %} {% endblock %}
For each table you've specified in the `@UseMoor` annotation on your database class, For each table you've specified in the `@DriftDatabase` annotation on your database class,
a corresponding getter for a table will be generated. That getter can be used to a corresponding getter for a table will be generated. That getter can be used to
run statements: run statements:
```dart ```dart
// inside the database class, the `todos` getter has been created by moor. // inside the database class, the `todos` getter has been created by drift.
@UseMoor(tables: [Todos, Categories]) @DriftDatabase(tables: [Todos, Categories])
class MyDatabase extends _$MyDatabase { class MyDatabase extends _$MyDatabase {
// the schemaVersion getter and the constructor from the previous page // the schemaVersion getter and the constructor from the previous page
@ -37,7 +37,7 @@ class MyDatabase extends _$MyDatabase {
## Select statements ## Select statements
You can create `select` statements by starting them with `select(tableName)`, where the You can create `select` statements by starting them with `select(tableName)`, where the
table name table name
is a field generated for you by moor. Each table used in a database will have a matching field is a field generated for you by drift. Each table used in a database will have a matching field
to run queries against. Any query can be run once with `get()` or be turned into an auto-updating to run queries against. Any query can be run once with `get()` or be turned into an auto-updating
stream using `watch()`. stream using `watch()`.
### Where ### Where
@ -72,7 +72,7 @@ You can also reverse the order by setting the `mode` property of the `OrderingTe
### Single values ### Single values
If you know a query is never going to return more than one row, wrapping the result in a `List` If you know a query is never going to return more than one row, wrapping the result in a `List`
can be tedious. Moor lets you work around that with `getSingle` and `watchSingle`: can be tedious. Drift lets you work around that with `getSingle` and `watchSingle`:
```dart ```dart
Stream<Todo> entryById(int id) { Stream<Todo> entryById(int id) {
return (select(todos)..where((t) => t.id.equals(id))).watchSingle(); return (select(todos)..where((t) => t.id.equals(id))).watchSingle();
@ -156,7 +156,7 @@ the statement will affect all rows in the table!
{% block "blocks/alert" title="Entries, companions - why do we need all of this?" %} {% block "blocks/alert" title="Entries, companions - why do we need all of this?" %}
You might have noticed that we used a `TodosCompanion` for the first update instead of You might have noticed that we used a `TodosCompanion` for the first update instead of
just passing a `Todo`. Moor generates the `Todo` class (also called _data just passing a `Todo`. Drift generates the `Todo` class (also called _data
class_ for the table) to hold a __full__ row with all its data. For _partial_ data, class_ for the table) to hold a __full__ row with all its data. For _partial_ data,
prefer to use companions. In the example above, we only set the the `category` column, prefer to use companions. In the example above, we only set the the `category` column,
so we used a companion. so we used a companion.
@ -271,23 +271,22 @@ Future<void> trackWord(String word) {
{% block "blocks/alert" title="Unique constraints and conflict targets" %} {% block "blocks/alert" title="Unique constraints and conflict targets" %}
> Both `insertOnConflictUpdate` and `onConflict: DoUpdate` use an `DO UPDATE` > Both `insertOnConflictUpdate` and `onConflict: DoUpdate` use an `DO UPDATE`
upsert in sql. This requires us to provide a so-called "conflict target", a upsert in sql. This requires us to provide a so-called "conflict target", a
set of columns to check for uniqueness violations. By default, moor will use set of columns to check for uniqueness violations. By default, drift will use
the table's primary key as conflict target. That works in most cases, but if the table's primary key as conflict target. That works in most cases, but if
you have custom `UNIQUE` constraints on some columns, you'll need to use you have custom `UNIQUE` constraints on some columns, you'll need to use
the `target` parameter on `DoUpdate` in Dart to include those columns. the `target` parameter on `DoUpdate` in Dart to include those columns.
{% endblock %} {% endblock %}
Note that this requires a fairly recent sqlite3 version (3.24.0) that might not Note that this requires a fairly recent sqlite3 version (3.24.0) that might not
be available on older Android devices when using `moor_flutter`. `moor_ffi` be available on older Android devices when using `moor_flutter`. `NativeDatabases`
includes the latest sqlite on Android, so consider using it if you want to and `sqlite3_flutter_libs` includes the latest sqlite on Android, so consider using
support upserts. it if you want to support upserts.
Also note that the returned rowid may not be accurate when an upsert took place. Also note that the returned rowid may not be accurate when an upsert took place.
### Returning ### Returning
Starting from moor version 4.3, you can use `insertReturning` to insert a row You can use `insertReturning` to insert a row or companion and immediately get the row it inserts.
or companion and immediately get the row it inserts.
The returned row contains all the default values and incrementing ids that were The returned row contains all the default values and incrementing ids that were
generated. generated.

View File

@ -1,33 +1,28 @@
--- ---
data: data:
title: "Moor internals" title: "Drift internals"
weight: 300000 weight: 300000
description: Work in progress documentation on moor internals description: Work in progress documentation on drift internals
template: layouts/docs/list template: layouts/docs/list
--- ---
## Using an unreleased moor version ## Using an unreleased drift version
To try out new moor features, you can choose to use a development or beta version of moor before it's To try out new drift features, you can choose to use a development or beta version of drift before it's
published to pub. For that, add an `dependency_overrides` section to your pubspec: published to pub. For that, add an `dependency_overrides` section to your pubspec:
```yaml ```yaml
dependency_overrides: dependency_overrides:
moor: drift:
git: git:
url: https://github.com/simolus3/moor.git url: https://github.com/simolus3/moor.git
ref: beta ref: beta
path: moor path: drift
moor_ffi: drift_dev:
git: git:
url: https://github.com/simolus3/moor.git url: https://github.com/simolus3/moor.git
ref: beta ref: beta
path: moor_ffi path: drift_dev
moor_generator:
git:
url: https://github.com/simolus3/moor.git
ref: beta
path: moor_generator
sqlparser: sqlparser:
git: git:
url: https://github.com/simolus3/moor.git url: https://github.com/simolus3/moor.git
@ -35,5 +30,5 @@ dependency_overrides:
path: sqlparser path: sqlparser
``` ```
If you're using `moor_flutter`, just exchange `moor_ffi` with `moor_flutter` in the package name If you're using `moor_flutter`, just exchange `drift` with `moor_flutter` in the package name
and path. To use the bleeding edge of moor, change `ref: beta` to `ref: develop` for all packages. and path. To use the bleeding edge of drift, change `ref: beta` to `ref: develop` for all packages.

View File

@ -1,33 +1,36 @@
--- ---
data: data:
title: Encryption title: Encryption
description: Use moor on encrypted databases description: Use drift on encrypted databases
template: layouts/docs/single template: layouts/docs/single
--- ---
There are two ways to use moor on encrypted databases. There are two ways to use drift on encrypted databases.
The `encrypted_moor` package is similar to `moor_flutter` and uses a platform plugin written in The `encrypted_moor` package is similar to `moor_flutter` and uses a platform plugin written in
Java. Java.
Alternatively, you can use the ffi-based implementation with the `sqlcipher_flutter_libs` package. Alternatively, you can use the ffi-based implementation with the `sqlcipher_flutter_libs` package.
## Using `encrypted_moor` ## Using `encrypted_moor`
Starting from 1.7, we have a version of moor that can work with encrypted databases by using the Starting from 1.7, we have a version of drift that can work with encrypted databases by using the
[sqflite_sqlcipher](https://pub.dev/packages/sqflite_sqlcipher) library [sqflite_sqlcipher](https://pub.dev/packages/sqflite_sqlcipher) library
by [@davidmartos96](https://github.com/davidmartos96). To use it, you need to by [@davidmartos96](https://github.com/davidmartos96). To use it, you need to
remove the dependency on `moor_flutter` from your `pubspec.yaml` and replace it remove the dependency on `moor_flutter` from your `pubspec.yaml` and replace it
with this: with this:
{% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %}
```yaml ```yaml
dependencies: dependencies:
moor: "$latest version" drift: ^{{ versions.drift }}
encrypted_moor: encrypted_moor:
git: git:
url: https://github.com/simolus3/moor.git url: https://github.com/simolus3/moor.git
path: extras/encryption path: extras/encryption
``` ```
Instead of importing `package:moor_flutter/moor_flutter` (or `package:moor/ffi.dart`) in your apps, Instead of importing `package:moor_flutter/moor_flutter` (or `package:drift/native.dart`) in your apps,
you would then import both `package:moor/moor.dart` and `package:encrypted_moor/encrypted_moor.dart`. you would then import both `package:drift/drift.dart` and `package:encrypted_moor/encrypted_moor.dart`.
Finally, you can replace `FlutterQueryExecutor` (or an `VmDatabase`) with an `EncryptedExecutor`. Finally, you can replace `FlutterQueryExecutor` (or an `VmDatabase`) with an `EncryptedExecutor`.
@ -37,10 +40,10 @@ Some extra steps may have to be taken in your project so that SQLCipher works co
[Read instructions](https://pub.dev/packages/sqflite_sqlcipher) (Usage and installation instructions of the package can be ignored, as that is handled internally by `moor`) [Read instructions](https://pub.dev/packages/sqflite_sqlcipher) (Usage and installation instructions of the package can be ignored, as that is handled internally by `moor`)
## Encrypted version of `moor/ffi` ## Encrypted version of a `NativeDatabase`
You can also use the new `moor/ffi` library with an encrypted executor. You can also use the new `drift/native` library with an encrypted executor.
This allows you to use an encrypted moor database on more platforms, which is particularly This allows you to use an encrypted drift database on more platforms, which is particularly
interesting for Desktop applications. interesting for Desktop applications.
### Setup ### Setup
@ -62,14 +65,14 @@ of the regular `libsqlite3.so`:
```dart ```dart
import 'package:sqlite3/open.dart'; import 'package:sqlite3/open.dart';
// call this method before using moor // call this method before using drift
void setupSqlCipher() { void setupSqlCipher() {
open.overrideFor( open.overrideFor(
OperatingSystem.android, () => DynamicLibrary.open('libsqlcipher.so')); OperatingSystem.android, () => DynamicLibrary.open('libsqlcipher.so'));
} }
``` ```
When using moor on a background database, you need to call `setupSqlCipher` on the background isolate When using drift on a background database, you need to call `setupSqlCipher` on the background isolate
as well. as well.
On iOS and macOS, no additional setup is necessary - simply depend on `sqlcipher_flutter_libs`. On iOS and macOS, no additional setup is necessary - simply depend on `sqlcipher_flutter_libs`.
@ -83,14 +86,14 @@ of SQLCipher.
### Using ### Using
SQLCipher implements sqlite3's C api, which means that you can continue to use the `sqlite3` package SQLCipher implements sqlite3's C api, which means that you can continue to use the `sqlite3` package
or `moor/ffi` without changes. They're both fully compatible with `sqlcipher_flutter_libs`. or `drift/ffi` without changes. They're both fully compatible with `sqlcipher_flutter_libs`.
To actually encrypt a database, you must set an encryption key before using it. To actually encrypt a database, you must set an encryption key before using it.
A good place to do that in moor is the `setup` parameter of `VmDatabase`, which runs before moor A good place to do that in drift is the `setup` parameter of `NativeDatabase`, which runs before drift
is using the database in any way: is using the database in any way:
```dart ```dart
VmDatabase( NativeDatabase(
File(...), File(...),
setup: (rawDb) { setup: (rawDb) {
rawDb.execute("PRAGMA key = 'passphrase';"); rawDb.execute("PRAGMA key = 'passphrase';");

View File

@ -1,7 +1,7 @@
--- ---
data: data:
title: "Other engines" title: "Other engines"
description: "Use moor on the web or other platforms" description: "Use drift on the web or other platforms"
weight: 100 weight: 100
template: layouts/docs/list template: layouts/docs/list
--- ---

View File

@ -1,18 +1,18 @@
--- ---
data: data:
title: moor ffi (Desktop support) title: Native Drift (Desktop support)
description: Run moor on both mobile and desktop description: Run drift on both mobile and desktop
template: layouts/docs/single template: layouts/docs/single
--- ---
## Supported platforms ## Supported platforms
The `moor/ffi.dart` library uses the `sqlite3` package to send queries. The `drift/native.dart` library uses the `sqlite3` package to send queries.
At the moment, that package supports iOS, macOS and Android out of the box. Most Linux At the moment, that package supports iOS, macOS and Android out of the box. Most Linux
Distros have sqlite available as a shared library, those are supported as well. Distros have sqlite available as a shared library, those are supported as well.
If you're shipping apps for Windows and Linux, it is recommended that you bundle a If you're shipping apps for Windows and Linux, it is recommended that you bundle a
`sqlite3.so` and `sqlite3.dll` file with your app. You can then make `moor_ffi` `sqlite3.so` and `sqlite3.dll` file with your app. You can then make `drift`
support your setup by running this code before opening the database: support your setup by running this code before opening the database:
```dart ```dart
@ -37,24 +37,26 @@ DynamicLibrary _openOnLinux() {
``` ```
## Migrating from moor_flutter to moor ffi ## Migrating from moor_flutter to `drift/native` {#migrating-from-moor_flutter-to-moor-ffi}
First, adapt your `pubspec.yaml`: You can remove the `moor_flutter` dependency and instead First, adapt your `pubspec.yaml`: You can remove the `moor_flutter` dependency and instead
add both the `moor` and `sqlite3_flutter_libs` dependencies: add both the `drift` and `sqlite3_flutter_libs` dependencies:
{% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %}
```yaml ```yaml
dependencies: dependencies:
moor: ^3.0.0 drift: ^{{ versions.drift }}
sqlite3_flutter_libs: sqlite3_flutter_libs:
sqflite: ^1.1.7 # Still used to obtain the database location sqflite: ^1.1.7 # Still used to obtain the database location
dev_dependencies: dev_dependencies:
moor_generator: ^3.0.0 drift_dev: ^{{ versions.drift_dev }}
``` ```
Adapt your imports: Adapt your imports:
- In the file where you created a `FlutterQueryExecutor`, replace the `moor_flutter` import - In the file where you created a `FlutterQueryExecutor`, replace the `moor_flutter` import
with `package:moor/ffi.dart`. with `package:drift/native.dart`.
- In all other files where you might have imported `moor_flutter`, just import `package:moor/moor.dart`. - In all other files where you might have imported `moor_flutter`, just import `package:drift/drift.dart`.
Replace the executor. This code: Replace the executor. This code:
```dart ```dart
@ -78,7 +80,7 @@ Please be aware that `FlutterQueryExecutor.inDatabaseFolder` might yield a diffe
`path_provider` on Android. This can cause data loss if you've already shipped a version using `path_provider` on Android. This can cause data loss if you've already shipped a version using
`moor_flutter`. In that case, using `getDatabasePath` from sqflite is the suggested solution. `moor_flutter`. In that case, using `getDatabasePath` from sqflite is the suggested solution.
## Using moor ffi with an existing database ## Using native drift with an existing database {#using-moor-ffi-with-an-existing-database}
If your existing sqlite database is stored as a file, you can just use `VmDatabase(thatFile)` - no further If your existing sqlite database is stored as a file, you can just use `VmDatabase(thatFile)` - no further
changes are required. changes are required.
@ -88,7 +90,7 @@ It allows you to perform some async work before opening the database:
```dart ```dart
// before // before
VmDatabase(File('...')); NativeDatabase(File('...'));
// after // after
LazyDatabase(() async { LazyDatabase(() async {
@ -96,27 +98,27 @@ LazyDatabase(() async {
if (!await file.exists()) { if (!await file.exists()) {
// copy the file from an asset, or network, or any other source // copy the file from an asset, or network, or any other source
} }
return VmDatabase(file); return NativeDatabase(file);
}); });
``` ```
## Used compile options on Android ## Used compile options on Android
Note: Android is the only platform where moor_ffi will compile sqlite. The sqlite3 library from the system On Android, iOS and macOs, depending on `sqlite3_flutter_libs` will include a custom build of sqlite instead of
is used on all other platforms. The chosen options help reduce binary size by removing features not used by using the one from the system.
moor. Important options are marked in bold. The chosen options help reduce binary size by removing features not used by drift. Important options are marked in bold.
- We use the `-O3` performance option - We use the `-O3` performance option
- __SQLITE_DQS=0__: This will make sqlite not accept double-quoted strings (and instead parse them as identifiers). This matches - __SQLITE_DQS=0__: This will make sqlite not accept double-quoted strings (and instead parse them as identifiers). This matches
the behavior of moor and compiled queries the behavior of drift and compiled queries
- __SQLITE_THREADSAFE=0__: Since the majority of Flutter apps only use one isolate, thread safety is turned off. Note that you - __SQLITE_THREADSAFE=0__: Since the majority of Flutter apps only use one isolate, thread safety is turned off. Note that you
can still use the [isolate api]({{"../Advanced Features/isolates.md" | pageUrl}}) for background operations. As long as all can still use the [isolate api]({{"../Advanced Features/isolates.md" | pageUrl}}) for background operations. As long as all
database accesses happen from the same thread, there's no problem. database accesses happen from the same thread, there's no problem.
- SQLITE_DEFAULT_MEMSTATUS=0: The `sqlite3_status()` interfaces are not exposed by moor_ffi, so there's no point of having them. - SQLITE_DEFAULT_MEMSTATUS=0: The `sqlite3_status()` interfaces are not exposed by drift, so there's no point of having them.
- SQLITE_MAX_EXPR_DEPTH=0: Disables maximum depth when sqlite parses expressions, which can make the parser faster. - SQLITE_MAX_EXPR_DEPTH=0: Disables maximum depth when sqlite parses expressions, which can make the parser faster.
- `SQLITE_OMIT_AUTHORIZATION`, `SQLITE_OMIT_DECLTYPE`, __SQLITE_OMIT_DEPRECATED__, `SQLITE_OMIT_GET_TABLE`, `SQLITE_OMIT_LOAD_EXTENSION`, - `SQLITE_OMIT_AUTHORIZATION`, `SQLITE_OMIT_DECLTYPE`, __SQLITE_OMIT_DEPRECATED__, `SQLITE_OMIT_GET_TABLE`, `SQLITE_OMIT_LOAD_EXTENSION`,
`SQLITE_OMIT_PROGRESS_CALLBACK`, `SQLITE_OMIT_SHARED_CACHE`, `SQLITE_OMIT_TCL_VARIABLE`, `SQLITE_OMIT_TRACE`: Disables features not supported `SQLITE_OMIT_PROGRESS_CALLBACK`, `SQLITE_OMIT_SHARED_CACHE`, `SQLITE_OMIT_TCL_VARIABLE`, `SQLITE_OMIT_TRACE`: Disables features not supported
by moor. by drift.
- `SQLITE_USE_ALLOCA`: Allocate temporary memory on the stack - `SQLITE_USE_ALLOCA`: Allocate temporary memory on the stack
- `SQLITE_UNTESTABLE`: Remove util functions that are only required to test sqlite3 - `SQLITE_UNTESTABLE`: Remove util functions that are only required to test sqlite3
- `SQLITE_HAVE_ISNAN`: Use the `isnan` function from the system instead of the one shipped with sqlite3. - `SQLITE_HAVE_ISNAN`: Use the `isnan` function from the system instead of the one shipped with sqlite3.
@ -125,9 +127,9 @@ moor. Important options are marked in bold.
For more details on sqlite compile options, see [their documentation](https://www.sqlite.org/compile.html). For more details on sqlite compile options, see [their documentation](https://www.sqlite.org/compile.html).
## Moor-only functions ## Drift-only functions {#moor-only-functions}
`moor_ffi` includes additional sql functions not available in standard sqlite: The `NativeDatabase` includes additional sql functions not available in standard sqlite:
- `pow(base, exponent)` and `power(base, exponent)`: This function takes two numerical arguments and returns `base` raised to the power of `exponent`. - `pow(base, exponent)` and `power(base, exponent)`: This function takes two numerical arguments and returns `base` raised to the power of `exponent`.
If `base` or `exponent` aren't numerical values or null, this function will return `null`. This function behaves exactly like `pow` in `dart:math`. If `base` or `exponent` aren't numerical values or null, this function will return `null`. This function behaves exactly like `pow` in `dart:math`.
@ -140,14 +142,14 @@ For more details on sqlite compile options, see [their documentation](https://ww
Note that `NaN`, `-infinity` or `+infinity` are represented as `NULL` in sql. Note that `NaN`, `-infinity` or `+infinity` are represented as `NULL` in sql.
When enabling the `moor_ffi` module in your [build options]({{ "../Advanced Features/builder_options.md#available-extensions" | pageUrl }}), When enabling the `moor_ffi` module in your [build options]({{ "../Advanced Features/builder_options.md#available-extensions" | pageUrl }}),
the generator will allow you to use those functions in moor files or compiled queries. the generator will allow you to use those functions in drift files or compiled queries.
To use those methods from Dart, you need to import `package:moor/extensions/moor_ffi.dart`. To use those methods from Dart, you need to import `package:drift/extensions/native.dart`.
You can then use the additional functions like this: You can then use the additional functions like this:
```dart ```dart
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
// those methods are hidden behind another import because they're only available on moor_ffi // those methods are hidden behind another import because they're only available with a NativeDatabase
import 'package:moor/extensions/moor_ffi.dart'; import 'package:drift/extensions/native.dart';
class Coordinates extends Table { class Coordinates extends Table {
RealColumn get x => real()(); RealColumn get x => real()();

View File

@ -1,28 +1,32 @@
--- ---
data: data:
title: Web title: Web
description: Experimental support for moor and webapps. description: Experimental support for drift and webapps.
template: layouts/docs/single template: layouts/docs/single
path: web/ path: web/
--- ---
Starting from moor `1.6`, you can experimentally use moor in Dart webapps. Moor web supports You can experimentally use drift in Dart webapps. Drift web supports
Flutter Web, AngularDart, plain `dart:html` or any other web framework. Flutter Web, AngularDart, plain `dart:html` or any other web framework.
## Getting started ## Getting started
Instead of depending on `moor_flutter` in your pubspec, you need to depend on on `moor` directly. Apart from that, you can
follow the [getting started guide]({{ '../Getting started/index.md' | pageUrl }}).
Also, instead of using a `FlutterQueryExecutor` in your database classes, you can use a `WebDatabase` executor:
```dart
import 'package:moor/moor_web.dart';
@UseMoor(tables: [Todos, Categories]) From a perspective of the Dart code used, drift on the web is similar to drift on other platforms.
You can follow the [getting started guide]({{ '../Getting started/index.md' | pageUrl }}) for general
information on using drift.
Instead of using a `NativeDatabase` in your database classes, you can use a `WebDatabase` executor:
```dart
import 'package:drift/web.dart';
@DriftDatabase(tables: [Todos, Categories])
class MyDatabase extends _$MyDatabase { class MyDatabase extends _$MyDatabase {
// here, "app" is the name of the database - you can choose any name you want // here, "app" is the name of the database - you can choose any name you want
MyDatabase() : super(WebDatabase('app')); MyDatabase() : super(WebDatabase('app'));
``` ```
Moor web is built on top of the [sql.js](https://github.com/sql-js/sql.js/) library, which you need to include: Drift web is built on top of the [sql.js](https://github.com/sql-js/sql.js/) library, which you need to include:
```html ```html
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
@ -48,15 +52,15 @@ won't accept it otherwise.
## Sharing code between native apps and web ## Sharing code between native apps and web
If you want to share your database code between native applications and webapps, just import the If you want to share your database code between native applications and webapps, just import the
basic `moor` library into your database file. basic `drift/drift.dart` library into your database file.
And instead of passing a `VmDatabase` or `WebDatabase` to the `super` constructor, make the And instead of passing a `NativeDatabase` or `WebDatabase` to the `super` constructor, make the
`QueryExecutor` customizable: `QueryExecutor` customizable:
```dart ```dart
// don't import moor_web.dart or moor_flutter/moor_flutter.dart in shared code // don't import drift/web.dart or drift/native.dart in shared code
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
@UseMoor(/* ... */) @DriftDatabase(/* ... */)
class SharedDatabase extends _$MyDatabase { class SharedDatabase extends _$MyDatabase {
SharedDatabase(QueryExecutor e): super(e); SharedDatabase(QueryExecutor e): super(e);
} }
@ -66,13 +70,13 @@ In native Flutter apps, you can create an instance of your database with
```dart ```dart
// native.dart // native.dart
import 'package:moor/ffi.dart'; import 'package:drift/native.dart';
SharedDatabase constructDb() { SharedDatabase constructDb() {
final db = LazyDatabase(() async { final db = LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory(); final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite')); final file = File(p.join(dbFolder.path, 'db.sqlite'));
return VmDatabase(file); return NativeDatabase(file);
}); });
return SharedDatabase(db); return SharedDatabase(db);
} }
@ -82,7 +86,7 @@ On the web, you can use
```dart ```dart
// web.dart // web.dart
import 'package:moor/moor_web.dart'; import 'package:drift/web.dart';
SharedDatabase constructDb() { SharedDatabase constructDb() {
return SharedDatabase(WebDatabase('db')); return SharedDatabase(WebDatabase('db'));
@ -110,9 +114,9 @@ export 'unsupported.dart'
A ready example of this construct can also be found [here](https://github.com/rodydavis/moor_shared/blob/master/lib/src/database/database/unsupported.dart). A ready example of this construct can also be found [here](https://github.com/rodydavis/moor_shared/blob/master/lib/src/database/database/unsupported.dart).
## Debugging ## Debugging
You can see all queries sent from moor to the underlying database engine by enabling the `logStatements` You can see all queries sent from drift to the underlying database engine by enabling the `logStatements`
parameter on the `WebDatabase` - they will appear in the console. parameter on the `WebDatabase` - they will appear in the console.
When you have assertions enabled (e.g. in debug mode), moor will expose the underlying When you have assertions enabled (e.g. in debug mode), drift will expose the underlying
[database](https://sql.js.org/documentation/Database.html) [database](https://sql.js.org/documentation/Database.html)
object via `window.db`. If you need to quickly run a query to check the state of the database, you can use object via `window.db`. If you need to quickly run a query to check the state of the database, you can use
`db.exec(sql)`. `db.exec(sql)`.
@ -129,19 +133,19 @@ performant, since we don't have to encode binary blobs as strings.
To use this implementation on browsers that support it, replace `WebDatabase(name)` with: To use this implementation on browsers that support it, replace `WebDatabase(name)` with:
```dart ```dart
WebDatabase.withStorage(await MoorWebStorage.indexedDbIfSupported(name)) WebDatabase.withStorage(await DriftWebStorage.indexedDbIfSupported(name))
``` ```
Moor will automatically migrate data from local storage to `IndexedDb` when it is available. Drift will automatically migrate data from local storage to `IndexedDb` when it is available.
### Using web workers ### Using web workers
Starting from moor 4.1, you can offload the database to a background thread by using You can offload the database to a background thread by using
[Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).
Moor also supports [shared workers](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker), Drift also supports [shared workers](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker),
which allows you to seamlessly synchronize query-streams and updates across multiple tabs! which allows you to seamlessly synchronize query-streams and updates across multiple tabs!
Since web workers can't use local storage, you need to use `MoorWebStorage.indexedDb` instead of Since web workers can't use local storage, you need to use `DriftWebStorage.indexedDb` instead of
the regular implementation. the regular implementation.
The following example is meant to be used with a regular Dart web app, compiled using The following example is meant to be used with a regular Dart web app, compiled using
@ -150,23 +154,23 @@ Flutter users will have to use a different approach to compile service workers.
As long as you can compile a seperate Dart file (with a `main` function that's not your app) As long as you can compile a seperate Dart file (with a `main` function that's not your app)
into a JS file, you can use that as a worker too. into a JS file, you can use that as a worker too.
To write a web worker that will serve requests for moor, create a file called `worker.dart` in To write a web worker that will serve requests for drift, create a file called `worker.dart` in
the `web/` folder of your app. It could have the following content: the `web/` folder of your app. It could have the following content:
```dart ```dart
import 'dart:html'; import 'dart:html';
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
import 'package:moor/moor_web.dart'; import 'package:drift/web.dart';
import 'package:moor/remote.dart'; import 'package:drift/remote.dart';
void main() { void main() {
final self = SharedWorkerGlobalScope.instance; final self = SharedWorkerGlobalScope.instance;
self.importScripts('sql-wasm.js'); self.importScripts('sql-wasm.js');
final db = WebDatabase.withStorage(MoorWebStorage.indexedDb('worker', final db = WebDatabase.withStorage(DriftWebStorage.indexedDb('worker',
migrateFromLocalStorage: false, inWebWorker: true)); migrateFromLocalStorage: false, inWebWorker: true));
final server = MoorServer(DatabaseConnection.fromExecutor(db)); final server = DriftServer(DatabaseConnection.fromExecutor(db));
self.onConnect.listen((event) { self.onConnect.listen((event) {
final msg = event as MessageEvent; final msg = event as MessageEvent;
@ -175,16 +179,16 @@ void main() {
} }
``` ```
For more information on this api, see the [remote API](https://pub.dev/documentation/moor/latest/remote/remote-library.html). For more information on this api, see the [remote API](https://pub.dev/documentation/drift/latest/remote/remote-library.html).
Connecting to that worker is very simple with moor's web and remote apis. In your regular app code (outside of the worker), Connecting to that worker is very simple with drift's web and remote apis. In your regular app code (outside of the worker),
you can connect like this: you can connect like this:
```dart ```dart
import 'dart:html'; import 'dart:html';
import 'package:moor/remote.dart'; import 'package:drift/remote.dart';
import 'package:moor/moor_web.dart'; import 'package:drift/web.dart';
import 'package:web_worker_example/database.dart'; import 'package:web_worker_example/database.dart';
DatabaseConnection connectToWorker() { DatabaseConnection connectToWorker() {
@ -199,4 +203,4 @@ For more information on the `DatabaseConnection` class, see the documentation on
[isolates]({{ "../Advanced Features/isolates.md" | pageUrl }}). [isolates]({{ "../Advanced Features/isolates.md" | pageUrl }}).
A small, but working example is available under [extras/web_worker_example](https://github.com/simolus3/moor/tree/develop/extras/web_worker_example) A small, but working example is available under [extras/web_worker_example](https://github.com/simolus3/moor/tree/develop/extras/web_worker_example)
in the moor repository. in the drift repository.

View File

@ -2,33 +2,27 @@
data: data:
title: "Custom queries" title: "Custom queries"
weight: 10 weight: 10
description: Let moor generate Dart from your SQL statements description: Let drift generate Dart from your SQL statements
aliases: aliases:
- /queries/custom - /queries/custom
template: layouts/docs/single template: layouts/docs/single
--- ---
{% block "blocks/alert" title="Moor files!" color="warning" %} Although drift includes a fluent api that can be used to model most statements, advanced
With moor 2.0, we moved the new `.moor` files out of preview and added some powerful features to them.
They are easier to use than the approaches described here. While these features will continue to
be supported, moor files will get better tooling support in the future and we recommend to
migrate. See [their api]({{ "moor_files.md" | pageUrl }}) for details.
{% endblock %}
Although moor includes a fluent api that can be used to model most statements, advanced
features like `WITH` clauses or subqueries aren't supported yet. You can features like `WITH` clauses or subqueries aren't supported yet. You can
use these features with custom statements. You don't have to miss out on other benefits use these features with custom statements. You don't have to miss out on other benefits
moor brings, though: Moor helps you parse the result rows and custom queries also drift brings, though: Drift helps you parse the result rows and custom queries also
support auto-updating streams. support auto-updating streams.
## Statements with a generated api ## Statements with a generated api
Starting from version `1.5`, you can instruct moor to automatically generate a typesafe
You can instruct drift to automatically generate a typesafe
API for your select, update and delete statements. Of course, you can still write custom API for your select, update and delete statements. Of course, you can still write custom
sql manually. See the sections below for details. sql manually. See the sections below for details.
To use this feature, all you need to is define your queries in your `UseMoor` annotation: To use this feature, all you need to is define your queries in your `DriftDatabase` annotation:
```dart ```dart
@UseMoor( @DriftDatabase(
tables: [Todos, Categories], tables: [Todos, Categories],
queries: { queries: {
'categoriesWithCount': 'categoriesWithCount':
@ -39,13 +33,13 @@ class MyDatabase extends _$MyDatabase {
// rest of class stays the same // rest of class stays the same
} }
``` ```
After running the build step again, moor will have written the `CategoriesWithCountResult` class for you - After running the build step again, drift will have written the `CategoriesWithCountResult` class for you -
it will hold the result of your query. Also, the `_$MyDatabase` class from which you inherit will have the it will hold the result of your query. Also, the `_$MyDatabase` class from which you inherit will have the
methods `categoriesWithCount` (which runs the query once) and `watchCategoriesWithCount` (which returns methods `categoriesWithCount` (which runs the query once) and `watchCategoriesWithCount` (which returns
an auto-updating stream). an auto-updating stream).
Queries can have parameters in them by using the `?` or `:name` syntax. When your queries contains parameters, Queries can have parameters in them by using the `?` or `:name` syntax. When your queries contains parameters,
moor will figure out an appropriate type for them and include them in the generated methods. For instance, drift will figure out an appropriate type for them and include them in the generated methods. For instance,
`'categoryById': 'SELECT * FROM categories WHERE id = :id'` will generate the method `categoryById(int id)`. `'categoryById': 'SELECT * FROM categories WHERE id = :id'` will generate the method `categoryById(int id)`.
{% block "blocks/alert" title="On table names" color="info" %} {% block "blocks/alert" title="On table names" color="info" %}
@ -53,7 +47,7 @@ To use this feature, it's helpful to know how Dart tables are named in sql. For
override `tableName`, the name in sql will be the `snake_case` of the class name. So a Dart table override `tableName`, the name in sql will be the `snake_case` of the class name. So a Dart table
called `Categories` will be named `categories`, a table called `UserAddressInformation` would be called `Categories` will be named `categories`, a table called `UserAddressInformation` would be
called `user_address_information`. The same rule applies to column getters without an explicit name. called `user_address_information`. The same rule applies to column getters without an explicit name.
Tables and columns declared in [Moor files]({{ "moor_files.md" | pageUrl }}) will always have the Tables and columns declared in [Drift files]({{ "moor_files.md" | pageUrl }}) will always have the
name you specified. name you specified.
{% endblock %} {% endblock %}
@ -86,7 +80,7 @@ Stream<List<CategoryWithCount>> categoriesWithCount() {
readsFrom: {todos, categories}, // used for the stream: the stream will update when either table changes readsFrom: {todos, categories}, // used for the stream: the stream will update when either table changes
).watch().map((rows) { ).watch().map((rows) {
// we get list of rows here. We just have to turn the raw data from the row into a // we get list of rows here. We just have to turn the raw data from the row into a
// CategoryWithCount. As we defined the Category table earlier, moor knows how to parse // CategoryWithCount. As we defined the Category table earlier, drift knows how to parse
// a category. The only thing left to do manually is extracting the amount // a category. The only thing left to do manually is extracting the amount
return rows return rows
.map((row) => CategoryWithCount(Category.fromData(row.data, this), row.readInt('amount'))) .map((row) => CategoryWithCount(Category.fromData(row.data, this), row.readInt('amount')))
@ -95,7 +89,7 @@ Stream<List<CategoryWithCount>> categoriesWithCount() {
} }
``` ```
For custom selects, you should use the `readsFrom` parameter to specify from which tables the query is For custom selects, you should use the `readsFrom` parameter to specify from which tables the query is
reading. When using a `Stream`, moor will be able to know after which updates the stream should emit reading. When using a `Stream`, drift will be able to know after which updates the stream should emit
items. items.
You can also bind SQL variables by using question-mark placeholders and the `variables` parameter: You can also bind SQL variables by using question-mark placeholders and the `variables` parameter:
@ -115,6 +109,6 @@ Of course, you can also use indexed variables (like `?12`) - for more informatio
## Custom update statements ## Custom update statements
For update and delete statements, you can use `customUpdate`. Just like `customSelect`, that method For update and delete statements, you can use `customUpdate`. Just like `customSelect`, that method
also takes a sql statement and optional variables. You can also tell moor which tables will be also takes a sql statement and optional variables. You can also tell drift which tables will be
affected by your query using the optional `updates` parameter. That will help with other select affected by your query using the optional `updates` parameter. That will help with other select
streams, which will then update automatically. streams, which will then update automatically.

View File

@ -7,30 +7,30 @@ template: layouts/docs/single
--- ---
_Note_: Since `moor_flutter` uses the sqlite version shipped on the device, these extensions might not _Note_: Since `moor_flutter` uses the sqlite version shipped on the device, these extensions might not
be available on all devices. When using these extensions, using `moor_ffi` is strongly recommended. be available on all devices. When using these extensions, using a `NativeDatabase` is strongly recommended.
This enables the extensions listed here on all Android devices and on iOS 11 and later. This enables the extensions listed here on all Android and iOS devices.
## json1 ## json1
To enable the json1 extension in moor files and compiled queries, modify your To enable the json1 extension in drift files and compiled queries, modify your
[build options]({{ "../Advanced Features/builder_options.md" | pageUrl }}) to include [build options]({{ "../Advanced Features/builder_options.md" | pageUrl }}) to include
`json1` in the `sqlite_module` section. `json1` in the `sqlite_module` section.
The sqlite extension doesn't require any special tables and works on all text columns. In moor The sqlite extension doesn't require any special tables and works on all text columns. In drift
files and compiled queries, all `json` functions are available after enabling the extension. files and compiled queries, all `json` functions are available after enabling the extension.
Since the json extension is optional, enabling it in Dart requires a special import, Since the json extension is optional, enabling it in Dart requires a special import,
`package:moor/extensions/json1.dart`. An example that uses json functions in Dart is shown below: `package:drift/extensions/json1.dart`. An example that uses json functions in Dart is shown below:
```dart ```dart
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
import 'package:moor/extensions/json1.dart'; import 'package:drift/extensions/json1.dart';
class Contacts extends Table { class Contacts extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
TextColumn get data => text()(); TextColumn get data => text()();
} }
@UseMoor(tables: [Contacts]) @DriftDatabase(tables: [Contacts])
class Database extends _$Database { class Database extends _$Database {
// constructor and schemaVersion omitted for brevity // constructor and schemaVersion omitted for brevity
@ -51,11 +51,11 @@ You can learn more about the json1 extension on [sqlite.org](https://www.sqlite.
## fts5 ## fts5
The fts5 extension provides full-text search capabilities in sqlite tables. The fts5 extension provides full-text search capabilities in sqlite tables.
To enable the fts5 extension in moor files and compiled queries, modify the To enable the fts5 extension in drift files and compiled queries, modify the
[build options]({{ "../Advanced Features/builder_options.md" | pageUrl }}) to include [build options]({{ "../Advanced Features/builder_options.md" | pageUrl }}) to include
`fts5` in the `sqlite_module` section. `fts5` in the `sqlite_module` section.
Just like you'd expect when using sqlite, you can create a fts5 table in a moor file Just like you'd expect when using sqlite, you can create a fts5 table in a drift file
by using a `CREATE VIRTUAL TABLE` statement. by using a `CREATE VIRTUAL TABLE` statement.
```sql ```sql
CREATE VIRTUAL TABLE email USING fts5(sender, title, body); CREATE VIRTUAL TABLE email USING fts5(sender, title, body);
@ -69,4 +69,4 @@ emailsWithFts5: SELECT * FROM email WHERE email MATCH 'fts5' ORDER BY rank;
The `bm25`, `highlight` and `snippet` functions from fts5 can also be used in custom queries. The `bm25`, `highlight` and `snippet` functions from fts5 can also be used in custom queries.
It's not possible to declare fts5 tables, or queries on fts5 tables, in Dart. It's not possible to declare fts5 tables, or queries on fts5 tables, in Dart.
You can learn more about the fts5 extension on [sqlite.org](https://www.sqlite.org/fts5.html). You can learn more about the fts5 extension on [sqlite.org](https://www.sqlite.org/fts5.html).

View File

@ -2,11 +2,11 @@
data: data:
title: "Using SQL" title: "Using SQL"
weight: 30 weight: 30
description: Write typesafe sql with moor description: Write typesafe sql with drift
template: layouts/docs/list template: layouts/docs/list
--- ---
Moor let's you express a variety of queries in pure Dart. However, you don't have to miss out Drift let's you express a variety of queries in pure Dart. However, you don't have to miss out
on its features when you need more complex queries or simply prefer sql. Moor has a builtin on its features when you need more complex queries or simply prefer sql. Drift has a builtin
sql parser and analyzer, so it can generate a typesafe API for sql statements you write. sql parser and analyzer, so it can generate a typesafe API for sql statements you write.
It can also warn about errors in your sql at build time. It can also warn about errors in your sql at build time.

View File

@ -1,36 +1,37 @@
--- ---
data: data:
title: "Moor files" title: "Drift files"
weight: 1 weight: 1
description: Learn everything about the new `.moor` files which can contain tables and queries description: Learn everything about the new `.drift` files which can contain tables and queries
aliases: aliases:
- /docs/using-sql/custom_tables/ # Redirect from outdated "custom tables" page which has been deleted - /docs/using-sql/custom_tables/ # Redirect from outdated "custom tables" page which has been deleted
template: layouts/docs/single template: layouts/docs/single
--- ---
Moor files are a new feature that lets you write all your database code in SQL - moor will generate typesafe APIs for them. Drift files are a new feature that lets you write all your database code in SQL - drift will generate typesafe APIs for them.
## Getting started ## Getting started
To use this feature, lets create two files: `database.dart` and `tables.moor`. The Dart file only contains the minimum code To use this feature, lets create two files: `database.dart` and `tables.drift`. The Dart file only contains the minimum code
to setup the database: to setup the database:
```dart ```dart
import 'package:moor_flutter/moor_flutter.dart'; import 'package:drift/drift.dart';
import 'package:drift/native.dart';
part 'database.g.dart'; part 'database.g.dart';
@UseMoor( @DriftDatabase(
include: {'tables.moor'}, include: {'tables.drift'},
) )
class MoorDb extends _$MoorDb { class MyDb extends _$MyDb {
MoorDb() : super(FlutterQueryExecutor.inDatabaseFolder(path: 'app.db')); MyDb() : super(NativeDatabase.memory());
@override @override
int get schemaVersion => 1; int get schemaVersion => 1;
} }
``` ```
We can now declare tables and queries in the moor file: We can now declare tables and queries in the drift file:
```sql ```sql
CREATE TABLE todos ( CREATE TABLE todos (
id INT NOT NULL PRIMARY KEY AUTOINCREMENT, id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
@ -44,7 +45,7 @@ CREATE TABLE categories (
description TEXT NOT NULL description TEXT NOT NULL
) AS Category; -- the AS xyz after the table defines the data class name ) AS Category; -- the AS xyz after the table defines the data class name
-- You can also create an index or triggers with moor files -- You can also create an index or triggers with drift files
CREATE INDEX categories_description ON categories(description); CREATE INDEX categories_description ON categories(description);
-- we can put named sql queries in here as well: -- we can put named sql queries in here as well:
@ -54,13 +55,13 @@ allTodos: SELECT * FROM todos;
``` ```
After running the build runner with `flutter pub run build_runner build`, After running the build runner with `flutter pub run build_runner build`,
moor will write the `database.g.dart` drift will write the `database.g.dart`
file which contains the `_$MoorDb` superclass. Let's take a look at file which contains the `_$MyDb` superclass. Let's take a look at
what we got: what we got:
- Generated data classes (`Todo` and `Category`), and companion versions - Generated data classes (`Todo` and `Category`), and companion versions
for inserts (see [Dart Interop](#dart-interop) for info). By default, for inserts (see [Dart Interop](#dart-interop) for info). By default,
moor strips a trailing "s" from the table name for the class. That's why drift strips a trailing "s" from the table name for the class. That's why
we used `AS Category` on the second table - it would have been called we used `AS Category` on the second table - it would have been called
`Categorie` otherwise. `Categorie` otherwise.
- Methods to run the queries: - Methods to run the queries:
@ -81,7 +82,7 @@ Inside of named queries, you can use variables just like you would expect with
sql. We support regular variables (`?`), explicitly indexed variables (`?123`) sql. We support regular variables (`?`), explicitly indexed variables (`?123`)
and colon-named variables (`:id`). We don't support variables declared and colon-named variables (`:id`). We don't support variables declared
with @ or $. The compiler will attempt to infer the variable's type by with @ or $. The compiler will attempt to infer the variable's type by
looking at its context. This lets moor generate typesafe apis for your looking at its context. This lets drift generate typesafe apis for your
queries, the variables will be written as parameters to your method. queries, the variables will be written as parameters to your method.
When it's ambiguous, the analyzer might be unable to resolve the type of When it's ambiguous, the analyzer might be unable to resolve the type of
@ -110,20 +111,20 @@ enabled. Further, non-nullable variables are required by default.
### Arrays ### Arrays
If you want to check whether a value is in an array of values, you can If you want to check whether a value is in an array of values, you can
use `IN ?`. That's not valid sql, but moor will desugar that at runtime. So, for this query: use `IN ?`. That's not valid sql, but drift will desugar that at runtime. So, for this query:
```sql ```sql
entriesWithId: SELECT * FROM todos WHERE id IN ?; entriesWithId: SELECT * FROM todos WHERE id IN ?;
``` ```
Moor will generate a `Selectable<Todo> entriesWithId(List<int> ids)` method. Drift will generate a `Selectable<Todo> entriesWithId(List<int> ids)` method.
Running `entriesWithId([1,2])` would generate `SELECT * ... id IN (?1, ?2)` and Running `entriesWithId([1,2])` would generate `SELECT * ... id IN (?1, ?2)` and
bind the arguments accordingly. To make sure this works as expected, moor bind the arguments accordingly. To make sure this works as expected, drift
imposes two small restrictions: imposes two small restrictions:
1. __No explicit variables__: `WHERE id IN ?2` will be rejected at build time. 1. __No explicit variables__: `WHERE id IN ?2` will be rejected at build time.
As the variable is expanded, giving it a single index is invalid. As the variable is expanded, giving it a single index is invalid.
2. __No higher explicit index after a variable__: Running 2. __No higher explicit index after a variable__: Running
`WHERE id IN ? OR title = ?2` will also be rejected. Expanding the `WHERE id IN ? OR title = ?2` will also be rejected. Expanding the
variable can clash with the explicit index, which is why moor forbids variable can clash with the explicit index, which is why drift forbids
it. Of course, `id IN ? OR title = ?` will work as expected. it. Of course, `id IN ? OR title = ?` will work as expected.
## Supported column types ## Supported column types
@ -136,20 +137,20 @@ Additionally, columns that have the type name `BOOLEAN` or `DATETIME` will have
written as an `INTEGER` column when the table gets created. written as an `INTEGER` column when the table gets created.
## Imports ## Imports
You can put import statements at the top of a `moor` file: You can put import statements at the top of a `drift` file:
```sql ```sql
import 'other.moor'; -- single quotes are required for imports import 'other.drift'; -- single quotes are required for imports
``` ```
All tables reachable from the other file will then also be visible in All tables reachable from the other file will then also be visible in
the current file and to the database that `includes` it. If you want the current file and to the database that `includes` it. If you want
to declare queries on tables that were defined in another moor to declare queries on tables that were defined in another drift
file, you also need to import that file for the tables to be file, you also need to import that file for the tables to be
visible. visible.
Note that imports in moor file are always transitive, so in the above example Note that imports in drift file are always transitive, so in the above example
you would have all imports declared in `other.moor` available as well. you would have all imports declared in `other.drift` available as well.
There is no `export` mechanism for moor files. There is no `export` mechanism for drift files.
Importing Dart files into a moor file will also work - then, Importing Dart files into a drift file will also work - then,
all the tables declared via Dart tables can be used inside queries. all the tables declared via Dart tables can be used inside queries.
We support both relative imports and the `package:` imports you We support both relative imports and the `package:` imports you
know from Dart. know from Dart.
@ -179,7 +180,7 @@ routesWithPoints: SELECT r.id, r.name, f.*, t.* FROM routes r
INNER JOIN coordinates t ON t.id = r.to; INNER JOIN coordinates t ON t.id = r.to;
``` ```
To match the returned column names while avoiding name clashes in Dart, moor To match the returned column names while avoiding name clashes in Dart, drift
will generate a class having an `id`, `name`, `id1`, `lat`, `long`, `lat1` and will generate a class having an `id`, `name`, `id1`, `lat`, `long`, `lat1` and
a `long1` field. a `long1` field.
Of course, that's not helpful at all - was `lat1` coming from `from` or `to` Of course, that's not helpful at all - was `lat1` coming from `from` or `to`
@ -191,9 +192,9 @@ routesWithNestedPoints: SELECT r.id, r.name, f.**, t.** FROM routes r
INNER JOIN coordinates t ON t.id = r.to; INNER JOIN coordinates t ON t.id = r.to;
``` ```
As you can see, we can nest a result simply by using the moor-specific As you can see, we can nest a result simply by using the drift-specific
`table.**` syntax. `table.**` syntax.
For this query, moor will generate the following class: For this query, drift will generate the following class:
```dart ```dart
class RoutesWithNestedPointsResult { class RoutesWithNestedPointsResult {
final int id; final int id;
@ -215,21 +216,21 @@ At the moment, there are some limitations with this approach:
valued functions. valued functions.
You might be wondering how `**` works under the hood, since it's not valid sql. You might be wondering how `**` works under the hood, since it's not valid sql.
At build time, moor's generator will transform `**` into a list of all columns At build time, drift's generator will transform `**` into a list of all columns
from the referred table. For instance, if we had a table `foo` with an `id INT` from the referred table. For instance, if we had a table `foo` with an `id INT`
and a `bar TEXT` column. Then, `SELECT foo.** FROM foo` might be desugared to and a `bar TEXT` column. Then, `SELECT foo.** FROM foo` might be desugared to
`SELECT foo.id AS "nested_0.id", foo.bar AS "nested_0".bar FROM foo`. `SELECT foo.id AS "nested_0.id", foo.bar AS "nested_0".bar FROM foo`.
## Dart interop ## Dart interop
Moor files work perfectly together with moor's existing Dart API: Drift files work perfectly together with drift's existing Dart API:
- you can write Dart queries for tables declared in a moor file: - you can write Dart queries for tables declared in a drift file:
```dart ```dart
Future<void> insert(TodosCompanion companion) async { Future<void> insert(TodosCompanion companion) async {
await into(todos).insert(companion); await into(todos).insert(companion);
} }
``` ```
- by importing Dart files into a moor file, you can write sql queries for - by importing Dart files into a drift file, you can write sql queries for
tables declared in Dart. tables declared in Dart.
- generated methods for queries can be used in transactions, they work - generated methods for queries can be used in transactions, they work
together with auto-updating queries, etc. together with auto-updating queries, etc.
@ -247,7 +248,7 @@ $-variable in a query:
```sql ```sql
_filterTodos: SELECT * FROM todos WHERE $predicate; _filterTodos: SELECT * FROM todos WHERE $predicate;
``` ```
Moor will generate a `Selectable<Todo> _filterTodos(Expression<bool> predicate)` Drift will generate a `Selectable<Todo> _filterTodos(Expression<bool> predicate)`
method that can be used to construct dynamic filters at runtime: method that can be used to construct dynamic filters at runtime:
```dart ```dart
Stream<List<Todo>> watchInCategory(int category) { Stream<List<Todo>> watchInCategory(int category) {
@ -286,7 +287,7 @@ WHERE $predicate
``` ```
If you want to filter for the `start` point in Dart, you have to use If you want to filter for the `start` point in Dart, you have to use
an explicit [`alias`](https://pub.dev/documentation/moor/latest/moor/DatabaseConnectionUser/alias.html): an explicit [`alias`](https://pub.dev/documentation/drift/latest/drift/DatabaseConnectionUser/alias.html):
```dart ```dart
Future<List<Route>> routesByStart(int startPointId) { Future<List<Route>> routesByStart(int startPointId) {
@ -295,9 +296,9 @@ Future<List<Route>> routesByStart(int startPointId) {
} }
``` ```
Since moor 4.4, you can enable the `scoped_dart_components` [build option]({{ '../Advanced Features/builder_options.md' | pageUrl }}) You can enable the `scoped_dart_components` [build option]({{ '../Advanced Features/builder_options.md' | pageUrl }})
and let the generator help you here. and let the generator help you here.
When the option is enabled, moor would generate a `Expression<bool> Function(Routes r, Points start, Points end)` as a parameter, which When the option is enabled, drift would generate a `Expression<bool> Function(Routes r, Points start, Points end)` as a parameter, which
makes this a lot easier: makes this a lot easier:
```dart ```dart
@ -310,7 +311,7 @@ Future<List<Route>> routesByStart(int startPointId) {
### Type converters ### Type converters
You can import and use [type converters]({{ "../Advanced Features/type_converters.md" | pageUrl }}) You can import and use [type converters]({{ "../Advanced Features/type_converters.md" | pageUrl }})
written in Dart in a moor file. Importing a Dart file works with a regular `import` statement. written in Dart in a drift file. Importing a Dart file works with a regular `import` statement.
To apply a type converter on a column definition, you can use the `MAPPED BY` column constraints: To apply a type converter on a column definition, you can use the `MAPPED BY` column constraints:
```sql ```sql
CREATE TABLE users ( CREATE TABLE users (
@ -321,7 +322,7 @@ CREATE TABLE users (
``` ```
More details on type converts in moor files are available More details on type converts in drift files are available
[here]({{ "../Advanced Features/type_converters.md#using-converters-in-moor" | pageUrl }}). [here]({{ "../Advanced Features/type_converters.md#using-converters-in-moor" | pageUrl }}).
When using type converters, we recommend the [`apply_converters_on_variables`]({{ "../Advanced Features/builder_options.md" | pageUrl }}) When using type converters, we recommend the [`apply_converters_on_variables`]({{ "../Advanced Features/builder_options.md" | pageUrl }})
@ -331,8 +332,7 @@ With that option, the variable will be inferred to `Preferences` instead of `Str
### Existing row classes ### Existing row classes
Starting from moor 4.3, you can use custom row classes instead of having moor generate one for you. You can use custom row classes instead of having drift generate one for you.
For instance, let's say you had a Dart class defined as For instance, let's say you had a Dart class defined as
```dart ```dart
@ -344,7 +344,7 @@ class User {
} }
``` ```
Then, you can instruct moor to use that class as a row class as follows: Then, you can instruct drift to use that class as a row class as follows:
```sql ```sql
import 'row_class.dart'; --import for where the row class is defined import 'row_class.dart'; --import for where the row class is defined
@ -352,7 +352,7 @@ import 'row_class.dart'; --import for where the row class is defined
CREATE TABLE users ( CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY, id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
) WITH User; -- This tells moor to use the existing Dart class ) WITH User; -- This tells drift to use the existing Dart class
``` ```
When using custom row classes defined in another Dart file, you also need to import that file into the file where you define When using custom row classes defined in another Dart file, you also need to import that file into the file where you define
@ -361,7 +361,7 @@ For more general information on this feature, please check [this page]({{ '../Ad
## Result class names ## Result class names
For most queries, moor generates a new class to hold the result. This class is named after the query For most queries, drift generates a new class to hold the result. This class is named after the query
with a `Result` suffix, e.g. a `myQuery` query would get a `MyQueryResult` class. with a `Result` suffix, e.g. a `myQuery` query would get a `MyQueryResult` class.
You can change the name of a result class like this: You can change the name of a result class like this:
@ -371,25 +371,25 @@ routesWithNestedPoints AS FullRoute: SELECT r.id, -- ...
``` ```
This way, multiple queries can also share a single result class. As long as they have an identical result set, This way, multiple queries can also share a single result class. As long as they have an identical result set,
you can assign the same custom name to them and moor will only generate one class. you can assign the same custom name to them and drift will only generate one class.
For queries that select all columns from a table and nothing more, moor won't generate a new class For queries that select all columns from a table and nothing more, drift won't generate a new class
and instead re-use the dataclass that it generates either way. and instead re-use the dataclass that it generates either way.
Similarly, for queries with only one column, moor will just return that column directly instead of Similarly, for queries with only one column, drift will just return that column directly instead of
wrapping it in a result class. wrapping it in a result class.
It's not possible to override this behavior at the moment, so you can't customize the result class It's not possible to override this behavior at the moment, so you can't customize the result class
name of a query if it has a matching table or only has one column. name of a query if it has a matching table or only has one column.
## Supported statements ## Supported statements
At the moment, the following statements can appear in a `.moor` file. At the moment, the following statements can appear in a `.drift` file.
- `import 'other.moor'`: Import all tables and queries declared in the other file - `import 'other.drift'`: Import all tables and queries declared in the other file
into the current file. into the current file.
- DDL statements: You can put `CREATE TABLE`, `CREATE VIEW`, `CREATE INDEX` and `CREATE TRIGGER` statements - DDL statements: You can put `CREATE TABLE`, `CREATE VIEW`, `CREATE INDEX` and `CREATE TRIGGER` statements
into moor files. into drift files.
- Query statements: We support `INSERT`, `SELECT`, `UPDATE` and `DELETE` statements. - Query statements: We support `INSERT`, `SELECT`, `UPDATE` and `DELETE` statements.
All imports must come before DDL statements, and those must come before named queries. All imports must come before DDL statements, and those must come before named queries.
If you need support for another statement, or if moor rejects a query you think is valid, please If you need support for another statement, or if drift rejects a query you think is valid, please
create an issue! create an issue!

View File

@ -6,7 +6,7 @@ data:
template: layouts/docs/single template: layouts/docs/single
--- ---
Moor ships with an experimental analyzer plugin that provides real-time feedback on errors, Drift ships with an experimental analyzer plugin that provides real-time feedback on errors,
hints, folding and outline. hints, folding and outline.
## Features ## Features
@ -26,27 +26,27 @@ us here.
## Setup ## Setup
To use the plugin, you need a supported editor (see below). To use the plugin, you need a supported editor (see below).
First, tell the Dart analysis server to run the moor plugin. Create a file called First, tell the Dart analysis server to run the drift plugin. Create a file called
`analysis_options.yaml` in your project root, next to your pubspec. It should contain `analysis_options.yaml` in your project root, next to your pubspec. It should contain
this section: this section:
```yaml ```yaml
analyzer: analyzer:
plugins: plugins:
- moor - drift
``` ```
Then, follow the steps for the IDE you want to use. Then, follow the steps for the IDE you want to use.
### Using with VS Code ### Using with VS Code
Make sure that your project depends on moor 2.0 or later. Then To use the drift analyzer plugin in VS Code, use
1. Tell Dart Code to analyze moor files. Add this to your `settings.json`: 1. Tell Dart Code to analyze drift files. Add this to your `settings.json`:
```json ```json
"dart.additionalAnalyzerFileExtensions": ["moor"] "dart.additionalAnalyzerFileExtensions": ["drift"]
``` ```
2. close and re-open your IDE so that the analysis server is restarted. The analysis server will 2. close and re-open your IDE so that the analysis server is restarted. The analysis server will
then load the moor plugin and start providing analysis results for `.moor` files. Loading the plugin then load the drift plugin and start providing analysis results for `.drift` files. Loading the plugin
can take some time (around a minute for the first time). can take some time (around a minute for the first time).
### Other IDEs ### Other IDEs
@ -54,7 +54,7 @@ Make sure that your project depends on moor 2.0 or later. Then
Unfortunately, we can't support IntelliJ and Android Studio yet. Please vote on Unfortunately, we can't support IntelliJ and Android Studio yet. Please vote on
[this issue](https://youtrack.jetbrains.com/issue/WEB-41424) to help us here! [this issue](https://youtrack.jetbrains.com/issue/WEB-41424) to help us here!
As a workaround, you can configure IntellIJ to recognize moor files as sql. Moor-only As a workaround, you can configure IntellIJ to recognize drift files as sql. Drift-only
features like imports and Dart templates will report errors, but the rest of the features like imports and Dart templates will report errors, but the rest of the
syntax works well. See [this comment](https://github.com/simolus3/moor/issues/150#issuecomment-538582696) syntax works well. See [this comment](https://github.com/simolus3/moor/issues/150#issuecomment-538582696)
on how to set this up. on how to set this up.

View File

@ -6,7 +6,7 @@ template: layouts/docs/single
--- ---
{% block "blocks/pageinfo" %} {% block "blocks/pageinfo" %}
Do you have a moor-related package you want to share? Awesome, please let me know! Do you have a drift-related package you want to share? Awesome, please let me know!
Contact me on [Gitter](https://gitter.im/moor-dart/community), [Twitter](https://twitter.com/dersimolus) Contact me on [Gitter](https://gitter.im/moor-dart/community), [Twitter](https://twitter.com/dersimolus)
or via email to oss &lt;at&gt;simonbinder&lt;dot&gt;eu. or via email to oss &lt;at&gt;simonbinder&lt;dot&gt;eu.
{% endblock %} {% endblock %}
@ -14,7 +14,7 @@ or via email to oss &lt;at&gt;simonbinder&lt;dot&gt;eu.
## Moor inspector ## Moor inspector
[Chimerapps](https://github.com/Chimerapps) wrote the `moor_inspector` package and plugin for IntelliJ [Chimerapps](https://github.com/Chimerapps) wrote the `moor_inspector` package and plugin for IntelliJ
and Android Studio. You can use it to inspect a moor database right from your IDE! and Android Studio. You can use it to inspect a moor or drift database right from your IDE!
- The [`moor_inspector` package](https://pub.dev/packages/moor_inspector) on pub - The [`moor_inspector` package](https://pub.dev/packages/moor_inspector) on pub
- The [IntelliJ plugin](https://plugins.jetbrains.com/plugin/15364-moor-inspector) - The [IntelliJ plugin](https://plugins.jetbrains.com/plugin/15364-moor-inspector)
@ -23,11 +23,11 @@ and Android Studio. You can use it to inspect a moor database right from your ID
## moor_db_viewer ## moor_db_viewer
[moor_db_viewer](https://pub.dev/packages/moor_db_viewer) by [Koen Van Looveren](https://github.com/vanlooverenkoen) [moor_db_viewer](https://pub.dev/packages/moor_db_viewer) by [Koen Van Looveren](https://github.com/vanlooverenkoen)
is a package to view a moor database in your Flutter app directly. is a package to view a moor or drift database in your Flutter app directly.
It includes a graphical user interface showing you all rows for each table. You can also filter It includes a graphical user interface showing you all rows for each table. You can also filter
rows by columns that you've added to moor. rows by columns that you've added to your tables.
## moor2csv ## moor2csv
[Dhiman Seal](https://github.com/Dhi13man) wrote a package to export moor databases as csv files. [Dhiman Seal](https://github.com/Dhi13man) wrote a package to export moor or drift databases as csv files.
The package is [on pub](https://pub.dev/packages/moor2csv). The package is [on pub](https://pub.dev/packages/moor2csv).

View File

@ -52,7 +52,7 @@ manually deleting your app's data instead of a reinstall is necessary on some de
## How do I fix lints in generated files? ## How do I fix lints in generated files?
Based on your linter settings, you might see some warnings in the `.g.dart` files generated by moor. Since lints are mainly used for Based on your linter settings, you might see some warnings in the `.g.dart` files generated by drift. Since lints are mainly used for
human-written code, we recommend to disable static analysis on generated files. For that, generate a top-level file called human-written code, we recommend to disable static analysis on generated files. For that, generate a top-level file called
`analysis_options.yaml` in your project and add this content: `analysis_options.yaml` in your project and add this content:
```yaml ```yaml
@ -66,7 +66,7 @@ You might have to restart your IDE for the changes to apply.
## How can I inspect generated SQL? ## How can I inspect generated SQL?
All database implementations (`VmDatabase`, `FlutterQueryExecutor`, ...) have a `logStatements` parameter that All database implementations (`VmDatabase`, `FlutterQueryExecutor`, ...) have a `logStatements` parameter that
you can set to `true`. When enabled, moor will print the statements it runs. you can set to `true`. When enabled, drift will print the statements it runs.
## How do I insert data on the first app start? ## How do I insert data on the first app start?
@ -101,18 +101,18 @@ QueryExecutor databaseWithDefaultAsset(File file, String asset) {
} }
``` ```
## How does moor compare to X? ## How does drift compare to X?
There are a variety of good persistence libraries for Dart and Flutter. There are a variety of good persistence libraries for Dart and Flutter.
That said, here's an incomplete (and obviously biased) list of great libraries and how moor compares to them. That said, here's an incomplete (and obviously biased) list of great libraries and how drift compares to them.
If you have experience with any of these (or other) libraries and want to share how they compare to moor, please If you have experience with any of these (or other) libraries and want to share how they compare to drift, please
feel invited to contribute to this page. feel invited to contribute to this page.
### sqflite, sqlite3 ### sqflite, sqlite3
Sqflite is a Flutter package that provides bindings to the sqlite api for both iOS and Android. It's well maintained Sqflite is a Flutter package that provides bindings to the sqlite api for both iOS and Android. It's well maintained
and has stable api. In fact, the `moor_flutter` variant is built on top of sqflite. But even though sqflite and has stable api. In fact, the `moor_flutter` variant is built on top of sqflite. But even though sqflite
has an api to construct some simple queries in Dart, moor goes a bit further by has an api to construct some simple queries in Dart, drift goes a bit further by
* Generating typesafe mapping code for your queries * Generating typesafe mapping code for your queries
* Providing auto-updating streams for queries * Providing auto-updating streams for queries
@ -121,23 +121,24 @@ has an api to construct some simple queries in Dart, moor goes a bit further by
Still, for most apps that don't need these features, sqflite can be a very fitting persistence library. Still, for most apps that don't need these features, sqflite can be a very fitting persistence library.
The same thing applies to the `sqlite3` package - `package:moor/ffi.dart` uses that library, but provides The same thing applies to the `sqlite3` package - `package:drift/native.dart` uses that library, but provides
additional services on top. additional services on top.
### sqlcool ### sqlcool
Sqlcool is a lightweight library around sqflite that makes writing queries and schema management easier, it also has Sqlcool is a lightweight library around sqflite that makes writing queries and schema management easier, it also has
auto-updating streams. It can be a decent alternative to moor if you don't want/need generated code to parse the auto-updating streams. It can be a decent alternative to drift if you don't want/need generated code to parse the
result of your queries. result of your queries.
## floor ## floor
Floor also has a lot of convenience features like auto-updating queries and schema migrations. Similar to moor, you Floor also has a lot of convenience features like auto-updating queries and schema migrations. Similar to drift, you
define the structure of your database in Dart. Then, you have write queries in sql - the mapping code if generated define the structure of your database in Dart. Then, you have write queries in sql - the mapping code if generated
by floor. Moor has a [similar feature]({{ "Using SQL/custom_queries.md" | pageUrl }}), but it can also verify that your queries are valid at compile time. Moor by floor. Drift has a [similar feature]({{ "Using SQL/custom_queries.md" | pageUrl }}), but it can also verify that your queries are valid at compile time. Drift
additionally has an api that let's you write some queries in Dart instead of sql. additionally has an api that let's you write some queries in Dart instead of sql.
A difference between these two is that Floor let's you write your own classes and generates mapping code around that. A difference between these two is that Floor let's you write your own classes and generates mapping code around that.
Moor generates most classes for you, which can make it easier to use, but makes the api less flexible in some By default, drift generates most classes for you, which can make it easier to use, but makes the api less flexible in some
instances. instances.
Drift can also be used with [custom row classes]({{ 'Advanced Features/custom_row_classes.md' | pageUrl }}) though.
## firebase ## firebase
Both the Realtime Database and Cloud Datastore are easy to use persistence libraries that can sync across devices while Both the Realtime Database and Cloud Datastore are easy to use persistence libraries that can sync across devices while
@ -149,9 +150,9 @@ Firebase is a very good option when
- your data model can be expressed as documents instead of relations - your data model can be expressed as documents instead of relations
- you don't have your own backend, but still need to synchronize data - you don't have your own backend, but still need to synchronize data
## Can I view a moor database? ## Can I view a drift database?
Yes! Moor stores its data in a sqlite3 database file that can be extracted from the device and inspected locally. Yes! Drift stores its data in a sqlite3 database file that can be extracted from the device and inspected locally.
To inspect a database on a device directly, you can use the [`moor_db_viewer`](https://pub.dev/packages/moor_db_viewer) To inspect a database on a device directly, you can use the [`moor_db_viewer`](https://pub.dev/packages/moor_db_viewer)
package by Koen Van Looveren. package by Koen Van Looveren.

View File

@ -1,29 +1,29 @@
--- ---
data: data:
title: "Documentation & Guides" title: "Documentation & Guides"
description: Welcome to moor's documentation. This site shows you what moor can do and how to use it. description: Welcome to drift's documentation. This site shows you what drift can do and how to use it.
template: layouts/docs/list template: layouts/docs/list
--- ---
## Welcome to moor ## Welcome to drift
Moor is a reactive persistence library for Dart and Flutter applications. It's built on top Drift is a reactive persistence library for Dart and Flutter applications. It's built on top
of database libraries like [sqflite](https://pub.dev/packages/sqflite) or [sql.js](https://github.com/sql-js/sql.js/) of database libraries like [sqflite](https://pub.dev/packages/sqflite) or [sql.js](https://github.com/sql-js/sql.js/)
and provides additional features, like: and provides additional features, like:
- __Type safety__: Instead of writing sql queries manually and parsing the `List<Map<String, dynamic>>` that they - __Type safety__: Instead of writing sql queries manually and parsing the `List<Map<String, dynamic>>` that they
return, moor turns rows into objects of your choice. return, drift turns rows into objects of your choice.
- __Stream queries__: Moor let's you "watch" your queries with zero additional effort. Any query can be turned into - __Stream queries__: Drift let's you "watch" your queries with zero additional effort. Any query can be turned into
an auto-updating stream that emits new items when the underlying data changes. an auto-updating stream that emits new items when the underlying data changes.
- __Fluent queries__: Moor generates a Dart api that you can use to write queries and automatically get their results. - __Fluent queries__: Drift generates a Dart api that you can use to write queries and automatically get their results.
Keep an updated list of all users with `select(users).watch()`. That's it! No sql to write, no rows to parse. Keep an updated list of all users with `select(users).watch()`. That's it! No sql to write, no rows to parse.
- __Typesafe sql__: If you prefer to write sql, that's fine! Moor has an sql parser and analyzer built in. It can parse - __Typesafe sql__: If you prefer to write sql, that's fine! Drift has an sql parser and analyzer built in. It can parse
your queries at compile time, figure out what columns they're going to return and generate Dart code to represent your your queries at compile time, figure out what columns they're going to return and generate Dart code to represent your
rows. rows.
- __Migration utils__: Moor makes writing migrations easier thanks to utility functions like `.createAllTables()`. - __Migration utils__: Drift makes writing migrations easier thanks to utility functions like `.createAllTables()`.
You don't need to manually write your `CREATE TABLE` statements and keep them updated. You don't need to manually write your `CREATE TABLE` statements and keep them updated.
And much more! Moor validates data before inserting it, so you can get helpful error messages instead of just an And much more! Drift validates data before inserting it, so you can get helpful error messages instead of just an
sql error code. Of course, it supports transactions. And DAOs. And efficient batched insert statements. The list goes on. sql error code. Of course, it supports transactions. And DAOs. And efficient batched insert statements. The list goes on.
Check out these in-depth articles to learn about moor and how to use its features. Check out these in-depth articles to learn about drift and how to use its features.

View File

@ -1,26 +1,24 @@
--- ---
data: data:
title: "Supported platforms" title: "Supported platforms"
description: All platforms supported by moor, and how to use them description: All platforms supported by drift, and how to use them
template: layouts/docs/single template: layouts/docs/single
--- ---
Being built ontop of the sqlite3 database, moor can run on almost every Dart platform. Being built ontop of the sqlite3 database, drift can run on almost every Dart platform.
Since the initial release of moor, the Dart and Flutter ecosystems have changed a lot. Since the initial release, the Dart and Flutter ecosystems have changed a lot.
For instance, `dart:ffi` wasn't a thing when moor first came out, and now it's the basis To clear confusion about different drift packages and when to use them, this document
for moor's most popular implemention. lists all supported platforms and how to use drift when building apps for them.
To clear confusion about different moor packages and when to use them, this document
lists all supported platforms and how to use moor when building apps for them.
To achive platform independence, moor separates its core apis from a platform-specific To achive platform independence, drift separates its core apis from a platform-specific
database implementation. The core apis are pure-Dart and run on all Dart platforms, even database implementation. The core apis are pure-Dart and run on all Dart platforms, even
outside of Flutter. When writing moor apps, prefer to mainly use the apis in outside of Flutter. When writing drift apps, prefer to mainly use the apis in
`package:moor/moor.dart` as they are guaranteed to work across all platforms. `package:drift/drift.dart` as they are guaranteed to work across all platforms.
Depending on your platform, you can choose a different `QueryExecutor`. Depending on your platform, you can choose a different `QueryExecutor`.
## Mobile (Android and iOS) ## Mobile (Android and iOS)
There are two moor implementations for mobile that you can use: There are two drift implementations for mobile that you can use:
### using `moor_flutter` ### using `moor_flutter`
@ -29,16 +27,16 @@ only works on Android and iOS.
For new projects, we generally recommend the newer ffi-based implementation, but `moor_flutter` For new projects, we generally recommend the newer ffi-based implementation, but `moor_flutter`
is still maintained and suppported. is still maintained and suppported.
### using `moor/ffi` ### using `drift/native`
The new `package:moor/ffi.dart` implementation uses `dart:ffi` to bind to sqlite3's native C apis. The new `package:drift/native.dart` implementation uses `dart:ffi` to bind to sqlite3's native C apis.
This is the recommended approach for newer projects as described in the [getting started]({{ "Getting started/index.md" | pageUrl }}) guide. This is the recommended approach for newer projects as described in the [getting started]({{ "Getting started/index.md" | pageUrl }}) guide.
To ensure that your app ships with the latest sqlite3 version, also add a dependency to the `sqlite3_flutter_libs` To ensure that your app ships with the latest sqlite3 version, also add a dependency to the `sqlite3_flutter_libs`
package when using `package:moor/ffi.dart`! package when using `package:drift/native.dart`!
{% block "blocks/alert" title="A note on ffi and Android" %} {% block "blocks/alert" title="A note on ffi and Android" %}
> `package:moor/ffi.dart` is the recommended moor implementation for new Android apps. > `package:drift/native.dart` is the recommended drift implementation for new Android apps.
However, there are some smaller issues on some devices that you should be aware of: However, there are some smaller issues on some devices that you should be aware of:
- Using `sqlite3_flutter_libs` will include prebuilt binaries for 32-bit `x86` devices which you - Using `sqlite3_flutter_libs` will include prebuilt binaries for 32-bit `x86` devices which you
@ -57,28 +55,28 @@ package when using `package:moor/ffi.dart`!
_Main article: [Web]({{ "Other engines/web.md" | pageUrl }})_ _Main article: [Web]({{ "Other engines/web.md" | pageUrl }})_
For apps that run on the web, you can use moor's experimental web implementation, located For apps that run on the web, you can use drift's experimental web implementation, located
in `package:moor/moor_web.dart`. in `package:drift/web.dart`.
As it binds to [sql.js](https://github.com/sql-js/sql.js), special setup is required. Please As it binds to [sql.js](https://github.com/sql-js/sql.js), special setup is required. Please
read the main article for details. read the main article for details.
## Desktop ## Desktop
Moor also supports all major Desktop operating systems where Dart runs on by using the Drift also supports all major Desktop operating systems where Dart runs on by using the
`VmDatabase` from `package:moor/ffi.dart`. Depending on your operating system, further `NativeDatabase` from `package:drift/native.dart`. Depending on your operating system, further
setup might be required: setup might be required:
### Windows ### Windows
On Windows, you can [download sqlite](https://www.sqlite.org/download.html) and extract On Windows, you can [download sqlite](https://www.sqlite.org/download.html) and extract
`sqlite3.dll` into a folder that's in your `PATH` environment variable to use moor. `sqlite3.dll` into a folder that's in your `PATH` environment variable to use drift.
You can also ship a custom `sqlite3.dll` along with your app. See the section below for You can also ship a custom `sqlite3.dll` along with your app. See the section below for
details. details.
### Linux ### Linux
On most distributions, `libsqlite3.so` is installed already. If you only need to use moor for On most distributions, `libsqlite3.so` is installed already. If you only need to use drift for
development, you can just install the sqlite3 libraries. On Ubuntu and other Debian-based development, you can just install the sqlite3 libraries. On Ubuntu and other Debian-based
distros, you can install the `libsqlite3-dev` package for this. Virtually every other distribution distros, you can install the `libsqlite3-dev` package for this. Virtually every other distribution
will also have a prebuilt package for sqlite. will also have a prebuilt package for sqlite.
@ -88,12 +86,12 @@ details.
### macOS ### macOS
This one is easy! Just use the `VmDatabase` from `package:moor/ffi.dart`. No further setup is This one is easy! Just use the `VmDatabase` from `package:drift/native.dart`. No further setup is
necessary. necessary.
If you need a custom sqlite3 library, or want to make sure that your app will always use a If you need a custom sqlite3 library, or want to make sure that your app will always use a
specific sqlite3 version, you can also ship that version with your app. specific sqlite3 version, you can also ship that version with your app.
When depending on `sqlite3_flutter_libs`, moor will automatically use that version which is When depending on `sqlite3_flutter_libs`, drift will automatically use that version which is
usually more recent than the `sqlite3` version that comes with macOS. usually more recent than the `sqlite3` version that comes with macOS.
### Bundling sqlite with your app ### Bundling sqlite with your app
@ -115,7 +113,7 @@ import 'package:sqlite3/open.dart';
void main() { void main() {
open.overrideFor(OperatingSystem.linux, _openOnLinux); open.overrideFor(OperatingSystem.linux, _openOnLinux);
// After setting all the overrides, you can use moor! // After setting all the overrides, you can use drift!
} }
DynamicLibrary _openOnLinux() { DynamicLibrary _openOnLinux() {
@ -126,7 +124,7 @@ DynamicLibrary _openOnLinux() {
// _openOnWindows could be implemented similarly by opening `sqlite3.dll` // _openOnWindows could be implemented similarly by opening `sqlite3.dll`
``` ```
Be sure to use moor _after_ you set the platform-specific overrides. Be sure to use drift _after_ you set the platform-specific overrides.
When you use moor in [another isolate]({{ 'Advanced Features/isolates.md' | pageUrl }}), When you usedrift in [another isolate]({{ 'Advanced Features/isolates.md' | pageUrl }}),
you'll also need to apply the opening overrides on that background isolate. you'll also need to apply the opening overrides on that background isolate.
You can call them in the isolate's entrypoint before using any moor apis. You can call them in the isolate's entrypoint before using any drift apis.

View File

@ -1,26 +1,24 @@
--- ---
data: data:
title: "Testing" title: "Testing"
description: Guide on writing unit tests for moor databases description: Guide on writing unit tests for drift databases
template: layouts/docs/single template: layouts/docs/single
--- ---
Flutter apps using moor can always be tested with [integration tests](https://flutter.dev/docs/cookbook/testing/integration/introduction) Flutter apps using drift can always be tested with [integration tests](https://flutter.dev/docs/cookbook/testing/integration/introduction)
running on a real device. This guide focuses on writing unit tests for a database written in moor. running on a real device. This guide focuses on writing unit tests for a database written in drift.
Those tests can be run and debugged on your computer without additional setup, you don't need a Those tests can be run and debugged on your computer without additional setup, you don't need a
physical device to run them. physical device to run them.
## Setup ## Setup
For tests, you need to use a `VmDatabase` included in `moor` version `3.3.0` and above. You can also test your database on older moor For this guide, we're going to test a very simple database that stores user names. The only important change from a regular drift
versions by using the `moor_ffi` package.
For this guide, we're going to test a very simple database that stores user names. The only important change from a regular moor
database is the constructor: We make the `QueryExecutor` argument explicit instead of having a no-args constructor that passes database is the constructor: We make the `QueryExecutor` argument explicit instead of having a no-args constructor that passes
a `FlutterQueryExecutor` to the superclass. a fixed executor (like a `FlutterQueryExecutor` or a `NativeDatabase`) to the superclass:
```dart ```dart
import 'package:moor/moor.dart'; import 'package:drift/drift.dart';
part 'database.g.dart'; part 'database.g.dart';
@ -29,7 +27,7 @@ class Users extends Table {
TextColumn get name => text()(); TextColumn get name => text()();
} }
@UseMoor(tables: [Users]) @DriftDatabase(tables: [Users])
class MyDatabase extends _$MyDatabase { class MyDatabase extends _$MyDatabase {
MyDatabase(QueryExecutor e) : super(e); MyDatabase(QueryExecutor e) : super(e);
@ -76,9 +74,9 @@ We can create an in-memory version of the database by using a
place to open the database is the `setUp` and `tearDown` methods from place to open the database is the `setUp` and `tearDown` methods from
`package:test`: `package:test`:
```dart ```dart
import 'package:moor_ffi/moor_ffi.dart'; import 'package:drift/native.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
// the file defined above, you can test any moor database of course // the file defined above, you can test any drift database of course
import 'database.dart'; import 'database.dart';
void main() { void main() {
@ -117,5 +115,5 @@ test('stream emits a new user when the name updates', () async {
## Testing migrations ## Testing migrations
Moor can help you generate code for schema migrations. For more details, see Drift can help you generate code for schema migrations. For more details, see
[this guide]({{ "Advanced Features/migrations.md#verifying-migrations" | pageUrl }}). [this guide]({{ "Advanced Features/migrations.md#verifying-migrations" | pageUrl }}).

View File

@ -2,14 +2,14 @@
data: data:
title: "Transactions" title: "Transactions"
weight: 70 weight: 70
description: Run multiple queries atomically description: Run multiple statements atomically
template: layouts/docs/single template: layouts/docs/single
aliases: aliases:
- /transactions/ - /transactions/
--- ---
Moor has support for transactions and allows multiple queries to run atomically, Drift has support for transactions and allows multiple statements to run atomically,
so that none of their changes is visible to the main database until the transaction so that none of their changes is visible to the main database until the transaction
is finished. is finished.
To begin a transaction, call the `transaction` method on your database or a DAO. To begin a transaction, call the `transaction` method on your database or a DAO.

View File

@ -10,7 +10,7 @@ path: ""
<a class="btn btn-lg btn-primary mr-3 mb-4" href="{{ 'docs/index' | pageUrl }}"> <a class="btn btn-lg btn-primary mr-3 mb-4" href="{{ 'docs/index' | pageUrl }}">
Learn more <i class="fas fa-arrow-alt-circle-right ml-2"></i> Learn more <i class="fas fa-arrow-alt-circle-right ml-2"></i>
</a> </a>
<a class="btn btn-lg btn-secondary mr-3 mb-4" href="https://pub.dev/packages/moor"> <a class="btn btn-lg btn-secondary mr-3 mb-4" href="https://pub.dev/packages/drift">
Get from pub <i class="fas fa-code ml-2 "></i> Get from pub <i class="fas fa-code ml-2 "></i>
</a> </a>
@ -23,7 +23,7 @@ path: ""
{% endblock %} {% endblock %}
{% block "blocks/lead.html" color="dark" %} {% block "blocks/lead.html" color="dark" %}
Moor is an easy to use, reactive persistence library for Flutter apps. Define tables in Dart or Drift is an easy to use, reactive persistence library for Flutter apps. Define tables in Dart or
SQL and enjoy a fluent query API, auto-updating streams and more! SQL and enjoy a fluent query API, auto-updating streams and more!
{% endblock %} {% endblock %}
@ -31,18 +31,18 @@ SQL and enjoy a fluent query API, auto-updating streams and more!
{% block "blocks/feature.html" icon="fas fa-lightbulb" title="Declarative tables, fluent queries" %} {% block "blocks/feature.html" icon="fas fa-lightbulb" title="Declarative tables, fluent queries" %}
{% block "blocks/markdown.html" %} {% block "blocks/markdown.html" %}
With moor, you can write your database tables in pure Dart without having to miss out on With drift, you can write your database tables in pure Dart without having to miss out on
advanced sqlite features. Moor will take care of creating the tables and generate code advanced sqlite features. Drift will take care of creating the tables and generate code
that allows you run fluent queries on your data. that allows you run fluent queries on your data.
[Get started now]({{ "docs/Getting started/index.md" | pageUrl }}) [Get started now]({{ "docs/Getting started/index.md" | pageUrl }})
{% endblock %} {% endblock %}
{% endblock %} {% endblock %}
{% block "blocks/feature.html" icon="fas fa-database" title="Prefer SQL? Moor got you covered!" %} {% block "blocks/feature.html" icon="fas fa-database" title="Prefer SQL? Drift got you covered!" %}
{% block "blocks/markdown.html" %} {% block "blocks/markdown.html" %}
Moor contains a powerful sql parser and analyzer, allowing it to create typesafe APIs for all your sql queries. All sql queries are Drift contains a powerful sql parser and analyzer, allowing it to create typesafe APIs for all your sql queries. All sql queries are
validated and analyzed during build-time, so moor can provide hints about potential errors quickly and generate efficient mapping validated and analyzed during build-time, so drift can provide hints about potential errors quickly and generate efficient mapping
code. code.
[Learn more]({{ 'docs/Using SQL/index.md' | pageUrl }}) [Learn more]({{ 'docs/Using SQL/index.md' | pageUrl }})
@ -51,9 +51,9 @@ code.
{% block "blocks/feature.html" icon="fas fa-star" title="And much more!" %} {% block "blocks/feature.html" icon="fas fa-star" title="And much more!" %}
{% block "blocks/markdown.html" %} {% block "blocks/markdown.html" %}
Or should I say, much moor? Moor provides auto-updating straems for all your queries, makes dealing with transactions and migrations easy Drift provides auto-updating streams for all your queries, makes dealing with transactions and migrations easy
and lets your write modular database code with DAOs. We even have a [sql IDE]({{ 'docs/Using SQL/sql_ide.md' | pageUrl }}) builtin to the project and lets your write modular database code with DAOs. We even have a [sql IDE]({{ 'docs/Using SQL/sql_ide.md' | pageUrl }}) builtin to the project
When using moor, working with databases in Dart is fun! When using drift, working with databases in Dart is fun!
{% endblock %} {% endblock %}
{% endblock %} {% endblock %}
@ -61,22 +61,22 @@ When using moor, working with databases in Dart is fun!
{% block "blocks/section.html" color="light" type="section" %} {% block "blocks/section.html" color="light" type="section" %}
{% block "blocks/markdown.html" %} {% block "blocks/markdown.html" %}
## Key moor features ## Key features
Here are some of the many ways moor helps you write awesome database code: Here are some of the many ways drift helps you write awesome database code:
* __Auto-updating streams__: With moor, any query - no matter how complex - can be turned into a stream that emits new data as the underlying data changes. * __Auto-updating streams__: With drift, any query - no matter how complex - can be turned into a stream that emits new data as the underlying data changes.
* __Polyglot__: Moor lets you write queries in a fluent Dart api or directly in SQL - you can even embed Dart expressions in SQL. * __Polyglot__: Drift lets you write queries in a fluent Dart api or directly in SQL - you can even embed Dart expressions in SQL.
* __Boilerplate-free__: Stop writing mapping code yourself - moor can take of that. Moor generates Dart code around your data so you can focus * __Boilerplate-free__: Stop writing mapping code yourself - drift can take of that. Drift generates Dart code around your data so you can focus
on building great apps. on building great apps.
* __Flexible__: Want to write queries in SQL? Moor verifies them at compile time and generates Dart apis for them. Prefer to write them in Dart? * __Flexible__: Want to write queries in SQL? Drift verifies them at compile time and generates Dart apis for them. Prefer to write them in Dart?
Moor will generate efficient SQL for Dart queries too. Drift will generate efficient SQL for Dart queries too.
* __Easy to learn__: Instead of having to learn yet another ORM, moor lets you write queries in SQL and generates typesafe wrappers. Queries and tables * __Easy to learn__: Instead of having to learn yet another ORM, drift lets you write queries in SQL and generates typesafe wrappers. Queries and tables
can also be written in Dart that looks similar to SQL without loosing type-safety. can also be written in Dart that looks similar to SQL without loosing type-safety.
* __Fast _and_ powerful__: With the new `ffi` backend, moor can outperform key-value stores without putting any compromises on the integrity * __Fast _and_ powerful__: With the new `ffi` backend, drift can outperform key-value stores without putting any compromises on the integrity
and flexibility that relational databases provide. Moor is the only major persistence library with builtin support for multiple isolates. and flexibility that relational databases provide. Drift is the only major persistence library with builtin support for multiple isolates.
* __Well tested and production ready__: Each component of moor is verified by a wide range of unit and integration tests. Moor powers many Flutter apps * __Well tested and production ready__: Each component of drift is verified by a wide range of unit and integration tests. Drift powers many Flutter apps
in production. in production.
* __Cross-Platform__: Moor works on iOS, Android, Linux, macOS, Windows and on the web. It doesn't even require Flutter. See [supported platforms]({{ "docs/platforms.md" | pageUrl }}). * __Cross-Platform__: Drift works on iOS, Android, Linux, macOS, Windows and on the web. It doesn't even require Flutter. See [supported platforms]({{ "docs/platforms.md" | pageUrl }}).
{% endblock %} {% endblock %}
{% endblock %} {% endblock %}