update for new serializer
This commit is contained in:
parent
47606e1d51
commit
5ed22259c3
12 changed files with 270 additions and 47 deletions
|
@ -14,6 +14,7 @@ class Orm {
|
|||
const Orm({this.tableName, this.generateMigrations: true});
|
||||
}
|
||||
|
||||
@deprecated
|
||||
class Join {
|
||||
final Type against;
|
||||
final String foreignKey;
|
||||
|
|
|
@ -399,3 +399,39 @@ class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
|
|||
return parts.isEmpty ? null : parts.join(' AND ');
|
||||
}
|
||||
}
|
||||
|
||||
class MapSqlExpressionBuilder<K, V, Key extends SqlExpressionBuilder<K>,
|
||||
Value extends SqlExpressionBuilder<V>> extends SqlExpressionBuilder {
|
||||
final Key key;
|
||||
final Value value;
|
||||
bool _hasValue = false;
|
||||
String _raw;
|
||||
|
||||
MapSqlExpressionBuilder(Query query, String columnName, this.key, this.value)
|
||||
: super(query, columnName);
|
||||
|
||||
UnsupportedError _unsupported() =>
|
||||
UnsupportedError('JSON/JSONB does not support this operation.');
|
||||
|
||||
@override
|
||||
String compile() {
|
||||
var parts = <String>[_raw, key.compile(), value.compile()];
|
||||
parts.removeWhere((s) => s == null);
|
||||
return parts.isEmpty ? null : parts.join(' && ');
|
||||
}
|
||||
|
||||
@override
|
||||
bool get hasValue => key.hasValue || value.hasValue || _hasValue;
|
||||
|
||||
@override
|
||||
void isBetween(lower, upper) => throw _unsupported();
|
||||
|
||||
@override
|
||||
void isIn(Iterable values) => throw _unsupported();
|
||||
|
||||
@override
|
||||
void isNotBetween(lower, upper) => throw _unsupported();
|
||||
|
||||
@override
|
||||
void isNotIn(Iterable values) => throw _unsupported();
|
||||
}
|
||||
|
|
|
@ -111,6 +111,10 @@ class ColumnType {
|
|||
static const ColumnType varBinaryMax = const ColumnType('varbinary(max)');
|
||||
static const ColumnType image = const ColumnType('image');
|
||||
|
||||
// JSON.
|
||||
static const ColumnType json = const ColumnType('json');
|
||||
static const ColumnType jsonb = const ColumnType('jsonb');
|
||||
|
||||
// Misc.
|
||||
static const ColumnType sqlVariant = const ColumnType('sql_variant');
|
||||
static const ColumnType uniqueIdentifier =
|
||||
|
|
|
@ -26,12 +26,14 @@ targets:
|
|||
- test/models/customer.dart
|
||||
- test/models/foot.dart
|
||||
- test/models/fruit.dart
|
||||
- test/models/has_map.dart
|
||||
- test/models/role.dart
|
||||
$default:
|
||||
dependencies:
|
||||
- :_standalone
|
||||
sources:
|
||||
- test/models/book.dart
|
||||
# - test/models/has_car.dart
|
||||
- test/models/leg.dart
|
||||
- test/models/order.dart
|
||||
- test/models/tree.dart
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:async';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:angel_model/angel_model.dart';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:angel_serialize_generator/angel_serialize_generator.dart';
|
||||
import 'package:build/build.dart';
|
||||
|
@ -11,8 +12,7 @@ import 'orm_build_context.dart';
|
|||
Builder migrationBuilder(BuilderOptions options) {
|
||||
return new SharedPartBuilder([
|
||||
new MigrationGenerator(
|
||||
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false,
|
||||
autoIdAndDateFields: options.config['auto_id_and_date_fields'] != false)
|
||||
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false)
|
||||
], 'angel_migration');
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
/// If `true` (default), then field names will automatically be (de)serialized as snake_case.
|
||||
final bool autoSnakeCaseNames;
|
||||
|
||||
/// If `true` (default), then the schema will automatically add id, created_at and updated_at fields.
|
||||
final bool autoIdAndDateFields;
|
||||
|
||||
const MigrationGenerator(
|
||||
{this.autoSnakeCaseNames: true, this.autoIdAndDateFields: true});
|
||||
const MigrationGenerator({this.autoSnakeCaseNames: true});
|
||||
|
||||
@override
|
||||
Future<String> generateForAnnotatedElement(
|
||||
|
@ -45,13 +41,8 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
}
|
||||
|
||||
var resolver = await buildStep.resolver;
|
||||
var ctx = await buildOrmContext(
|
||||
element as ClassElement,
|
||||
annotation,
|
||||
buildStep,
|
||||
resolver,
|
||||
autoSnakeCaseNames != false,
|
||||
autoIdAndDateFields != false);
|
||||
var ctx = await buildOrmContext(element as ClassElement, annotation,
|
||||
buildStep, resolver, autoSnakeCaseNames != false);
|
||||
var lib = generateMigrationLibrary(
|
||||
ctx, element as ClassElement, resolver, buildStep);
|
||||
if (lib == null) return null;
|
||||
|
@ -73,6 +64,8 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
Method buildUpMigration(OrmBuildContext ctx, LibraryBuilder lib) {
|
||||
return new Method((meth) {
|
||||
var autoIdAndDateFields = const TypeChecker.fromRuntime(Model)
|
||||
.isAssignableFromType(ctx.buildContext.clazz.type);
|
||||
meth
|
||||
..name = 'up'
|
||||
..annotations.add(refer('override'))
|
||||
|
|
|
@ -27,7 +27,6 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
BuildStep buildStep,
|
||||
Resolver resolver,
|
||||
bool autoSnakeCaseNames,
|
||||
bool autoIdAndDateFields,
|
||||
{bool heedExclude: true}) async {
|
||||
// Check for @generatedSerializable
|
||||
// ignore: unused_local_variable
|
||||
|
@ -44,8 +43,8 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
if (_cache.containsKey(id)) {
|
||||
return _cache[id];
|
||||
}
|
||||
var buildCtx = await buildContext(clazz, annotation, buildStep, resolver,
|
||||
autoSnakeCaseNames, autoIdAndDateFields,
|
||||
var buildCtx = await buildContext(
|
||||
clazz, annotation, buildStep, resolver, autoSnakeCaseNames,
|
||||
heedExclude: heedExclude);
|
||||
var ormAnnotation = reviveORMAnnotation(annotation);
|
||||
var ctx = new OrmBuildContext(
|
||||
|
@ -66,7 +65,10 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
column = reviveColumn(new ConstantReader(columnAnnotation));
|
||||
}
|
||||
|
||||
if (column == null && field.name == 'id' && autoIdAndDateFields == true) {
|
||||
if (column == null &&
|
||||
field.name == 'id' &&
|
||||
const TypeChecker.fromRuntime(Model)
|
||||
.isAssignableFromType(buildCtx.clazz.type)) {
|
||||
// This is only for PostgreSQL, so implementations without a `serial` type
|
||||
// must handle it accordingly, of course.
|
||||
column = const Column(type: ColumnType.serial);
|
||||
|
@ -76,7 +78,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
// Guess what kind of column this is...
|
||||
column = new Column(
|
||||
type: inferColumnType(
|
||||
field.type,
|
||||
buildCtx.resolveSerializedFieldType(field.name),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -133,8 +135,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
.firstAnnotationOf(modelType.element)),
|
||||
buildStep,
|
||||
resolver,
|
||||
autoSnakeCaseNames,
|
||||
autoIdAndDateFields);
|
||||
autoSnakeCaseNames);
|
||||
|
||||
var ormAnn = const TypeChecker.fromRuntime(Orm)
|
||||
.firstAnnotationOf(modelType.element);
|
||||
|
@ -176,7 +177,9 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
ctx.buildContext.aliases[name] = relation.localKey;
|
||||
|
||||
if (!ctx.effectiveFields.any((f) => f.name == field.name)) {
|
||||
if (field.name != 'id' || !autoIdAndDateFields) {
|
||||
if (field.name != 'id' ||
|
||||
!const TypeChecker.fromRuntime(Model)
|
||||
.isAssignableFromType(ctx.buildContext.clazz.type)) {
|
||||
var rf = new RelationFieldImpl(name,
|
||||
field.type.element.context.typeProvider.intType, field.name);
|
||||
ctx.effectiveFields.add(rf);
|
||||
|
@ -212,6 +215,8 @@ ColumnType inferColumnType(DartType type) {
|
|||
return ColumnType.boolean;
|
||||
if (const TypeChecker.fromRuntime(DateTime).isAssignableFromType(type))
|
||||
return ColumnType.timeStamp;
|
||||
if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type))
|
||||
return ColumnType.jsonb;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:angel_model/angel_model.dart';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:angel_serialize_generator/angel_serialize_generator.dart';
|
||||
import 'package:angel_serialize_generator/build_context.dart';
|
||||
|
@ -12,8 +14,7 @@ import 'orm_build_context.dart';
|
|||
Builder ormBuilder(BuilderOptions options) {
|
||||
return new SharedPartBuilder([
|
||||
new OrmGenerator(
|
||||
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false,
|
||||
autoIdAndDateFields: options.config['auto_id_and_date_fields'] != false)
|
||||
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false)
|
||||
], 'angel_orm');
|
||||
}
|
||||
|
||||
|
@ -26,16 +27,15 @@ TypeReference futureOf(String type) {
|
|||
/// Builder that generates `.orm.g.dart`, with an abstract `FooOrm` class.
|
||||
class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||
final bool autoSnakeCaseNames;
|
||||
final bool autoIdAndDateFields;
|
||||
|
||||
OrmGenerator({this.autoSnakeCaseNames, this.autoIdAndDateFields});
|
||||
OrmGenerator({this.autoSnakeCaseNames});
|
||||
|
||||
@override
|
||||
Future<String> generateForAnnotatedElement(
|
||||
Element element, ConstantReader annotation, BuildStep buildStep) async {
|
||||
if (element is ClassElement) {
|
||||
var ctx = await buildOrmContext(element, annotation, buildStep,
|
||||
buildStep.resolver, autoSnakeCaseNames, autoIdAndDateFields);
|
||||
buildStep.resolver, autoSnakeCaseNames);
|
||||
var lib = buildOrmLibrary(buildStep.inputId, ctx);
|
||||
return lib.accept(new DartEmitter()).toString();
|
||||
} else {
|
||||
|
@ -146,10 +146,10 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
for (var field in ctx.effectiveFields) {
|
||||
Reference type = convertTypeReference(field.type);
|
||||
if (isSpecialId(field)) type = refer('int');
|
||||
if (isSpecialId(ctx, field)) type = refer('int');
|
||||
|
||||
var expr = (refer('row').index(literalNum(i++)));
|
||||
if (isSpecialId(field))
|
||||
if (isSpecialId(ctx, field))
|
||||
expr = expr.property('toString').call([]);
|
||||
else if (field is RelationFieldImpl)
|
||||
continue;
|
||||
|
@ -229,7 +229,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
relation.type == RelationshipType.hasMany) {
|
||||
var foreign = ctx.relationTypes[relation];
|
||||
var additionalFields = foreign.effectiveFields
|
||||
.where((f) => f.name != 'id' || !isSpecialId(f))
|
||||
.where((f) => f.name != 'id' || !isSpecialId(ctx, f))
|
||||
.map((f) => literalString(
|
||||
foreign.buildContext.resolveFieldName(f.name)));
|
||||
var joinArgs = [relation.localKey, relation.foreignKey]
|
||||
|
@ -284,7 +284,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
// Just call getOne() again
|
||||
if (ctx.effectiveFields.any((f) =>
|
||||
isSpecialId(f) ||
|
||||
isSpecialId(ctx, f) ||
|
||||
(ctx.columns[f.name]?.indexType ==
|
||||
IndexType.primaryKey))) {
|
||||
b.addExpression(refer('where')
|
||||
|
@ -370,7 +370,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
'but ${ctx.buildContext.clazz.name} has a @HasMany() relation that expects such a field.';
|
||||
});
|
||||
|
||||
var queryValue = (isSpecialId(localField))
|
||||
var queryValue = (isSpecialId(ctx, localField))
|
||||
? 'int.parse(model.id)'
|
||||
: 'model.${localField.name}';
|
||||
var cascadeText =
|
||||
|
@ -445,10 +445,12 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
});
|
||||
}
|
||||
|
||||
bool isSpecialId(FieldElement field) {
|
||||
bool isSpecialId(OrmBuildContext ctx, FieldElement field) {
|
||||
return field is ShimFieldImpl &&
|
||||
field is! RelationFieldImpl &&
|
||||
(field.name == 'id' && autoIdAndDateFields);
|
||||
(field.name == 'id' &&
|
||||
const TypeChecker.fromRuntime(Model)
|
||||
.isAssignableFromType(ctx.buildContext.clazz.type));
|
||||
}
|
||||
|
||||
Class buildWhereClass(OrmBuildContext ctx) {
|
||||
|
@ -475,23 +477,31 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
// Add builders for each field
|
||||
for (var field in ctx.effectiveFields) {
|
||||
var name = field.name;
|
||||
DartType type;
|
||||
Reference builderType;
|
||||
|
||||
if (const TypeChecker.fromRuntime(int).isExactlyType(field.type) ||
|
||||
const TypeChecker.fromRuntime(double).isExactlyType(field.type) ||
|
||||
isSpecialId(field)) {
|
||||
try {
|
||||
type = ctx.buildContext.resolveSerializedFieldType(field.name);
|
||||
} on StateError {
|
||||
type = field.type;
|
||||
}
|
||||
|
||||
if (const TypeChecker.fromRuntime(int).isExactlyType(type) ||
|
||||
const TypeChecker.fromRuntime(double).isExactlyType(type) ||
|
||||
isSpecialId(ctx, field)) {
|
||||
builderType = new TypeReference((b) => b
|
||||
..symbol = 'NumericSqlExpressionBuilder'
|
||||
..types.add(refer(isSpecialId(field) ? 'int' : field.type.name)));
|
||||
} else if (const TypeChecker.fromRuntime(String)
|
||||
.isExactlyType(field.type)) {
|
||||
..types.add(refer(isSpecialId(ctx, field) ? 'int' : type.name)));
|
||||
} else if (const TypeChecker.fromRuntime(String).isExactlyType(type)) {
|
||||
builderType = refer('StringSqlExpressionBuilder');
|
||||
} else if (const TypeChecker.fromRuntime(bool)
|
||||
.isExactlyType(field.type)) {
|
||||
} else if (const TypeChecker.fromRuntime(bool).isExactlyType(type)) {
|
||||
builderType = refer('BooleanSqlExpressionBuilder');
|
||||
} else if (const TypeChecker.fromRuntime(DateTime)
|
||||
.isExactlyType(field.type)) {
|
||||
.isExactlyType(type)) {
|
||||
builderType = refer('DateTimeSqlExpressionBuilder');
|
||||
} else if (const TypeChecker.fromRuntime(Map)
|
||||
.isAssignableFromType(type)) {
|
||||
builderType = refer('MapSqlExpressionBuilder');
|
||||
} else if (ctx.relations.containsKey(field.name)) {
|
||||
var relation = ctx.relations[field.name];
|
||||
if (relation.type != RelationshipType.belongsTo)
|
||||
|
@ -545,7 +555,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
// Each field generates a getter for setter
|
||||
for (var field in ctx.effectiveFields) {
|
||||
var name = ctx.buildContext.resolveFieldName(field.name);
|
||||
var type = isSpecialId(field)
|
||||
var type = isSpecialId(ctx, field)
|
||||
? refer('int')
|
||||
: convertTypeReference(field.type);
|
||||
|
||||
|
@ -584,7 +594,8 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
var args = <String, Expression>{};
|
||||
|
||||
for (var field in ctx.effectiveFields) {
|
||||
if (isSpecialId(field) || field is RelationFieldImpl) continue;
|
||||
if (isSpecialId(ctx, field) || field is RelationFieldImpl)
|
||||
continue;
|
||||
args[ctx.buildContext.resolveFieldName(field.name)] =
|
||||
refer('model').property(field.name);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/// Tests for @hasOne...
|
||||
library angel_orm_generator.test.has_one_test;
|
||||
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'models/foot.dart';
|
||||
import 'models/leg.dart';
|
||||
|
|
|
@ -10,6 +10,6 @@ part 'author.g.dart';
|
|||
@orm
|
||||
abstract class _Author extends Model {
|
||||
@Column(length: 255, indexType: IndexType.unique)
|
||||
@DefaultValue('Tobe Osakwe')
|
||||
@SerializableField(defaultValue: 'Tobe Osakwe')
|
||||
String get name;
|
||||
}
|
||||
|
|
12
angel_orm_generator/test/models/has_car.dart
Normal file
12
angel_orm_generator/test/models/has_car.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
import 'package:angel_migration/angel_migration.dart';
|
||||
import 'package:angel_model/angel_model.dart';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:angel_serialize/angel_serialize.dart';
|
||||
import 'car.dart';
|
||||
// part 'has_car.g.dart';
|
||||
|
||||
@orm
|
||||
@serializable
|
||||
abstract class _PackageJson extends Model {
|
||||
Car get car;
|
||||
}
|
12
angel_orm_generator/test/models/has_map.dart
Normal file
12
angel_orm_generator/test/models/has_map.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
import 'package:angel_migration/angel_migration.dart';
|
||||
import 'package:angel_model/angel_model.dart';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:angel_serialize/angel_serialize.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
part 'has_map.g.dart';
|
||||
|
||||
@orm
|
||||
@serializable
|
||||
abstract class _HasMap {
|
||||
Map get value;
|
||||
}
|
148
angel_orm_generator/test/models/has_map.g.dart
Normal file
148
angel_orm_generator/test/models/has_map.g.dart
Normal file
|
@ -0,0 +1,148 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'has_map.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// MigrationGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class HasMapMigration extends Migration {
|
||||
@override
|
||||
up(Schema schema) {
|
||||
schema.create('has_maps', (table) {
|
||||
table.declare('value', new ColumnType('jsonb'));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
down(Schema schema) {
|
||||
schema.drop('has_maps');
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// OrmGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class HasMapQuery extends Query<HasMap, HasMapQueryWhere> {
|
||||
HasMapQuery() {
|
||||
_where = new HasMapQueryWhere(this);
|
||||
}
|
||||
|
||||
@override
|
||||
final HasMapQueryValues values = new HasMapQueryValues();
|
||||
|
||||
HasMapQueryWhere _where;
|
||||
|
||||
@override
|
||||
get tableName {
|
||||
return 'has_maps';
|
||||
}
|
||||
|
||||
@override
|
||||
get fields {
|
||||
return const ['value'];
|
||||
}
|
||||
|
||||
@override
|
||||
HasMapQueryWhere get where {
|
||||
return _where;
|
||||
}
|
||||
|
||||
@override
|
||||
HasMapQueryWhere newWhereClause() {
|
||||
return new HasMapQueryWhere(this);
|
||||
}
|
||||
|
||||
static HasMap parseRow(List row) {
|
||||
if (row.every((x) => x == null)) return null;
|
||||
var model = new HasMap(value: (row[0] as Map<dynamic, dynamic>));
|
||||
return model;
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return parseRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
class HasMapQueryWhere extends QueryWhere {
|
||||
HasMapQueryWhere(HasMapQuery query)
|
||||
: value = new MapSqlExpressionBuilder(query, 'value');
|
||||
|
||||
final MapSqlExpressionBuilder value;
|
||||
|
||||
@override
|
||||
get expressionBuilders {
|
||||
return [value];
|
||||
}
|
||||
}
|
||||
|
||||
class HasMapQueryValues extends MapQueryValues {
|
||||
Map<dynamic, dynamic> get value {
|
||||
return (values['value'] as Map<dynamic, dynamic>);
|
||||
}
|
||||
|
||||
set value(Map<dynamic, dynamic> value) => values['value'] = value;
|
||||
void copyFrom(HasMap model) {
|
||||
values.addAll({'value': model.value});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
||||
@generatedSerializable
|
||||
class HasMap implements _HasMap {
|
||||
const HasMap({Map<dynamic, dynamic> this.value});
|
||||
|
||||
@override
|
||||
final Map<dynamic, dynamic> value;
|
||||
|
||||
HasMap copyWith({Map<dynamic, dynamic> value}) {
|
||||
return new HasMap(value: value ?? this.value);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
return other is _HasMap &&
|
||||
const MapEquality<dynamic, dynamic>(
|
||||
keys: const DefaultEquality(), values: const DefaultEquality())
|
||||
.equals(other.value, value);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashObjects([value]);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return HasMapSerializer.toMap(this);
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// SerializerGenerator
|
||||
// **************************************************************************
|
||||
|
||||
abstract class HasMapSerializer {
|
||||
static HasMap fromMap(Map map) {
|
||||
return new HasMap(
|
||||
value: map['value'] is Map
|
||||
? (map['value'] as Map).cast<dynamic, dynamic>()
|
||||
: null);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_HasMap model) {
|
||||
if (model == null) {
|
||||
return null;
|
||||
}
|
||||
return {'value': model.value};
|
||||
}
|
||||
}
|
||||
|
||||
abstract class HasMapFields {
|
||||
static const List<String> allFields = const <String>[value];
|
||||
|
||||
static const String value = 'value';
|
||||
}
|
Loading…
Reference in a new issue