mirror of https://github.com/AMT-Cheif/drift.git
Migrate rest of documentation to drift
This commit is contained in:
parent
e91207e9e4
commit
3157d687e5
|
@ -8,10 +8,10 @@ aliases:
|
|||
- "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.
|
||||
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 also see the section on [recommended options](#recommended-options) for
|
||||
advice on which options to use.
|
||||
|
@ -24,28 +24,28 @@ to your `pubspec.yaml`):
|
|||
targets:
|
||||
$default:
|
||||
builders:
|
||||
moor_generator:
|
||||
drift_dev:
|
||||
options:
|
||||
compact_query_methods: true
|
||||
```
|
||||
|
||||
## 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
|
||||
constructor to generated data classes. By default, we only write a `.fromJson`
|
||||
constructor that takes a `Map<String, dynamic>`.
|
||||
* `override_hash_and_equals_in_result_sets`: boolean. When moor generates another class
|
||||
to hold the result of generated select queries, this flag controls whether moor should
|
||||
* `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 drift should
|
||||
override `operator ==` and `hashCode` in those classes. In recent versions, it will also
|
||||
override `toString` if this option is enabled.
|
||||
* `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`.
|
||||
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.
|
||||
This flag is enabled by default in moor 3.0, but it can still be disabled.
|
||||
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 and drift, but it can still be disabled.
|
||||
* `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
|
||||
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
|
||||
this case).
|
||||
* `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`).
|
||||
You can always override the json key by using a `JSON KEY` column constraint
|
||||
(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.
|
||||
Modules have to be enabled explicitly because they're not supported on all platforms. See the following section for
|
||||
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.
|
||||
* `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.
|
||||
* `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`.
|
||||
|
@ -97,7 +97,7 @@ version:
|
|||
targets:
|
||||
$default:
|
||||
builders:
|
||||
moor_generator:
|
||||
drift_dev:
|
||||
options:
|
||||
sqlite:
|
||||
version: "3.34"
|
||||
|
@ -112,15 +112,15 @@ minimum version needed in options.
|
|||
### Available extensions
|
||||
|
||||
__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
|
||||
only available when using `moor_ffi`.
|
||||
only available when using a `NativeDatabase`.
|
||||
|
||||
```yaml
|
||||
targets:
|
||||
$default:
|
||||
builders:
|
||||
moor_generator:
|
||||
drift_dev:
|
||||
options:
|
||||
sqlite:
|
||||
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
|
||||
- [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.
|
||||
- `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 }}).
|
||||
- `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.
|
||||
|
||||
## 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:
|
||||
|
||||
- `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.
|
||||
|
||||
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
|
||||
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
|
||||
method, you can disable this option.
|
||||
|
||||
## Using moor classes in other builders
|
||||
|
||||
Starting with moor 2.4, it's possible to use classes generated by moor in other builders.
|
||||
## Using drift classes 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
|
||||
and minor code changes. Put this content in a file called `build.yaml` next to your `pubspec.yaml`:
|
||||
|
||||
```yaml
|
||||
targets:
|
||||
$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
|
||||
builders:
|
||||
moor_generator|moor_generator_not_shared:
|
||||
drift_dev|not_shared:
|
||||
enabled: true
|
||||
# If needed, you can configure the builder like this:
|
||||
# options:
|
||||
# skip_verification_code: true
|
||||
# use_experimental_inference: true
|
||||
# This builder is necessary for moor-file preprocessing. You can disable it if you're not
|
||||
# using .moor files with type converters.
|
||||
moor_generator|preparing_builder:
|
||||
# This builder is necessary for drift-file preprocessing. You can disable it if you're not
|
||||
# using .drift files with type converters.
|
||||
drift_dev|preparing_builder:
|
||||
enabled: true
|
||||
|
||||
run_built_value:
|
||||
dependencies: ['your_package_name']
|
||||
builders:
|
||||
# Disable moor builders. By default, those would run on each target
|
||||
moor_generator:
|
||||
# Disable drift builders. By default, those would run on each target
|
||||
drift_dev:
|
||||
enabled: false
|
||||
moor_generator|preparing_builder:
|
||||
drift_dev|preparing_builder:
|
||||
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'`.
|
||||
If you use moor _and_ another builder in the same file, you'll need both `.g.dart` and `.moor.dart` as part-files.
|
||||
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 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
|
||||
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).
|
||||
If you run into any problems with this approach, feel free to open an issue on drift.
|
||||
|
||||
### The technicalities, explained
|
||||
|
||||
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.
|
||||
For this to work, each builder first writes a `.part` file with its name. For instance, if you used `moor`
|
||||
and `built_value` in the same project, those part files could be called `.moor.part` and `.built_value.part`.
|
||||
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 `.drift.part` and `.built_value.part`.
|
||||
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`
|
||||
file, or use any classes or methods defined in it. To fix that, moor offers an optional builder -
|
||||
`moor_generator|moor_generator_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
|
||||
file, or use any classes or methods defined in it. To fix that, drift offers an optional builder -
|
||||
`drift_dev|not_shared` - that will generate a separate part file only containing
|
||||
code generated by drift. So most of the work resolves around disabling the default generator of drift
|
||||
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
|
||||
why we split the builders up into multiple targets. The first target will only run moor, the second
|
||||
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 drift, the second
|
||||
target has a dependency on the first one and will run all the other builders.
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
data:
|
||||
title: "Custom row classes"
|
||||
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
|
||||
---
|
||||
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
|
@ -39,7 +39,7 @@ class User {
|
|||
A row class must adhere to the following requirements:
|
||||
|
||||
- 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)
|
||||
- The type of a constructor argument must be equal to the type of a column,
|
||||
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:
|
||||
|
||||
- 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 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
|
||||
|
||||
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
|
||||
`@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
|
||||
class into the moor file.
|
||||
class into the drift file.
|
||||
|
||||
```sql
|
||||
import 'user.dart'; -- or what the Dart file is called
|
||||
|
@ -117,10 +117,10 @@ class User implements Insertable<User> {
|
|||
|
||||
## 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:
|
||||
|
||||
- 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
|
||||
for all users.
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
- 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
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ available from your main database class. Consider the following code:
|
|||
```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
|
||||
// that should use this dao.
|
||||
@UseDao(tables: [Todos])
|
||||
@DriftAccessor(tables: [Todos])
|
||||
class TodosDao extends DatabaseAccessor<MyDatabase> with _$TodosDaoMixin {
|
||||
// this constructor is required so that the main database can create an instance
|
||||
// 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.
|
||||
|
|
|
@ -10,7 +10,7 @@ template: layouts/docs/single
|
|||
---
|
||||
|
||||
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`
|
||||
expects an expression that returns a boolean.
|
||||
|
||||
|
@ -37,7 +37,7 @@ Future<List<Animal>> findAnimalsByLegs(int legCount) {
|
|||
|
||||
## Boolean algebra
|
||||
You can nest boolean expressions by using the `&`, `|` operators and the `not` method
|
||||
exposed by moor:
|
||||
exposed by drift:
|
||||
|
||||
```dart
|
||||
// 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
|
||||
that you can use operators and comparisons on them.
|
||||
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:
|
||||
|
||||
|
@ -113,7 +113,7 @@ Again, the `isNotIn` function works the other way around.
|
|||
|
||||
## 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
|
||||
once.
|
||||
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()`
|
||||
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 }})
|
||||
|
||||
### group_concat
|
||||
|
@ -198,7 +198,7 @@ For more information, see the [list of functions]({{ "../Other engines/vm.md#moo
|
|||
|
||||
## Subqueries
|
||||
|
||||
Starting from version 4.1, moor has basic support for subqueries in expressions.
|
||||
Drift has basic support for subqueries in expressions.
|
||||
|
||||
### 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.
|
||||
Then, we can use `subqueryExpression` to embed that query into an expression that we're using as
|
||||
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
|
||||
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
|
||||
[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.
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
data:
|
||||
title: Advanced Features
|
||||
weight: 20
|
||||
description: Learn about some advanced features of moor
|
||||
description: Learn about some advanced features of drift
|
||||
template: layouts/docs/list
|
||||
---
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
---
|
||||
data:
|
||||
title: Isolates
|
||||
description: Using moor databases on a background isolate
|
||||
description: Using drift databases on a background isolate
|
||||
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
|
||||
|
||||
To use the isolate api, first enable the appropriate [build option]({{ "builder_options.md" | pageUrl }}) by
|
||||
|
@ -20,13 +14,13 @@ content:
|
|||
targets:
|
||||
$default:
|
||||
builders:
|
||||
moor_generator:
|
||||
drift_dev:
|
||||
options:
|
||||
generate_connect_constructor: true
|
||||
```
|
||||
Next, re-run the build. You can now add another constructor to the generated database class:
|
||||
```dart
|
||||
@UseMoor(...)
|
||||
@DriftDatabase(...)
|
||||
class TodoDb extends _$TodoDb {
|
||||
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
|
||||
```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
|
||||
DatabaseConnection _backgroundConnection() {
|
||||
|
@ -53,12 +47,12 @@ DatabaseConnection _backgroundConnection() {
|
|||
}
|
||||
|
||||
void main() async {
|
||||
// create a moor executor in a new background isolate. If you want to start the isolate yourself, you
|
||||
// can also call MoorIsolate.inCurrent() from the background isolate
|
||||
MoorIsolate isolate = await MoorIsolate.spawn(_backgroundConnection);
|
||||
// create a drift executor in a new background isolate. If you want to start the isolate yourself, you
|
||||
// can also call DriftIsolate.inCurrent() from the background isolate
|
||||
DriftIsolate isolate = await DriftIsolate.spawn(_backgroundConnection);
|
||||
|
||||
// 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();
|
||||
|
||||
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
|
||||
`DatabaseConnection.delayed` constructor introduced in moor 3.4. In the example above, you
|
||||
If you need to construct the database outside of an `async` context, you can use the
|
||||
`DatabaseConnection.delayed` constructor. In the example above, you
|
||||
could synchronously obtain a `TodoDb` by using:
|
||||
|
||||
```dart
|
||||
Future<DatabaseConnection> _connectAsync() async {
|
||||
MoorIsolate isolate = await MoorIsolate.spawn(_backgroundConnection);
|
||||
DriftIsolate isolate = await DriftIsolate.spawn(_backgroundConnection);
|
||||
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
|
||||
immediately. Internally, moor will connect when the first query is sent to the database.
|
||||
This can be helpful when using drift in DI frameworks, since you have the database available
|
||||
immediately. Internally, drift will connect when the first query is sent to the database.
|
||||
|
||||
### 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.
|
||||
|
||||
```dart
|
||||
Future<MoorIsolate> _createMoorIsolate() async {
|
||||
Future<DriftIsolate> _createDriftIsolate() async {
|
||||
// this method is called from the main isolate. Since we can't use
|
||||
// getApplicationDocumentsDirectory on a background isolate, we calculate
|
||||
// the database path in the foreground isolate and then inform the
|
||||
|
@ -110,31 +104,31 @@ Future<MoorIsolate> _createMoorIsolate() async {
|
|||
_IsolateStartRequest(receivePort.sendPort, path),
|
||||
);
|
||||
|
||||
// _startBackground will send the MoorIsolate to this ReceivePort
|
||||
return await receivePort.first as MoorIsolate;
|
||||
// _startBackground will send the DriftIsolate to this ReceivePort
|
||||
return await receivePort.first as DriftIsolate;
|
||||
}
|
||||
|
||||
void _startBackground(_IsolateStartRequest request) {
|
||||
// this is the entry point from the background isolate! Let's create
|
||||
// the database from the path we received
|
||||
final executor = VmDatabase(File(request.targetPath));
|
||||
// we're using MoorIsolate.inCurrent here as this method already runs on a
|
||||
// background isolate. If we used MoorIsolate.spawn, a third isolate would be
|
||||
final executor = NativeDatabase(File(request.targetPath));
|
||||
// we're using DriftIsolate.inCurrent here as this method already runs on a
|
||||
// background isolate. If we used DriftIsolate.spawn, a third isolate would be
|
||||
// started which is not what we want!
|
||||
final moorIsolate = MoorIsolate.inCurrent(
|
||||
final driftIsolate = DriftIsolate.inCurrent(
|
||||
() => DatabaseConnection.fromExecutor(executor),
|
||||
);
|
||||
// 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
|
||||
// functions can only take one parameter.
|
||||
class _IsolateStartRequest {
|
||||
final SendPort sendMoorIsolate;
|
||||
final SendPort sendDriftIsolate;
|
||||
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:
|
||||
|
||||
```dart
|
||||
DatabaseConnection _createMoorIsolateAndConnect() {
|
||||
DatabaseConnection _createDriftIsolateAndConnect() {
|
||||
return DatabaseConnection.delayed(() async {
|
||||
final isolate = await _createMoorIsolate();
|
||||
final isolate = await _createDriftIsolate();
|
||||
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
|
||||
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
|
||||
`_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
|
||||
locators like `get_it` come to mind) may also need to be initialized seperately on the background
|
||||
isolate.
|
||||
|
@ -165,54 +159,54 @@ isolate.
|
|||
|
||||
### Shutting down the isolate
|
||||
|
||||
Since multiple `DatabaseConnection`s can exist to a specific `MoorIsolate`, simply calling
|
||||
`Database.close` won't stop the isolate. You can use the `MoorIsolate.shutdownAll()` for that.
|
||||
Since multiple `DatabaseConnection`s can exist to a specific `DriftIsolate`, simply calling
|
||||
`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.
|
||||
|
||||
## 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
|
||||
`MoorIsolate.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
|
||||
`DriftIsolate.spawn` from the `main` method in your Flutter or Dart app. Similar to the example above,
|
||||
you could then use drift from the main isolate by connecting with `DriftIsolate.connect` and passing that
|
||||
connection to a generated database class.
|
||||
|
||||
__One executor isolate, multiple client isolates__: The `MoorIsolate` can be sent across multiple
|
||||
isolates, each of which can use `MoorIsolate.connect` on their own. This is useful to implement
|
||||
__One executor isolate, multiple client isolates__: The `DriftIsolate` can be sent across multiple
|
||||
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:
|
||||
|
||||
- The moor executor isolate
|
||||
- The drift executor isolate
|
||||
- A foreground isolate, probably for Flutter
|
||||
- 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
|
||||
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
|
||||
also update query streams.
|
||||
|
||||
To safely send a `MoorIsolate` instance across a `SendPort`, it's recommended to instead send the
|
||||
underlying `SendPort` used internally by `MoorIsolate`:
|
||||
To safely send a `DriftIsolate` instance across a `SendPort`, it's recommended to instead send the
|
||||
underlying `SendPort` used internally by `DriftIsolate`:
|
||||
|
||||
```dart
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Instead, send the underlying SendPort:
|
||||
void shareMoorIsolate(MoorIsolate isolate, SendPort sendPort) {
|
||||
void shareDriftIsolate(DriftIsolate isolate, SendPort sendPort) {
|
||||
sendPort.send(isolate.connectPort);
|
||||
}
|
||||
```
|
||||
|
||||
The receiving end can reconstruct a `MoorIsolate` from a `SendPort` by using the
|
||||
`MoorIsolate.fromConnectPort` constructor. That `MoorIsolate` behaves exactly like the original
|
||||
The receiving end can reconstruct a `DriftIsolate` from a `SendPort` by using the
|
||||
`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.
|
||||
|
||||
## 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
|
||||
- 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
|
||||
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
|
||||
frames because of moor, using a background isolate is probably not necessary for your app.
|
||||
isolates, and that's exactly what drift has to do internally. If you're not running into dropped
|
||||
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.
|
||||
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.
|
||||
Internally, the `MoorIsolate` 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`
|
||||
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 `DriftIsolate`
|
||||
object across many isolates and connect multiple times. The actual server logic that listens on
|
||||
the port is in a private `_MoorServer` class.
|
||||
- __Client isolates__: Any number of clients in any number of isolates can connect to a `MoorIsolate`.
|
||||
The client acts as a moor backend, which means that all queries are built on the client isolate. The
|
||||
the port is in a private `RunningDriftServer` class.
|
||||
- __Client isolates__: Any number of clients in any number of isolates can connect to a `DriftIsolate`.
|
||||
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
|
||||
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.
|
||||
|
@ -242,20 +236,20 @@ Internally, moor uses the following model to implement this api:
|
|||
## Independent isolates
|
||||
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
You can store the [`connectPort`](https://moor.simonbinder.eu/api/isolate/moorisolate/connectport) of a `MoorIsolate`
|
||||
be used to transparently share a drift isolate between such workers.
|
||||
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.
|
||||
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.
|
||||
|
||||
Please note that, at the moment, Flutter still has some inherent problems with spawning isolates from background engines
|
||||
|
|
|
@ -10,7 +10,7 @@ template: layouts/docs/single
|
|||
|
||||
## 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
|
||||
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 }}).
|
||||
|
@ -182,7 +182,7 @@ comes from multiple rows. Common questions include
|
|||
- 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
|
||||
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 }}).
|
||||
|
||||
_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.
|
||||
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.
|
||||
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.
|
||||
|
||||
```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
|
||||
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.
|
||||
Moor 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,
|
||||
Drift provides a special method for this case - instead of using `select`, we use `selectOnly`.
|
||||
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.
|
||||
|
||||
```dart
|
||||
|
|
|
@ -8,7 +8,7 @@ aliases:
|
|||
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`
|
||||
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
|
||||
```
|
||||
|
||||
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
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
@ -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`.
|
||||
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.
|
||||
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`.
|
||||
Of course, moor won't attempt to copy `newColumns` from the old table either.
|
||||
`TableMigration`. Drift will ensure that those columns have a default value or a transformation in `columnTransformer`.
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
- 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" %}
|
||||
> 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).
|
||||
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 %}
|
||||
|
||||
### 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.
|
||||
|
||||
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_v1.dart
|
||||
schema_v2.dart
|
||||
moor_schemas/
|
||||
moor_schema_v1.json
|
||||
moor_schema_v2.json
|
||||
drift_schemas/
|
||||
drift_schema_v1.json
|
||||
drift_schema_v2.json
|
||||
pubspec.yaml
|
||||
```
|
||||
|
||||
The generated migrations implementation and the schema jsons will be generated by moor.
|
||||
To start writing schemas, create an empty folder named `moor_schemas` in your project.
|
||||
The generated migrations implementation and the schema jsons will be generated by drift.
|
||||
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.
|
||||
|
||||
#### 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:
|
||||
|
||||
```
|
||||
$ mkdir moor_schemas
|
||||
$ dart pub run moor_generator schema dump lib/database/database.dart moor_schemas/moor_schema_v1.json
|
||||
$ mkdir drift_schemas
|
||||
$ 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
|
||||
|
@ -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:
|
||||
|
||||
```
|
||||
$ 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`.
|
||||
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
|
||||
|
||||
After you exported the database schema into a folder, you can generate old versions of your database class
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
```
|
||||
$ dart pub run moor_generator schema generate moor_schemas/ test/generated/
|
||||
$ dart run drift_dev schema generate drift_schemas/ test/generated/
|
||||
```
|
||||
|
||||
### 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:test/test.dart';
|
||||
import 'package:moor_generator/api/migrations.dart';
|
||||
import 'package:drift_dev/api/migrations.dart';
|
||||
|
||||
// The generated directory from before.
|
||||
import 'generated/schema.dart';
|
||||
|
@ -323,8 +323,8 @@ void main() {
|
|||
SchemaVerifier verifier;
|
||||
|
||||
setUpAll(() {
|
||||
// GeneratedHelper() was generated by moor, the verifier is an api
|
||||
// provided by moor_generator.
|
||||
// GeneratedHelper() was generated by drift, the verifier is an api
|
||||
// provided by drift_generator.
|
||||
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.
|
||||
|
||||
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.
|
||||
To enable this feature, pass the `--data-classes` and `--companions` command-line arguments to the `moor_generator schema generate`
|
||||
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 `drift_dev schema generate`
|
||||
command.
|
||||
|
||||
Then, you can import the generated classes with an alias:
|
||||
|
|
|
@ -7,10 +7,10 @@ aliases:
|
|||
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
|
||||
[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.
|
||||
|
||||
## Using converters in Dart
|
||||
|
@ -19,7 +19,7 @@ package here to make the example simpler.
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart' as j;
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:drift/drift.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:
|
||||
```dart
|
||||
// stores preferences as strings
|
||||
|
@ -74,7 +74,7 @@ class Users extends Table {
|
|||
```
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
```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.
|
||||
|
||||
## 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
|
||||
`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.
|
||||
|
||||
```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 = ?`.
|
||||
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
|
||||
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.
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
---
|
||||
data:
|
||||
title: "Command line tools for moor"
|
||||
description: A set of CLI tools to interact with moor files
|
||||
title: "Command line tools for drift"
|
||||
description: A set of CLI tools to interact with drift projects
|
||||
path: /cli/
|
||||
template: layouts/docs/single
|
||||
---
|
||||
|
||||
{% 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 %}
|
||||
|
||||
## 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.
|
||||
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
|
||||
|
@ -20,12 +20,12 @@ In either case, the tool should be run from the same folder where you keep your
|
|||
|
||||
## 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.
|
||||
╷
|
||||
38 │ defaultConfig: INSERT INTO config DEFAULT VALUES;
|
||||
|
@ -38,16 +38,16 @@ Exits with error code `1` if any error was found.
|
|||
|
||||
## 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.
|
||||
|
||||
```
|
||||
$ pub run moor_generator identify-databases
|
||||
$ dart run drift_dev identify-databases
|
||||
|
||||
Starting to scan in /home/simon/IdeaProjects/moor/moor...
|
||||
INFO: example/example.dart has moor databases or daos: Database
|
||||
INFO: lib/src/data/database.dart has moor databases or daos: AppDatabase
|
||||
INFO: test/fake_db.dart has moor databases or daos: TodoDb, SomeDao
|
||||
Starting to scan in /tmp/example/ ...
|
||||
INFO: example/example.dart has drift databases or daos: Database
|
||||
INFO: lib/src/data/database.dart has drift databases or daos: AppDatabase
|
||||
INFO: test/fake_db.dart has drift databases or daos: TodoDb, SomeDao
|
||||
```
|
||||
|
||||
## Schema tools
|
||||
|
@ -55,11 +55,11 @@ INFO: test/fake_db.dart has moor databases or daos: TodoDb, SomeDao
|
|||
### Export
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
$ 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
|
||||
|
@ -67,7 +67,7 @@ The generated file (`schema.json` in this case) contains information about all
|
|||
- tables, including detailed information about columns
|
||||
- triggers
|
||||
- indices
|
||||
- `@create`-queries from included moor files
|
||||
- `@create`-queries from included drift files
|
||||
- dependecies thereof
|
||||
|
||||
Exporting a schema can be used to generate test code for your schema migrations. For details,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
data:
|
||||
title: "Existing databases"
|
||||
description: Using moor with an existing database
|
||||
description: Using drift with an existing database
|
||||
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
|
||||
|
||||
|
@ -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)
|
||||
on your development machine.
|
||||
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).
|
||||
Simply include it in your pubspec:
|
||||
|
@ -26,13 +26,13 @@ flutter:
|
|||
|
||||
## 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.
|
||||
In moor, you can use a [LazyDatabase](https://pub.dev/documentation/moor/latest/moor/LazyDatabase-class.html)
|
||||
to perform that work just before your moor database is opened:
|
||||
In drift, you can use a [LazyDatabase](https://pub.dev/documentation/drift/latest/drift/LazyDatabase-class.html)
|
||||
to perform that work just before your drift database is opened:
|
||||
|
||||
```dart
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:flutter/services.dart' show rootBundle;
|
||||
|
||||
LazyDatabase _openConnection() {
|
||||
|
@ -56,7 +56,7 @@ LazyDatabase _openConnection() {
|
|||
Finally, use that method to open your database:
|
||||
|
||||
```dart
|
||||
@UseMoor(tables: [Todos, Categories])
|
||||
@DriftDatabase(tables: [Todos, Categories])
|
||||
class MyDatabase extends _$MyDatabase {
|
||||
MyDatabase() : super(_openConnection());
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
data:
|
||||
title: "Examples"
|
||||
weight: 3
|
||||
description: Example apps using moor
|
||||
description: Example apps using drift
|
||||
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,
|
||||
written with moor. [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).
|
||||
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/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.
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
---
|
||||
data:
|
||||
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
|
||||
---
|
||||
|
||||
## Defining the model
|
||||
|
||||
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
|
||||
class BuyableItems extends Table {
|
||||
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
|
||||
quite annoying. Let's write a single class to represent an entire shopping
|
||||
cart that:
|
||||
|
|
|
@ -8,7 +8,7 @@ template: layouts/docs/single
|
|||
|
||||
{% block "blocks/pageinfo" %}
|
||||
__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 %}
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
```dart
|
||||
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)`.
|
||||
|
||||
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).
|
||||
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.
|
||||
|
||||
## Nullability
|
||||
|
||||
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()`:
|
||||
```dart
|
||||
|
@ -109,7 +109,7 @@ can be more efficient, but doesn't support dynamic values.
|
|||
|
||||
## 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`
|
||||
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
|
||||
|
||||
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 }}).
|
||||
|
||||
| Dart type | Column | Corresponding SQLite type |
|
||||
|
@ -146,11 +146,11 @@ Note that the mapping for `boolean`, `dateTime` and type converters only applies
|
|||
the database.
|
||||
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.
|
||||
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
|
||||
|
||||
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`:
|
||||
|
||||
```dart
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
data:
|
||||
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
|
||||
template: layouts/docs/list
|
||||
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).
|
||||
|
||||
## Adding the dependency
|
||||
First, lets add moor to your project's `pubspec.yaml`.
|
||||
At the moment, the current version of `moor` is [](https://pub.dev/packages/moor)
|
||||
and the latest version of `moor_generator` is [](https://pub.dev/packages/moor_generator).
|
||||
First, lets add drift to your project's `pubspec.yaml`.
|
||||
At the moment, the current version of `drift` is [](https://pub.dev/packages/drift)
|
||||
and the latest version of `drift_dev` is [](https://pub.dev/packages/drift_dev).
|
||||
|
||||
{% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %}
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
moor: ^{{ versions.moor }}
|
||||
drift: ^{{ versions.drift }}
|
||||
sqlite3_flutter_libs: ^0.5.0
|
||||
path_provider: ^2.0.0
|
||||
path: ^{{ versions.path }}
|
||||
|
||||
dev_dependencies:
|
||||
moor_generator: ^{{ versions.moor_generator }}
|
||||
drift_dev: ^{{ versions.drift_dev }}
|
||||
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:
|
||||
|
||||
- `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,
|
||||
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
|
||||
- `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
|
||||
|
||||
{% include "partials/changed_to_ffi" %}
|
||||
|
||||
### 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
|
||||
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,
|
||||
// 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';
|
||||
|
||||
// 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()();
|
||||
}
|
||||
|
||||
// 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"
|
||||
// in the table name.
|
||||
@DataClassName("Category")
|
||||
|
@ -69,9 +69,9 @@ class Categories extends Table {
|
|||
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.
|
||||
@UseMoor(tables: [Todos, Categories])
|
||||
@DriftDatabase(tables: [Todos, Categories])
|
||||
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.
|
||||
|
||||
## 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
|
||||
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
|
||||
follows:
|
||||
```dart
|
||||
// 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/path.dart' as p;
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'dart:io';
|
||||
|
||||
LazyDatabase _openConnection() {
|
||||
|
@ -104,11 +104,11 @@ LazyDatabase _openConnection() {
|
|||
// for your app.
|
||||
final dbFolder = await getApplicationDocumentsDirectory();
|
||||
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 {
|
||||
// we tell the database where to store the data with this constructor
|
||||
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
|
||||
to know to write selects, updates and inserts in moor!
|
||||
to know to write selects, updates and inserts in drift!
|
||||
|
|
|
@ -2,54 +2,54 @@
|
|||
data:
|
||||
title: "Getting started with sql"
|
||||
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
|
||||
---
|
||||
|
||||
The regular [getting started guide]({{ "index.md" | pageUrl }}) explains how to get started with moor by
|
||||
declaring both tables and queries in Dart. This version will focus on how to use moor with SQL instead.
|
||||
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 drift with SQL instead.
|
||||
|
||||
## Adding the dependency
|
||||
First, lets add moor to your project's `pubspec.yaml`.
|
||||
At the moment, the current version of `moor` is [](https://pub.dev/packages/moor)
|
||||
and the latest version of `moor_generator` is [](https://pub.dev/packages/moor_generator)
|
||||
First, lets add drift to your project's `pubspec.yaml`.
|
||||
At the moment, the current version of `drift` is [](https://pub.dev/packages/drift)
|
||||
and the latest version of `drift_dev` is [](https://pub.dev/packages/drift_dev).
|
||||
|
||||
{% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %}
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
moor: ^{{ versions.moor }}
|
||||
drift: ^{{ versions.drift }}
|
||||
sqlite3_flutter_libs: ^0.5.0
|
||||
path_provider: ^2.0.0
|
||||
path: ^{{ versions.path }}
|
||||
|
||||
dev_dependencies:
|
||||
moor_generator: ^{{ versions.moor_generator }}
|
||||
drift_dev: ^{{ versions.drift_dev }}
|
||||
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:
|
||||
|
||||
- `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,
|
||||
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
|
||||
- `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
|
||||
|
||||
{% include "partials/changed_to_ffi" %}
|
||||
|
||||
## Declaring tables and queries
|
||||
|
||||
To declare tables and queries in sql, create a file called `tables.moor`
|
||||
next to your Dart files (for instance in `lib/database/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.drift`).
|
||||
|
||||
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
|
||||
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.
|
||||
```sql
|
||||
-- this is the tables.moor file
|
||||
-- this is the tables.drift file
|
||||
CREATE TABLE todos (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT,
|
||||
|
@ -78,37 +78,37 @@ countEntries:
|
|||
```
|
||||
|
||||
{% block "blocks/alert" title="On that AS Category" %}
|
||||
Moor 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
|
||||
Drift will generate Dart classes for your tables, and the name of those
|
||||
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
|
||||
(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.
|
||||
{% endblock %}
|
||||
|
||||
## Generating matching code
|
||||
|
||||
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
|
||||
have to write a small Dart class that moor will then read. Lets create
|
||||
a file called `database.dart` next to the `tables.moor` file you wrote
|
||||
run them. Drift needs to know which tables are used in a database, so we
|
||||
have to write a small Dart class that drift will then read. Lets create
|
||||
a file called `database.dart` next to the `tables.drift` file you wrote
|
||||
in the previous step.
|
||||
|
||||
```dart
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
// 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/path.dart' as p;
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@UseMoor(
|
||||
// relative import for the moor file. Moor also supports `package:`
|
||||
@DriftDatabase(
|
||||
// relative import for the drift file. Drift also supports `package:`
|
||||
// imports
|
||||
include: {'tables.moor'},
|
||||
include: {'tables.drift'},
|
||||
)
|
||||
class AppDb extends _$AppDb {
|
||||
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
|
||||
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
|
||||
row from the respective table.
|
||||
- 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
|
||||
`countEntries` query.
|
||||
- A `_$AppDb` superclass. It takes care of creating the tables when
|
||||
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
|
||||
`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
|
||||
of the `category` column we're comparing it to.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
- 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
|
||||
[expressions]({{ "../Advanced Features/expressions.md" | pageUrl }}) in Dart
|
||||
- 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.
|
|
@ -2,7 +2,7 @@
|
|||
data:
|
||||
title: "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
|
||||
aliases:
|
||||
- /queries/
|
||||
|
@ -13,12 +13,12 @@ template: layouts/docs/single
|
|||
__Note__: This assumes that you've already completed [the setup]({{ "index.md" | pageUrl }}).
|
||||
{% 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
|
||||
run statements:
|
||||
```dart
|
||||
// inside the database class, the `todos` getter has been created by moor.
|
||||
@UseMoor(tables: [Todos, Categories])
|
||||
// inside the database class, the `todos` getter has been created by drift.
|
||||
@DriftDatabase(tables: [Todos, Categories])
|
||||
class MyDatabase extends _$MyDatabase {
|
||||
|
||||
// the schemaVersion getter and the constructor from the previous page
|
||||
|
@ -37,7 +37,7 @@ class MyDatabase extends _$MyDatabase {
|
|||
## Select statements
|
||||
You can create `select` statements by starting them with `select(tableName)`, where the
|
||||
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
|
||||
stream using `watch()`.
|
||||
### Where
|
||||
|
@ -72,7 +72,7 @@ You can also reverse the order by setting the `mode` property of the `OrderingTe
|
|||
|
||||
### Single values
|
||||
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
|
||||
Stream<Todo> entryById(int id) {
|
||||
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?" %}
|
||||
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,
|
||||
prefer to use companions. In the example above, we only set the the `category` column,
|
||||
so we used a companion.
|
||||
|
@ -271,23 +271,22 @@ Future<void> trackWord(String word) {
|
|||
{% block "blocks/alert" title="Unique constraints and conflict targets" %}
|
||||
> Both `insertOnConflictUpdate` and `onConflict: DoUpdate` use an `DO UPDATE`
|
||||
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
|
||||
you have custom `UNIQUE` constraints on some columns, you'll need to use
|
||||
the `target` parameter on `DoUpdate` in Dart to include those columns.
|
||||
{% endblock %}
|
||||
|
||||
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`
|
||||
includes the latest sqlite on Android, so consider using it if you want to
|
||||
support upserts.
|
||||
be available on older Android devices when using `moor_flutter`. `NativeDatabases`
|
||||
and `sqlite3_flutter_libs` includes the latest sqlite on Android, so consider using
|
||||
it if you want to support upserts.
|
||||
|
||||
Also note that the returned rowid may not be accurate when an upsert took place.
|
||||
|
||||
### Returning
|
||||
|
||||
Starting from moor version 4.3, you can use `insertReturning` to insert a row
|
||||
or companion and immediately get the row it inserts.
|
||||
You can use `insertReturning` to insert a row or companion and immediately get the row it inserts.
|
||||
The returned row contains all the default values and incrementing ids that were
|
||||
generated.
|
||||
|
||||
|
|
|
@ -1,33 +1,28 @@
|
|||
---
|
||||
data:
|
||||
title: "Moor internals"
|
||||
title: "Drift internals"
|
||||
weight: 300000
|
||||
description: Work in progress documentation on moor internals
|
||||
description: Work in progress documentation on drift internals
|
||||
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:
|
||||
|
||||
```yaml
|
||||
dependency_overrides:
|
||||
moor:
|
||||
drift:
|
||||
git:
|
||||
url: https://github.com/simolus3/moor.git
|
||||
ref: beta
|
||||
path: moor
|
||||
moor_ffi:
|
||||
path: drift
|
||||
drift_dev:
|
||||
git:
|
||||
url: https://github.com/simolus3/moor.git
|
||||
ref: beta
|
||||
path: moor_ffi
|
||||
moor_generator:
|
||||
git:
|
||||
url: https://github.com/simolus3/moor.git
|
||||
ref: beta
|
||||
path: moor_generator
|
||||
path: drift_dev
|
||||
sqlparser:
|
||||
git:
|
||||
url: https://github.com/simolus3/moor.git
|
||||
|
@ -35,5 +30,5 @@ dependency_overrides:
|
|||
path: sqlparser
|
||||
```
|
||||
|
||||
If you're using `moor_flutter`, just exchange `moor_ffi` 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.
|
||||
If you're using `moor_flutter`, just exchange `drift` with `moor_flutter` in the package name
|
||||
and path. To use the bleeding edge of drift, change `ref: beta` to `ref: develop` for all packages.
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
---
|
||||
data:
|
||||
title: Encryption
|
||||
description: Use moor on encrypted databases
|
||||
description: Use drift on encrypted databases
|
||||
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
|
||||
Java.
|
||||
Alternatively, you can use the ffi-based implementation with the `sqlcipher_flutter_libs` package.
|
||||
|
||||
## 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
|
||||
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
|
||||
with this:
|
||||
|
||||
{% assign versions = 'package:moor_documentation/versions.json' | readString | json_decode %}
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
moor: "$latest version"
|
||||
drift: ^{{ versions.drift }}
|
||||
encrypted_moor:
|
||||
git:
|
||||
url: https://github.com/simolus3/moor.git
|
||||
path: extras/encryption
|
||||
```
|
||||
|
||||
Instead of importing `package:moor_flutter/moor_flutter` (or `package:moor/ffi.dart`) in your apps,
|
||||
you would then import both `package:moor/moor.dart` and `package:encrypted_moor/encrypted_moor.dart`.
|
||||
Instead of importing `package:moor_flutter/moor_flutter` (or `package:drift/native.dart`) in your apps,
|
||||
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`.
|
||||
|
||||
|
@ -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`)
|
||||
|
||||
## Encrypted version of `moor/ffi`
|
||||
## Encrypted version of a `NativeDatabase`
|
||||
|
||||
You can also use the new `moor/ffi` library with an encrypted executor.
|
||||
This allows you to use an encrypted moor database on more platforms, which is particularly
|
||||
You can also use the new `drift/native` library with an encrypted executor.
|
||||
This allows you to use an encrypted drift database on more platforms, which is particularly
|
||||
interesting for Desktop applications.
|
||||
|
||||
### Setup
|
||||
|
@ -62,14 +65,14 @@ of the regular `libsqlite3.so`:
|
|||
```dart
|
||||
import 'package:sqlite3/open.dart';
|
||||
|
||||
// call this method before using moor
|
||||
// call this method before using drift
|
||||
void setupSqlCipher() {
|
||||
open.overrideFor(
|
||||
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.
|
||||
|
||||
On iOS and macOS, no additional setup is necessary - simply depend on `sqlcipher_flutter_libs`.
|
||||
|
@ -83,14 +86,14 @@ of SQLCipher.
|
|||
### Using
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
```dart
|
||||
VmDatabase(
|
||||
NativeDatabase(
|
||||
File(...),
|
||||
setup: (rawDb) {
|
||||
rawDb.execute("PRAGMA key = 'passphrase';");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
data:
|
||||
title: "Other engines"
|
||||
description: "Use moor on the web or other platforms"
|
||||
description: "Use drift on the web or other platforms"
|
||||
weight: 100
|
||||
template: layouts/docs/list
|
||||
---
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
---
|
||||
data:
|
||||
title: moor ffi (Desktop support)
|
||||
description: Run moor on both mobile and desktop
|
||||
title: Native Drift (Desktop support)
|
||||
description: Run drift on both mobile and desktop
|
||||
template: layouts/docs/single
|
||||
---
|
||||
|
||||
## 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
|
||||
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
|
||||
`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:
|
||||
|
||||
```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
|
||||
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
|
||||
dependencies:
|
||||
moor: ^3.0.0
|
||||
drift: ^{{ versions.drift }}
|
||||
sqlite3_flutter_libs:
|
||||
sqflite: ^1.1.7 # Still used to obtain the database location
|
||||
dev_dependencies:
|
||||
moor_generator: ^3.0.0
|
||||
drift_dev: ^{{ versions.drift_dev }}
|
||||
```
|
||||
|
||||
Adapt your imports:
|
||||
|
||||
- In the file where you created a `FlutterQueryExecutor`, replace the `moor_flutter` import
|
||||
with `package:moor/ffi.dart`.
|
||||
- In all other files where you might have imported `moor_flutter`, just import `package:moor/moor.dart`.
|
||||
with `package:drift/native.dart`.
|
||||
- In all other files where you might have imported `moor_flutter`, just import `package:drift/drift.dart`.
|
||||
|
||||
Replace the executor. This code:
|
||||
```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
|
||||
`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
|
||||
changes are required.
|
||||
|
@ -88,7 +90,7 @@ It allows you to perform some async work before opening the database:
|
|||
|
||||
```dart
|
||||
// before
|
||||
VmDatabase(File('...'));
|
||||
NativeDatabase(File('...'));
|
||||
|
||||
// after
|
||||
LazyDatabase(() async {
|
||||
|
@ -96,27 +98,27 @@ LazyDatabase(() async {
|
|||
if (!await file.exists()) {
|
||||
// copy the file from an asset, or network, or any other source
|
||||
}
|
||||
return VmDatabase(file);
|
||||
return NativeDatabase(file);
|
||||
});
|
||||
```
|
||||
|
||||
## Used compile options on Android
|
||||
|
||||
Note: Android is the only platform where moor_ffi will compile sqlite. The sqlite3 library from the system
|
||||
is used on all other platforms. The chosen options help reduce binary size by removing features not used by
|
||||
moor. Important options are marked in bold.
|
||||
On Android, iOS and macOs, depending on `sqlite3_flutter_libs` will include a custom build of sqlite instead of
|
||||
using the one from the system.
|
||||
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
|
||||
- __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
|
||||
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.
|
||||
- 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_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
|
||||
by moor.
|
||||
by drift.
|
||||
- `SQLITE_USE_ALLOCA`: Allocate temporary memory on the stack
|
||||
- `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.
|
||||
|
@ -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).
|
||||
|
||||
## 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`.
|
||||
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.
|
||||
|
||||
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:
|
||||
```dart
|
||||
import 'package:moor/moor.dart';
|
||||
// those methods are hidden behind another import because they're only available on moor_ffi
|
||||
import 'package:moor/extensions/moor_ffi.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
// those methods are hidden behind another import because they're only available with a NativeDatabase
|
||||
import 'package:drift/extensions/native.dart';
|
||||
|
||||
class Coordinates extends Table {
|
||||
RealColumn get x => real()();
|
||||
|
|
|
@ -1,28 +1,32 @@
|
|||
---
|
||||
data:
|
||||
title: Web
|
||||
description: Experimental support for moor and webapps.
|
||||
description: Experimental support for drift and webapps.
|
||||
template: layouts/docs/single
|
||||
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.
|
||||
|
||||
## 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 {
|
||||
// here, "app" is the name of the database - you can choose any name you want
|
||||
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
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
@ -48,15 +52,15 @@ won't accept it otherwise.
|
|||
## Sharing code between native apps and web
|
||||
|
||||
If you want to share your database code between native applications and webapps, just import the
|
||||
basic `moor` library into your database file.
|
||||
And instead of passing a `VmDatabase` or `WebDatabase` to the `super` constructor, make the
|
||||
basic `drift/drift.dart` library into your database file.
|
||||
And instead of passing a `NativeDatabase` or `WebDatabase` to the `super` constructor, make the
|
||||
`QueryExecutor` customizable:
|
||||
|
||||
```dart
|
||||
// don't import moor_web.dart or moor_flutter/moor_flutter.dart in shared code
|
||||
import 'package:moor/moor.dart';
|
||||
// don't import drift/web.dart or drift/native.dart in shared code
|
||||
import 'package:drift/drift.dart';
|
||||
|
||||
@UseMoor(/* ... */)
|
||||
@DriftDatabase(/* ... */)
|
||||
class SharedDatabase extends _$MyDatabase {
|
||||
SharedDatabase(QueryExecutor e): super(e);
|
||||
}
|
||||
|
@ -66,13 +70,13 @@ In native Flutter apps, you can create an instance of your database with
|
|||
|
||||
```dart
|
||||
// native.dart
|
||||
import 'package:moor/ffi.dart';
|
||||
import 'package:drift/native.dart';
|
||||
|
||||
SharedDatabase constructDb() {
|
||||
final db = LazyDatabase(() async {
|
||||
final dbFolder = await getApplicationDocumentsDirectory();
|
||||
final file = File(p.join(dbFolder.path, 'db.sqlite'));
|
||||
return VmDatabase(file);
|
||||
return NativeDatabase(file);
|
||||
});
|
||||
return SharedDatabase(db);
|
||||
}
|
||||
|
@ -82,7 +86,7 @@ On the web, you can use
|
|||
|
||||
```dart
|
||||
// web.dart
|
||||
import 'package:moor/moor_web.dart';
|
||||
import 'package:drift/web.dart';
|
||||
|
||||
SharedDatabase constructDb() {
|
||||
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).
|
||||
|
||||
## 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.
|
||||
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)
|
||||
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)`.
|
||||
|
@ -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:
|
||||
|
||||
```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
|
||||
|
||||
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).
|
||||
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!
|
||||
|
||||
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 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)
|
||||
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:
|
||||
|
||||
```dart
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:moor/moor_web.dart';
|
||||
import 'package:moor/remote.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/web.dart';
|
||||
import 'package:drift/remote.dart';
|
||||
|
||||
void main() {
|
||||
final self = SharedWorkerGlobalScope.instance;
|
||||
self.importScripts('sql-wasm.js');
|
||||
|
||||
final db = WebDatabase.withStorage(MoorWebStorage.indexedDb('worker',
|
||||
final db = WebDatabase.withStorage(DriftWebStorage.indexedDb('worker',
|
||||
migrateFromLocalStorage: false, inWebWorker: true));
|
||||
final server = MoorServer(DatabaseConnection.fromExecutor(db));
|
||||
final server = DriftServer(DatabaseConnection.fromExecutor(db));
|
||||
|
||||
self.onConnect.listen((event) {
|
||||
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:
|
||||
|
||||
```dart
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:moor/remote.dart';
|
||||
import 'package:moor/moor_web.dart';
|
||||
import 'package:drift/remote.dart';
|
||||
import 'package:drift/web.dart';
|
||||
import 'package:web_worker_example/database.dart';
|
||||
|
||||
DatabaseConnection connectToWorker() {
|
||||
|
@ -199,4 +203,4 @@ For more information on the `DatabaseConnection` class, see the documentation on
|
|||
[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)
|
||||
in the moor repository.
|
||||
in the drift repository.
|
|
@ -2,33 +2,27 @@
|
|||
data:
|
||||
title: "Custom queries"
|
||||
weight: 10
|
||||
description: Let moor generate Dart from your SQL statements
|
||||
description: Let drift generate Dart from your SQL statements
|
||||
aliases:
|
||||
- /queries/custom
|
||||
template: layouts/docs/single
|
||||
---
|
||||
|
||||
{% block "blocks/alert" title="Moor files!" color="warning" %}
|
||||
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
|
||||
Although drift 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
|
||||
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.
|
||||
|
||||
## 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
|
||||
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
|
||||
@UseMoor(
|
||||
@DriftDatabase(
|
||||
tables: [Todos, Categories],
|
||||
queries: {
|
||||
'categoriesWithCount':
|
||||
|
@ -39,13 +33,13 @@ class MyDatabase extends _$MyDatabase {
|
|||
// 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
|
||||
methods `categoriesWithCount` (which runs the query once) and `watchCategoriesWithCount` (which returns
|
||||
an auto-updating stream).
|
||||
|
||||
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)`.
|
||||
|
||||
{% 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
|
||||
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.
|
||||
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.
|
||||
{% endblock %}
|
||||
|
||||
|
@ -86,7 +80,7 @@ Stream<List<CategoryWithCount>> categoriesWithCount() {
|
|||
readsFrom: {todos, categories}, // used for the stream: the stream will update when either table changes
|
||||
).watch().map((rows) {
|
||||
// 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
|
||||
return rows
|
||||
.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
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
streams, which will then update automatically.
|
||||
|
|
|
@ -7,30 +7,30 @@ template: layouts/docs/single
|
|||
---
|
||||
|
||||
_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.
|
||||
This enables the extensions listed here on all Android devices and on iOS 11 and later.
|
||||
be available on all devices. When using these extensions, using a `NativeDatabase` is strongly recommended.
|
||||
This enables the extensions listed here on all Android and iOS devices.
|
||||
|
||||
## 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
|
||||
`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.
|
||||
|
||||
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
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:moor/extensions/json1.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/extensions/json1.dart';
|
||||
|
||||
class Contacts extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
TextColumn get data => text()();
|
||||
}
|
||||
|
||||
@UseMoor(tables: [Contacts])
|
||||
@DriftDatabase(tables: [Contacts])
|
||||
class Database extends _$Database {
|
||||
// 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
|
||||
|
||||
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
|
||||
`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.
|
||||
```sql
|
||||
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.
|
||||
|
||||
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).
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
data:
|
||||
title: "Using SQL"
|
||||
weight: 30
|
||||
description: Write typesafe sql with moor
|
||||
description: Write typesafe sql with drift
|
||||
template: layouts/docs/list
|
||||
---
|
||||
|
||||
Moor 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
|
||||
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. Drift has a builtin
|
||||
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.
|
|
@ -1,36 +1,37 @@
|
|||
---
|
||||
data:
|
||||
title: "Moor files"
|
||||
title: "Drift files"
|
||||
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:
|
||||
- /docs/using-sql/custom_tables/ # Redirect from outdated "custom tables" page which has been deleted
|
||||
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
|
||||
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:
|
||||
```dart
|
||||
import 'package:moor_flutter/moor_flutter.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@UseMoor(
|
||||
include: {'tables.moor'},
|
||||
@DriftDatabase(
|
||||
include: {'tables.drift'},
|
||||
)
|
||||
class MoorDb extends _$MoorDb {
|
||||
MoorDb() : super(FlutterQueryExecutor.inDatabaseFolder(path: 'app.db'));
|
||||
class MyDb extends _$MyDb {
|
||||
MyDb() : super(NativeDatabase.memory());
|
||||
|
||||
@override
|
||||
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
|
||||
CREATE TABLE todos (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
|
@ -44,7 +45,7 @@ CREATE TABLE categories (
|
|||
description TEXT NOT NULL
|
||||
) 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);
|
||||
|
||||
-- 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`,
|
||||
moor will write the `database.g.dart`
|
||||
file which contains the `_$MoorDb` superclass. Let's take a look at
|
||||
drift will write the `database.g.dart`
|
||||
file which contains the `_$MyDb` superclass. Let's take a look at
|
||||
what we got:
|
||||
|
||||
- Generated data classes (`Todo` and `Category`), and companion versions
|
||||
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
|
||||
`Categorie` otherwise.
|
||||
- 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`)
|
||||
and colon-named variables (`:id`). We don't support variables declared
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
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.
|
||||
2. __No higher explicit index after a variable__: Running
|
||||
`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.
|
||||
|
||||
## 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.
|
||||
|
||||
## 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
|
||||
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
|
||||
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
|
||||
visible.
|
||||
Note that imports in moor file are always transitive, so in the above example
|
||||
you would have all imports declared in `other.moor` available as well.
|
||||
There is no `export` mechanism for moor files.
|
||||
Note that imports in drift file are always transitive, so in the above example
|
||||
you would have all imports declared in `other.drift` available as well.
|
||||
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.
|
||||
We support both relative imports and the `package:` imports you
|
||||
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;
|
||||
```
|
||||
|
||||
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
|
||||
a `long1` field.
|
||||
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;
|
||||
```
|
||||
|
||||
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.
|
||||
For this query, moor will generate the following class:
|
||||
For this query, drift will generate the following class:
|
||||
```dart
|
||||
class RoutesWithNestedPointsResult {
|
||||
final int id;
|
||||
|
@ -215,21 +216,21 @@ At the moment, there are some limitations with this approach:
|
|||
valued functions.
|
||||
|
||||
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`
|
||||
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`.
|
||||
|
||||
## 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
|
||||
Future<void> insert(TodosCompanion companion) async {
|
||||
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.
|
||||
- generated methods for queries can be used in transactions, they work
|
||||
together with auto-updating queries, etc.
|
||||
|
@ -247,7 +248,7 @@ $-variable in a query:
|
|||
```sql
|
||||
_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:
|
||||
```dart
|
||||
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
|
||||
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
|
||||
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.
|
||||
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:
|
||||
|
||||
```dart
|
||||
|
@ -310,7 +311,7 @@ Future<List<Route>> routesByStart(int startPointId) {
|
|||
### Type converters
|
||||
|
||||
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:
|
||||
```sql
|
||||
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 }}).
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
```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
|
||||
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 (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
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
|
||||
|
@ -361,7 +361,7 @@ For more general information on this feature, please check [this page]({{ '../Ad
|
|||
|
||||
## 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.
|
||||
|
||||
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,
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
## 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.
|
||||
- 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.
|
||||
|
||||
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!
|
|
@ -6,7 +6,7 @@ data:
|
|||
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.
|
||||
|
||||
## Features
|
||||
|
@ -26,27 +26,27 @@ us here.
|
|||
## Setup
|
||||
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
|
||||
this section:
|
||||
```yaml
|
||||
analyzer:
|
||||
plugins:
|
||||
- moor
|
||||
- drift
|
||||
```
|
||||
|
||||
Then, follow the steps for the IDE you want to use.
|
||||
|
||||
### 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
|
||||
"dart.additionalAnalyzerFileExtensions": ["moor"]
|
||||
"dart.additionalAnalyzerFileExtensions": ["drift"]
|
||||
```
|
||||
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).
|
||||
|
||||
### 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
|
||||
[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
|
||||
syntax works well. See [this comment](https://github.com/simolus3/moor/issues/150#issuecomment-538582696)
|
||||
on how to set this up.
|
||||
|
|
|
@ -6,7 +6,7 @@ template: layouts/docs/single
|
|||
---
|
||||
|
||||
{% 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)
|
||||
or via email to oss <at>simonbinder<dot>eu.
|
||||
{% endblock %}
|
||||
|
@ -14,7 +14,7 @@ or via email to oss <at>simonbinder<dot>eu.
|
|||
## Moor inspector
|
||||
|
||||
[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 [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](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
|
||||
rows by columns that you've added to moor.
|
||||
rows by columns that you've added to your tables.
|
||||
|
||||
## moor2csv
|
||||
|
||||
[Dhiman Seal](https://github.com/Dhi13man) wrote a package to export moor databases as csv files.
|
||||
The package is [on pub](https://pub.dev/packages/moor2csv).
|
||||
[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).
|
||||
|
|
|
@ -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?
|
||||
|
||||
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
|
||||
`analysis_options.yaml` in your project and add this content:
|
||||
```yaml
|
||||
|
@ -66,7 +66,7 @@ You might have to restart your IDE for the changes to apply.
|
|||
## How can I inspect generated SQL?
|
||||
|
||||
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?
|
||||
|
||||
|
@ -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.
|
||||
|
||||
That said, here's an incomplete (and obviously biased) list of great libraries and how moor compares to them.
|
||||
If you have experience with any of these (or other) libraries and want to share how they compare to moor, please
|
||||
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 drift, please
|
||||
feel invited to contribute to this page.
|
||||
|
||||
### sqflite, sqlite3
|
||||
|
||||
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
|
||||
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
|
||||
* 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.
|
||||
|
||||
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.
|
||||
|
||||
### sqlcool
|
||||
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.
|
||||
|
||||
## 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
|
||||
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.
|
||||
|
||||
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.
|
||||
Drift can also be used with [custom row classes]({{ 'Advanced Features/custom_row_classes.md' | pageUrl }}) though.
|
||||
|
||||
## firebase
|
||||
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
|
||||
- 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)
|
||||
package by Koen Van Looveren.
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
---
|
||||
data:
|
||||
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
|
||||
---
|
||||
|
||||
## 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/)
|
||||
and provides additional features, like:
|
||||
|
||||
- __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.
|
||||
- __Stream queries__: Moor let's you "watch" your queries with zero additional effort. Any query can be turned into
|
||||
return, drift turns rows into objects of your choice.
|
||||
- __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.
|
||||
- __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.
|
||||
- __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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
---
|
||||
data:
|
||||
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
|
||||
---
|
||||
|
||||
Being built ontop of the sqlite3 database, moor can run on almost every Dart platform.
|
||||
Since the initial release of moor, 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
|
||||
for moor's most popular implemention.
|
||||
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.
|
||||
Being built ontop of the sqlite3 database, drift can run on almost every Dart platform.
|
||||
Since the initial release, the Dart and Flutter ecosystems have changed a lot.
|
||||
To clear confusion about different drift packages and when to use them, this document
|
||||
lists all supported platforms and how to use drift 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
|
||||
outside of Flutter. When writing moor apps, prefer to mainly use the apis in
|
||||
`package:moor/moor.dart` as they are guaranteed to work across all platforms.
|
||||
outside of Flutter. When writing drift apps, prefer to mainly use the apis in
|
||||
`package:drift/drift.dart` as they are guaranteed to work across all platforms.
|
||||
Depending on your platform, you can choose a different `QueryExecutor`.
|
||||
|
||||
## 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`
|
||||
|
||||
|
@ -29,16 +27,16 @@ only works on Android and iOS.
|
|||
For new projects, we generally recommend the newer ffi-based implementation, but `moor_flutter`
|
||||
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.
|
||||
|
||||
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" %}
|
||||
> `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:
|
||||
|
||||
- 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 }})_
|
||||
|
||||
For apps that run on the web, you can use moor's experimental web implementation, located
|
||||
in `package:moor/moor_web.dart`.
|
||||
For apps that run on the web, you can use drift's experimental web implementation, located
|
||||
in `package:drift/web.dart`.
|
||||
As it binds to [sql.js](https://github.com/sql-js/sql.js), special setup is required. Please
|
||||
read the main article for details.
|
||||
|
||||
## Desktop
|
||||
|
||||
Moor 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
|
||||
Drift also supports all major Desktop operating systems where Dart runs on by using the
|
||||
`NativeDatabase` from `package:drift/native.dart`. Depending on your operating system, further
|
||||
setup might be required:
|
||||
|
||||
### Windows
|
||||
|
||||
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
|
||||
details.
|
||||
|
||||
### 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
|
||||
distros, you can install the `libsqlite3-dev` package for this. Virtually every other distribution
|
||||
will also have a prebuilt package for sqlite.
|
||||
|
@ -88,12 +86,12 @@ details.
|
|||
|
||||
### 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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
### Bundling sqlite with your app
|
||||
|
@ -115,7 +113,7 @@ import 'package:sqlite3/open.dart';
|
|||
void main() {
|
||||
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() {
|
||||
|
@ -126,7 +124,7 @@ DynamicLibrary _openOnLinux() {
|
|||
// _openOnWindows could be implemented similarly by opening `sqlite3.dll`
|
||||
```
|
||||
|
||||
Be sure to use moor _after_ you set the platform-specific overrides.
|
||||
When you use moor in [another isolate]({{ 'Advanced Features/isolates.md' | pageUrl }}),
|
||||
Be sure to use drift _after_ you set the platform-specific overrides.
|
||||
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 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.
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
---
|
||||
data:
|
||||
title: "Testing"
|
||||
description: Guide on writing unit tests for moor databases
|
||||
description: Guide on writing unit tests for drift databases
|
||||
|
||||
template: layouts/docs/single
|
||||
---
|
||||
|
||||
Flutter apps using moor 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.
|
||||
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 drift.
|
||||
Those tests can be run and debugged on your computer without additional setup, you don't need a
|
||||
physical device to run them.
|
||||
|
||||
## 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
|
||||
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
|
||||
For this guide, we're going to test a very simple database that stores user names. The only important change from a regular drift
|
||||
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
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
|
@ -29,7 +27,7 @@ class Users extends Table {
|
|||
TextColumn get name => text()();
|
||||
}
|
||||
|
||||
@UseMoor(tables: [Users])
|
||||
@DriftDatabase(tables: [Users])
|
||||
class MyDatabase extends _$MyDatabase {
|
||||
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
|
||||
`package:test`:
|
||||
```dart
|
||||
import 'package:moor_ffi/moor_ffi.dart';
|
||||
import 'package:drift/native.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';
|
||||
|
||||
void main() {
|
||||
|
@ -117,5 +115,5 @@ test('stream emits a new user when the name updates', () async {
|
|||
|
||||
## 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 }}).
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
data:
|
||||
title: "Transactions"
|
||||
weight: 70
|
||||
description: Run multiple queries atomically
|
||||
description: Run multiple statements atomically
|
||||
|
||||
template: layouts/docs/single
|
||||
aliases:
|
||||
- /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
|
||||
is finished.
|
||||
To begin a transaction, call the `transaction` method on your database or a DAO.
|
||||
|
|
|
@ -10,7 +10,7 @@ path: ""
|
|||
<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>
|
||||
</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>
|
||||
</a>
|
||||
|
||||
|
@ -23,7 +23,7 @@ path: ""
|
|||
{% endblock %}
|
||||
|
||||
{% 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!
|
||||
{% 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/markdown.html" %}
|
||||
With moor, 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
|
||||
With drift, you can write your database tables in pure Dart without having to miss out on
|
||||
advanced sqlite features. Drift will take care of creating the tables and generate code
|
||||
that allows you run fluent queries on your data.
|
||||
|
||||
[Get started now]({{ "docs/Getting started/index.md" | pageUrl }})
|
||||
{% 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" %}
|
||||
Moor 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
|
||||
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 drift can provide hints about potential errors quickly and generate efficient mapping
|
||||
code.
|
||||
|
||||
[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/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
|
||||
When using moor, working with databases in Dart is fun!
|
||||
When using drift, working with databases in Dart is fun!
|
||||
{% 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/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.
|
||||
* __Polyglot__: Moor 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
|
||||
* __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__: 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 - drift can take of that. Drift generates Dart code around your data so you can focus
|
||||
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?
|
||||
Moor 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
|
||||
* __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?
|
||||
Drift will generate efficient SQL for Dart queries too.
|
||||
* __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.
|
||||
* __Fast _and_ powerful__: With the new `ffi` backend, moor 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.
|
||||
* __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
|
||||
* __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. Drift is the only major persistence library with builtin support for multiple isolates.
|
||||
* __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.
|
||||
* __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 %}
|
||||
|
|
Loading…
Reference in New Issue