diff --git a/packages/orm/angel_orm_generator/example/main.dart b/packages/orm/angel_orm_generator/example/main.dart index 321794ac..438c2b19 100644 --- a/packages/orm/angel_orm_generator/example/main.dart +++ b/packages/orm/angel_orm_generator/example/main.dart @@ -4,13 +4,14 @@ import 'package:angel_model/angel_model.dart'; import 'package:angel_orm/angel_orm.dart'; import 'package:angel_orm/src/query.dart'; import 'package:angel_serialize/angel_serialize.dart'; +import 'package:optional/optional.dart'; part 'main.g.dart'; void main() async { var query = EmployeeQuery() ..where!.firstName.equals('Rich') ..where!.lastName.equals('Person') - ..orWhere((w) => w!.salary.greaterThanOrEqualTo(75000)) + ..orWhere((w) => w.salary.greaterThanOrEqualTo(75000)) ..join('companies', 'company_id', 'id'); var richPerson = await (query.getOne(_FakeExecutor()) as FutureOr); @@ -23,7 +24,7 @@ class _FakeExecutor extends QueryExecutor { @override Future> query( String tableName, String? query, Map substitutionValues, - [returningFields]) async { + [returningFields = const []]) async { var now = DateTime.now(); print( '_FakeExecutor received query: $query and values: $substitutionValues'); diff --git a/packages/orm/angel_orm_generator/example/main.g.dart b/packages/orm/angel_orm_generator/example/main.g.dart index b5cb3b47..faa48672 100644 --- a/packages/orm/angel_orm_generator/example/main.g.dart +++ b/packages/orm/angel_orm_generator/example/main.g.dart @@ -30,7 +30,7 @@ class EmployeeMigration extends Migration { // OrmGenerator // ************************************************************************** -class EmployeeQuery extends Query { +class EmployeeQuery extends Query { EmployeeQuery({Set? trampoline}) { trampoline ??= {}; trampoline.add(tableName); @@ -75,8 +75,10 @@ class EmployeeQuery extends Query { return EmployeeQueryWhere(this); } - static Employee? parseRow(List row) { - if (row.every((x) => x == null)) return null; + static Optional parseRow(List row) { + if (row.every((x) => x == null)) { + return Optional.empty(); + } var model = Employee( id: (row[0] as String?), createdAt: (row[1] as DateTime?), @@ -85,11 +87,11 @@ class EmployeeQuery extends Query { firstName: (row[4] as String?), lastName: (row[5] as String?), salary: double.tryParse(row[6].toString())); - return model; + return Optional.of(model); } @override - Employee? deserialize(List row) { + Optional deserialize(List row) { return parseRow(row); } } diff --git a/packages/orm/angel_orm_generator/lib/src/migration_generator.dart b/packages/orm/angel_orm_generator/lib/src/migration_generator.dart index 1649a4ce..ab57ab89 100644 --- a/packages/orm/angel_orm_generator/lib/src/migration_generator.dart +++ b/packages/orm/angel_orm_generator/lib/src/migration_generator.dart @@ -42,11 +42,11 @@ class MigrationGenerator extends GeneratorForAnnotation { return null; } - var resolver = await buildStep.resolver; + var resolver = buildStep.resolver; var ctx = await buildOrmContext({}, element, annotation, buildStep, resolver, autoSnakeCaseNames != false); var lib = generateMigrationLibrary(ctx, element, resolver, buildStep); - if (lib == null) return null; + //if (lib == null) return null; return DartFormatter().format(lib.accept(DartEmitter()).toString()); } @@ -79,7 +79,7 @@ class MigrationGenerator extends GeneratorForAnnotation { ..body = Block((closureBody) { var table = refer('table'); - List dup = []; + var dup = []; ctx.columns.forEach((name, col) { // Skip custom-expression columns. if (col.hasExpression) return; @@ -106,13 +106,16 @@ class MigrationGenerator extends GeneratorForAnnotation { if (relationship.localKey == key) return; } } - - dup.add(key); + if (key != null) { + dup.add(key); + } else { + print('Skip: key is null'); + } } String? methodName; - List positional = [literal(key)]; - Map named = {}; + var positional = [literal(key)]; + var named = {}; if (autoIdAndDateFields != false && name == 'id') { methodName = 'serial'; @@ -195,7 +198,7 @@ class MigrationGenerator extends GeneratorForAnnotation { try { var index = ConstantReader(defaultValue).read('index').intValue; - if (index != null) defaultExpr = literalNum(index); + defaultExpr = literalNum(index); } catch (_) { // Extremely weird error occurs here: `Not an instance of int`. // Definitely an analyzer issue. diff --git a/packages/orm/angel_orm_generator/lib/src/orm_build_context.dart b/packages/orm/angel_orm_generator/lib/src/orm_build_context.dart index a2bc1279..8c5713cc 100644 --- a/packages/orm/angel_orm_generator/lib/src/orm_build_context.dart +++ b/packages/orm/angel_orm_generator/lib/src/orm_build_context.dart @@ -247,7 +247,7 @@ Future buildOrmContext( var enumFields = joinTypeType.element.fields.where((f) => f.isEnumConstant).toList(); - for (int i = 0; i < enumFields.length; i++) { + for (var i = 0; i < enumFields.length; i++) { if (enumFields[i].computeConstantValue() == joinTypeRdr) { joinType = JoinType.values[i]; break; @@ -411,6 +411,7 @@ class RelationFieldImpl extends ShimFieldImpl { String get originalFieldName => originalField.name; + @override PropertyAccessorElement? get getter => originalField.getter; } diff --git a/packages/orm/angel_orm_generator/lib/src/readers.dart b/packages/orm/angel_orm_generator/lib/src/readers.dart index 7b169676..a061b861 100644 --- a/packages/orm/angel_orm_generator/lib/src/readers.dart +++ b/packages/orm/angel_orm_generator/lib/src/readers.dart @@ -72,7 +72,7 @@ class RelationshipReader { orElse: () { throw '${ctx.buildContext.clazz.name} has no field that maps to the name "$localKey", ' 'but it has a @HasMany() relation that expects such a field.'; - } as FieldElement Function()?); + }); } FieldElement findForeignField(OrmBuildContext? ctx) { @@ -82,6 +82,6 @@ class RelationshipReader { orElse: () { throw '${foreign.buildContext.clazz.name} has no field that maps to the name "$foreignKey", ' 'but ${ctx!.buildContext.clazz.name} has a @HasMany() relation that expects such a field.'; - } as FieldElement Function()?); + }); } } diff --git a/packages/orm/angel_orm_generator/pubspec.yaml b/packages/orm/angel_orm_generator/pubspec.yaml index 2b8e3381..f7c270c6 100644 --- a/packages/orm/angel_orm_generator/pubspec.yaml +++ b/packages/orm/angel_orm_generator/pubspec.yaml @@ -57,3 +57,4 @@ dev_dependencies: pedantic: ^1.11.0 postgres: ^2.3.2 test: ^1.17.3 + optional: ^6.0.0-nullsafety.2 \ No newline at end of file diff --git a/packages/orm/angel_orm_test/lib/src/many_to_many_test.dart b/packages/orm/angel_orm_test/lib/src/many_to_many_test.dart index 5b291f7b..f94e2d2b 100644 --- a/packages/orm/angel_orm_test/lib/src/many_to_many_test.dart +++ b/packages/orm/angel_orm_test/lib/src/many_to_many_test.dart @@ -95,15 +95,22 @@ manyToManyTests(FutureOr Function() createExecutor, Future fetchThosakwe() async { var query = UserQuery()..where!.id.equals(int.parse(thosakwe!.id!)); - return (await query.getOne(executor)).value; + var userOpt = await query.getOne(executor); + expect(userOpt.isPresent, true); + if (userOpt.isPresent) { + return userOpt.value; + } else { + return null; + } } test('fetch roles for user', () async { printSeparator('Fetch roles for user test'); - var user = await (fetchThosakwe() as FutureOr); - expect(user.roles, hasLength(2)); - expect(user.roles, contains(canPub)); - expect(user.roles, contains(canSub)); + var user = await fetchThosakwe(); + + expect(user?.roles, hasLength(2)); + expect(user?.roles, contains(canPub)); + expect(user?.roles, contains(canSub)); }); test('fetch users for role', () async { @@ -122,12 +129,18 @@ manyToManyTests(FutureOr Function() createExecutor, ..username = 'Prince' ..password = 'Rogers' ..email = 'Nelson'; - var user = await (userQuery.insert(executor) as FutureOr); - expect(user.roles, isEmpty); + var userOpt = await userQuery.insert(executor); + expect(userOpt.isPresent, true); + userOpt.ifPresent((user) async { + expect(user.roles, isEmpty); - // Fetch again, just to be doubly sure. - var query = UserQuery()..where!.id.equals(user.idAsInt!); - var fetched = await (query.getOne(executor) as FutureOr); - expect(fetched.roles, isEmpty); + // Fetch again, just to be doubly sure. + var query = UserQuery()..where!.id.equals(user.idAsInt!); + var fetchedOpt = await query.getOne(executor); + expect(fetchedOpt.isPresent, true); + fetchedOpt.ifPresent((fetched) { + expect(fetched.roles, isEmpty); + }); + }); }); }