dart-backend / angel

A polished, production-ready backend framework in Dart for the VM, AOT, and Flutter.
https://github.com/dukefirehawk/angel
BSD 3-Clause "New" or "Revised" License
171 stars 22 forks source link

Generated code of ORM doesn't compile #75

Closed jaumard closed 1 year ago

jaumard commented 1 year ago

The generated code for the following class doesn't compile:


import 'package:angel3_migration/angel3_migration.dart';
import 'package:angel3_orm/angel3_orm.dart';
import 'package:angel3_serialize/angel3_serialize.dart';
import 'package:optional/optional.dart';

part 'loan.g.dart';

@Orm(tableName: 'mx_cashadvanceproposalrequest', generateMigrations: false)
@serializable
abstract class _Loan {
  /// A unique identifier corresponding to this item.
  int? id;

  List<String> get invoicePhotos;

  String get product;

  String get invoiceReference;

  String get uuid;

  String get partner;

  DateTime get added;

  int get status;

  int get usage;

  int get supplierType;

  double get amount;

  DateTime get lastMod;

  int get reimbursementDays;

  int get merchantId;

  int get shopId;

  int? get supplierId;

  int? get fees;

  bool get isEnabled;

  bool get skippedEligibilityTest;

  bool get onBehalfOfSomeoneElse;

}
It generate this: ``` // GENERATED CODE - DO NOT MODIFY BY HAND part of 'loan.dart'; // ************************************************************************** // OrmGenerator // ************************************************************************** class LoanQuery extends Query { LoanQuery({Query? parent, Set? trampoline}) : super(parent: parent) { trampoline ??= {}; trampoline.add(tableName); _where = LoanQueryWhere(this); } @override final LoanQueryValues values = LoanQueryValues(); List _selectedFields = []; LoanQueryWhere? _where; @override Map get casts { return {'amount': 'char'}; } @override String get tableName { return 'mx_cashadvanceproposalrequest'; } @override List get fields { const _fields = [ 'id', 'invoice_photos', 'product', 'invoice_reference', 'uuid', 'partner', 'added', 'status', 'usage', 'supplier_type', 'amount', 'last_mod', 'reimbursement_days', 'merchant_id', 'shop_id', 'supplier_id', 'fees', 'is_enabled', 'skipped_eligibility_test', 'on_behalf_of_someone_else' ]; return _selectedFields.isEmpty ? _fields : _fields.where((field) => _selectedFields.contains(field)).toList(); } LoanQuery select(List selectedFields) { _selectedFields = selectedFields; return this; } @override LoanQueryWhere? get where { return _where; } @override LoanQueryWhere newWhereClause() { return LoanQueryWhere(this); } Optional parseRow(List row) { if (row.every((x) => x == null)) { return Optional.empty(); } var model = Loan( id: fields.contains('id') ? (row[0] as int?) : null, invoicePhotos: fields.contains('invoice_photos') ? (row[1] as List) : null, product: fields.contains('product') ? (row[2] as String) : '', invoiceReference: fields.contains('invoice_reference') ? (row[3] as String) : '', uuid: fields.contains('uuid') ? (row[4] as String) : '', partner: fields.contains('partner') ? (row[5] as String) : '', added: fields.contains('added') ? mapToDateTime(row[6]) : DateTime.parse("1970-01-01 00:00:00"), status: fields.contains('status') ? (row[7] as int) : 0, usage: fields.contains('usage') ? (row[8] as int) : 0, supplierType: fields.contains('supplier_type') ? (row[9] as int) : 0, amount: fields.contains('amount') ? mapToDouble(row[10]) : 0.0, lastMod: fields.contains('last_mod') ? mapToDateTime(row[11]) : DateTime.parse("1970-01-01 00:00:00"), reimbursementDays: fields.contains('reimbursement_days') ? (row[12] as int) : 0, merchantId: fields.contains('merchant_id') ? (row[13] as int) : 0, shopId: fields.contains('shop_id') ? (row[14] as int) : 0, supplierId: fields.contains('supplier_id') ? (row[15] as int?) : null, fees: fields.contains('fees') ? (row[16] as int?) : null, isEnabled: fields.contains('is_enabled') ? mapToBool(row[17]) : false, skippedEligibilityTest: fields.contains('skipped_eligibility_test') ? mapToBool(row[18]) : false, onBehalfOfSomeoneElse: fields.contains('on_behalf_of_someone_else') ? mapToBool(row[19]) : false); return Optional.of(model); } @override Optional deserialize(List row) { return parseRow(row); } } class LoanQueryWhere extends QueryWhere { LoanQueryWhere(LoanQuery query) : id = NumericSqlExpressionBuilder(query, 'id'), invoicePhotos = ListSqlExpressionBuilder(query, 'invoice_photos'), product = StringSqlExpressionBuilder(query, 'product'), invoiceReference = StringSqlExpressionBuilder(query, 'invoice_reference'), uuid = StringSqlExpressionBuilder(query, 'uuid'), partner = StringSqlExpressionBuilder(query, 'partner'), added = DateTimeSqlExpressionBuilder(query, 'added'), status = NumericSqlExpressionBuilder(query, 'status'), usage = NumericSqlExpressionBuilder(query, 'usage'), supplierType = NumericSqlExpressionBuilder(query, 'supplier_type'), amount = NumericSqlExpressionBuilder(query, 'amount'), lastMod = DateTimeSqlExpressionBuilder(query, 'last_mod'), reimbursementDays = NumericSqlExpressionBuilder(query, 'reimbursement_days'), merchantId = NumericSqlExpressionBuilder(query, 'merchant_id'), shopId = NumericSqlExpressionBuilder(query, 'shop_id'), supplierId = NumericSqlExpressionBuilder(query, 'supplier_id'), fees = NumericSqlExpressionBuilder(query, 'fees'), isEnabled = BooleanSqlExpressionBuilder(query, 'is_enabled'), skippedEligibilityTest = BooleanSqlExpressionBuilder(query, 'skipped_eligibility_test'), onBehalfOfSomeoneElse = BooleanSqlExpressionBuilder(query, 'on_behalf_of_someone_else'); final NumericSqlExpressionBuilder id; final ListSqlExpressionBuilder invoicePhotos; final StringSqlExpressionBuilder product; final StringSqlExpressionBuilder invoiceReference; final StringSqlExpressionBuilder uuid; final StringSqlExpressionBuilder partner; final DateTimeSqlExpressionBuilder added; final NumericSqlExpressionBuilder status; final NumericSqlExpressionBuilder usage; final NumericSqlExpressionBuilder supplierType; final NumericSqlExpressionBuilder amount; final DateTimeSqlExpressionBuilder lastMod; final NumericSqlExpressionBuilder reimbursementDays; final NumericSqlExpressionBuilder merchantId; final NumericSqlExpressionBuilder shopId; final NumericSqlExpressionBuilder supplierId; final NumericSqlExpressionBuilder fees; final BooleanSqlExpressionBuilder isEnabled; final BooleanSqlExpressionBuilder skippedEligibilityTest; final BooleanSqlExpressionBuilder onBehalfOfSomeoneElse; @override List get expressionBuilders { return [ id, invoicePhotos, product, invoiceReference, uuid, partner, added, status, usage, supplierType, amount, lastMod, reimbursementDays, merchantId, shopId, supplierId, fees, isEnabled, skippedEligibilityTest, onBehalfOfSomeoneElse ]; } } class LoanQueryValues extends MapQueryValues { @override Map get casts { return {'invoice_photos': 'jsonb', 'amount': 'double precision'}; } int? get id { return (values['id'] as int?); } set id(int? value) => values['id'] = value; List get invoicePhotos { return (json.decode((values['invoice_photos'] as String)) as List); } set invoicePhotos(List value) => values['invoice_photos'] = json.encode(value); String get product { return (values['product'] as String); } set product(String value) => values['product'] = value; String get invoiceReference { return (values['invoice_reference'] as String); } set invoiceReference(String value) => values['invoice_reference'] = value; String get uuid { return (values['uuid'] as String); } set uuid(String value) => values['uuid'] = value; String get partner { return (values['partner'] as String); } set partner(String value) => values['partner'] = value; DateTime get added { return (values['added'] as DateTime); } set added(DateTime value) => values['added'] = value; int get status { return (values['status'] as int); } set status(int value) => values['status'] = value; int get usage { return (values['usage'] as int); } set usage(int value) => values['usage'] = value; int get supplierType { return (values['supplier_type'] as int); } set supplierType(int value) => values['supplier_type'] = value; double get amount { return double.tryParse((values['amount'] as String)) ?? 0.0; } set amount(double value) => values['amount'] = value.toString(); DateTime get lastMod { return (values['last_mod'] as DateTime); } set lastMod(DateTime value) => values['last_mod'] = value; int get reimbursementDays { return (values['reimbursement_days'] as int); } set reimbursementDays(int value) => values['reimbursement_days'] = value; int get merchantId { return (values['merchant_id'] as int); } set merchantId(int value) => values['merchant_id'] = value; int get shopId { return (values['shop_id'] as int); } set shopId(int value) => values['shop_id'] = value; int? get supplierId { return (values['supplier_id'] as int?); } set supplierId(int? value) => values['supplier_id'] = value; int? get fees { return (values['fees'] as int?); } set fees(int? value) => values['fees'] = value; bool get isEnabled { return (values['is_enabled'] as bool); } set isEnabled(bool value) => values['is_enabled'] = value; bool get skippedEligibilityTest { return (values['skipped_eligibility_test'] as bool); } set skippedEligibilityTest(bool value) => values['skipped_eligibility_test'] = value; bool get onBehalfOfSomeoneElse { return (values['on_behalf_of_someone_else'] as bool); } set onBehalfOfSomeoneElse(bool value) => values['on_behalf_of_someone_else'] = value; void copyFrom(Loan model) { id = model.id; invoicePhotos = model.invoicePhotos; product = model.product; invoiceReference = model.invoiceReference; uuid = model.uuid; partner = model.partner; added = model.added; status = model.status; usage = model.usage; supplierType = model.supplierType; amount = model.amount; lastMod = model.lastMod; reimbursementDays = model.reimbursementDays; merchantId = model.merchantId; shopId = model.shopId; supplierId = model.supplierId; fees = model.fees; isEnabled = model.isEnabled; skippedEligibilityTest = model.skippedEligibilityTest; onBehalfOfSomeoneElse = model.onBehalfOfSomeoneElse; } } // ************************************************************************** // JsonModelGenerator // ************************************************************************** @generatedSerializable class Loan extends _Loan { Loan( {this.id, List invoicePhotos = const [], required this.product, required this.invoiceReference, required this.uuid, required this.partner, required this.added, required this.status, required this.usage, required this.supplierType, required this.amount, required this.lastMod, required this.reimbursementDays, required this.merchantId, required this.shopId, this.supplierId, this.fees, required this.isEnabled, required this.skippedEligibilityTest, required this.onBehalfOfSomeoneElse}) : invoicePhotos = List.unmodifiable(invoicePhotos); /// A unique identifier corresponding to this item. @override int? id; @override List invoicePhotos; @override String product; @override String invoiceReference; @override String uuid; @override String partner; @override DateTime added; @override int status; @override int usage; @override int supplierType; @override double amount; @override DateTime lastMod; @override int reimbursementDays; @override int merchantId; @override int shopId; @override int? supplierId; @override int? fees; @override bool isEnabled; @override bool skippedEligibilityTest; @override bool onBehalfOfSomeoneElse; Loan copyWith( {int? id, List? invoicePhotos, String? product, String? invoiceReference, String? uuid, String? partner, DateTime? added, int? status, int? usage, int? supplierType, double? amount, DateTime? lastMod, int? reimbursementDays, int? merchantId, int? shopId, int? supplierId, int? fees, bool? isEnabled, bool? skippedEligibilityTest, bool? onBehalfOfSomeoneElse}) { return Loan( id: id ?? this.id, invoicePhotos: invoicePhotos ?? this.invoicePhotos, product: product ?? this.product, invoiceReference: invoiceReference ?? this.invoiceReference, uuid: uuid ?? this.uuid, partner: partner ?? this.partner, added: added ?? this.added, status: status ?? this.status, usage: usage ?? this.usage, supplierType: supplierType ?? this.supplierType, amount: amount ?? this.amount, lastMod: lastMod ?? this.lastMod, reimbursementDays: reimbursementDays ?? this.reimbursementDays, merchantId: merchantId ?? this.merchantId, shopId: shopId ?? this.shopId, supplierId: supplierId ?? this.supplierId, fees: fees ?? this.fees, isEnabled: isEnabled ?? this.isEnabled, skippedEligibilityTest: skippedEligibilityTest ?? this.skippedEligibilityTest, onBehalfOfSomeoneElse: onBehalfOfSomeoneElse ?? this.onBehalfOfSomeoneElse); } @override bool operator ==(other) { return other is _Loan && other.id == id && ListEquality(DefaultEquality()) .equals(other.invoicePhotos, invoicePhotos) && other.product == product && other.invoiceReference == invoiceReference && other.uuid == uuid && other.partner == partner && other.added == added && other.status == status && other.usage == usage && other.supplierType == supplierType && other.amount == amount && other.lastMod == lastMod && other.reimbursementDays == reimbursementDays && other.merchantId == merchantId && other.shopId == shopId && other.supplierId == supplierId && other.fees == fees && other.isEnabled == isEnabled && other.skippedEligibilityTest == skippedEligibilityTest && other.onBehalfOfSomeoneElse == onBehalfOfSomeoneElse; } @override int get hashCode { return hashObjects([ id, invoicePhotos, product, invoiceReference, uuid, partner, added, status, usage, supplierType, amount, lastMod, reimbursementDays, merchantId, shopId, supplierId, fees, isEnabled, skippedEligibilityTest, onBehalfOfSomeoneElse ]); } @override String toString() { return 'Loan(id=$id, invoicePhotos=$invoicePhotos, product=$product, invoiceReference=$invoiceReference, uuid=$uuid, partner=$partner, added=$added, status=$status, usage=$usage, supplierType=$supplierType, amount=$amount, lastMod=$lastMod, reimbursementDays=$reimbursementDays, merchantId=$merchantId, shopId=$shopId, supplierId=$supplierId, fees=$fees, isEnabled=$isEnabled, skippedEligibilityTest=$skippedEligibilityTest, onBehalfOfSomeoneElse=$onBehalfOfSomeoneElse)'; } Map toJson() { return LoanSerializer.toMap(this); } } // ************************************************************************** // SerializerGenerator // ************************************************************************** const LoanSerializer loanSerializer = LoanSerializer(); class LoanEncoder extends Converter { const LoanEncoder(); @override Map convert(Loan model) => LoanSerializer.toMap(model); } class LoanDecoder extends Converter { const LoanDecoder(); @override Loan convert(Map map) => LoanSerializer.fromMap(map); } class LoanSerializer extends Codec { const LoanSerializer(); @override LoanEncoder get encoder => const LoanEncoder(); @override LoanDecoder get decoder => const LoanDecoder(); static Loan fromMap(Map map) { return Loan( id: map['id'] as int?, invoicePhotos: map['invoice_photos'] is Iterable ? (map['invoice_photos'] as Iterable).cast().toList() : [], product: map['product'] as String, invoiceReference: map['invoice_reference'] as String, uuid: map['uuid'] as String, partner: map['partner'] as String, added: map['added'] != null ? (map['added'] is DateTime ? (map['added'] as DateTime) : DateTime.parse(map['added'].toString())) : DateTime.parse("1970-01-01 00:00:00"), status: map['status'] as int, usage: map['usage'] as int, supplierType: map['supplier_type'] as int, amount: map['amount'] as double, lastMod: map['last_mod'] != null ? (map['last_mod'] is DateTime ? (map['last_mod'] as DateTime) : DateTime.parse(map['last_mod'].toString())) : DateTime.parse("1970-01-01 00:00:00"), reimbursementDays: map['reimbursement_days'] as int, merchantId: map['merchant_id'] as int, shopId: map['shop_id'] as int, supplierId: map['supplier_id'] as int?, fees: map['fees'] as int?, isEnabled: map['is_enabled'] as bool, skippedEligibilityTest: map['skipped_eligibility_test'] as bool, onBehalfOfSomeoneElse: map['on_behalf_of_someone_else'] as bool); } static Map toMap(_Loan? model) { if (model == null) { throw FormatException("Required field [model] cannot be null"); } return { 'id': model.id, 'invoice_photos': model.invoicePhotos, 'product': model.product, 'invoice_reference': model.invoiceReference, 'uuid': model.uuid, 'partner': model.partner, 'added': model.added.toIso8601String(), 'status': model.status, 'usage': model.usage, 'supplier_type': model.supplierType, 'amount': model.amount, 'last_mod': model.lastMod.toIso8601String(), 'reimbursement_days': model.reimbursementDays, 'merchant_id': model.merchantId, 'shop_id': model.shopId, 'supplier_id': model.supplierId, 'fees': model.fees, 'is_enabled': model.isEnabled, 'skipped_eligibility_test': model.skippedEligibilityTest, 'on_behalf_of_someone_else': model.onBehalfOfSomeoneElse }; } } abstract class LoanFields { static const List allFields = [ id, invoicePhotos, product, invoiceReference, uuid, partner, added, status, usage, supplierType, amount, lastMod, reimbursementDays, merchantId, shopId, supplierId, fees, isEnabled, skippedEligibilityTest, onBehalfOfSomeoneElse ]; static const String id = 'id'; static const String invoicePhotos = 'invoice_photos'; static const String product = 'product'; static const String invoiceReference = 'invoice_reference'; static const String uuid = 'uuid'; static const String partner = 'partner'; static const String added = 'added'; static const String status = 'status'; static const String usage = 'usage'; static const String supplierType = 'supplier_type'; static const String amount = 'amount'; static const String lastMod = 'last_mod'; static const String reimbursementDays = 'reimbursement_days'; static const String merchantId = 'merchant_id'; static const String shopId = 'shop_id'; static const String supplierId = 'supplier_id'; static const String fees = 'fees'; static const String isEnabled = 'is_enabled'; static const String skippedEligibilityTest = 'skipped_eligibility_test'; static const String onBehalfOfSomeoneElse = 'on_behalf_of_someone_else'; } ```

Errors are:

error: The argument type 'List<String>?' can't be assigned to the parameter type 'List<String>'. (argument_type_not_assignable at [dashboard_server] lib/src/loans/models/loan.g.dart:84)
error: A value of type 'List<dynamic>' can't be returned from the function 'invoicePhotos' because it has a return type of 'List<String>'. (return_of_invalid_type at [dashboard_server] lib/src/loans/models/loan.g.dart:228)

Any idea what's wrong? I stop compiling when adding the List<String> field, is that not supported?

dukefirehawk commented 1 year ago

This is caused by 2 bugs in the angel3_orm_generator pacakge. Will be fixed in the upcoming release. In the meantime, you could directly make the following changes to the generated class, loan_g.dart.

  1. Line 83-84

    invoicePhotos:
      fields.contains('invoice_photos') ? (row[1] as List<String>) : [],
    1. Line 227-229
    List<String> get invoicePhotos {
       return (json.decode((values['invoice_photos'] as String)) as List).cast<String>();
    }
dukefirehawk commented 1 year ago

Fixed and released in angel3_orm_generator 7.0.0