Merged master
This commit is contained in:
commit
bdf7d33c54
12 changed files with 161 additions and 21 deletions
|
@ -71,7 +71,11 @@ class MariaDbMigrationRunner implements MigrationRunner {
|
||||||
var curBatch = 0;
|
var curBatch = 0;
|
||||||
if (result.isNotEmpty) {
|
if (result.isNotEmpty) {
|
||||||
var firstRow = result.toList();
|
var firstRow = result.toList();
|
||||||
curBatch = int.tryParse(firstRow[0][0] ?? '0') as int;
|
var firstBatch = firstRow[0][0] ?? 0;
|
||||||
|
if (firstBatch is! int) {
|
||||||
|
int.tryParse(firstBatch) as int;
|
||||||
|
}
|
||||||
|
curBatch = firstBatch;
|
||||||
}
|
}
|
||||||
var batch = curBatch + 1;
|
var batch = curBatch + 1;
|
||||||
|
|
||||||
|
@ -105,7 +109,11 @@ class MariaDbMigrationRunner implements MigrationRunner {
|
||||||
var curBatch = 0;
|
var curBatch = 0;
|
||||||
if (result.isNotEmpty) {
|
if (result.isNotEmpty) {
|
||||||
var firstRow = result.toList();
|
var firstRow = result.toList();
|
||||||
curBatch = int.tryParse(firstRow[0][0]) as int;
|
var firstBatch = firstRow[0][0];
|
||||||
|
if (firstBatch is! int) {
|
||||||
|
int.tryParse(firstBatch) as int;
|
||||||
|
}
|
||||||
|
curBatch = firstBatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = await connection
|
result = await connection
|
||||||
|
|
|
@ -125,12 +125,18 @@ Future<OrmBuildContext?> buildOrmContext(
|
||||||
buildCtx.resolveSerializedFieldType(field.name),
|
buildCtx.resolveSerializedFieldType(field.name),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
var isEnumField =
|
||||||
|
(field.type is InterfaceType && field.type.element is EnumElement);
|
||||||
|
var hasColumnAnnotation =
|
||||||
|
(columnAnnotation?.getField('type')?.hasKnownValue ?? false);
|
||||||
column = Column(
|
column = Column(
|
||||||
isNullable: column.isNullable,
|
isNullable: column.isNullable,
|
||||||
length: column.length,
|
length: column.length,
|
||||||
indexType: column.indexType,
|
indexType: column.indexType,
|
||||||
type: inferColumnType(field.type),
|
// Only infer type when not set by the @Column annotation, for enums
|
||||||
|
type: (isEnumField && hasColumnAnnotation)
|
||||||
|
? column.type
|
||||||
|
: inferColumnType(field.type),
|
||||||
defaultValue: column.defaultValue,
|
defaultValue: column.defaultValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:analyzer/dart/element/nullability_suffix.dart';
|
import 'package:analyzer/dart/element/nullability_suffix.dart';
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:angel3_orm/angel3_orm.dart';
|
import 'package:angel3_orm/angel3_orm.dart';
|
||||||
|
import 'package:angel3_serialize/angel3_serialize.dart';
|
||||||
import 'package:angel3_serialize_generator/angel3_serialize_generator.dart';
|
import 'package:angel3_serialize_generator/angel3_serialize_generator.dart';
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
import 'package:code_builder/code_builder.dart' hide LibraryBuilder;
|
import 'package:code_builder/code_builder.dart' hide LibraryBuilder;
|
||||||
|
@ -277,11 +278,8 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
* EnumType.values[(row[3] as int)] : null,
|
* EnumType.values[(row[3] as int)] : null,
|
||||||
*/
|
*/
|
||||||
var isNull = expr.equalTo(literalNull);
|
var isNull = expr.equalTo(literalNull);
|
||||||
|
final parseExpression = _deserializeEnumExpression(field, expr);
|
||||||
Reference enumType =
|
expr = isNull.conditional(literalNull, parseExpression);
|
||||||
convertTypeReference(fType, ignoreNullabilityCheck: true);
|
|
||||||
expr = isNull.conditional(literalNull,
|
|
||||||
enumType.property('values').index(expr.asA(refer('int'))));
|
|
||||||
} else if (fType.isDartCoreBool) {
|
} else if (fType.isDartCoreBool) {
|
||||||
// Generated Code: mapToBool(row[i])
|
// Generated Code: mapToBool(row[i])
|
||||||
expr = refer('mapToBool').call([expr]);
|
expr = refer('mapToBool').call([expr]);
|
||||||
|
@ -892,9 +890,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
var value = refer('values').index(literalString(name!));
|
var value = refer('values').index(literalString(name!));
|
||||||
|
|
||||||
if (fType is InterfaceType && fType.element is EnumElement) {
|
if (fType is InterfaceType && fType.element is EnumElement) {
|
||||||
var asInt = value.asA(refer('int'));
|
value = _deserializeEnumExpression(field, value);
|
||||||
var t = convertTypeReference(fType, ignoreNullabilityCheck: true);
|
|
||||||
value = t.property('values').index(asInt);
|
|
||||||
} else if (const TypeChecker.fromRuntime(List)
|
} else if (const TypeChecker.fromRuntime(List)
|
||||||
.isAssignableFromType(fType)) {
|
.isAssignableFromType(fType)) {
|
||||||
value = refer('json')
|
value = refer('json')
|
||||||
|
@ -926,7 +922,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
Expression value = refer('value');
|
Expression value = refer('value');
|
||||||
|
|
||||||
if (fType is InterfaceType && fType.element is EnumElement) {
|
if (fType is InterfaceType && fType.element is EnumElement) {
|
||||||
value = CodeExpression(Code('value?.index'));
|
value = _serializeEnumExpression(field, value);
|
||||||
} else if (const TypeChecker.fromRuntime(List)
|
} else if (const TypeChecker.fromRuntime(List)
|
||||||
.isAssignableFromType(fType)) {
|
.isAssignableFromType(fType)) {
|
||||||
value = refer('json').property('encode').call([value]);
|
value = refer('json').property('encode').call([value]);
|
||||||
|
@ -1005,4 +1001,45 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve the [Expression] to parse a serialized enumeration field.
|
||||||
|
/// Takes into account the [SerializableField] properties.
|
||||||
|
/// Defaults to `enum.values[index as int]`
|
||||||
|
Expression _deserializeEnumExpression(FieldElement field, Expression expr) {
|
||||||
|
Reference enumType =
|
||||||
|
convertTypeReference(field.type, ignoreNullabilityCheck: true);
|
||||||
|
const TypeChecker serializableFieldTypeChecker =
|
||||||
|
TypeChecker.fromRuntime(SerializableField);
|
||||||
|
final annotation = serializableFieldTypeChecker.firstAnnotationOf(field);
|
||||||
|
Expression? parseExpr;
|
||||||
|
if (null != annotation) {
|
||||||
|
final deserializer = annotation.getField('deserializer')?.toSymbolValue();
|
||||||
|
if (null != deserializer) {
|
||||||
|
var type = 'int';
|
||||||
|
final serializesTo = annotation.getField('serializesTo')?.toTypeValue();
|
||||||
|
if (null != serializesTo) {
|
||||||
|
type = serializesTo.element!.displayName;
|
||||||
|
}
|
||||||
|
parseExpr = Reference(deserializer).expression([expr.asA(refer(type))]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parseExpr ??
|
||||||
|
enumType.property('values').index(expr.asA(refer('int')));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the [Expression] to serialize the enumeration field.
|
||||||
|
/// Takes into account the [SerializableField] properties.
|
||||||
|
Expression _serializeEnumExpression(FieldElement field, Expression expr) {
|
||||||
|
const TypeChecker serializableFieldTypeChecker =
|
||||||
|
TypeChecker.fromRuntime(SerializableField);
|
||||||
|
final annotation = serializableFieldTypeChecker.firstAnnotationOf(field);
|
||||||
|
Expression? parseExpr;
|
||||||
|
if (null != annotation) {
|
||||||
|
final serializer = annotation.getField('serializer')?.toSymbolValue();
|
||||||
|
if (null != serializer) {
|
||||||
|
parseExpr = Reference(serializer).expression([expr]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parseExpr ?? CodeExpression(Code('value?.index'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,16 @@ dev_dependencies:
|
||||||
build_runner: ^2.0.1
|
build_runner: ^2.0.1
|
||||||
test: ^1.21.0
|
test: ^1.21.0
|
||||||
lints: ^2.0.0
|
lints: ^2.0.0
|
||||||
# dependency_overrides:
|
|
||||||
|
dependency_overrides:
|
||||||
# angel3_serialize:
|
# angel3_serialize:
|
||||||
# path: ../../serialize/angel_serialize
|
# path: ../../serialize/angel_serialize
|
||||||
# angel3_serialize_generator:
|
# angel3_serialize_generator:
|
||||||
# path: ../../serialize/angel_serialize_generator
|
# path: ../../serialize/angel_serialize_generator
|
||||||
# angel3_model:
|
# angel3_model:
|
||||||
# path: ../../model
|
# path: ../../model
|
||||||
# angel3_orm_test:
|
angel3_orm_test:
|
||||||
# path: ../angel_orm_test
|
path: ../angel_orm_test
|
||||||
# angel3_orm:
|
# angel3_orm:
|
||||||
# path: ../angel_orm
|
# path: ../angel_orm
|
||||||
# angel3_orm_generator:
|
# angel3_orm_generator:
|
||||||
|
|
|
@ -84,6 +84,8 @@ Future<MariaDbExecutor> _connectToMariaDb(List<String> schemas) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executor for MySQL
|
// Executor for MySQL
|
||||||
|
// create user 'test'@'localhost' identified by 'test123';
|
||||||
|
// GRANT ALL PRIVILEGES ON orm_test.* to 'test'@'localhost' WITH GRANT OPTION;
|
||||||
Future<MySqlExecutor> _connectToMySql(List<String> schemas) async {
|
Future<MySqlExecutor> _connectToMySql(List<String> schemas) async {
|
||||||
var connection = await MySQLConnection.createConnection(
|
var connection = await MySQLConnection.createConnection(
|
||||||
databaseName: 'orm_test',
|
databaseName: 'orm_test',
|
||||||
|
@ -91,7 +93,7 @@ Future<MySqlExecutor> _connectToMySql(List<String> schemas) async {
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
userName: Platform.environment['MYSQL_USERNAME'] ?? 'test',
|
userName: Platform.environment['MYSQL_USERNAME'] ?? 'test',
|
||||||
password: Platform.environment['MYSQL_PASSWORD'] ?? 'test123',
|
password: Platform.environment['MYSQL_PASSWORD'] ?? 'test123',
|
||||||
secure: true);
|
secure: !('false' == Platform.environment['MYSQL_SECURE']));
|
||||||
|
|
||||||
await connection.connect(timeoutMs: 10000);
|
await connection.connect(timeoutMs: 10000);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
CREATE TABLE IF NOT EXISTS has_cars (
|
CREATE TABLE IF NOT EXISTS has_cars (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
type int not null,
|
type int not null,
|
||||||
|
color varchar(1),
|
||||||
created_at datetime,
|
created_at datetime,
|
||||||
updated_at datetime
|
updated_at datetime
|
||||||
);
|
);
|
|
@ -1,6 +1,7 @@
|
||||||
CREATE TEMPORARY TABLE "has_cars" (
|
CREATE TEMPORARY TABLE "has_cars" (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
type int not null,
|
type int not null,
|
||||||
|
color varchar(1),
|
||||||
created_at timestamp,
|
created_at timestamp,
|
||||||
updated_at timestamp
|
updated_at timestamp
|
||||||
);
|
);
|
|
@ -13,11 +13,14 @@ void enumAndNestedTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
});
|
});
|
||||||
|
|
||||||
test('insert', () async {
|
test('insert', () async {
|
||||||
var query = HasCarQuery()..values.type = CarType.sedan;
|
var query = HasCarQuery()
|
||||||
|
..values.type = CarType.sedan
|
||||||
|
..values.color = Color.red;
|
||||||
var resultOpt = await (query.insert(executor));
|
var resultOpt = await (query.insert(executor));
|
||||||
expect(resultOpt.isPresent, true);
|
expect(resultOpt.isPresent, true);
|
||||||
resultOpt.ifPresent((result) {
|
resultOpt.ifPresent((result) {
|
||||||
expect(result.type, CarType.sedan);
|
expect(result.type, CarType.sedan);
|
||||||
|
expect(result.color, Color.red);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
11
packages/orm/angel_orm_test/lib/src/enum_test.dart
Normal file
11
packages/orm/angel_orm_test/lib/src/enum_test.dart
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import 'package:angel3_orm_test/src/models/has_car.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
/// See https://github.com/dukefirehawk/angel/pull/98
|
||||||
|
test('enum field with custom deserializer should be parsed consistently', () {
|
||||||
|
final query = HasCarQuery();
|
||||||
|
final hasCar = query.parseRow([null, null, null, 'R', null]).value;
|
||||||
|
expect(hasCar.color, equals(Color.red));
|
||||||
|
});
|
||||||
|
}
|
|
@ -11,6 +11,22 @@ part 'has_car.g.dart';
|
||||||
|
|
||||||
enum CarType { sedan, suv, atv }
|
enum CarType { sedan, suv, atv }
|
||||||
|
|
||||||
|
Color? codeToColor(String? code) => code == null
|
||||||
|
? null
|
||||||
|
: Color.values.firstWhere((color) => color.code == code);
|
||||||
|
|
||||||
|
String? colorToCode(Color? color) => color?.code;
|
||||||
|
|
||||||
|
enum Color {
|
||||||
|
red('R'),
|
||||||
|
green('G'),
|
||||||
|
blue('B');
|
||||||
|
|
||||||
|
const Color(this.code);
|
||||||
|
|
||||||
|
final String code;
|
||||||
|
}
|
||||||
|
|
||||||
@orm
|
@orm
|
||||||
@serializable
|
@serializable
|
||||||
abstract class _HasCar extends Model {
|
abstract class _HasCar extends Model {
|
||||||
|
@ -21,4 +37,12 @@ abstract class _HasCar extends Model {
|
||||||
|
|
||||||
@SerializableField(isNullable: false, defaultValue: CarType.sedan)
|
@SerializableField(isNullable: false, defaultValue: CarType.sedan)
|
||||||
CarType? get type;
|
CarType? get type;
|
||||||
|
|
||||||
|
@SerializableField(
|
||||||
|
serializesTo: String,
|
||||||
|
serializer: #colorToCode,
|
||||||
|
deserializer: #codeToColor,
|
||||||
|
)
|
||||||
|
@Column(type: ColumnType.varChar, length: 1)
|
||||||
|
Color? color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,13 @@ class HasCarMigration extends Migration {
|
||||||
table.serial('id').primaryKey();
|
table.serial('id').primaryKey();
|
||||||
table.timeStamp('created_at');
|
table.timeStamp('created_at');
|
||||||
table.timeStamp('updated_at');
|
table.timeStamp('updated_at');
|
||||||
|
table.declareColumn(
|
||||||
|
'color',
|
||||||
|
Column(
|
||||||
|
type: ColumnType('varchar'),
|
||||||
|
length: 1,
|
||||||
|
),
|
||||||
|
);
|
||||||
table.integer('type').defaultsTo(0);
|
table.integer('type').defaultsTo(0);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -63,6 +70,7 @@ class HasCarQuery extends Query<HasCar, HasCarQueryWhere> {
|
||||||
'id',
|
'id',
|
||||||
'created_at',
|
'created_at',
|
||||||
'updated_at',
|
'updated_at',
|
||||||
|
'color',
|
||||||
'type',
|
'type',
|
||||||
];
|
];
|
||||||
return _selectedFields.isEmpty
|
return _selectedFields.isEmpty
|
||||||
|
@ -95,10 +103,15 @@ class HasCarQuery extends Query<HasCar, HasCarQueryWhere> {
|
||||||
fields.contains('created_at') ? mapToNullableDateTime(row[1]) : null,
|
fields.contains('created_at') ? mapToNullableDateTime(row[1]) : null,
|
||||||
updatedAt:
|
updatedAt:
|
||||||
fields.contains('updated_at') ? mapToNullableDateTime(row[2]) : null,
|
fields.contains('updated_at') ? mapToNullableDateTime(row[2]) : null,
|
||||||
type: fields.contains('type')
|
color: fields.contains('color')
|
||||||
? row[3] == null
|
? row[3] == null
|
||||||
? null
|
? null
|
||||||
: CarType.values[(row[3] as int)]
|
: codeToColor((row[3] as String))
|
||||||
|
: null,
|
||||||
|
type: fields.contains('type')
|
||||||
|
? row[4] == null
|
||||||
|
? null
|
||||||
|
: CarType.values[(row[4] as int)]
|
||||||
: null,
|
: null,
|
||||||
);
|
);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
|
@ -124,6 +137,10 @@ class HasCarQueryWhere extends QueryWhere {
|
||||||
query,
|
query,
|
||||||
'updated_at',
|
'updated_at',
|
||||||
),
|
),
|
||||||
|
color = StringSqlExpressionBuilder(
|
||||||
|
query,
|
||||||
|
'color',
|
||||||
|
),
|
||||||
type = EnumSqlExpressionBuilder<CarType?>(
|
type = EnumSqlExpressionBuilder<CarType?>(
|
||||||
query,
|
query,
|
||||||
'type',
|
'type',
|
||||||
|
@ -136,6 +153,8 @@ class HasCarQueryWhere extends QueryWhere {
|
||||||
|
|
||||||
final DateTimeSqlExpressionBuilder updatedAt;
|
final DateTimeSqlExpressionBuilder updatedAt;
|
||||||
|
|
||||||
|
final StringSqlExpressionBuilder color;
|
||||||
|
|
||||||
final EnumSqlExpressionBuilder<CarType?> type;
|
final EnumSqlExpressionBuilder<CarType?> type;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -144,6 +163,7 @@ class HasCarQueryWhere extends QueryWhere {
|
||||||
id,
|
id,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
|
color,
|
||||||
type,
|
type,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -170,6 +190,11 @@ class HasCarQueryValues extends MapQueryValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
set updatedAt(DateTime? value) => values['updated_at'] = value;
|
set updatedAt(DateTime? value) => values['updated_at'] = value;
|
||||||
|
Color? get color {
|
||||||
|
return codeToColor((values['color'] as String));
|
||||||
|
}
|
||||||
|
|
||||||
|
set color(Color? value) => values['color'] = colorToCode(value);
|
||||||
CarType? get type {
|
CarType? get type {
|
||||||
return CarType.values[(values['type'] as int)];
|
return CarType.values[(values['type'] as int)];
|
||||||
}
|
}
|
||||||
|
@ -178,6 +203,7 @@ class HasCarQueryValues extends MapQueryValues {
|
||||||
void copyFrom(HasCar model) {
|
void copyFrom(HasCar model) {
|
||||||
createdAt = model.createdAt;
|
createdAt = model.createdAt;
|
||||||
updatedAt = model.updatedAt;
|
updatedAt = model.updatedAt;
|
||||||
|
color = model.color;
|
||||||
type = model.type;
|
type = model.type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +218,7 @@ class HasCar extends _HasCar {
|
||||||
this.id,
|
this.id,
|
||||||
this.createdAt,
|
this.createdAt,
|
||||||
this.updatedAt,
|
this.updatedAt,
|
||||||
|
this.color,
|
||||||
this.type = CarType.sedan,
|
this.type = CarType.sedan,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -207,6 +234,9 @@ class HasCar extends _HasCar {
|
||||||
@override
|
@override
|
||||||
DateTime? updatedAt;
|
DateTime? updatedAt;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? color;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CarType? type;
|
CarType? type;
|
||||||
|
|
||||||
|
@ -214,12 +244,14 @@ class HasCar extends _HasCar {
|
||||||
String? id,
|
String? id,
|
||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
|
Color? color,
|
||||||
CarType? type,
|
CarType? type,
|
||||||
}) {
|
}) {
|
||||||
return HasCar(
|
return HasCar(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
|
color: color ?? this.color,
|
||||||
type: type ?? this.type);
|
type: type ?? this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +261,7 @@ class HasCar extends _HasCar {
|
||||||
other.id == id &&
|
other.id == id &&
|
||||||
other.createdAt == createdAt &&
|
other.createdAt == createdAt &&
|
||||||
other.updatedAt == updatedAt &&
|
other.updatedAt == updatedAt &&
|
||||||
|
other.color == color &&
|
||||||
other.type == type;
|
other.type == type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,13 +271,14 @@ class HasCar extends _HasCar {
|
||||||
id,
|
id,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
|
color,
|
||||||
type,
|
type,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'HasCar(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, type=$type)';
|
return 'HasCar(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, color=$color, type=$type)';
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
|
@ -296,6 +330,7 @@ class HasCarSerializer extends Codec<HasCar, Map> {
|
||||||
? (map['updated_at'] as DateTime)
|
? (map['updated_at'] as DateTime)
|
||||||
: DateTime.parse(map['updated_at'].toString()))
|
: DateTime.parse(map['updated_at'].toString()))
|
||||||
: null,
|
: null,
|
||||||
|
color: codeToColor(map['color']),
|
||||||
type: map['type'] as CarType? ?? CarType.sedan);
|
type: map['type'] as CarType? ?? CarType.sedan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +342,7 @@ class HasCarSerializer extends Codec<HasCar, Map> {
|
||||||
'id': model.id,
|
'id': model.id,
|
||||||
'created_at': model.createdAt?.toIso8601String(),
|
'created_at': model.createdAt?.toIso8601String(),
|
||||||
'updated_at': model.updatedAt?.toIso8601String(),
|
'updated_at': model.updatedAt?.toIso8601String(),
|
||||||
|
'color': colorToCode(model.color),
|
||||||
'type': model.type
|
'type': model.type
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -317,6 +353,7 @@ abstract class HasCarFields {
|
||||||
id,
|
id,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
|
color,
|
||||||
type,
|
type,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -326,5 +363,7 @@ abstract class HasCarFields {
|
||||||
|
|
||||||
static const String updatedAt = 'updated_at';
|
static const String updatedAt = 'updated_at';
|
||||||
|
|
||||||
|
static const String color = 'color';
|
||||||
|
|
||||||
static const String type = 'type';
|
static const String type = 'type';
|
||||||
}
|
}
|
||||||
|
|
7
pubspec.yaml
Normal file
7
pubspec.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
name: angel_workspace
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.18.0 <3.0.0'
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
melos: 3.0.0
|
Loading…
Reference in a new issue