import 'dart:convert'; import 'package:meta/meta.dart'; import 'package:moor/moor.dart'; /// Common interface for objects which can be inserted or updated into a /// database. @optionalTypeArgs abstract class Insertable { /// Used internally by moor. T createCompanion>(bool nullToAbsent); } /// A common supertype for all data classes generated by moor. Data classes are /// immutable structures that represent a single row in a database table. abstract class DataClass { const DataClass(); /// Converts this object into a representation that can be encoded with /// [json]. The [serializer] can be used to configure how individual values /// will be encoded. Map toJson( {ValueSerializer serializer = const ValueSerializer.defaults()}); /// Converts this object into a json representation. The [serializer] can be /// used to configure how individual values will be encoded. String toJsonString( {ValueSerializer serializer = const ValueSerializer.defaults()}) { return json.encode(toJson(serializer: serializer)); } /// Used internally be generated code @protected static dynamic parseJson(String jsonString) { return json.decode(jsonString); } } /// An update companion for a [DataClass] which is used to write data into a /// database using [InsertStatement.insert] or [UpdateStatement.write]. /// /// See also: /// - the explanation in the changelog for 1.5 /// - https://github.com/simolus3/moor/issues/25 abstract class UpdateCompanion implements Insertable { const UpdateCompanion(); @override T createCompanion>(bool nullToAbsent) { return this as T; } } /// A wrapper around arbitrary data [T] to indicate presence or absence /// explicitly. class Value { final bool present; final T value; const Value.use(this.value) : present = true; const Value.absent() : value = null, present = false; } /// Serializer responsible for mapping atomic types from and to json. abstract class ValueSerializer { const ValueSerializer(); /// The default serializer encodes date times as a unix-timestamp in /// milliseconds. const factory ValueSerializer.defaults() = _DefaultValueSerializer; /// Converts the [value] to something that can be passed to /// [JsonCodec.encode]. dynamic toJson(T value); /// Inverse of [toJson]: Converts a value obtained from [JsonCodec.decode] /// into a value that can be hold by data classes. T fromJson(dynamic json); } class _DefaultValueSerializer extends ValueSerializer { const _DefaultValueSerializer(); @override T fromJson(json) { if (T == DateTime) { return DateTime.fromMillisecondsSinceEpoch(json as int) as T; } return json as T; } @override dynamic toJson(T value) { if (value is DateTime) { return value.millisecondsSinceEpoch; } return value; } }