mirror of https://github.com/AMT-Cheif/drift.git
Write correct mapping code for custom objects
This commit is contained in:
parent
bf4d16add6
commit
ff93af231c
|
@ -109,6 +109,40 @@ class ColumnBuilder<
|
|||
|
||||
/// Uses a custom [converter] to store custom Dart objects in a single column
|
||||
/// and automatically mapping them from and to sql.
|
||||
///
|
||||
/// An example might look like this:
|
||||
/// ```dart
|
||||
/// // this is the custom object with we want to store in a column. It
|
||||
/// // can be as complex as you want it to be
|
||||
/// class MyCustomObject {
|
||||
/// final String data;
|
||||
/// MyCustomObject(this.data);
|
||||
/// }
|
||||
///
|
||||
/// class CustomConverter extends TypeConverter<MyCustomObject, String> {
|
||||
/// // this class is responsible for turning a custom object into a string.
|
||||
/// // this is easy here, but more complex objects could be serialized using
|
||||
/// // json or any other method of your choice.
|
||||
/// const CustomConverter();
|
||||
/// @override
|
||||
/// MyCustomObject mapToDart(String fromDb) {
|
||||
/// return fromDb == null ? null : MyCustomObject(fromDb);
|
||||
/// }
|
||||
///
|
||||
/// @override
|
||||
/// String mapToSql(MyCustomObject value) {
|
||||
/// return value?.data;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// In that case, you could have a table with this column
|
||||
/// ```dart
|
||||
/// TextColumn get custom => text().map(const CustomConverter())();
|
||||
/// ```
|
||||
/// The generated row class will then use a `MyFancyClass` instead of a
|
||||
/// `String`, which would usually be used for [Table.text] columns.
|
||||
Builder map<T>(TypeConverter<T, ResultDartType> converter) => null;
|
||||
|
||||
/// Turns this column builder into a column. This method won't actually be
|
||||
|
|
|
@ -853,16 +853,18 @@ class TableWithoutPKData extends DataClass
|
|||
final effectivePrefix = prefix ?? '';
|
||||
final intType = db.typeSystem.forDartType<int>();
|
||||
final doubleType = db.typeSystem.forDartType<double>();
|
||||
final myCustomObjectType = db.typeSystem.forDartType<MyCustomObject>();
|
||||
final stringType = db.typeSystem.forDartType<String>();
|
||||
final customConverter = const CustomConverter();
|
||||
return TableWithoutPKData(
|
||||
notReallyAnId: intType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}not_really_an_id']),
|
||||
someFloat: doubleType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}some_float']),
|
||||
custom: myCustomObjectType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}custom']),
|
||||
custom: customConverter.mapToDart(
|
||||
stringType.mapFromDatabaseResponse(data['${effectivePrefix}custom'])),
|
||||
);
|
||||
}
|
||||
|
||||
factory TableWithoutPKData.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer serializer = const ValueSerializer.defaults()}) {
|
||||
return TableWithoutPKData(
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:moor_generator/src/model/specified_column.dart';
|
||||
import 'package:moor_generator/src/model/specified_table.dart';
|
||||
import 'package:moor_generator/src/options.dart';
|
||||
import 'package:recase/recase.dart';
|
||||
|
@ -77,8 +78,9 @@ class DataClassWriter {
|
|||
..write("final effectivePrefix = prefix ?? '';");
|
||||
|
||||
final dartTypeToResolver = <String, String>{};
|
||||
final columnToTypeMapper = <SpecifiedColumn, String>{};
|
||||
|
||||
final types = table.columns.map((c) => c.dartTypeName).toSet();
|
||||
final types = table.columns.map((c) => c.variableTypeName).toSet();
|
||||
for (var usedType in types) {
|
||||
// final intType = db.typeSystem.forDartType<int>();
|
||||
final resolver = '${ReCase(usedType).camelCase}Type';
|
||||
|
@ -88,17 +90,30 @@ class DataClassWriter {
|
|||
.write('final $resolver = db.typeSystem.forDartType<$usedType>();\n');
|
||||
}
|
||||
|
||||
for (var column in table.columns.where((c) => c.typeConverter != null)) {
|
||||
final name = '${column.dartGetterName}Converter';
|
||||
columnToTypeMapper[column] = name;
|
||||
|
||||
buffer.write('final $name = ${column.typeConverter.toSource()};');
|
||||
}
|
||||
|
||||
// finally, the mighty constructor invocation:
|
||||
buffer.write('return $dataClassName(');
|
||||
|
||||
for (var column in table.columns) {
|
||||
// id: intType.mapFromDatabaseResponse(data["id])
|
||||
final getter = column.dartGetterName;
|
||||
final resolver = dartTypeToResolver[column.dartTypeName];
|
||||
final resolver = dartTypeToResolver[column.variableTypeName];
|
||||
final columnName = "'\${effectivePrefix}${column.name.name}'";
|
||||
final typeParser = '$resolver.mapFromDatabaseResponse(data[$columnName])';
|
||||
|
||||
buffer.write('$getter: $typeParser,');
|
||||
var loadType = '$resolver.mapFromDatabaseResponse(data[$columnName])';
|
||||
|
||||
if (columnToTypeMapper.containsKey(column)) {
|
||||
final converter = columnToTypeMapper[column];
|
||||
loadType = '$converter.mapToDart($loadType)';
|
||||
}
|
||||
|
||||
buffer.write('$getter: $loadType,');
|
||||
}
|
||||
|
||||
buffer.write(');}\n');
|
||||
|
|
Loading…
Reference in New Issue