From e7488f9a77794457f26ea2c6f45cb8f8e630a254 Mon Sep 17 00:00:00 2001 From: Moshe Dicker Date: Wed, 16 Oct 2024 15:04:13 -0400 Subject: [PATCH] ok, great --- docs/docs/Internals/index.md | 4 +- docs/docs/_redirects | 2 + .../dataclass.md} | 189 +++++++++++----- docs/docs/dart_api/manager.md | 8 +- docs/docs/dart_api/tables.md | 59 ++++- docs/docs/faq.md | 2 +- docs/docs/migrating_to_drift.md | 2 +- docs/docs/sql_api/custom_types.md | 0 docs/docs/sql_api/drift_files.md | 14 +- docs/docs/type_converters.md | 211 ------------------ docs/docs/upgrading.md | 2 +- docs/lib/snippets/dart_api/dataclass.dart | 75 +++++++ docs/lib/snippets/dart_api/references.dart | 41 ---- docs/lib/snippets/dart_api/tables.dart | 29 ++- docs/mkdocs/mkdocs.yml | 22 +- 15 files changed, 305 insertions(+), 355 deletions(-) rename docs/docs/{custom_row_classes.md => dart_api/dataclass.md} (72%) create mode 100644 docs/docs/sql_api/custom_types.md delete mode 100644 docs/docs/type_converters.md create mode 100644 docs/lib/snippets/dart_api/dataclass.dart delete mode 100644 docs/lib/snippets/dart_api/references.dart diff --git a/docs/docs/Internals/index.md b/docs/docs/Internals/index.md index e1ebcec47..58bf7540e 100644 --- a/docs/docs/Internals/index.md +++ b/docs/docs/Internals/index.md @@ -1,7 +1,7 @@ --- -title: Drift internals -description: Work in progress documentation on drift internals +title: Install from GitHub +description: How to install drift from GitHub --- diff --git a/docs/docs/_redirects b/docs/docs/_redirects index 3e159efc8..2bcd583b6 100644 --- a/docs/docs/_redirects +++ b/docs/docs/_redirects @@ -53,4 +53,6 @@ /docs/platforms/postgres/ /Platforms/postgres/ /docs/advanced-features/daos/ /dart_api/daos/ /api/* https://pub.dev/documentation/drift/latest/index.html +https://drift.simonbinder.eu/custom_row_classes/ /dart_api/dataclass/ +https://drift.simonbinder.eu/type_converters/ /dart_api/tables/#custom-types diff --git a/docs/docs/custom_row_classes.md b/docs/docs/dart_api/dataclass.md similarity index 72% rename from docs/docs/custom_row_classes.md rename to docs/docs/dart_api/dataclass.md index bd7c925dd..29c3742dc 100644 --- a/docs/docs/custom_row_classes.md +++ b/docs/docs/dart_api/dataclass.md @@ -1,23 +1,112 @@ --- -title: Custom row classes -description: Use your own classes as data classes for drift tables +title: Dataclass +description: Dataclass for reading and writing data to the database. --- -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: 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. -As a solution, drift allows you to use your own classes as data classes for the database. -## Using custom classes +# Generated Dataclass -To use a custom row class, simply annotate your table definition with `@UseRowClass`. +Drift generates a dataclass for each table in your database. These dataclasses represent query results and come with built-in equality, hashing, and serialization support. They also include a `copyWith` method for easy modification. + +**Example:** + +For a `Users` table, Drift automatically generates a `User` dataclass. This dataclass is used for all read operations from the `Users` table, ensuring type-safe and structured data retrieval. + +{{ load_snippet('generated-dataclass','lib/snippets/dart_api/dataclass.dart.excerpt.json') }} + +## Dataclass Name + +The dataclass name is derived from the table name. + +- If the name ends in `s`, the dataclass name will be the name with `s` removed. + - Example: `Users` -> `User` +- Otherwise, the dataclass name will be the name with `Data` appended. + - Example: `UserInfo` -> `UserInfoData` + + +To use a custom name use the `@DataClassName` annotation. + +**Example:** + +{{ load_snippet('data-class-name','lib/snippets/dart_api/dataclass.dart.excerpt.json') }} + +## Json serialization + +### Key names +When serializing to json, the generated dataclass will use the column name in `snake_case` for the json keys. + +**Example:** + +{{ load_snippet('default-json-keys','lib/snippets/dart_api/dataclass.dart.excerpt.json') }} + +```json +{ + "id": 1, + "title": "Todo 1", + "created_at": "2024-02-29T12:00:00Z" +} +``` + +### Custom json keys + +To use a custom name for JSON serialization, use the `@JsonKey` annotation. + +**Example:** + +{{ load_snippet('custom-json-keys','lib/snippets/dart_api/dataclass.dart.excerpt.json') }} + +```json +{ + "id": 1, + "title": "Todo 1", + "created": "2024-02-29T12:00:00Z" +} +``` + +If you prefer to use the actual column name in SQL as the JSON key, set `use_sql_column_name_as_json_key` to `true` in the `build.yaml` file. + +```yaml title="build.yaml" +targets: + $default: + builders: + drift_dev: + options: + use_sql_column_name_as_json_key : true +``` +For more details on customizing column names in SQL, refer to the [column name](tables.md#named) documentation. + +## Companions + +In addition to the generated dataclass representing a complete row, Drift also generates a companion object for each table, which represents a partial row and can be used to update existing rows. + +
+ +{{ load_snippet('generated-companion','lib/snippets/dart_api/dataclass.dart.excerpt.json') }} + +
+1. `o()` is just a helper function that creates a `UsersCompanion`. + +### Value object +When using the companion object to update a row, optional fields must be wrapped in a `Value` object. This is used by Drift to distinguish between `null` and not present values. + +{{ load_snippet('generated-value','lib/snippets/dart_api/dataclass.dart.excerpt.json') }} + +## Custom dataclass + +The generated dataclass works well for most cases, but you might want to use your own class as a dataclass for a table. + +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. + +!!! note "Row Class" + + In the documentation, we use the terms _row class_ and _dataclass_ interchangeably. + Both refer to a class that represents a row of a database table. + +To use a custom row class, simply annotate your table definition with `@UseRowClass`. {{ load_snippet('start','lib/snippets/custom_row_classes/default.dart.excerpt.json','lib/snippets/custom_row_classes/named.dart.excerpt.json') }} @@ -46,6 +135,32 @@ If you want to use another constructor, set the `constructor` parameter on the {{ load_snippet('named','lib/snippets/custom_row_classes/default.dart.excerpt.json','lib/snippets/custom_row_classes/named.dart.excerpt.json') }} +### Custom companions + +In most cases, generated companion classes are the right tool for updates and inserts. +If you prefer to use your custom row class for inserts, just make it implement `Insertable`, where +`T` is the tye of your row class itself. +For instance, the previous class could be changed like this: + +```dart +class User implements Insertable { + final int id; + final String name; + final DateTime birthDate; + + User({required this.id, required this.name, required this.birthDate}); + + @override + Map toColumns(bool nullToAbsent) { + return UsersCompanion( + id: Value(id), + name: Value(name), + birthDate: Value(birthDate), + ).toColumns(nullToAbsent); + } +} +``` + ### Static and asynchronous factories Starting with drift 2.0, the custom constructor set with the `constructor` @@ -65,7 +180,7 @@ class User { } ``` -### Existing row classes in drift files +### Custom dataclass in drift files 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 @@ -98,33 +213,7 @@ CREATE TABLE users( ) WITH User.myNamedConstructor; ``` -## Inserts and updates with custom classes - -In most cases, generated companion classes are the right tool for updates and inserts. -If you prefer to use your custom row class for inserts, just make it implement `Insertable`, where -`T` is the name of your row class itself. -For instance, the previous class could be changed like this: - -```dart -class User implements Insertable { - final int id; - final String name; - final DateTime birthDate; - - User({required this.id, required this.name, required this.birthDate}); - - @override - Map toColumns(bool nullToAbsent) { - return UsersCompanion( - id: Value(id), - name: Value(name), - birthDate: Value(birthDate), - ).toColumns(nullToAbsent); - } -} -``` - -## Existing row classes for queries +#### Custom dataclass for queries Existing row classes may also be applied to named queries defined in a `.drift` file. They have a similar syntax, adding the `WITH` keyword after the name of the query: @@ -257,25 +346,3 @@ If you have questions about existing result classes, or think you have found an properly handled, please [start a discussion](https://github.com/simolus3/drift/discussions/new) in the drift repository, thanks! -## When custom classes make sense - -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, 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. -- Custom superclasses: A custom row class can extend and class and implement or mix-in other classes - as desired. -- Other code generators: Since you control the row class, you can make better use of other builders like - `json_serializable` or `built_value`. - -## Limitations - -These restrictions will be gradually lifted in upcoming drift versions. Follow [#1134](https://github.com/simolus3/drift/issues/1134) for details. - -For now, this feature is subject to the following limitations: - -- In drift files, you can only use the default unnamed constructor - diff --git a/docs/docs/dart_api/manager.md b/docs/docs/dart_api/manager.md index 99e021aff..a241bec8e 100644 --- a/docs/docs/dart_api/manager.md +++ b/docs/docs/dart_api/manager.md @@ -1,17 +1,11 @@ --- -title: Manager +title: Queries description: Use easier bindings for common queries. --- - -With generated code, drift allows writing SQL queries in type-safe Dart. -While this is provides lots of flexibility, it requires familiarity with SQL. -As a simpler alternative, drift 2.18 introduced a new set of APIs designed to -make common queries much easier to write. - The examples on this page use the database from the [setup](../setup.md) instructions. diff --git a/docs/docs/dart_api/tables.md b/docs/docs/dart_api/tables.md index 45d9fb4dd..c72b41d0a 100644 --- a/docs/docs/dart_api/tables.md +++ b/docs/docs/dart_api/tables.md @@ -179,7 +179,7 @@ Columns can be customized with several options. These options are available on a Customize this by setting the `case_from_dart_to_sql` option in your `build.yaml` file. - ```yaml + ```yaml title="build.yaml" targets: $default: builders: @@ -258,7 +258,6 @@ Every table in a database should have a primary key - a column or set of columns --- - ## Multi-column uniqueness To enforce that a combination of columns is unique, override the `uniqueKeys` getter in your table class. @@ -328,13 +327,22 @@ See the [DateTime Guide](../guides/datetime-migrations.md) for more information --- + ## Custom types Any Dart type can be stored in the database by converting it to one of the built-in types. -Define a class which extends `TypeConverter` and implement the `toSql` and `fromSql` methods to convert between the Dart type and the type stored in the database. +Use the `.map()` method on the column to apply a `TypeConverter` to a column. -Apply the converter to a column using the `.map()` method on the column. +To create a custom type converter: + +1. Define a class that extends `TypeConverter`, where: + - `D` is the Dart type you want to use in your code + - `S` is the SQL type that will be stored in the database +2. Implement the `toSql(D value)` and `fromSql(S fromDb)` methods +3. Mix in `JsonTypeConverter` to enable serialization to/from JSON (Optional). + - This is optional, but recommended for dataclasses. + - Use the same generic parameters as the `TypeConverter` class. #### Example: @@ -348,6 +356,9 @@ Apply the converter to a column using the `.map()` method on the column. In this case, we are storing `Duration`. 2. Built-in type we are converting to. In this case, we are converting `Duration` to `int`. +3. Mix in `JsonTypeConverter` so that we can serialize dataclasses to/from JSON. + +Apply the converter to a column using the `.map()` method on the column. {{ load_snippet('apply_converter','lib/snippets/dart_api/tables.dart.excerpt.json') }} @@ -361,9 +372,43 @@ Now we can use the `Duration` type as if it were a built-in type. Consider using a package like `equatable`, `freezed` or `dart_mappable` to create classes which implement this automatically. -### JSON conversion +??? note "Different Types for JSON and SQL Serialization" + + If you would like to convert to a different type for JSON and SQL serialization, use `JsonTypeConverter2` instead of `JsonTypeConverter`. + + **Example:** + + A common use case is to store a `Preferences` object as a JSON string in the database, but represent it as a `Map` in JSON. + + ??? example "`Preferences` Class" + + {{ load_snippet('jsonserializable_type','lib/snippets/dart_api/tables.dart.excerpt.json') }} -Drift offers a convenient way to store JSON serializable types using `TypeConverter.json()`. +
+ {{ load_snippet('custom_json_converter','lib/snippets/dart_api/tables.dart.excerpt.json', indent=4) }} +
+ + This is how the above example looks like in JSON: + + **Before:** + + ```json + { + "preferences": "{\"isDarkMode\": true, \"language\": \"en\"}" + } + ``` + + **After:** + + ```json + { + "preferences": {"isDarkMode": true, "language": "en"} + } + ``` + +### JSON types + +Drift offers a convenient way to store JSON serializable objects using `TypeConverter.json()`. **Example:** @@ -373,7 +418,7 @@ Drift offers a convenient way to store JSON serializable types using `TypeConver {{ load_snippet('jsonserializable_type','lib/snippets/dart_api/tables.dart.excerpt.json') }} - +--- ### Enums diff --git a/docs/docs/faq.md b/docs/docs/faq.md index f63642a22..920a96b53 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -1,6 +1,6 @@ --- -title: Frequently asked questions +title: FAQ --- diff --git a/docs/docs/migrating_to_drift.md b/docs/docs/migrating_to_drift.md index 417f7ccd5..677474375 100644 --- a/docs/docs/migrating_to_drift.md +++ b/docs/docs/migrating_to_drift.md @@ -1,6 +1,6 @@ --- -title: Migrating to drift +title: Migrate to Drift description: Resources on how to migrate to drift from other database packages. --- diff --git a/docs/docs/sql_api/custom_types.md b/docs/docs/sql_api/custom_types.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/docs/sql_api/drift_files.md b/docs/docs/sql_api/drift_files.md index c6d314746..62d13ef32 100644 --- a/docs/docs/sql_api/drift_files.md +++ b/docs/docs/sql_api/drift_files.md @@ -343,18 +343,24 @@ SELECT FROM users; ``` -More details on type converts in drift files are available -[here](../type_converters.md#using-converters-in-drift). - When using type converters, we recommend the [`apply_converters_on_variables`](../generation_options/index.md) 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`. +Drift files also have special support for implicit enum converters: -### Existing row classes +```sql +import 'status.dart'; +CREATE TABLE tasks ( + id INTEGER NOT NULL PRIMARY KEY, + status ENUM(Status) +); +``` +Of course, the [warning](../dart_api/tables.md#implicit-enum-converters) about automatic enum converters also applies to drift files. +### Existing row classes 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 diff --git a/docs/docs/type_converters.md b/docs/docs/type_converters.md deleted file mode 100644 index 52396ccb8..000000000 --- a/docs/docs/type_converters.md +++ /dev/null @@ -1,211 +0,0 @@ ---- - -title: Type converters -description: Store more complex data in columns with type converters - ---- - -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. 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 - -{{ load_snippet('start','lib/snippets/type_converters/converters.dart.excerpt.json') }} - -Next, we have to tell drift how to store a `Preferences` object in the database. We write -a `TypeConverter` for that: - -{{ load_snippet('converter','lib/snippets/type_converters/converters.dart.excerpt.json') }} - -Finally, we can use that converter in a table declaration: - -{{ load_snippet('table','lib/snippets/type_converters/converters.dart.excerpt.json') }} - -The generated `User` class will then have a `preferences` column of type -`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"). - -!!! warning "Caution with equality" - - - If your converter returns an object that is not comparable by value, the generated dataclass will not - be comparable by value. Consider implementing `==` and `hashCode` on those classes. - - - - -Since applying type converters for JSON conversion is so common, drift provides a helper -for that. For instance, we could declare the type converter as a field in the -`Preferences` class: - -{{ load_snippet('simplified','lib/snippets/type_converters/converters.dart.excerpt.json') }} - -!!! info "Why JSON converters?" - - By default, type converters are only applied to the mapping from Dart to and from SQL. - Drift also generates `fromJson` and `toJson` methods on data classes, and those don't - apply type converters by default. - By mixing in `JsonTypeConverter`, you tell drift that the converter should also be considered - for JSON serialization. - - -### 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, drift has the integrated `intEnum` column type to make this -easier. - -```dart -enum Status { - none, - running, - stopped, - paused -} - -class Tasks extends Table { - IntColumn get id => integer().autoIncrement()(); - IntColumn get status => intEnum()(); -} -``` - -!!! warning "Caution with enums" - - - It can be easy to accidentally invalidate your database by introducing another enum value. - For instance, let's say we inserted a `Task` into the database in the above example and set its - `Status` to `running` (index = 1). - Now we modify `Status` enum to include another entry: - ```dart - enum Status { - none, - starting, // new! - running, - stopped, - paused - } - ``` - When selecting the task, it will now report as `starting`, as that's the new value at index 1. - For this reason, it's best to add new values at the end of the enumeration, where they can't conflict - with existing values. Otherwise you'd need to bump your schema version and run a custom update statement - to fix this. - - - - -If you prefer to store the enum as a text, you can use `textEnum` instead. - -```dart -enum Status { - none, - running, - stopped, - paused -} - -class Tasks extends Table { - IntColumn get id => integer().autoIncrement()(); - TextColumn get status => textEnum()(); -} -``` - -!!! warning "Caution with enums" - - - It can be easy to accidentally invalidate your database by renaming your enum values. - For instance, let's say we inserted a `Task` into the database in the above example and set its - `Status` to `running`. - Now we modify `Status` enum to rename `running` into `processing`: - ```dart - enum Status { - none, - processing, - stopped, - paused - } - ``` - When selecting the task, it won't be able to find the enum value `running` anymore, and will throw an error. - - For this reason, it's best to not modify the name of your enum values. Otherwise you'd need to bump your schema version and run a custom update statement to fix this. - - - - -Also note that you can't apply another type converter on a column declared with an enum converter. - -## Using converters in drift 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 drift for the type converter to -be available. - -```sql -import 'preferences.dart'; - -CREATE TABLE users ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - name TEXT, - preferences TEXT MAPPED BY `const PreferenceConverter()` -); -``` - -When using type converters in drift files, we recommend the [`apply_converters_on_variables`](generation_options/index.md) -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`. - -Drift files also have special support for implicit enum converters: - -```sql -import 'status.dart'; - -CREATE TABLE tasks ( - id INTEGER NOT NULL PRIMARY KEY, - status ENUM(Status) -); -``` - -Of course, the warning about automatic enum converters also applies to drift files. - -## Type converters and json serialization - -By default, type converters only apply to the conversion from Dart to the database. They don't impact how -values are serialized to and from JSON. -If you want to apply the same conversion to JSON as well, make your type converter mix-in the -`JsonTypeConverter` class. -You can also override the `toJson` and `fromJson` methods to customize serialization as long as the types -stay the compatible. -The type converter returned by `TypeConverter.json` already implements `JsonTypeConverter`, so it will -apply to generated row classes as well. - -If the JSON type you want to serialize to is different to the SQL type you're -mapping to, you can mix-in `JsonTypeConverter2` instead. -For instance, say you have a type converter mapping to a complex Dart type -`MyObject`. In SQL, you might want to store this as an `String`. But when -serializing to JSON, you may want to use a `Map`. Here, simply -add the `JsonTypeConverter2>` mixin to -your type converter. - -As an alternative to using JSON type converters, you can use a custom [`ValueSerializer`](https://drift.simonbinder.eu/api/drift/valueserializer-class) -and pass it to the serialization methods. - -## Type converters and SQL - -In database rows, columns to which a type converter has been applied are storing the result of -`toSql()`. Drift will apply the type converter automatically when reading or writing rows, but they -are not applied automatically when creating your own [expressions]('dart_api/expressions.md'). -For example, filtering for values with [`column.equals`](https://drift.simonbinder.eu/api/drift/expression/equals) -will compare not apply the type converter, you'd be comparing the underlying database values. - -On columns with type converters, [`equalsValue`](https://drift.simonbinder.eu/api/drift/generatedcolumnwithtypeconverter/equalsvalue) -can be used instead - unlike `equals`, `equasValue` will apply the converter before emtting a comparison in SQL. -If you need to apply the converter for other comparisons as well, you can do that manually with `column.converter.toSql`. - -For variables used in queries that are part of a [drift file]('sql_api/drift_files.md'), type converters will be -applied by default if the `apply_converters_on_variables` [builder option]('generation_options/index.md') is enabled (which it is by default). diff --git a/docs/docs/upgrading.md b/docs/docs/upgrading.md index 741da25ac..3d690bb8a 100644 --- a/docs/docs/upgrading.md +++ b/docs/docs/upgrading.md @@ -1,6 +1,6 @@ --- -title: Upgrading +title: Upgrading Drift description: How to upgrade between major drift versions --- diff --git a/docs/lib/snippets/dart_api/dataclass.dart b/docs/lib/snippets/dart_api/dataclass.dart new file mode 100644 index 000000000..73f522275 --- /dev/null +++ b/docs/lib/snippets/dart_api/dataclass.dart @@ -0,0 +1,75 @@ +import 'dart:convert'; + +import 'package:drift/drift.dart'; + +part 'dataclass.g.dart'; + +// #docregion table +class Users extends Table { + late final id = integer().autoIncrement()(); + late final name = text()(); +} + +// #enddocregion table +// #docregion data-class-name +@DataClassName('Category') +class Categories extends Table { + late final id = integer().autoIncrement()(); + late final title = text()(); +} +// #enddocregion data-class-name + +// #docregion default-json-keys +class Todos extends Table { + late final id = integer().autoIncrement()(); + late final title = text()(); + late final createdAt = dateTime().withDefault(currentDateAndTime)(); +} +// #enddocregion default-json-keys + +class Todos1 extends Table { + // #docregion custom-json-keys + @JsonKey('created') + late final createdAt = dateTime().withDefault(currentDateAndTime)(); + // #enddocregion custom-json-keys +} + +@DriftDatabase(tables: [Users, Categories]) +class Database extends _$Database { + Database(super.e); + + @override + int get schemaVersion => 1; +} + +void _query(Database db) async { + // #docregion generated-dataclass + // Read a single user from the database. + final User user = await db.managers.users.filter((f) => f.id(1)).getSingle(); + + /// Interact with the user in a type-safe manner. + print("Hello ${user.name}!"); + // #enddocregion generated-dataclass + + // #docregion generated-companion + // Create a new user with the Manager API + await db.managers.users.create((o) => o(name: "New user") /* (1)! */); + + // Update the user with the Manager API + await db.managers.users + .filter((f) => f.id(1)) + .update((o) => o(name: Value("New user")) /* (1)! */); + + // Create a new user with the Core API + db.into(db.users).insert(UsersCompanion.insert(name: "New user")); + + // Update the user with the Core API + await (db.update(db.users)..where((tbl) => tbl.id.equals(1))) + .write(UsersCompanion(name: Value("New user"))); + // #enddocregion generated-companion + + // #docregion generated-value + await (db.update(db.users)..where((tbl) => tbl.id.equals(1))) + .write(UsersCompanion(name: Value("New user"))); + // #enddocregion generated-value +} diff --git a/docs/lib/snippets/dart_api/references.dart b/docs/lib/snippets/dart_api/references.dart deleted file mode 100644 index 1ac158b15..000000000 --- a/docs/lib/snippets/dart_api/references.dart +++ /dev/null @@ -1,41 +0,0 @@ -// ignore_for_file: unused_local_variable, unused_element - -import 'dart:convert'; - -import 'package:drift/drift.dart'; - -import 'package:drift_flutter/drift_flutter.dart'; - -part 'references.g.dart'; - -// #docregion many-to-one -class Users extends Table { - late final id = integer().autoIncrement()(); - late final email = text()(); - late final group = integer().references(Groups, #id)(); -} - -class Groups extends Table { - late final id = integer().autoIncrement()(); - late final name = text()(); -} -// #enddocregion many-to-one - -@DriftDatabase(tables: [Users, Groups]) -class Database extends _$Database { - Database(super.e); - - @override - int get schemaVersion => 1; -} - -void _query(Database db) async { - // #docregion many-to-one-usage - // Create a Admin group - final groupId = await db.managers.groups.create((o) => o(name: "Admin")); - - // Create a user in that group - await db.managers.users - .create((o) => o(email: "user@domain.com", group: groupId)); - // #enddocregion many-to-one-usage -} diff --git a/docs/lib/snippets/dart_api/tables.dart b/docs/lib/snippets/dart_api/tables.dart index fdc8787f1..504c31b65 100644 --- a/docs/lib/snippets/dart_api/tables.dart +++ b/docs/lib/snippets/dart_api/tables.dart @@ -166,6 +166,7 @@ class Preferences { // #docregion json_converter class Accounts extends Table { + late final name = text()(); late final preferences = text().map(TypeConverter.json( fromJson: (json) => Preferences.fromJson(json as Map), toJson: (column) => column.toJson()))(); @@ -174,9 +175,7 @@ class Accounts extends Table { // #docregion custom_json_converter class PreferencesConverter extends TypeConverter - with - JsonTypeConverter2 /*(2)!*/ > { + with JsonTypeConverter2> { @override Preferences fromJson(Map json) { return Preferences.fromJson(json); @@ -211,9 +210,8 @@ class ColumnConstraint extends Table { } // #docregion converter -/// Converter for [Duration] to [int] and vice versa -class DurationConverter - extends TypeConverter { +class DurationConverter extends TypeConverter + with JsonTypeConverter /*(3)!*/ { const DurationConverter(); @override @@ -285,9 +283,10 @@ void _query3() async { void _query4() async { final db = CatDatabase(driftDatabase(name: "categories")); // #docregion use_converter - db.managers.employees.create( + await db.managers.employees.createReturning( (create) => create(vacationTimeRemaining: const Duration(days: 10)), ); + // #enddocregion use_converter } @@ -306,4 +305,18 @@ class Patients extends Table { late final name = text()(); late final age = integer()(); } -// #enddocregion index \ No newline at end of file +// #enddocregion index + +// #docregion references +class TodoItems extends Table { + // ... + IntColumn get category => + integer().nullable().references(TodoCategories, #id)(); +} + +@DataClassName("Category") +class TodoCategories extends Table { + IntColumn get id => integer().autoIncrement()(); + // and more columns... +} +// #enddocregion references \ No newline at end of file diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index 5e774c52f..9d8c2830b 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -93,12 +93,13 @@ nav: - index.md - Documentation: - Getting Started: setup.md - - Dart API: - - dart_api/manager.md - - dart_api/tables.md + - dart_api/tables.md + - dart_api/dataclass.md + - dart_api/manager.md + - dart_api/transactions.md + - Core API: - dart_api/select.md - dart_api/writes.md - - dart_api/transactions.md - dart_api/expressions.md - dart_api/schema_inspection.md - dart_api/views.md @@ -109,16 +110,15 @@ nav: - sql_api/types.md - sql_api/extensions.md - sql_api/custom_queries.md - # - sql_api/sql_ide.md + - sql_api/custom_types.md + - sql_api/sql_ide.md - Migrations: - Getting Started: Migrations/index.md - Migrations/exports.md - Migrations/step_by_step.md - Migrations/tests.md - Migrations/api.md - - type_converters.md - - custom_row_classes.md - - Generation options: + - Code Generation: - Getting Started: generation_options/index.md - generation_options/modular.md - generation_options/in_other_builders.md @@ -133,9 +133,6 @@ nav: - testing.md - faq.md - community_tools.md - - Internals: Internals/index.md - - migrating_to_drift.md - - upgrading.md - Examples: - Examples/index.md - Examples/flutter.md @@ -148,6 +145,9 @@ nav: - Tools/devtools.md - Guides: - guides/datetime-migrations.md + - upgrading.md + - migrating_to_drift.md + - Internals/index.md - Pub: https://pub.dev/packages/drift docs_dir: "../docs"