diff --git a/docs/docs/type_converters.md b/docs/docs/type_converters.md new file mode 100644 index 00000000..ab27f434 --- /dev/null +++ b/docs/docs/type_converters.md @@ -0,0 +1,75 @@ +--- +layout: feature +title: Type converters +since: 1.7 +nav_order: 8 +permalink: /type_converters +--- + +# Type converters +Moor supports a variety of types out of the box, but sometimes you need to store more complex types. +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 +column. Moor supports any Dart object, but using that package can make serialization easier. +```dart +import 'dart:convert'; + +import 'package:json_annotation/json_annotation.dart' as j; +import 'package:moor/moor.dart'; + +part 'database.g.dart'; + +@j.JsonSerializable() +class Preferences { + bool receiveEmails; + String selectedTheme; + + Preferences(this.receiveEmails, this.selectedTheme); + + factory Preferences.fromJson(Map json) => + _$PreferencesFromJson(json); + + Map toJson() => _$PreferencesToJson(this); +} +``` + +Next, we have to tell moor how to store a `Preferences` object in the database. We write +a `TypeConverter` for that: +```dart +// stores preferences as strings +class PreferenceConverter extends TypeConverter { + const PreferenceConverter(); + @override + Preferences mapToDart(String fromDb) { + if (fromDb == null) { + return null; + } + return Preferences.fromJson(json.decode(fromDb) as Map); + } + + @override + String mapToSql(Preferences value) { + if (value == null) { + return null; + } + + return json.encode(value.toJson()); + } +} +``` + +Finally, we can use that converter in a table declaration: +```dart +class Users extends Table { + IntColumn get id => integer().autoIncrement()(); + TextColumn get name => text()(); + + TextColumn get preferences => + text().map(const PreferenceConverter()).nullable()(); +} +``` + +The generated `User` class will then have a `preferences` column of type +`Preferences`. Moor 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" | absolute_url }}). \ No newline at end of file diff --git a/extras/encryption/README.md b/extras/encryption/README.md index 58c6e464..daa92a8a 100644 --- a/extras/encryption/README.md +++ b/extras/encryption/README.md @@ -15,5 +15,7 @@ dependencies: path: extras/encryption ``` -Then, instead using a `FlutterQueryExecutor`, -`import 'package:encrypted_moor/encrypted_moor.dart'` and use the `EncryptedExecutor`. \ No newline at end of file +To use this, you can stop depending on `moor_flutter`. Then, instead of using +a `FlutterQueryExecutor`, import `package:moor/moor.dart` and `package:encrypted_moor/encrypted_moor.dart`. + +You can then replace the `FlutterQueryExecutor` with an `EncryptedExecutor`. diff --git a/moor/CHANGELOG.md b/moor/CHANGELOG.md index 3b45f396..13546d7d 100644 --- a/moor/CHANGELOG.md +++ b/moor/CHANGELOG.md @@ -1,5 +1,9 @@ ## unreleased -- Support custom columns +- Support custom columns via type converters. See the [docs](https://moor.simonbinder.eu/type_converters) +for details on how to use this feature. +- New `backends` api, making it easier to write database drivers that work with moor. Apart from +`moor_flutter`, new experimental backends can be checked out from git: + 1. `encrypted_moor`: An encrypted moor database: https://github.com/simolus3/moor/tree/develop/extras/encryption ## 1.6.0 - Experimental web support! See [the documentation](https://moor.simonbinder.eu/web) for details.