From 630b301555695c070139d9faf126590ce3136d3f Mon Sep 17 00:00:00 2001 From: thomashii Date: Sun, 2 Jan 2022 15:21:17 +0800 Subject: [PATCH] Fixed ORM Generator --- packages/orm/angel_migration/CHANGELOG.md | 4 + packages/orm/angel_migration/README.md | 6 +- .../orm/angel_migration/lib/src/column.dart | 2 +- .../orm/angel_migration/lib/src/schema.dart | 4 +- packages/orm/angel_migration/pubspec.yaml | 2 +- .../orm/angel_migration_runner/CHANGELOG.md | 4 + packages/orm/angel_migration_runner/README.md | 4 +- .../angel_migration_runner/example/main.dart | 25 +- .../orm/angel_migration_runner/lib/mysql.dart | 3 + .../lib/src/mysql/runner.dart | 157 +++ .../lib/src/mysql/schema.dart | 74 ++ .../lib/src/mysql/table.dart | 169 +++ .../lib/src/postgres/runner.dart | 5 +- .../lib/src/postgres/table.dart | 2 +- .../orm/angel_migration_runner/pubspec.yaml | 5 +- packages/orm/angel_orm/CHANGELOG.md | 5 + packages/orm/angel_orm/README.md | 5 + packages/orm/angel_orm/lib/src/migration.dart | 8 +- .../orm/angel_orm/lib/src/query_base.dart | 3 - packages/orm/angel_orm/lib/src/relations.dart | 4 +- packages/orm/angel_orm/pubspec.yaml | 2 +- packages/orm/angel_orm_generator/CHANGELOG.md | 5 + packages/orm/angel_orm_generator/README.md | 5 + .../lib/src/migration_generator.dart | 28 +- .../lib/src/orm_build_context.dart | 15 +- .../lib/src/orm_generator.dart | 76 +- .../angel_orm_generator/lib/src/readers.dart | 8 +- packages/orm/angel_orm_generator/pubspec.yaml | 7 +- packages/orm/angel_orm_mysql/README.md | 7 + packages/orm/angel_orm_postgres/README.md | 6 +- packages/orm/angel_orm_postgres/pubspec.yaml | 10 +- .../lib/src/belongs_to_test.dart | 8 +- .../angel_orm_test/lib/src/has_many_test.dart | 6 +- .../angel_orm_test/lib/src/has_one_test.dart | 2 +- .../angel_orm_test/lib/src/models/book.dart | 4 +- .../angel_orm_test/lib/src/models/book.g.dart | 67 +- .../angel_orm_test/lib/src/models/car.dart | 1 - .../angel_orm_test/lib/src/models/car.g.dart | 15 +- .../lib/src/models/custom_expr.dart | 1 - .../lib/src/models/custom_expr.g.dart | 41 +- .../lib/src/models/email_indexed.g.dart | 121 +- .../lib/src/models/fortune.dart | 2 +- .../lib/src/models/fortune.g.dart | 10 +- .../lib/src/models/has_car.dart | 1 - .../lib/src/models/has_car.g.dart | 31 +- .../lib/src/models/has_map.dart | 2 - .../lib/src/models/has_map.g.dart | 39 +- .../angel_orm_test/lib/src/models/leg.dart | 1 - .../angel_orm_test/lib/src/models/leg.g.dart | 34 +- .../angel_orm_test/lib/src/models/order.dart | 1 - .../lib/src/models/order.g.dart | 49 +- .../angel_orm_test/lib/src/models/tree.dart | 4 +- .../angel_orm_test/lib/src/models/tree.g.dart | 34 +- .../lib/src/models/unorthodox.dart | 7 +- .../lib/src/models/unorthodox.g.dart | 185 +-- .../angel_orm_test/lib/src/models/user.dart | 2 - .../angel_orm_test/lib/src/models/user.g.dart | 149 +-- .../angel_orm_test/lib/src/models/world.dart | 2 +- .../lib/src/models/world.g.dart | 26 +- packages/orm/angel_orm_test/pubspec.yaml | 10 +- .../orm/orm_builder/analysis_options.yaml | 1 + .../orm_builder/lib/src/belongs_to_test.dart | 175 +++ .../orm/orm_builder/lib/src/models/book.dart | 28 + .../orm_builder/lib/src/models/book.g.dart | 617 ++++++++++ .../orm/orm_builder/lib/src/models/user.dart | 38 + .../orm_builder/lib/src/models/user.g.dart | 1002 +++++++++++++++++ packages/orm/orm_builder/lib/src/util.dart | 12 + packages/orm/orm_builder/pubspec.yaml | 31 + 68 files changed, 2941 insertions(+), 478 deletions(-) create mode 100644 packages/orm/angel_migration_runner/lib/mysql.dart create mode 100644 packages/orm/angel_migration_runner/lib/src/mysql/runner.dart create mode 100644 packages/orm/angel_migration_runner/lib/src/mysql/schema.dart create mode 100644 packages/orm/angel_migration_runner/lib/src/mysql/table.dart create mode 100644 packages/orm/orm_builder/analysis_options.yaml create mode 100644 packages/orm/orm_builder/lib/src/belongs_to_test.dart create mode 100644 packages/orm/orm_builder/lib/src/models/book.dart create mode 100644 packages/orm/orm_builder/lib/src/models/book.g.dart create mode 100644 packages/orm/orm_builder/lib/src/models/user.dart create mode 100644 packages/orm/orm_builder/lib/src/models/user.g.dart create mode 100644 packages/orm/orm_builder/lib/src/util.dart create mode 100644 packages/orm/orm_builder/pubspec.yaml diff --git a/packages/orm/angel_migration/CHANGELOG.md b/packages/orm/angel_migration/CHANGELOG.md index a7a86d17..2a152f9e 100755 --- a/packages/orm/angel_migration/CHANGELOG.md +++ b/packages/orm/angel_migration/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 4.0.2 + +* Updated default varchar column size to 255 + ## 4.0.1 * Updated linter to `package:lints` diff --git a/packages/orm/angel_migration/README.md b/packages/orm/angel_migration/README.md index bb98a778..a10eff3c 100755 --- a/packages/orm/angel_migration/README.md +++ b/packages/orm/angel_migration/README.md @@ -7,6 +7,8 @@ A database migration framework built for Angel3 ORM. -Supported database: +## Supported database -* postgresql version 10, 11, 12, 13 and 14 +* PostgreSQL version 10 or later +* MySQL 8.0 or later +* MariaBb 10.2.1 or later diff --git a/packages/orm/angel_migration/lib/src/column.dart b/packages/orm/angel_migration/lib/src/column.dart index c7be58bb..41be1f13 100755 --- a/packages/orm/angel_migration/lib/src/column.dart +++ b/packages/orm/angel_migration/lib/src/column.dart @@ -19,7 +19,7 @@ class MigrationColumn extends Column { MigrationColumn(ColumnType type, {bool isNullable = true, - int length = 256, + int length = 255, IndexType indexType = IndexType.standardIndex, defaultValue}) : super(type: type, length: length) { diff --git a/packages/orm/angel_migration/lib/src/schema.dart b/packages/orm/angel_migration/lib/src/schema.dart index 68a6234a..b70236cb 100755 --- a/packages/orm/angel_migration/lib/src/schema.dart +++ b/packages/orm/angel_migration/lib/src/schema.dart @@ -4,7 +4,9 @@ abstract class Schema { void drop(String tableName, {bool cascade = false}); void dropAll(Iterable tableNames, {bool cascade = false}) { - tableNames.forEach((n) => drop(n, cascade: cascade)); + for (var n in tableNames) { + drop(n, cascade: cascade); + } } void create(String tableName, void Function(Table table) callback); diff --git a/packages/orm/angel_migration/pubspec.yaml b/packages/orm/angel_migration/pubspec.yaml index 077c4ed4..2de66339 100755 --- a/packages/orm/angel_migration/pubspec.yaml +++ b/packages/orm/angel_migration/pubspec.yaml @@ -1,5 +1,5 @@ name: angel3_migration -version: 4.0.1 +version: 4.0.2 description: Database migration runtime for Angel3 ORM. Use this package to define schemas. homepage: https://angel3-framework.web.app/ repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_migration diff --git a/packages/orm/angel_migration_runner/CHANGELOG.md b/packages/orm/angel_migration_runner/CHANGELOG.md index 28546afb..89b8e418 100755 --- a/packages/orm/angel_migration_runner/CHANGELOG.md +++ b/packages/orm/angel_migration_runner/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 4.1.0 + +* Added support `MySQL` database support + ## 4.0.2 * Updated README diff --git a/packages/orm/angel_migration_runner/README.md b/packages/orm/angel_migration_runner/README.md index 530508cb..0a33aa3d 100755 --- a/packages/orm/angel_migration_runner/README.md +++ b/packages/orm/angel_migration_runner/README.md @@ -9,4 +9,6 @@ Command-line based database migration runner for Angel3 ORM. Supported database: -* postgresql version 10, 11, 12, 13 and 14 +* Postgresql version 10, 11, 12, 13 and 14 +* MySQL version 5, 6 and 7 +* Maria 10 diff --git a/packages/orm/angel_migration_runner/example/main.dart b/packages/orm/angel_migration_runner/example/main.dart index 0c2f3ac4..bf795df7 100755 --- a/packages/orm/angel_migration_runner/example/main.dart +++ b/packages/orm/angel_migration_runner/example/main.dart @@ -1,13 +1,16 @@ import 'package:angel3_migration/angel3_migration.dart'; import 'package:angel3_migration_runner/angel3_migration_runner.dart'; import 'package:angel3_migration_runner/postgres.dart'; +import 'package:angel3_migration_runner/mysql.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:postgres/postgres.dart'; +import 'package:mysql1/mysql1.dart'; + import 'todo.dart'; -var migrationRunner = PostgresMigrationRunner( - PostgreSQLConnection('127.0.0.1', 5432, 'test', - username: 'postgres', password: 'postgres'), +var postgresqlMigrationRunner = PostgresMigrationRunner( + PostgreSQLConnection('127.0.0.1', 5432, 'demo', + username: 'demouser', password: 'demo123'), migrations: [ UserMigration(), TodoMigration(), @@ -15,7 +18,21 @@ var migrationRunner = PostgresMigrationRunner( ], ); -void main(List args) => runMigrations(migrationRunner, args); +var mysqlMigrationRunner = MysqlMigrationRunner( + ConnectionSettings( + host: 'localhost', + port: 3306, + user: 'demouser', + password: 'demo123', + db: 'demo'), + migrations: [ + UserMigration(), + TodoMigration(), + FooMigration(), + ], +); + +void main(List args) => runMigrations(postgresqlMigrationRunner, args); class FooMigration extends Migration { @override diff --git a/packages/orm/angel_migration_runner/lib/mysql.dart b/packages/orm/angel_migration_runner/lib/mysql.dart new file mode 100644 index 00000000..9a1e2106 --- /dev/null +++ b/packages/orm/angel_migration_runner/lib/mysql.dart @@ -0,0 +1,3 @@ +export 'src/mysql/runner.dart'; +export 'src/mysql/schema.dart'; +export 'src/mysql/table.dart'; diff --git a/packages/orm/angel_migration_runner/lib/src/mysql/runner.dart b/packages/orm/angel_migration_runner/lib/src/mysql/runner.dart new file mode 100644 index 00000000..e8444877 --- /dev/null +++ b/packages/orm/angel_migration_runner/lib/src/mysql/runner.dart @@ -0,0 +1,157 @@ +import 'dart:async'; +import 'dart:collection'; +import 'package:angel3_migration/angel3_migration.dart'; +import 'package:logging/logging.dart'; +import 'package:mysql1/mysql1.dart'; +import '../runner.dart'; +import '../util.dart'; +import 'schema.dart'; + +class MysqlMigrationRunner implements MigrationRunner { + final _log = Logger('PostgresMigrationRunner'); + + final Map migrations = {}; + final ConnectionSettings settings; + final Queue _migrationQueue = Queue(); + late MySqlConnection connection; + bool _connected = false; + + MysqlMigrationRunner(this.settings, + {Iterable migrations = const [], bool connected = false}) { + if (migrations.isNotEmpty == true) migrations.forEach(addMigration); + _connected = connected == true; + } + + @override + void addMigration(Migration migration) { + _migrationQueue.addLast(migration); + } + + Future _init() async { + while (_migrationQueue.isNotEmpty) { + var migration = _migrationQueue.removeFirst(); + var path = await absoluteSourcePath(migration.runtimeType); + migrations.putIfAbsent(path.replaceAll('\\', '\\\\'), () => migration); + } + + if (!_connected) { + connection = await MySqlConnection.connect(settings); + _connected = true; + } + + await connection.query(''' + CREATE TABLE IF NOT EXISTS "migrations" ( + id serial, + batch integer, + path varchar, + PRIMARY KEY(id) + ); + ''').then((result) { + _log.info('Check and create "migrations" table'); + }).catchError((e) { + _log.severe('Failed to create "migrations" table.'); + }); + } + + @override + Future up() async { + await _init(); + var r = await connection.query('SELECT path from migrations;'); + var existing = r.expand((x) => x).cast(); + var toRun = []; + + migrations.forEach((k, v) { + if (!existing.contains(k)) toRun.add(k); + }); + + if (toRun.isNotEmpty) { + var r = await connection.query('SELECT MAX(batch) from migrations;'); + var rTmp = r.toList(); + var curBatch = (rTmp[0][0] ?? 0) as int; + var batch = curBatch + 1; + + for (var k in toRun) { + var migration = migrations[k]!; + var schema = MysqlSchema(); + migration.up(schema); + _log.info('Added "$k" into "migrations" table.'); + await schema.run(connection).then((_) { + return connection.transaction((ctx) async { + var result = await ctx.query( + "INSERT INTO MIGRATIONS (batch, path) VALUES ($batch, '$k')"); + + return result.affectedRowCount; + }); + //return connection.execute( + // 'INSERT INTO MIGRATIONS (batch, path) VALUES ($batch, \'$k\');'); + }).catchError((e) { + _log.severe('Failed to insert into "migrations" table.'); + }); + } + } else { + _log.warning('Nothing to add into "migrations" table.'); + } + } + + @override + Future rollback() async { + await _init(); + + var r = await connection.query('SELECT MAX(batch) from migrations;'); + var rTmp = r.toList(); + var curBatch = (rTmp[0][0] ?? 0) as int; + + r = await connection + .query('SELECT path from migrations WHERE batch = $curBatch;'); + var existing = r.expand((x) => x).cast(); + var toRun = []; + + migrations.forEach((k, v) { + if (existing.contains(k)) toRun.add(k); + }); + + if (toRun.isNotEmpty) { + for (var k in toRun.reversed) { + var migration = migrations[k]!; + var schema = MysqlSchema(); + migration.down(schema); + _log.info('Removed "$k" from "migrations" table.'); + await schema.run(connection).then((_) { + return connection + .query('DELETE FROM migrations WHERE path = \'$k\';'); + }); + } + } else { + _log.warning('Nothing to remove from "migrations" table.'); + } + } + + @override + Future reset() async { + await _init(); + var r = await connection + .query('SELECT path from migrations ORDER BY batch DESC;'); + var existing = r.expand((x) => x).cast(); + var toRun = existing.where(migrations.containsKey).toList(); + + if (toRun.isNotEmpty) { + for (var k in toRun.reversed) { + var migration = migrations[k]!; + var schema = MysqlSchema(); + migration.down(schema); + _log.info('Removed "$k" from "migrations" table.'); + await schema.run(connection).then((_) { + return connection + .query('DELETE FROM migrations WHERE path = \'$k\';'); + }); + } + } else { + _log.warning('Nothing to remove from "migrations" table.'); + } + } + + @override + Future close() { + return connection.close(); + } +} diff --git a/packages/orm/angel_migration_runner/lib/src/mysql/schema.dart b/packages/orm/angel_migration_runner/lib/src/mysql/schema.dart new file mode 100644 index 00000000..fa006691 --- /dev/null +++ b/packages/orm/angel_migration_runner/lib/src/mysql/schema.dart @@ -0,0 +1,74 @@ +import 'dart:async'; +import 'package:angel3_migration/angel3_migration.dart'; +import 'package:angel3_migration_runner/src/mysql/table.dart'; +import 'package:logging/logging.dart'; +import 'package:mysql1/mysql1.dart'; + +class MysqlSchema extends Schema { + final _log = Logger('MysqlSchema'); + + final int _indent; + final StringBuffer _buf; + + MysqlSchema._(this._buf, this._indent); + + factory MysqlSchema() => MysqlSchema._(StringBuffer(), 0); + + Future run(MySqlConnection connection) async { + //return connection.execute(compile()); + var result = await connection.transaction((ctx) async { + var sql = compile(); + var result = await ctx.query(sql).catchError((e) { + _log.severe('Failed to run query: [ $sql ]', e); + }); + return result.affectedRowCount; + }); + + return (result is int) ? result : 0; + } + + String compile() => _buf.toString(); + + void _writeln(String str) { + for (var i = 0; i < _indent; i++) { + _buf.write(' '); + } + + _buf.writeln(str); + } + + @override + void drop(String tableName, {bool cascade = false}) { + var c = cascade == true ? ' CASCADE' : ''; + _writeln('DROP TABLE "$tableName"$c;'); + } + + @override + void alter(String tableName, void Function(MutableTable table) callback) { + var tbl = MysqlAlterTable(tableName); + callback(tbl); + _writeln('ALTER TABLE "$tableName"'); + tbl.compile(_buf, _indent + 1); + _buf.write(';'); + } + + void _create( + String tableName, void Function(Table table) callback, bool ifNotExists) { + var op = ifNotExists ? ' IF NOT EXISTS' : ''; + var tbl = MysqlTable(); + callback(tbl); + _writeln('CREATE TABLE$op "$tableName" ('); + tbl.compile(_buf, _indent + 1); + _buf.writeln(); + _writeln(');'); + } + + @override + void create(String tableName, void Function(Table table) callback) => + _create(tableName, callback, false); + + @override + void createIfNotExists( + String tableName, void Function(Table table) callback) => + _create(tableName, callback, true); +} diff --git a/packages/orm/angel_migration_runner/lib/src/mysql/table.dart b/packages/orm/angel_migration_runner/lib/src/mysql/table.dart new file mode 100644 index 00000000..8b4b758e --- /dev/null +++ b/packages/orm/angel_migration_runner/lib/src/mysql/table.dart @@ -0,0 +1,169 @@ +import 'dart:collection'; +import 'package:angel3_orm/angel3_orm.dart'; +import 'package:angel3_migration/angel3_migration.dart'; +import 'package:charcode/ascii.dart'; + +abstract class MysqlGenerator { + static String columnType(MigrationColumn column) { + var str = column.type.name; + if (column.type.hasSize) { + return '$str(${column.length})'; + } else { + return str; + } + } + + static String compileColumn(MigrationColumn column) { + var buf = StringBuffer(columnType(column)); + + if (column.isNullable == false) buf.write(' NOT NULL'); + if (column.defaultValue != null) { + String s; + var value = column.defaultValue; + if (value is RawSql) { + s = value.value; + } else if (value is String) { + var b = StringBuffer(); + for (var ch in value.codeUnits) { + if (ch == $single_quote) { + b.write("\\'"); + } else { + b.writeCharCode(ch); + } + } + s = b.toString(); + } else { + s = value.toString(); + } + + buf.write(' DEFAULT $s'); + } + + if (column.indexType == IndexType.unique) { + buf.write(' UNIQUE'); + } else if (column.indexType == IndexType.primaryKey) { + buf.write(' PRIMARY KEY'); + } + + for (var ref in column.externalReferences) { + buf.write(' ' + compileReference(ref)); + } + + return buf.toString(); + } + + static String compileReference(MigrationColumnReference ref) { + var buf = + StringBuffer('REFERENCES "${ref.foreignTable}"("${ref.foreignKey}")'); + if (ref.behavior != null) buf.write(' ' + ref.behavior!); + return buf.toString(); + } +} + +class MysqlTable extends Table { + final Map _columns = {}; + + @override + MigrationColumn declareColumn(String name, Column column) { + if (_columns.containsKey(name)) { + throw StateError('Cannot redeclare column "$name".'); + } + var col = MigrationColumn.from(column); + _columns[name] = col; + return col; + } + + void compile(StringBuffer buf, int indent) { + var i = 0; + + _columns.forEach((name, column) { + var col = MysqlGenerator.compileColumn(column); + if (i++ > 0) buf.writeln(','); + + for (var i = 0; i < indent; i++) { + buf.write(' '); + } + + buf.write('"$name" $col'); + }); + } +} + +class MysqlAlterTable extends Table implements MutableTable { + final Map _columns = {}; + final String tableName; + final Queue _stack = Queue(); + + MysqlAlterTable(this.tableName); + + void compile(StringBuffer buf, int indent) { + var i = 0; + + while (_stack.isNotEmpty) { + var str = _stack.removeFirst(); + + if (i++ > 0) buf.writeln(','); + + for (var i = 0; i < indent; i++) { + buf.write(' '); + } + + buf.write(str); + } + + if (i > 0) buf.writeln(';'); + + i = 0; + _columns.forEach((name, column) { + var col = MysqlGenerator.compileColumn(column); + if (i++ > 0) buf.writeln(','); + + for (var i = 0; i < indent; i++) { + buf.write(' '); + } + + buf.write('ADD COLUMN "$name" $col'); + }); + } + + @override + MigrationColumn declareColumn(String name, Column column) { + if (_columns.containsKey(name)) { + throw StateError('Cannot redeclare column "$name".'); + } + var col = MigrationColumn.from(column); + _columns[name] = col; + return col; + } + + @override + void dropNotNull(String name) { + _stack.add('ALTER COLUMN "$name" DROP NOT NULL'); + } + + @override + void setNotNull(String name) { + _stack.add('ALTER COLUMN "$name" SET NOT NULL'); + } + + @override + void changeColumnType(String name, ColumnType type, {int length = 256}) { + _stack.add('ALTER COLUMN "$name" TYPE ' + + MysqlGenerator.columnType(MigrationColumn(type, length: length))); + } + + @override + void renameColumn(String name, String newName) { + _stack.add('RENAME COLUMN "$name" TO "$newName"'); + } + + @override + void dropColumn(String name) { + _stack.add('DROP COLUMN "$name"'); + } + + @override + void rename(String newName) { + _stack.add('RENAME TO "$newName"'); + } +} diff --git a/packages/orm/angel_migration_runner/lib/src/postgres/runner.dart b/packages/orm/angel_migration_runner/lib/src/postgres/runner.dart index b6ef48bb..90715061 100755 --- a/packages/orm/angel_migration_runner/lib/src/postgres/runner.dart +++ b/packages/orm/angel_migration_runner/lib/src/postgres/runner.dart @@ -76,7 +76,7 @@ class PostgresMigrationRunner implements MigrationRunner { await schema.run(connection).then((_) { return connection.transaction((ctx) async { var result = await ctx.query( - "INSERT INTO MIGRATIONS (batch, path) VALUES ($batch, \'$k\')"); + "INSERT INTO MIGRATIONS (batch, path) VALUES ($batch, '$k')"); return result.affectedRowCount; }); @@ -95,7 +95,8 @@ class PostgresMigrationRunner implements MigrationRunner { Future rollback() async { await _init(); - var r = await connection.query('SELECT MAX(batch) from migrations;'); + PostgreSQLResult r = + await connection.query('SELECT MAX(batch) from migrations;'); var curBatch = (r[0][0] ?? 0) as int; r = await connection .query('SELECT path from migrations WHERE batch = $curBatch;'); diff --git a/packages/orm/angel_migration_runner/lib/src/postgres/table.dart b/packages/orm/angel_migration_runner/lib/src/postgres/table.dart index ba53d156..dfbf76b3 100755 --- a/packages/orm/angel_migration_runner/lib/src/postgres/table.dart +++ b/packages/orm/angel_migration_runner/lib/src/postgres/table.dart @@ -9,7 +9,7 @@ abstract class PostgresGenerator { if (column.type.hasSize) { return '$str(${column.length})'; } else { - return '$str'; + return str; } } diff --git a/packages/orm/angel_migration_runner/pubspec.yaml b/packages/orm/angel_migration_runner/pubspec.yaml index f0360ae9..62081a3b 100755 --- a/packages/orm/angel_migration_runner/pubspec.yaml +++ b/packages/orm/angel_migration_runner/pubspec.yaml @@ -1,5 +1,5 @@ name: angel3_migration_runner -version: 4.0.2 +version: 4.1.0 description: Command-line based database migration runner for Angel3's ORM. homepage: https://angel3-framework.web.app/ repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_migration_runner @@ -10,7 +10,8 @@ dependencies: angel3_orm: ^4.0.0 args: ^2.1.0 charcode: ^1.2.0 - postgres: ^2.3.2 + postgres: ^2.4.0 + mysql1: ^0.19.2 logging: ^1.0.0 dev_dependencies: lints: ^1.0.0 diff --git a/packages/orm/angel_orm/CHANGELOG.md b/packages/orm/angel_orm/CHANGELOG.md index 2bbc30da..4dbc079d 100644 --- a/packages/orm/angel_orm/CHANGELOG.md +++ b/packages/orm/angel_orm/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 4.0.4 + +* Changed default varchar size to 255 +* Changed default primary key to serial + ## 4.0.3 * Removed debugging messages diff --git a/packages/orm/angel_orm/README.md b/packages/orm/angel_orm/README.md index bcac756f..43f12ff6 100644 --- a/packages/orm/angel_orm/README.md +++ b/packages/orm/angel_orm/README.md @@ -7,4 +7,9 @@ Runtime support for Angel3 ORM. Includes a clean, database-agnostic query builder and relationship/join support. +## Supported database + +* PostgreSQL version 10, 11, 12, 13 and 14 +* MySQL 8.0 or later + For documentation about the ORM, see [Developer Guide](https://angel3-docs.dukefirehawk.com/guides/orm) diff --git a/packages/orm/angel_orm/lib/src/migration.dart b/packages/orm/angel_orm/lib/src/migration.dart index 26a89f8c..9af765e4 100644 --- a/packages/orm/angel_orm/lib/src/migration.dart +++ b/packages/orm/angel_orm/lib/src/migration.dart @@ -17,6 +17,9 @@ class Column { /// If `true`, a SQL field will be nullable. final bool isNullable; + /// Specifies this column name. + final String name; + /// Specifies the length of a `VARCHAR`. final int length; @@ -31,7 +34,8 @@ class Column { const Column( {this.isNullable = true, - this.length = 256, + this.length = 255, + this.name = "", this.type = ColumnType.varChar, this.indexType = IndexType.none, this.expression}); @@ -41,7 +45,7 @@ class Column { } class PrimaryKey extends Column { - const PrimaryKey({ColumnType columnType = ColumnType.varChar}) + const PrimaryKey({ColumnType columnType = ColumnType.serial}) : super(type: columnType, indexType: IndexType.primaryKey); } diff --git a/packages/orm/angel_orm/lib/src/query_base.dart b/packages/orm/angel_orm/lib/src/query_base.dart index 53ae04bb..17a62159 100644 --- a/packages/orm/angel_orm/lib/src/query_base.dart +++ b/packages/orm/angel_orm/lib/src/query_base.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'package:logging/logging.dart'; import 'query_executor.dart'; import 'union.dart'; @@ -7,8 +6,6 @@ import 'package:optional/optional.dart'; /// A base class for objects that compile to SQL queries, typically within an ORM. abstract class QueryBase { - final _log = Logger('QueryBase'); - /// Casts to perform when querying the database. Map get casts => {}; diff --git a/packages/orm/angel_orm/lib/src/relations.dart b/packages/orm/angel_orm/lib/src/relations.dart index 6dac4674..ab7097e7 100644 --- a/packages/orm/angel_orm/lib/src/relations.dart +++ b/packages/orm/angel_orm/lib/src/relations.dart @@ -12,14 +12,14 @@ class Relationship { final String? localKey; final String? foreignKey; final String? foreignTable; - final bool? cascadeOnDelete; + final bool cascadeOnDelete; final JoinType? joinType; const Relationship(this.type, {this.localKey, this.foreignKey, this.foreignTable, - this.cascadeOnDelete, + this.cascadeOnDelete = false, this.joinType}); } diff --git a/packages/orm/angel_orm/pubspec.yaml b/packages/orm/angel_orm/pubspec.yaml index 41663be8..724e9e51 100644 --- a/packages/orm/angel_orm/pubspec.yaml +++ b/packages/orm/angel_orm/pubspec.yaml @@ -1,5 +1,5 @@ name: angel3_orm -version: 4.0.3 +version: 4.0.4 description: Runtime support for Angel3 ORM. Includes base classes for queries. homepage: https://angel3-framework.web.app/ repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm diff --git a/packages/orm/angel_orm_generator/CHANGELOG.md b/packages/orm/angel_orm_generator/CHANGELOG.md index c70b788a..49af1d4f 100644 --- a/packages/orm/angel_orm_generator/CHANGELOG.md +++ b/packages/orm/angel_orm_generator/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 4.1.3 + +* Fixed issue #24, incorrect class casting +* Fixed `@belongsTo` to generate correct table creation query + ## 4.1.2 * Updated linter to `package:lints` diff --git a/packages/orm/angel_orm_generator/README.md b/packages/orm/angel_orm_generator/README.md index 238a9051..6343de30 100644 --- a/packages/orm/angel_orm_generator/README.md +++ b/packages/orm/angel_orm_generator/README.md @@ -19,3 +19,8 @@ Run the following command to generate the required `.g.dart` files for Angel3 OR ```bash dart run build_runner build ``` + +## Supported database + +* PostgreSQL version 10, 11, 12, 13 and 14 +* MySQL 8.0 or later 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 692876a4..96cc1127 100644 --- a/packages/orm/angel_orm_generator/lib/src/migration_generator.dart +++ b/packages/orm/angel_orm_generator/lib/src/migration_generator.dart @@ -73,6 +73,7 @@ class MigrationGenerator extends GeneratorForAnnotation { Method buildUpMigration(OrmBuildContext ctx, LibraryBuilder lib) { return Method((meth) { + // Check to see if clazz extends Model class var autoIdAndDateFields = const TypeChecker.fromRuntime(Model) .isAssignableFromType(ctx.buildContext.clazz.thisType); meth @@ -165,7 +166,7 @@ class MigrationGenerator extends GeneratorForAnnotation { var colType = refer('Column'); var columnTypeType = refer('ColumnType'); - if (col.length == null) { + if (col.length == 0) { methodName = 'declare'; provColumn = columnTypeType.newInstance([ literal(col.type.name), @@ -268,10 +269,31 @@ class MigrationGenerator extends GeneratorForAnnotation { // var field = table.property('integer').call([literal(key)]); // // .references('user', 'id').onDeleteCascade() + + // Check to see if foreign clazz extends Model class + var foreignTableType = + relationship.foreign?.buildContext.clazz.thisType; + var foreignAautoIdAndDateFields = false; + if (foreignTableType != null) { + foreignAautoIdAndDateFields = + const TypeChecker.fromRuntime(Model) + .isAssignableFromType(foreignTableType); + } + var columnTypeType = refer('ColumnType'); var key = relationship.localKey; - var keyType = relationship - .foreign!.columns[relationship.foreignKey!]!.type.name; + + // Default to `int` if foreign class extends Model with implicit 'id' + // as primary key + String? keyType; + if (foreignAautoIdAndDateFields != false && + relationship.foreignKey == "id") { + keyType = "int"; + } else { + var foreigColumnName = + relationship.foreign?.columns[relationship.foreignKey!]; + keyType = foreigColumnName?.type.name; + } var field = table.property('declare').call([ literal(key), 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 fbd5d659..cef4823d 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 @@ -3,14 +3,12 @@ import 'dart:async'; import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; -import 'package:angel3_model/angel3_model.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/build_context.dart'; import 'package:angel3_serialize_generator/context.dart'; import 'package:build/build.dart'; -import 'package:collection/collection.dart' show IterableExtension; import 'package:inflection3/inflection3.dart'; import 'package:recase/recase.dart'; import 'package:source_gen/source_gen.dart'; @@ -105,11 +103,11 @@ Future buildOrmContext( // Read all fields for (var field in buildCtx.fields) { // Check for column annotation... - Column? column; var element = _findElement(field); var columnAnnotation = columnTypeChecker.firstAnnotationOf(element); // print('${element.name} => $columnAnnotation'); + Column? column; if (columnAnnotation != null) { column = reviveColumn(ConstantReader(columnAnnotation)); } @@ -281,6 +279,7 @@ Future buildOrmContext( if (relation.type == RelationshipType.belongsTo) { var localKey = relation.localKey; + if (localKey != null) { var name = ReCase(localKey).camelCase; ctx.buildContext.aliases[name] = localKey; @@ -292,10 +291,14 @@ Future buildOrmContext( if (foreign != null) { if (isSpecialId(foreign, foreignField)) { - //type = field.type.element.context.typeProvider.intType; - type = field.type; + // Use integer + type = field.type.element?.library?.typeProvider.intType + as DartType; + + //type = field.type.element?.context.typeProvider.intType; } } + var rf = RelationFieldImpl(name, relation, type, field); ctx.effectiveFields.add(rf); } @@ -389,7 +392,7 @@ Column reviveColumn(ConstantReader cr) { return Column( isNullable: cr.peek('isNullable')?.boolValue ?? false, - length: cr.peek('length')?.intValue ?? 256, + length: cr.peek('length')?.intValue ?? 255, type: columnType, indexType: indexType, ); diff --git a/packages/orm/angel_orm_generator/lib/src/orm_generator.dart b/packages/orm/angel_orm_generator/lib/src/orm_generator.dart index 2bfed44e..4d35bf13 100644 --- a/packages/orm/angel_orm_generator/lib/src/orm_generator.dart +++ b/packages/orm/angel_orm_generator/lib/src/orm_generator.dart @@ -192,9 +192,7 @@ class OrmGenerator extends GeneratorForAnnotation { m ..name = 'parseRow' ..static = true - ..returns = TypeReference((b) => b - ..symbol = '${rc.pascalCase}' - ..isNullable = true) //refer('${rc.pascalCase}?') + ..returns = refer('Optional<${rc.pascalCase}>') ..requiredParameters.add(Parameter((b) => b ..name = 'row' ..type = refer('List'))) @@ -233,8 +231,8 @@ class OrmGenerator extends GeneratorForAnnotation { args[field.name] = expr; } - b.statements - .add(Code('if (row.every((x) => x == null)) { return null; }')); + b.statements.add(Code( + 'if (row.every((x) => x == null)) { return Optional.empty(); }')); b.addExpression(ctx.buildContext.modelClassType .newInstance([], args).assignVar('model')); @@ -270,30 +268,52 @@ class OrmGenerator extends GeneratorForAnnotation { .property('parseRow') .call([skipToList]); - var baseClass = '${foreign.buildContext.originalClassName}'; + //var baseClass = '${foreign.buildContext.originalClassName}'; + //var modelClass = + // foreign.buildContext.modelClassNameRecase.pascalCase; // Assume: baseclass starts with "_" //'_${foreign.buildContext.modelClassNameRecase.pascalCase}'; - if (relation.type == RelationshipType.hasMany) { - parsed = literalList([parsed.asA(refer(baseClass))]); - var pp = parsed.accept(DartEmitter(useNullSafetySyntax: true)); - parsed = CodeExpression(Code('$pp')); - //Code('$pp.where((x) => x != null).toList()')); - } + //if (relation.type == RelationshipType.hasMany) { + // parsed = literalList([parsed.asA(refer(modelClass))]); + //parsed = literalList([parsed.asA(refer(baseClass))]); + // var pp = parsed.accept(DartEmitter(useNullSafetySyntax: true)); + // parsed = CodeExpression(Code('$pp')); + //Code('$pp.where((x) => x != null).toList()')); + //} + + //var expr = + // refer('model').property('copyWith').call([], {name: parsed}); + //var block = + // Block((b) => b.addExpression(refer('model').assign(expr))); + + var stmt = parsed.assignVar('modelOpt'); + //var e = refer('Optional').property('ifPresent').call([]); + + var val = + (relation.type == RelationshipType.hasMany) ? '[m]' : 'm'; + var code = Code(''' + modelOpt.ifPresent((m) { + model = model.copyWith($name: $val); + }) + '''); + + var block = Block((b) { + b.addExpression(stmt); + b.addExpression(CodeExpression(code)); + }); - var expr = - refer('model').property('copyWith').call([], {name: parsed}); - var block = - Block((b) => b.addExpression(refer('model').assign(expr))); var blockStr = block.accept(DartEmitter(useNullSafetySyntax: true)); + var ifStr = 'if (row.length > $i) { $blockStr }'; b.statements.add(Code(ifStr)); i += foreign.effectiveFields.length; }); - b.addExpression(refer('model').returned); + b.addExpression( + refer('Optional.of').call([refer('model')]).returned); }); })); @@ -307,9 +327,7 @@ class OrmGenerator extends GeneratorForAnnotation { ..name = 'row' ..type = refer('List'))) ..body = Block((b) { - b.addExpression(refer('Optional.ofNullable').call([ - refer('parseRow').call([refer('row')]) - ]).returned); + b.addExpression(refer('parseRow').call([refer('row')]).returned); }); })); @@ -375,18 +393,18 @@ class OrmGenerator extends GeneratorForAnnotation { relationForeign.buildContext.resolveFieldName(f.name)); var additionalFields = []; - additionalStrs.forEach((element) { + for (var element in additionalStrs) { if (element != null) { additionalFields.add(literalString(element)); } - }); + } var joinArgs = []; - [relation.localKey, relation.foreignKey].forEach((element) { + for (var element in [relation.localKey, relation.foreignKey]) { if (element != null) { joinArgs.add(literalString(element)); } - }); + } // In the case of a many-to-many, we don't generate a subquery field, // as it easily leads to stack overflows. @@ -556,10 +574,9 @@ class OrmGenerator extends GeneratorForAnnotation { .accept(DartEmitter(useNullSafetySyntax: true)) .toString() .replaceAll('?', ''); - merge.add(''' - $name: $typeLiteral.from(l.$name)..addAll(model.$name) - '''); + $name: $typeLiteral.from(l.$name ?? [])..addAll(model.$name ?? []) + '''); } }); @@ -621,7 +638,6 @@ class OrmGenerator extends GeneratorForAnnotation { var initializers = []; // Add builders for each field - for (var field in ctx.effectiveNormalFields) { String? name = field.name; @@ -645,7 +661,7 @@ class OrmGenerator extends GeneratorForAnnotation { //log.fine('$name type = [$typeName]'); builderType = TypeReference((b) => b ..symbol = 'NumericSqlExpressionBuilder' - ..types.add(refer('$typeName'))); + ..types.add(refer(typeName))); } else if (type is InterfaceType && type.element.isEnum) { builderType = TypeReference((b) => b ..symbol = 'EnumSqlExpressionBuilder' @@ -670,7 +686,7 @@ class OrmGenerator extends GeneratorForAnnotation { // Detect relationship } else if (name.endsWith('Id')) { - //log.fine('Relationship detected = $name'); + log.fine('Foreign Relationship detected = $name'); var relation = ctx.relations[name.replaceAll('Id', '')]; if (relation != null) { //if (relation?.type != RelationshipType.belongsTo) { diff --git a/packages/orm/angel_orm_generator/lib/src/readers.dart b/packages/orm/angel_orm_generator/lib/src/readers.dart index bd1d7745..9964d4fd 100644 --- a/packages/orm/angel_orm_generator/lib/src/readers.dart +++ b/packages/orm/angel_orm_generator/lib/src/readers.dart @@ -30,7 +30,7 @@ class RelationshipReader { final String? localKey; final String? foreignKey; final String? foreignTable; - final bool? cascadeOnDelete; + final bool cascadeOnDelete; final DartType? through; final OrmBuildContext? foreign; final OrmBuildContext? throughContext; @@ -40,7 +40,7 @@ class RelationshipReader { {this.localKey, this.foreignKey, this.foreignTable, - this.cascadeOnDelete, + this.cascadeOnDelete = false, this.through, this.foreign, this.throughContext, @@ -75,13 +75,13 @@ class RelationshipReader { }); } - FieldElement findForeignField(OrmBuildContext? ctx) { + FieldElement findForeignField(OrmBuildContext ctx) { var foreign = throughContext ?? this.foreign!; return foreign.effectiveFields.firstWhere( (f) => foreign.buildContext.resolveFieldName(f.name) == foreignKey, 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.'; + 'but ${ctx.buildContext.clazz.name} has a @HasMany() relation that expects such a field.'; }); } } diff --git a/packages/orm/angel_orm_generator/pubspec.yaml b/packages/orm/angel_orm_generator/pubspec.yaml index cce0c485..daeb92b9 100644 --- a/packages/orm/angel_orm_generator/pubspec.yaml +++ b/packages/orm/angel_orm_generator/pubspec.yaml @@ -1,5 +1,5 @@ name: angel3_orm_generator -version: 4.1.2 +version: 4.1.3 description: Code generators for Angel3 ORM. Generates query builder classes. homepage: https://angel3-framework.web.app/ repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_generator @@ -30,4 +30,9 @@ dev_dependencies: postgres: ^2.4.0 test: ^1.17.3 lints: ^1.0.0 +dependency_overrides: + angel3_orm: + path: ../angel_orm + angel3_migration: + path: ../angel_migration \ No newline at end of file diff --git a/packages/orm/angel_orm_mysql/README.md b/packages/orm/angel_orm_mysql/README.md index 2fc3e3d4..2220fe28 100644 --- a/packages/orm/angel_orm_mysql/README.md +++ b/packages/orm/angel_orm_mysql/README.md @@ -7,4 +7,11 @@ Mysql support for Angel3 ORM. +## Supported database + +* MySQL 8.0 or later +* MariaDb 10.2.1 or later + +**Note** ORM for MySQL requires support for `WITH` SQL Syntax + For documentation about the ORM, head to the main project repo: diff --git a/packages/orm/angel_orm_postgres/README.md b/packages/orm/angel_orm_postgres/README.md index 6d781b6d..c9e7691e 100644 --- a/packages/orm/angel_orm_postgres/README.md +++ b/packages/orm/angel_orm_postgres/README.md @@ -5,6 +5,10 @@ [![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion) [![License](https://img.shields.io/github/license/dukefirehawk/angel)](https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_postgres/LICENSE) -Postgresql support for Angel3 ORM. Supported version: 10, 11, 12, 13 and 14 +Postgresql support for Angel3 ORM. + +## Supported PosgtreSQL + +* version 10 or later For documentation about the ORM, see [Developer Guide](https://angel3-docs.dukefirehawk.com/guides/orm) diff --git a/packages/orm/angel_orm_postgres/pubspec.yaml b/packages/orm/angel_orm_postgres/pubspec.yaml index c8faa2f5..04b255a7 100644 --- a/packages/orm/angel_orm_postgres/pubspec.yaml +++ b/packages/orm/angel_orm_postgres/pubspec.yaml @@ -16,8 +16,8 @@ dev_dependencies: angel3_orm_test: ^3.0.0 test: ^1.17.5 lints: ^1.0.0 -#dependency_overrides: -# angel3_orm_test: -# path: ../angel_orm_test -# angel3_orm: -# path: ../angel_orm +dependency_overrides: + angel3_orm_test: + path: ../angel_orm_test + angel3_orm: + path: ../angel_orm diff --git a/packages/orm/angel_orm_test/lib/src/belongs_to_test.dart b/packages/orm/angel_orm_test/lib/src/belongs_to_test.dart index 9adf39e8..f05badfb 100644 --- a/packages/orm/angel_orm_test/lib/src/belongs_to_test.dart +++ b/packages/orm/angel_orm_test/lib/src/belongs_to_test.dart @@ -26,8 +26,8 @@ void belongsToTests(FutureOr Function() createExecutor, // And a book var bookQuery = BookQuery(); bookQuery.values - ..authorId = int.parse(jkRowling!.id!) - ..partnerAuthorId = int.parse(jameson!.id!) + ..authorId = jkRowling?.idAsInt ?? 0 + ..partnerAuthorId = jameson?.idAsInt ?? 0 ..name = 'Deathly Hallows'; deathlyHallows = (await bookQuery.insert(executor)).value; @@ -162,13 +162,13 @@ void belongsToTests(FutureOr Function() createExecutor, // that should return correctly. test('returns empty on false subquery', () async { printSeparator('False subquery test'); - var query = BookQuery()..author!.where!.name.equals('Billie Jean'); + var query = BookQuery()..author.where!.name.equals('Billie Jean'); expect(await query.get(executor), isEmpty); }); test('returns values on true subquery', () async { printSeparator('True subquery test'); - var query = BookQuery()..author!.where!.name.like('%Rowling%'); + var query = BookQuery()..author.where!.name.like('%Rowling%'); expect(await query.get(executor), [deathlyHallows]); }); }); diff --git a/packages/orm/angel_orm_test/lib/src/has_many_test.dart b/packages/orm/angel_orm_test/lib/src/has_many_test.dart index 7cd47297..80f149d6 100644 --- a/packages/orm/angel_orm_test/lib/src/has_many_test.dart +++ b/packages/orm/angel_orm_test/lib/src/has_many_test.dart @@ -31,8 +31,8 @@ void hasManyTests(FutureOr Function() createExecutor, void verify(Tree tree) { //print(tree.fruits!.map(FruitSerializer.toMap).toList()); expect(tree.fruits, hasLength(2)); - expect(tree.fruits![0].commonName, apple!.commonName); - expect(tree.fruits![1].commonName, banana!.commonName); + expect(tree.fruits[0].commonName, apple!.commonName); + expect(tree.fruits[1].commonName, banana!.commonName); } setUp(() async { @@ -86,7 +86,7 @@ void hasManyTests(FutureOr Function() createExecutor, test('returns empty on false subquery', () async { var tq = TreeQuery() ..where!.id.equals(treeId) - ..fruits!.where!.commonName.equals('Kiwi'); + ..fruits.where!.commonName.equals('Kiwi'); var treeOpt = await (tq.getOne(executor)); expect(treeOpt.isPresent, true); treeOpt.ifPresent((tree) { diff --git a/packages/orm/angel_orm_test/lib/src/has_one_test.dart b/packages/orm/angel_orm_test/lib/src/has_one_test.dart index 4901416e..22cbe06f 100644 --- a/packages/orm/angel_orm_test/lib/src/has_one_test.dart +++ b/packages/orm/angel_orm_test/lib/src/has_one_test.dart @@ -115,7 +115,7 @@ void hasOneTests(FutureOr Function() createExecutor, test('sets null on false subquery', () async { var legQuery = LegQuery() ..where!.id.equals(originalLeg!.idAsInt) - ..foot!.where!.legId.equals(originalLeg!.idAsInt + 1024); + ..foot.where!.legId.equals(originalLeg!.idAsInt + 1024); var legOpt = await (legQuery.getOne(executor)); expect(legOpt.isPresent, true); legOpt.ifPresent((leg) { diff --git a/packages/orm/angel_orm_test/lib/src/models/book.dart b/packages/orm/angel_orm_test/lib/src/models/book.dart index 6684164f..91c6b398 100644 --- a/packages/orm/angel_orm_test/lib/src/models/book.dart +++ b/packages/orm/angel_orm_test/lib/src/models/book.dart @@ -1,7 +1,6 @@ library angel_orm3.generator.models.book; import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:optional/optional.dart'; @@ -26,4 +25,7 @@ abstract class _Author extends Model { @Column(length: 255, indexType: IndexType.unique) @SerializableField(defaultValue: 'Tobe Osakwe') String? get name; + + //@Column(name: "pub") + //String? publisher; } diff --git a/packages/orm/angel_orm_test/lib/src/models/book.g.dart b/packages/orm/angel_orm_test/lib/src/models/book.g.dart index 8ea9cbe6..27c20d09 100644 --- a/packages/orm/angel_orm_test/lib/src/models/book.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/book.g.dart @@ -13,12 +13,10 @@ class BookMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.varChar('name'); + table.varChar('name', length: 255); + table.declare('author_id', ColumnType('int')).references('authors', 'id'); table - .declare('author_id', ColumnType('serial')) - .references('authors', 'id'); - table - .declare('partner_author_id', ColumnType('serial')) + .declare('partner_author_id', ColumnType('int')) .references('authors', 'id'); }); } @@ -36,7 +34,9 @@ class AuthorMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.varChar('name', length: 255).defaultsTo('Tobe Osakwe'); + table.varChar('name', length: 255) + ..defaultsTo('Tobe Osakwe') + ..unique(); }); } @@ -70,9 +70,9 @@ class BookQuery extends Query { BookQueryWhere? _where; - AuthorQuery? _author; + late AuthorQuery _author; - AuthorQuery? _partnerAuthor; + late AuthorQuery _partnerAuthor; @override Map get casts { @@ -135,11 +135,11 @@ class BookQuery extends Query { return parseRow(row); } - AuthorQuery? get author { + AuthorQuery get author { return _author; } - AuthorQuery? get partnerAuthor { + AuthorQuery get partnerAuthor { return _partnerAuthor; } } @@ -193,16 +193,16 @@ class BookQueryValues extends MapQueryValues { } set updatedAt(DateTime? value) => values['updated_at'] = value; - int? get authorId { - return (values['author_id'] as int?); + int get authorId { + return (values['author_id'] as int); } - set authorId(int? value) => values['author_id'] = value; - int? get partnerAuthorId { - return (values['partner_author_id'] as int?); + set authorId(int value) => values['author_id'] = value; + int get partnerAuthorId { + return (values['partner_author_id'] as int); } - set partnerAuthorId(int? value) => values['partner_author_id'] = value; + set partnerAuthorId(int value) => values['partner_author_id'] = value; String? get name { return (values['name'] as String?); } @@ -213,10 +213,10 @@ class BookQueryValues extends MapQueryValues { updatedAt = model.updatedAt; name = model.name; if (model.author != null) { - values['author_id'] = model.author!.id; + values['author_id'] = model.author?.id; } if (model.partnerAuthor != null) { - values['partner_author_id'] = model.partnerAuthor!.id; + values['partner_author_id'] = model.partnerAuthor?.id; } } } @@ -267,8 +267,8 @@ class AuthorQuery extends Query { id: row[0].toString(), createdAt: (row[1] as DateTime?), updatedAt: (row[2] as DateTime?), - name: (row[3]) as String?); - return Optional.ofNullable(model); + name: (row[3] as String?)); + return Optional.of(model); } @override @@ -425,7 +425,7 @@ class Author extends _Author { DateTime? updatedAt; @override - final String? name; + String? name; Author copyWith( {String? id, DateTime? createdAt, DateTime? updatedAt, String? name}) { @@ -455,7 +455,7 @@ class Author extends _Author { return 'Author(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, name=$name)'; } - Map? toJson() { + Map toJson() { return AuthorSerializer.toMap(this); } } @@ -492,12 +492,12 @@ class BookSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, author: map['author'] != null @@ -509,7 +509,10 @@ class BookSerializer extends Codec { name: map['name'] as String?); } - static Map toMap(_Book model) { + static Map toMap(_Book? model) { + if (model == null) { + return {}; + } return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), @@ -546,11 +549,11 @@ abstract class BookFields { const AuthorSerializer authorSerializer = AuthorSerializer(); -class AuthorEncoder extends Converter { +class AuthorEncoder extends Converter { const AuthorEncoder(); @override - Map? convert(Author model) => AuthorSerializer.toMap(model); + Map convert(Author model) => AuthorSerializer.toMap(model); } class AuthorDecoder extends Converter { @@ -560,7 +563,7 @@ class AuthorDecoder extends Converter { Author convert(Map map) => AuthorSerializer.fromMap(map); } -class AuthorSerializer extends Codec { +class AuthorSerializer extends Codec { const AuthorSerializer(); @override @@ -572,20 +575,20 @@ class AuthorSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, name: map['name'] as String? ?? 'Tobe Osakwe'); } - static Map? toMap(_Author? model) { + static Map toMap(_Author? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, diff --git a/packages/orm/angel_orm_test/lib/src/models/car.dart b/packages/orm/angel_orm_test/lib/src/models/car.dart index 8782f647..26e1f148 100644 --- a/packages/orm/angel_orm_test/lib/src/models/car.dart +++ b/packages/orm/angel_orm_test/lib/src/models/car.dart @@ -1,7 +1,6 @@ library angel_orm3.generator.models.car; import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:optional/optional.dart'; diff --git a/packages/orm/angel_orm_test/lib/src/models/car.g.dart b/packages/orm/angel_orm_test/lib/src/models/car.g.dart index 3bd8bf41..6a055cf1 100644 --- a/packages/orm/angel_orm_test/lib/src/models/car.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/car.g.dart @@ -13,8 +13,8 @@ class CarMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.varChar('make'); - table.varChar('description'); + table.varChar('make', length: 255); + table.varChar('description', length: 255); table.boolean('family_friendly'); table.timeStamp('recalled_at'); }); @@ -309,12 +309,12 @@ class CarSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, make: map['make'] as String?, @@ -322,12 +322,15 @@ class CarSerializer extends Codec { familyFriendly: map['family_friendly'] as bool?, recalledAt: map['recalled_at'] != null ? (map['recalled_at'] is DateTime - ? (map['recalled_at'] as DateTime?) + ? (map['recalled_at'] as DateTime) : DateTime.parse(map['recalled_at'].toString())) : null); } - static Map toMap(_Car model) { + static Map toMap(_Car? model) { + if (model == null) { + return {}; + } return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), diff --git a/packages/orm/angel_orm_test/lib/src/models/custom_expr.dart b/packages/orm/angel_orm_test/lib/src/models/custom_expr.dart index 605d1b3e..beef30a3 100644 --- a/packages/orm/angel_orm_test/lib/src/models/custom_expr.dart +++ b/packages/orm/angel_orm_test/lib/src/models/custom_expr.dart @@ -1,5 +1,4 @@ import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:optional/optional.dart'; diff --git a/packages/orm/angel_orm_test/lib/src/models/custom_expr.g.dart b/packages/orm/angel_orm_test/lib/src/models/custom_expr.g.dart index 96352be7..24b8427a 100644 --- a/packages/orm/angel_orm_test/lib/src/models/custom_expr.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/custom_expr.g.dart @@ -29,9 +29,9 @@ class AlphabetMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.varChar('value'); + table.varChar('value', length: 255); table - .declare('numbers_id', ColumnType('serial')) + .declare('numbers_id', ColumnType('int')) .references('numbers', 'id'); }); } @@ -165,7 +165,7 @@ class AlphabetQuery extends Query { AlphabetQueryWhere? _where; - NumbersQuery? _numbers; + late NumbersQuery _numbers; @override Map get casts { @@ -215,7 +215,7 @@ class AlphabetQuery extends Query { return parseRow(row); } - NumbersQuery? get numbers { + NumbersQuery get numbers { return _numbers; } } @@ -270,17 +270,17 @@ class AlphabetQueryValues extends MapQueryValues { } set value(String? value) => values['value'] = value; - int? get numbersId { - return (values['numbers_id'] as int?); + int get numbersId { + return (values['numbers_id'] as int); } - set numbersId(int? value) => values['numbers_id'] = value; + set numbersId(int value) => values['numbers_id'] = value; void copyFrom(Alphabet model) { createdAt = model.createdAt; updatedAt = model.updatedAt; value = model.value; if (model.numbers != null) { - values['numbers_id'] = model.numbers!.id; + values['numbers_id'] = model.numbers?.id; } } } @@ -336,7 +336,7 @@ class Numbers extends _Numbers { return 'Numbers(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, two=$two)'; } - Map? toJson() { + Map toJson() { return NumbersSerializer.toMap(this); } } @@ -408,11 +408,11 @@ class Alphabet extends _Alphabet { const NumbersSerializer numbersSerializer = NumbersSerializer(); -class NumbersEncoder extends Converter { +class NumbersEncoder extends Converter { const NumbersEncoder(); @override - Map? convert(Numbers model) => NumbersSerializer.toMap(model); + Map convert(Numbers model) => NumbersSerializer.toMap(model); } class NumbersDecoder extends Converter { @@ -422,7 +422,7 @@ class NumbersDecoder extends Converter { Numbers convert(Map map) => NumbersSerializer.fromMap(map); } -class NumbersSerializer extends Codec { +class NumbersSerializer extends Codec { const NumbersSerializer(); @override @@ -434,20 +434,20 @@ class NumbersSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, two: map['two'] as int?); } - static Map? toMap(_Numbers? model) { + static Map toMap(_Numbers? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, @@ -498,12 +498,12 @@ class AlphabetSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, value: map['value'] as String?, @@ -512,7 +512,10 @@ class AlphabetSerializer extends Codec { : null); } - static Map toMap(_Alphabet model) { + static Map toMap(_Alphabet? model) { + if (model == null) { + return {}; + } return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), diff --git a/packages/orm/angel_orm_test/lib/src/models/email_indexed.g.dart b/packages/orm/angel_orm_test/lib/src/models/email_indexed.g.dart index 72fc90e2..85236a5e 100644 --- a/packages/orm/angel_orm_test/lib/src/models/email_indexed.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/email_indexed.g.dart @@ -10,7 +10,7 @@ class RoleMigration extends Migration { @override void up(Schema schema) { schema.create('roles', (table) { - table.declare('role', ColumnType('varchar')).primaryKey(); + table.varChar('role', length: 255).primaryKey(); }); } @@ -43,9 +43,9 @@ class UserMigration extends Migration { @override void up(Schema schema) { schema.create('users', (table) { - table.varChar('email').primaryKey(); - table.varChar('name'); - table.varChar('password'); + table.varChar('email', length: 255).primaryKey(); + table.varChar('name', length: 255); + table.varChar('password', length: 255); }); } @@ -75,7 +75,7 @@ class RoleQuery extends Query { @override final RoleQueryValues values = RoleQueryValues(); - late RoleQueryWhere _where; + RoleQueryWhere? _where; @override Map get casts { @@ -108,12 +108,12 @@ class RoleQuery extends Query { } var model = Role(role: (row[0] as String?)); if (row.length > 1) { - var rowDataOpt = UserQuery.parseRow(row.skip(1).take(3).toList()); - rowDataOpt.ifPresent((m) { + var modelOpt = UserQuery.parseRow(row.skip(1).take(3).toList()); + modelOpt.ifPresent((m) { model = model.copyWith(users: [m]); }); } - return Optional.ofNullable(model); + return Optional.of(model); } @override @@ -123,8 +123,8 @@ class RoleQuery extends Query { @override bool canCompile(trampoline) { - return (!(trampoline.contains('roles') == true && - trampoline.contains('role_users') == true)); + return (!(trampoline.contains('roles') && + trampoline.contains('role_users'))); } @override @@ -139,7 +139,8 @@ class RoleQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - users: List<_User>.from(l.users)..addAll(model.users)); + users: List<_User>.from(l.users ?? []) + ..addAll(model.users ?? [])); } }); }); @@ -157,7 +158,8 @@ class RoleQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - users: List<_User>.from(l.users)..addAll(model.users)); + users: List<_User>.from(l.users ?? []) + ..addAll(model.users ?? [])); } }); }); @@ -175,7 +177,8 @@ class RoleQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - users: List<_User>.from(l.users)..addAll(model.users)); + users: List<_User>.from(l.users ?? []) + ..addAll(model.users ?? [])); } }); }); @@ -230,9 +233,9 @@ class RoleUserQuery extends Query { RoleUserQueryWhere? _where; - RoleQuery? _role; + late RoleQuery _role; - UserQuery? _user; + late UserQuery _user; @override Map get casts { @@ -276,7 +279,7 @@ class RoleUserQuery extends Query { model = model.copyWith(user: m); }); } - return Optional.ofNullable(model); + return Optional.of(model); } @override @@ -284,11 +287,11 @@ class RoleUserQuery extends Query { return parseRow(row); } - RoleQuery? get role { + RoleQuery get role { return _role; } - UserQuery? get user { + UserQuery get user { return _user; } } @@ -326,10 +329,10 @@ class RoleUserQueryValues extends MapQueryValues { set userEmail(String? value) => values['user_email'] = value; void copyFrom(RoleUser model) { if (model.role != null) { - values['role_role'] = model.role!.role; + values['role_role'] = model.role?.role; } if (model.user != null) { - values['user_email'] = model.user!.email; + values['user_email'] = model.user?.email; } } } @@ -390,10 +393,6 @@ class UserQuery extends Query { modelOpt.ifPresent((m) { model = model.copyWith(roles: [m]); }); - -// roles: [RoleQuery.parseRow(row.skip(3).take(1).toList())] -// .where((x) => x != null) -// .toList()); } return Optional.of(model); } @@ -405,8 +404,8 @@ class UserQuery extends Query { @override bool canCompile(trampoline) { - return (!(trampoline.contains('users') == true && - trampoline.contains('role_users') == true)); + return (!(trampoline.contains('users') && + trampoline.contains('role_users'))); } @override @@ -421,7 +420,8 @@ class UserQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - roles: List<_Role>.from(l.roles)..addAll(model.roles)); + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); } }); }); @@ -439,7 +439,8 @@ class UserQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - roles: List<_Role>.from(l.roles)..addAll(model.roles)); + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); } }); }); @@ -457,7 +458,8 @@ class UserQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - roles: List<_Role>.from(l.roles)..addAll(model.roles)); + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); } }); }); @@ -516,23 +518,23 @@ class UserQueryValues extends MapQueryValues { @generatedSerializable class Role implements _Role { - const Role({this.role, this.users = const []}); + Role({this.role, this.users = const []}); @override - final String? role; + String? role; @override - final List<_User> users; + List<_User> users; - Role copyWith({String? role, List<_User> users = const []}) { - return Role(role: role ?? this.role, users: users); + Role copyWith({String? role, List<_User>? users}) { + return Role(role: role ?? this.role, users: users ?? this.users); } @override bool operator ==(other) { return other is _Role && other.role == role && - ListEquality<_User?>(DefaultEquality<_User>()) + ListEquality<_User>(DefaultEquality<_User>()) .equals(other.users, users); } @@ -553,13 +555,13 @@ class Role implements _Role { @generatedSerializable class RoleUser implements _RoleUser { - const RoleUser({this.role, this.user}); + RoleUser({this.role, this.user}); @override - final _Role? role; + _Role? role; @override - final _User? user; + _User? user; RoleUser copyWith({_Role? role, _User? user}) { return RoleUser(role: role ?? this.role, user: user ?? this.user); @@ -587,19 +589,19 @@ class RoleUser implements _RoleUser { @generatedSerializable class User implements _User { - const User({this.email, this.name, this.password, this.roles = const []}); + User({this.email, this.name, this.password, this.roles = const []}); @override - final String? email; + String? email; @override - final String? name; + String? name; @override - final String? password; + String? password; @override - final List<_Role> roles; + List<_Role> roles; User copyWith( {String? email, String? name, String? password, List<_Role>? roles}) { @@ -607,7 +609,7 @@ class User implements _User { email: email ?? this.email, name: name ?? this.name, password: password ?? this.password, - roles: roles ?? []); + roles: roles ?? this.roles); } @override @@ -641,11 +643,11 @@ class User implements _User { const RoleSerializer roleSerializer = RoleSerializer(); -class RoleEncoder extends Converter { +class RoleEncoder extends Converter { const RoleEncoder(); @override - Map? convert(Role model) => RoleSerializer.toMap(model); + Map convert(Role model) => RoleSerializer.toMap(model); } class RoleDecoder extends Converter { @@ -655,7 +657,7 @@ class RoleDecoder extends Converter { Role convert(Map map) => RoleSerializer.fromMap(map); } -class RoleSerializer extends Codec { +class RoleSerializer extends Codec { const RoleSerializer(); @override @@ -671,7 +673,10 @@ class RoleSerializer extends Codec { : []); } - static Map toMap(_Role model) { + static Map toMap(_Role? model) { + if (model == null) { + return {}; + } return { 'role': model.role, 'users': model.users.map((m) => UserSerializer.toMap(m)).toList() @@ -720,10 +725,13 @@ class RoleUserSerializer extends Codec { : null); } - static Map toMap(_RoleUser model) { + static Map toMap(_RoleUser? model) { + if (model == null) { + return {}; + } return { - 'role': (model.role != null) ? RoleSerializer.toMap(model.role!) : '', - 'user': (model.user != null) ? UserSerializer.toMap(model.user!) : '' + 'role': RoleSerializer.toMap(model.role), + 'user': UserSerializer.toMap(model.user) }; } } @@ -738,11 +746,11 @@ abstract class RoleUserFields { const UserSerializer userSerializer = UserSerializer(); -class UserEncoder extends Converter { +class UserEncoder extends Converter { const UserEncoder(); @override - Map? convert(User model) => UserSerializer.toMap(model); + Map convert(User model) => UserSerializer.toMap(model); } class UserDecoder extends Converter { @@ -752,7 +760,7 @@ class UserDecoder extends Converter { User convert(Map map) => UserSerializer.fromMap(map); } -class UserSerializer extends Codec { +class UserSerializer extends Codec { const UserSerializer(); @override @@ -770,7 +778,10 @@ class UserSerializer extends Codec { : []); } - static Map toMap(_User model) { + static Map toMap(_User? model) { + if (model == null) { + return {}; + } return { 'email': model.email, 'name': model.name, diff --git a/packages/orm/angel_orm_test/lib/src/models/fortune.dart b/packages/orm/angel_orm_test/lib/src/models/fortune.dart index 3f0a612c..6e4f49af 100644 --- a/packages/orm/angel_orm_test/lib/src/models/fortune.dart +++ b/packages/orm/angel_orm_test/lib/src/models/fortune.dart @@ -1,5 +1,4 @@ import 'package:angel3_migration/angel3_migration.dart'; -//import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:optional/optional.dart'; @@ -9,6 +8,7 @@ part 'fortune.g.dart'; @serializable @Orm(tableName: 'fortune') abstract class _Fortune { + @primaryKey int? id; @Column(length: 2048) diff --git a/packages/orm/angel_orm_test/lib/src/models/fortune.g.dart b/packages/orm/angel_orm_test/lib/src/models/fortune.g.dart index c5131189..94cf60c1 100644 --- a/packages/orm/angel_orm_test/lib/src/models/fortune.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/fortune.g.dart @@ -10,7 +10,7 @@ class FortuneMigration extends Migration { @override void up(Schema schema) { schema.create('fortune', (table) { - table.integer('id'); + table.integer('id').primaryKey(); table.varChar('message', length: 2048); }); } @@ -63,17 +63,17 @@ class FortuneQuery extends Query { return FortuneQueryWhere(this); } - static Fortune? parseRow(List row) { + static Optional parseRow(List row) { if (row.every((x) => x == null)) { - return null; + return Optional.empty(); } var model = Fortune(id: (row[0] as int?), message: (row[1] as String?)); - return model; + return Optional.of(model); } @override Optional deserialize(List row) { - return Optional.ofNullable(parseRow(row)); + return parseRow(row); } } diff --git a/packages/orm/angel_orm_test/lib/src/models/has_car.dart b/packages/orm/angel_orm_test/lib/src/models/has_car.dart index 1221011b..f9b1af00 100644 --- a/packages/orm/angel_orm_test/lib/src/models/has_car.dart +++ b/packages/orm/angel_orm_test/lib/src/models/has_car.dart @@ -1,5 +1,4 @@ import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:optional/optional.dart'; diff --git a/packages/orm/angel_orm_test/lib/src/models/has_car.g.dart b/packages/orm/angel_orm_test/lib/src/models/has_car.g.dart index 0fb00c3f..ad105820 100644 --- a/packages/orm/angel_orm_test/lib/src/models/has_car.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/has_car.g.dart @@ -13,7 +13,7 @@ class HasCarMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.integer('type'); + table.integer('type').defaultsTo(0); }); } @@ -73,7 +73,7 @@ class HasCarQuery extends Query { id: row[0].toString(), createdAt: (row[1] as DateTime?), updatedAt: (row[2] as DateTime?), - type: row[3] == null ? null : CarType.values[(row[3] as int)]); + type: row[3] == null ? null : CarType?.values[(row[3] as int)]); return Optional.of(model); } @@ -88,8 +88,8 @@ class HasCarQueryWhere extends QueryWhere { : id = NumericSqlExpressionBuilder(query, 'id'), createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'), updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at'), - type = - EnumSqlExpressionBuilder(query, 'type', (v) => v!.index); + type = EnumSqlExpressionBuilder( + query, 'type', (v) => v?.index as int); final NumericSqlExpressionBuilder id; @@ -126,8 +126,8 @@ class HasCarQueryValues extends MapQueryValues { } set updatedAt(DateTime? value) => values['updated_at'] = value; - CarType get type { - return CarType.values[(values['type'] as int)]; + CarType? get type { + return CarType?.values[(values['type'] as int)]; } set type(CarType? value) => values['type'] = value?.index; @@ -159,7 +159,7 @@ class HasCar extends _HasCar { DateTime? updatedAt; @override - final CarType? type; + CarType? type; HasCar copyWith( {String? id, DateTime? createdAt, DateTime? updatedAt, CarType? type}) { @@ -230,31 +230,30 @@ class HasCarSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, - type: map['type'] is CarType + type: map['type'] is CarType? ? (map['type'] as CarType?) : (map['type'] is int - ? CarType.values[map['type'] as int] + ? CarType?.values[map['type'] as int] : CarType.sedan)); } - static Map toMap(_HasCar model) { - if (model.type == null) { - throw FormatException("Missing required field 'type' on HasCar."); + static Map toMap(_HasCar? model) { + if (model == null) { + return {}; } - return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), 'updated_at': model.updatedAt?.toIso8601String(), - 'type': model.type == null ? null : CarType.values.indexOf(model.type!) + 'type': model.type != null ? CarType.values.indexOf(model.type!) : null }; } } diff --git a/packages/orm/angel_orm_test/lib/src/models/has_map.dart b/packages/orm/angel_orm_test/lib/src/models/has_map.dart index e6b89e9b..02e6ccb5 100644 --- a/packages/orm/angel_orm_test/lib/src/models/has_map.dart +++ b/packages/orm/angel_orm_test/lib/src/models/has_map.dart @@ -1,8 +1,6 @@ -import 'dart:convert'; import 'package:angel3_migration/angel3_migration.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; -import 'package:collection/collection.dart'; import 'package:optional/optional.dart'; part 'has_map.g.dart'; diff --git a/packages/orm/angel_orm_test/lib/src/models/has_map.g.dart b/packages/orm/angel_orm_test/lib/src/models/has_map.g.dart index 2ec4a112..11b8bcb3 100644 --- a/packages/orm/angel_orm_test/lib/src/models/has_map.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/has_map.g.dart @@ -10,8 +10,10 @@ class HasMapMigration extends Migration { @override void up(Schema schema) { schema.create('has_maps', (table) { - table.declare('value', ColumnType('jsonb')); - table.declare('list', ColumnType('jsonb')); + table.declareColumn( + 'value', Column(type: ColumnType('jsonb'), length: 255)); + table.declareColumn( + 'list', Column(type: ColumnType('jsonb'), length: 255)); }); } @@ -67,10 +69,9 @@ class HasMapQuery extends Query { if (row.every((x) => x == null)) { return Optional.empty(); } - - var m = row[0] as Map; - var l = row[1] as List; - var model = HasMap(value: m, list: l); + var model = HasMap( + value: (row[0] as Map?), + list: (row[1] as List?)); return Optional.of(model); } @@ -101,16 +102,16 @@ class HasMapQueryValues extends MapQueryValues { return {'list': 'jsonb'}; } - Map get value { - return (values['value'] as Map); + Map? get value { + return (values['value'] as Map?); } - set value(Map value) => values['value'] = value; - List get list { + set value(Map? value) => values['value'] = value; + List? get list { return (json.decode((values['list'] as String)) as List); } - set list(List value) => values['list'] = json.encode(value); + set list(List? value) => values['list'] = json.encode(value); void copyFrom(HasMap model) { value = model.value; list = model.list; @@ -123,17 +124,16 @@ class HasMapQueryValues extends MapQueryValues { @generatedSerializable class HasMap implements _HasMap { - const HasMap({this.value = const {}, this.list = const []}); + HasMap({this.value, this.list = const []}); @override - final Map value; + Map? value; @override - final List list; + List? list; - HasMap copyWith( - {Map value = const {}, List list = const []}) { - return HasMap(value: value, list: list); + HasMap copyWith({Map? value, List? list}) { + return HasMap(value: value ?? this.value, list: list ?? this.list); } @override @@ -197,7 +197,10 @@ class HasMapSerializer extends Codec { : []); } - static Map toMap(_HasMap model) { + static Map toMap(_HasMap? model) { + if (model == null) { + return {}; + } return {'value': model.value, 'list': model.list}; } } diff --git a/packages/orm/angel_orm_test/lib/src/models/leg.dart b/packages/orm/angel_orm_test/lib/src/models/leg.dart index 7d1ddbfd..0aeee175 100644 --- a/packages/orm/angel_orm_test/lib/src/models/leg.dart +++ b/packages/orm/angel_orm_test/lib/src/models/leg.dart @@ -1,7 +1,6 @@ library angel3_orm_generator.test.models.leg; import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:optional/optional.dart'; diff --git a/packages/orm/angel_orm_test/lib/src/models/leg.g.dart b/packages/orm/angel_orm_test/lib/src/models/leg.g.dart index 30249dde..109d0123 100644 --- a/packages/orm/angel_orm_test/lib/src/models/leg.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/leg.g.dart @@ -13,7 +13,7 @@ class LegMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.varChar('name'); + table.varChar('name', length: 255); }); } @@ -31,7 +31,8 @@ class FootMigration extends Migration { table.timeStamp('created_at'); table.timeStamp('updated_at'); table.integer('leg_id'); - table.declare('n_toes', ColumnType('decimal')); + table.declareColumn( + 'n_toes', Column(type: ColumnType('decimal'), length: 255)); }); } @@ -67,7 +68,7 @@ class LegQuery extends Query { LegQueryWhere? _where; - FootQuery? _foot; + late FootQuery _foot; @override Map get casts { @@ -117,7 +118,7 @@ class LegQuery extends Query { return parseRow(row); } - FootQuery? get foot { + FootQuery get foot { return _foot; } } @@ -416,7 +417,7 @@ class Foot extends _Foot { return 'Foot(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, legId=$legId, nToes=$nToes)'; } - Map? toJson() { + Map toJson() { return FootSerializer.toMap(this); } } @@ -453,12 +454,12 @@ class LegSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, foot: map['foot'] != null @@ -467,7 +468,10 @@ class LegSerializer extends Codec { name: map['name'] as String?); } - static Map toMap(_Leg model) { + static Map toMap(_Leg? model) { + if (model == null) { + return {}; + } return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), @@ -500,11 +504,11 @@ abstract class LegFields { const FootSerializer footSerializer = FootSerializer(); -class FootEncoder extends Converter { +class FootEncoder extends Converter { const FootEncoder(); @override - Map? convert(Foot model) => FootSerializer.toMap(model); + Map convert(Foot model) => FootSerializer.toMap(model); } class FootDecoder extends Converter { @@ -514,7 +518,7 @@ class FootDecoder extends Converter { Foot convert(Map map) => FootSerializer.fromMap(map); } -class FootSerializer extends Codec { +class FootSerializer extends Codec { const FootSerializer(); @override @@ -526,21 +530,21 @@ class FootSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, legId: map['leg_id'] as int?, nToes: map['n_toes'] as double?); } - static Map? toMap(_Foot? model) { + static Map toMap(_Foot? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, diff --git a/packages/orm/angel_orm_test/lib/src/models/order.dart b/packages/orm/angel_orm_test/lib/src/models/order.dart index ce5818e8..1c01398d 100644 --- a/packages/orm/angel_orm_test/lib/src/models/order.dart +++ b/packages/orm/angel_orm_test/lib/src/models/order.dart @@ -1,7 +1,6 @@ library angel3_orm_generator.test.models.order; import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:optional/optional.dart'; diff --git a/packages/orm/angel_orm_test/lib/src/models/order.g.dart b/packages/orm/angel_orm_test/lib/src/models/order.g.dart index 41591f3f..b5b3172b 100644 --- a/packages/orm/angel_orm_test/lib/src/models/order.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/order.g.dart @@ -17,7 +17,7 @@ class OrderMigration extends Migration { table.timeStamp('order_date'); table.integer('shipper_id'); table - .declare('customer_id', ColumnType('serial')) + .declare('customer_id', ColumnType('int')) .references('customers', 'id'); }); } @@ -64,7 +64,7 @@ class OrderQuery extends Query { OrderQueryWhere? _where; - CustomerQuery? _customer; + late CustomerQuery _customer; @override Map get casts { @@ -124,7 +124,7 @@ class OrderQuery extends Query { return parseRow(row); } - CustomerQuery? get customer { + CustomerQuery get customer { return _customer; } } @@ -188,11 +188,11 @@ class OrderQueryValues extends MapQueryValues { } set updatedAt(DateTime? value) => values['updated_at'] = value; - int? get customerId { - return (values['customer_id'] as int?); + int get customerId { + return (values['customer_id'] as int); } - set customerId(int? value) => values['customer_id'] = value; + set customerId(int value) => values['customer_id'] = value; int? get employeeId { return (values['employee_id'] as int?); } @@ -215,7 +215,7 @@ class OrderQueryValues extends MapQueryValues { orderDate = model.orderDate; shipperId = model.shipperId; if (model.customer != null) { - values['customer_id'] = model.customer!.id; + values['customer_id'] = model.customer?.id; } } } @@ -348,16 +348,16 @@ class Order extends _Order { DateTime? updatedAt; @override - final _Customer? customer; + _Customer? customer; @override - final int? employeeId; + int? employeeId; @override - final DateTime? orderDate; + DateTime? orderDate; @override - final int? shipperId; + int? shipperId; Order copyWith( {String? id, @@ -446,7 +446,7 @@ class Customer extends _Customer { return 'Customer(id=$id, createdAt=$createdAt, updatedAt=$updatedAt)'; } - Map? toJson() { + Map toJson() { return CustomerSerializer.toMap(this); } } @@ -483,12 +483,12 @@ class OrderSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, customer: map['customer'] != null @@ -497,13 +497,16 @@ class OrderSerializer extends Codec { employeeId: map['employee_id'] as int?, orderDate: map['order_date'] != null ? (map['order_date'] is DateTime - ? (map['order_date'] as DateTime?) + ? (map['order_date'] as DateTime) : DateTime.parse(map['order_date'].toString())) : null, shipperId: map['shipper_id'] as int?); } - static Map toMap(_Order model) { + static Map toMap(_Order? model) { + if (model == null) { + return {}; + } return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), @@ -544,11 +547,11 @@ abstract class OrderFields { const CustomerSerializer customerSerializer = CustomerSerializer(); -class CustomerEncoder extends Converter { +class CustomerEncoder extends Converter { const CustomerEncoder(); @override - Map? convert(Customer model) => CustomerSerializer.toMap(model); + Map convert(Customer model) => CustomerSerializer.toMap(model); } class CustomerDecoder extends Converter { @@ -558,7 +561,7 @@ class CustomerDecoder extends Converter { Customer convert(Map map) => CustomerSerializer.fromMap(map); } -class CustomerSerializer extends Codec { +class CustomerSerializer extends Codec { const CustomerSerializer(); @override @@ -570,19 +573,19 @@ class CustomerSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null); } - static Map? toMap(_Customer? model) { + static Map toMap(_Customer? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, diff --git a/packages/orm/angel_orm_test/lib/src/models/tree.dart b/packages/orm/angel_orm_test/lib/src/models/tree.dart index 7a27b5bd..022f402d 100644 --- a/packages/orm/angel_orm_test/lib/src/models/tree.dart +++ b/packages/orm/angel_orm_test/lib/src/models/tree.dart @@ -1,10 +1,8 @@ library angel3_orm_generator.test.models.tree; import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; -import 'package:collection/collection.dart'; import 'package:optional/optional.dart'; part 'tree.g.dart'; @@ -16,7 +14,7 @@ class _Tree extends Model { int? rings; @hasMany - List<_Fruit>? fruits; + List<_Fruit> fruits = []; } @serializable diff --git a/packages/orm/angel_orm_test/lib/src/models/tree.g.dart b/packages/orm/angel_orm_test/lib/src/models/tree.g.dart index b7c61f83..6d9a6a55 100644 --- a/packages/orm/angel_orm_test/lib/src/models/tree.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/tree.g.dart @@ -13,7 +13,7 @@ class TreeMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.declare('rings', ColumnType('smallint')); + table.integer('rings').unique(); }); } @@ -31,7 +31,7 @@ class FruitMigration extends Migration { table.timeStamp('created_at'); table.timeStamp('updated_at'); table.integer('tree_id'); - table.varChar('common_name'); + table.varChar('common_name', length: 255); }); } @@ -67,7 +67,7 @@ class TreeQuery extends Query { TreeQueryWhere? _where; - FruitQuery? _fruits; + late FruitQuery _fruits; @override Map get casts { @@ -117,7 +117,7 @@ class TreeQuery extends Query { return parseRow(row); } - FruitQuery? get fruits { + FruitQuery get fruits { return _fruits; } @@ -382,20 +382,20 @@ class Tree extends _Tree { int? rings; @override - List<_Fruit>? fruits; + List<_Fruit> fruits; Tree copyWith( {String? id, DateTime? createdAt, DateTime? updatedAt, int? rings, - List<_Fruit> fruits = const []}) { + List<_Fruit>? fruits}) { return Tree( id: id ?? this.id, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, rings: rings ?? this.rings, - fruits: fruits); + fruits: fruits ?? this.fruits); } @override @@ -518,12 +518,12 @@ class TreeSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, rings: map['rings'] as int?, @@ -533,13 +533,16 @@ class TreeSerializer extends Codec { : []); } - static Map toMap(_Tree model) { + static Map toMap(_Tree? model) { + if (model == null) { + return {}; + } return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), 'updated_at': model.updatedAt?.toIso8601String(), 'rings': model.rings, - 'fruits': model.fruits?.map((m) => FruitSerializer.toMap(m)).toList() + 'fruits': model.fruits.map((m) => FruitSerializer.toMap(m)).toList() }; } } @@ -592,19 +595,22 @@ class FruitSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, treeId: map['tree_id'] as int?, commonName: map['common_name'] as String?); } - static Map toMap(_Fruit model) { + static Map toMap(_Fruit? model) { + if (model == null) { + return {}; + } return { 'id': model.id, 'created_at': model.createdAt?.toIso8601String(), diff --git a/packages/orm/angel_orm_test/lib/src/models/unorthodox.dart b/packages/orm/angel_orm_test/lib/src/models/unorthodox.dart index 7d6ef21b..3cc79bf3 100644 --- a/packages/orm/angel_orm_test/lib/src/models/unorthodox.dart +++ b/packages/orm/angel_orm_test/lib/src/models/unorthodox.dart @@ -1,5 +1,4 @@ import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:optional/optional.dart'; @@ -26,10 +25,10 @@ abstract class _WeirdJoin { _Song? get song; @HasMany(foreignKey: 'parent') - List<_Numba?>? get numbas; + List<_Numba> get numbas; @ManyToMany(_FooPivot) - List<_Foo?>? get foos; + List<_Foo> get foos; } @serializable @@ -59,7 +58,7 @@ abstract class _Foo { String? get bar; @ManyToMany(_FooPivot) - List<_WeirdJoin?>? get weirdJoins; + List<_WeirdJoin> get weirdJoins; } @serializable diff --git a/packages/orm/angel_orm_test/lib/src/models/unorthodox.g.dart b/packages/orm/angel_orm_test/lib/src/models/unorthodox.g.dart index 0e9df12b..4aadaf7a 100644 --- a/packages/orm/angel_orm_test/lib/src/models/unorthodox.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/unorthodox.g.dart @@ -10,7 +10,7 @@ class UnorthodoxMigration extends Migration { @override void up(Schema schema) { schema.create('unorthodoxes', (table) { - table.varChar('name'); + table.varChar('name', length: 255).primaryKey(); }); } @@ -45,7 +45,7 @@ class SongMigration extends Migration { table.timeStamp('created_at'); table.timeStamp('updated_at'); table.integer('weird_join_id'); - table.varChar('title'); + table.varChar('title', length: 255); }); } @@ -74,7 +74,7 @@ class FooMigration extends Migration { @override void up(Schema schema) { schema.create('foos', (table) { - table.varChar('bar').primaryKey(); + table.varChar('bar', length: 255).primaryKey(); }); } @@ -223,11 +223,11 @@ class WeirdJoinQuery extends Query { WeirdJoinQueryWhere? _where; - UnorthodoxQuery? _unorthodox; + late UnorthodoxQuery _unorthodox; - SongQuery? _song; + late SongQuery _song; - NumbaQuery? _numbas; + late NumbaQuery _numbas; @override Map get casts { @@ -291,22 +291,22 @@ class WeirdJoinQuery extends Query { return parseRow(row); } - UnorthodoxQuery? get unorthodox { + UnorthodoxQuery get unorthodox { return _unorthodox; } - SongQuery? get song { + SongQuery get song { return _song; } - NumbaQuery? get numbas { + NumbaQuery get numbas { return _numbas; } @override bool canCompile(trampoline) { - return (!(trampoline.contains('weird_joins') == true && - trampoline.contains('foo_pivots') == true)); + return (!(trampoline.contains('weird_joins') && + trampoline.contains('foo_pivots'))); } @override @@ -322,8 +322,8 @@ class WeirdJoinQuery extends Query { return out ..[idx] = l.copyWith( numbas: List<_Numba>.from(l.numbas ?? []) - ..addAll(List<_Numba>.from(model.numbas ?? [])), - foos: List<_Foo?>.from(l.foos ?? [])..addAll(model.foos ?? [])); + ..addAll(model.numbas ?? []), + foos: List<_Foo>.from(l.foos ?? [])..addAll(model.foos ?? [])); } }); }); @@ -341,9 +341,9 @@ class WeirdJoinQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - numbas: List<_Numba?>.from(l.numbas ?? []) + numbas: List<_Numba>.from(l.numbas ?? []) ..addAll(model.numbas ?? []), - foos: List<_Foo?>.from(l.foos ?? [])..addAll(model.foos ?? [])); + foos: List<_Foo>.from(l.foos ?? [])..addAll(model.foos ?? [])); } }); }); @@ -361,9 +361,9 @@ class WeirdJoinQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - numbas: List<_Numba?>.from(l.numbas ?? []) + numbas: List<_Numba>.from(l.numbas ?? []) ..addAll(model.numbas ?? []), - foos: List<_Foo?>.from(l.foos ?? [])..addAll(model.foos ?? [])); + foos: List<_Foo>.from(l.foos ?? [])..addAll(model.foos ?? [])); } }); }); @@ -404,7 +404,7 @@ class WeirdJoinQueryValues extends MapQueryValues { void copyFrom(WeirdJoin model) { id = model.id; if (model.unorthodox != null) { - values['join_name'] = model.unorthodox!.name; + values['join_name'] = model.unorthodox?.name; } } } @@ -670,7 +670,7 @@ class FooQuery extends Query { model = model.copyWith(weirdJoins: [m]); }); } - return Optional.ofNullable(model); + return Optional.of(model); } @override @@ -680,8 +680,8 @@ class FooQuery extends Query { @override bool canCompile(trampoline) { - return (!(trampoline.contains('foos') == true && - trampoline.contains('foo_pivots') == true)); + return (!(trampoline.contains('foos') && + trampoline.contains('foo_pivots'))); } @override @@ -789,9 +789,9 @@ class FooPivotQuery extends Query { FooPivotQueryWhere? _where; - WeirdJoinQuery? _weirdJoin; + late WeirdJoinQuery _weirdJoin; - FooQuery? _foo; + late FooQuery _foo; @override Map get casts { @@ -835,7 +835,7 @@ class FooPivotQuery extends Query { model = model.copyWith(foo: m); }); } - return Optional.ofNullable(model); + return Optional.of(model); } @override @@ -843,11 +843,11 @@ class FooPivotQuery extends Query { return parseRow(row); } - WeirdJoinQuery? get weirdJoin { + WeirdJoinQuery get weirdJoin { return _weirdJoin; } - FooQuery? get foo { + FooQuery get foo { return _foo; } } @@ -885,10 +885,10 @@ class FooPivotQueryValues extends MapQueryValues { set fooBar(String? value) => values['foo_bar'] = value; void copyFrom(FooPivot model) { if (model.weirdJoin != null) { - values['weird_join_id'] = model.weirdJoin!.id; + values['weird_join_id'] = model.weirdJoin?.id; } if (model.foo != null) { - values['foo_bar'] = model.foo!.bar; + values['foo_bar'] = model.foo?.bar; } } } @@ -899,10 +899,10 @@ class FooPivotQueryValues extends MapQueryValues { @generatedSerializable class Unorthodox implements _Unorthodox { - const Unorthodox({this.name}); + Unorthodox({this.name}); @override - final String? name; + String? name; Unorthodox copyWith({String? name}) { return Unorthodox(name: name ?? this.name); @@ -923,37 +923,41 @@ class Unorthodox implements _Unorthodox { return 'Unorthodox(name=$name)'; } - Map? toJson() { + Map toJson() { return UnorthodoxSerializer.toMap(this); } } @generatedSerializable class WeirdJoin implements _WeirdJoin { - const WeirdJoin( - {this.id, this.unorthodox, this.song, this.numbas, this.foos}); + WeirdJoin( + {this.id, + this.unorthodox, + this.song, + this.numbas = const [], + this.foos = const []}); @override - final int? id; + int? id; @override - final _Unorthodox? unorthodox; + _Unorthodox? unorthodox; @override - final _Song? song; + _Song? song; @override - final List<_Numba?>? numbas; + List<_Numba> numbas; @override - final List<_Foo?>? foos; + List<_Foo> foos; WeirdJoin copyWith( {int? id, _Unorthodox? unorthodox, _Song? song, - List<_Numba?>? numbas, - List<_Foo?>? foos}) { + List<_Numba>? numbas, + List<_Foo>? foos}) { return WeirdJoin( id: id ?? this.id, unorthodox: unorthodox ?? this.unorthodox, @@ -968,9 +972,9 @@ class WeirdJoin implements _WeirdJoin { other.id == id && other.unorthodox == unorthodox && other.song == song && - ListEquality<_Numba?>(DefaultEquality<_Numba>()) + ListEquality<_Numba>(DefaultEquality<_Numba>()) .equals(other.numbas, numbas) && - ListEquality<_Foo?>(DefaultEquality<_Foo>()).equals(other.foos, foos); + ListEquality<_Foo>(DefaultEquality<_Foo>()).equals(other.foos, foos); } @override @@ -983,7 +987,7 @@ class WeirdJoin implements _WeirdJoin { return 'WeirdJoin(id=$id, unorthodox=$unorthodox, song=$song, numbas=$numbas, foos=$foos)'; } - Map? toJson() { + Map toJson() { return WeirdJoinSerializer.toMap(this); } } @@ -1005,10 +1009,10 @@ class Song extends _Song { DateTime? updatedAt; @override - final int? weirdJoinId; + int? weirdJoinId; @override - final String? title; + String? title; Song copyWith( {String? id, @@ -1044,7 +1048,7 @@ class Song extends _Song { return 'Song(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, weirdJoinId=$weirdJoinId, title=$title)'; } - Map? toJson() { + Map toJson() { return SongSerializer.toMap(this); } } @@ -1078,20 +1082,20 @@ class Numba extends _Numba { return 'Numba(i=$i, parent=$parent)'; } - Map? toJson() { + Map toJson() { return NumbaSerializer.toMap(this); } } @generatedSerializable class Foo implements _Foo { - const Foo({this.bar, this.weirdJoins}); + Foo({this.bar, this.weirdJoins = const []}); @override - final String? bar; + String? bar; @override - final List<_WeirdJoin>? weirdJoins; + List<_WeirdJoin> weirdJoins; Foo copyWith({String? bar, List<_WeirdJoin>? weirdJoins}) { return Foo(bar: bar ?? this.bar, weirdJoins: weirdJoins ?? this.weirdJoins); @@ -1101,7 +1105,7 @@ class Foo implements _Foo { bool operator ==(other) { return other is _Foo && other.bar == bar && - ListEquality<_WeirdJoin?>(DefaultEquality<_WeirdJoin>()) + ListEquality<_WeirdJoin>(DefaultEquality<_WeirdJoin>()) .equals(other.weirdJoins, weirdJoins); } @@ -1115,20 +1119,20 @@ class Foo implements _Foo { return 'Foo(bar=$bar, weirdJoins=$weirdJoins)'; } - Map? toJson() { + Map toJson() { return FooSerializer.toMap(this); } } @generatedSerializable class FooPivot implements _FooPivot { - const FooPivot({this.weirdJoin, this.foo}); + FooPivot({this.weirdJoin, this.foo}); @override - final _WeirdJoin? weirdJoin; + _WeirdJoin? weirdJoin; @override - final _Foo? foo; + _Foo? foo; FooPivot copyWith({_WeirdJoin? weirdJoin, _Foo? foo}) { return FooPivot( @@ -1163,11 +1167,11 @@ class FooPivot implements _FooPivot { const UnorthodoxSerializer unorthodoxSerializer = UnorthodoxSerializer(); -class UnorthodoxEncoder extends Converter { +class UnorthodoxEncoder extends Converter { const UnorthodoxEncoder(); @override - Map? convert(Unorthodox model) => UnorthodoxSerializer.toMap(model); + Map convert(Unorthodox model) => UnorthodoxSerializer.toMap(model); } class UnorthodoxDecoder extends Converter { @@ -1177,7 +1181,7 @@ class UnorthodoxDecoder extends Converter { Unorthodox convert(Map map) => UnorthodoxSerializer.fromMap(map); } -class UnorthodoxSerializer extends Codec { +class UnorthodoxSerializer extends Codec { const UnorthodoxSerializer(); @override @@ -1188,9 +1192,9 @@ class UnorthodoxSerializer extends Codec { return Unorthodox(name: map['name'] as String?); } - static Map? toMap(_Unorthodox? model) { + static Map toMap(_Unorthodox? model) { if (model == null) { - return null; + return {}; } return {'name': model.name}; } @@ -1204,11 +1208,11 @@ abstract class UnorthodoxFields { const WeirdJoinSerializer weirdJoinSerializer = WeirdJoinSerializer(); -class WeirdJoinEncoder extends Converter { +class WeirdJoinEncoder extends Converter { const WeirdJoinEncoder(); @override - Map? convert(WeirdJoin model) => WeirdJoinSerializer.toMap(model); + Map convert(WeirdJoin model) => WeirdJoinSerializer.toMap(model); } class WeirdJoinDecoder extends Converter { @@ -1218,7 +1222,7 @@ class WeirdJoinDecoder extends Converter { WeirdJoin convert(Map map) => WeirdJoinSerializer.fromMap(map); } -class WeirdJoinSerializer extends Codec { +class WeirdJoinSerializer extends Codec { const WeirdJoinSerializer(); @override @@ -1237,23 +1241,23 @@ class WeirdJoinSerializer extends Codec { numbas: map['numbas'] is Iterable ? List.unmodifiable(((map['numbas'] as Iterable).whereType()) .map(NumbaSerializer.fromMap)) - : null, + : [], foos: map['foos'] is Iterable ? List.unmodifiable(((map['foos'] as Iterable).whereType()) .map(FooSerializer.fromMap)) - : null); + : []); } - static Map? toMap(_WeirdJoin? model) { + static Map toMap(_WeirdJoin? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, 'unorthodox': UnorthodoxSerializer.toMap(model.unorthodox), 'song': SongSerializer.toMap(model.song), - 'numbas': model.numbas?.map((m) => NumbaSerializer.toMap(m)).toList(), - 'foos': model.foos?.map((m) => FooSerializer.toMap(m)).toList() + 'numbas': model.numbas.map((m) => NumbaSerializer.toMap(m)).toList(), + 'foos': model.foos.map((m) => FooSerializer.toMap(m)).toList() }; } } @@ -1280,11 +1284,11 @@ abstract class WeirdJoinFields { const SongSerializer songSerializer = SongSerializer(); -class SongEncoder extends Converter { +class SongEncoder extends Converter { const SongEncoder(); @override - Map? convert(Song model) => SongSerializer.toMap(model); + Map convert(Song model) => SongSerializer.toMap(model); } class SongDecoder extends Converter { @@ -1294,7 +1298,7 @@ class SongDecoder extends Converter { Song convert(Map map) => SongSerializer.fromMap(map); } -class SongSerializer extends Codec { +class SongSerializer extends Codec { const SongSerializer(); @override @@ -1306,21 +1310,21 @@ class SongSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, weirdJoinId: map['weird_join_id'] as int?, title: map['title'] as String?); } - static Map? toMap(_Song? model) { + static Map toMap(_Song? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, @@ -1354,11 +1358,11 @@ abstract class SongFields { const NumbaSerializer numbaSerializer = NumbaSerializer(); -class NumbaEncoder extends Converter { +class NumbaEncoder extends Converter { const NumbaEncoder(); @override - Map? convert(Numba model) => NumbaSerializer.toMap(model); + Map convert(Numba model) => NumbaSerializer.toMap(model); } class NumbaDecoder extends Converter { @@ -1368,7 +1372,7 @@ class NumbaDecoder extends Converter { Numba convert(Map map) => NumbaSerializer.fromMap(map); } -class NumbaSerializer extends Codec { +class NumbaSerializer extends Codec { const NumbaSerializer(); @override @@ -1379,9 +1383,9 @@ class NumbaSerializer extends Codec { return Numba(i: map['i'] as int?, parent: map['parent'] as int?); } - static Map? toMap(_Numba? model) { + static Map toMap(_Numba? model) { if (model == null) { - return null; + return {}; } return {'i': model.i, 'parent': model.parent}; } @@ -1397,11 +1401,11 @@ abstract class NumbaFields { const FooSerializer fooSerializer = FooSerializer(); -class FooEncoder extends Converter { +class FooEncoder extends Converter { const FooEncoder(); @override - Map? convert(Foo model) => FooSerializer.toMap(model); + Map convert(Foo model) => FooSerializer.toMap(model); } class FooDecoder extends Converter { @@ -1411,7 +1415,7 @@ class FooDecoder extends Converter { Foo convert(Map map) => FooSerializer.fromMap(map); } -class FooSerializer extends Codec { +class FooSerializer extends Codec { const FooSerializer(); @override @@ -1425,17 +1429,17 @@ class FooSerializer extends Codec { ? List.unmodifiable( ((map['weird_joins'] as Iterable).whereType()) .map(WeirdJoinSerializer.fromMap)) - : null); + : []); } - static Map? toMap(_Foo? model) { + static Map toMap(_Foo? model) { if (model == null) { - return null; + return {}; } return { 'bar': model.bar, 'weird_joins': - model.weirdJoins?.map((m) => WeirdJoinSerializer.toMap(m)).toList() + model.weirdJoins.map((m) => WeirdJoinSerializer.toMap(m)).toList() }; } } @@ -1481,7 +1485,10 @@ class FooPivotSerializer extends Codec { : null); } - static Map toMap(_FooPivot model) { + static Map toMap(_FooPivot? model) { + if (model == null) { + return {}; + } return { 'weird_join': WeirdJoinSerializer.toMap(model.weirdJoin), 'foo': FooSerializer.toMap(model.foo) diff --git a/packages/orm/angel_orm_test/lib/src/models/user.dart b/packages/orm/angel_orm_test/lib/src/models/user.dart index 4cc93050..da28266e 100644 --- a/packages/orm/angel_orm_test/lib/src/models/user.dart +++ b/packages/orm/angel_orm_test/lib/src/models/user.dart @@ -1,10 +1,8 @@ library angel3_orm_generator.test.models.user; import 'package:angel3_migration/angel3_migration.dart'; -import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; -import 'package:collection/collection.dart'; import 'package:optional/optional.dart'; part 'user.g.dart'; diff --git a/packages/orm/angel_orm_test/lib/src/models/user.g.dart b/packages/orm/angel_orm_test/lib/src/models/user.g.dart index 11d1bf92..869f5b06 100644 --- a/packages/orm/angel_orm_test/lib/src/models/user.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/user.g.dart @@ -13,9 +13,9 @@ class UserMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.varChar('username'); - table.varChar('password'); - table.varChar('email'); + table.varChar('username', length: 255); + table.varChar('password', length: 255); + table.varChar('email', length: 255); }); } @@ -29,8 +29,8 @@ class RoleUserMigration extends Migration { @override void up(Schema schema) { schema.create('role_users', (table) { - table.declare('role_id', ColumnType('serial')).references('roles', 'id'); - table.declare('user_id', ColumnType('serial')).references('users', 'id'); + table.declare('role_id', ColumnType('int')).references('roles', 'id'); + table.declare('user_id', ColumnType('int')).references('users', 'id'); }); } @@ -47,7 +47,7 @@ class RoleMigration extends Migration { table.serial('id').primaryKey(); table.timeStamp('created_at'); table.timeStamp('updated_at'); - table.varChar('name'); + table.varChar('name', length: 255); }); } @@ -123,9 +123,9 @@ class UserQuery extends Query { password: (row[4] as String?), email: (row[5] as String?)); if (row.length > 6) { - var roleOpt = RoleQuery.parseRow(row.skip(6).take(4).toList()); - roleOpt.ifPresent((role) { - model = model.copyWith(roles: [role]); + var modelOpt = RoleQuery.parseRow(row.skip(6).take(4).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(roles: [m]); }); } return Optional.of(model); @@ -138,8 +138,8 @@ class UserQuery extends Query { @override bool canCompile(trampoline) { - return (!(trampoline.contains('users') == true && - trampoline.contains('role_users') == true)); + return (!(trampoline.contains('users') && + trampoline.contains('role_users'))); } @override @@ -154,7 +154,8 @@ class UserQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - roles: List<_Role>.from(l.roles)..addAll(model.roles)); + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); } }); }); @@ -172,7 +173,8 @@ class UserQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - roles: List<_Role>.from(l.roles)..addAll(model.roles)); + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); } }); }); @@ -190,7 +192,8 @@ class UserQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - roles: List<_Role>.from(l.roles)..addAll(model.roles)); + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); } }); }); @@ -297,9 +300,9 @@ class RoleUserQuery extends Query { RoleUserQueryWhere? _where; - RoleQuery? _role; + late RoleQuery _role; - UserQuery? _user; + late UserQuery _user; @override Map get casts { @@ -332,15 +335,15 @@ class RoleUserQuery extends Query { } var model = RoleUser(); if (row.length > 2) { - var roleOpt = RoleQuery.parseRow(row.skip(2).take(4).toList()); - roleOpt.ifPresent((role) { - model = model.copyWith(role: role); + var modelOpt = RoleQuery.parseRow(row.skip(2).take(4).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(role: m); }); } if (row.length > 6) { - var userOpt = UserQuery.parseRow(row.skip(6).take(6).toList()); - userOpt.ifPresent((user) { - model = model.copyWith(user: user); + var modelOpt = UserQuery.parseRow(row.skip(6).take(6).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(user: m); }); } return Optional.of(model); @@ -351,11 +354,11 @@ class RoleUserQuery extends Query { return parseRow(row); } - RoleQuery? get role { + RoleQuery get role { return _role; } - UserQuery? get user { + UserQuery get user { return _user; } } @@ -381,22 +384,22 @@ class RoleUserQueryValues extends MapQueryValues { return {}; } - int? get roleId { - return (values['role_id'] as int?); + int get roleId { + return (values['role_id'] as int); } - set roleId(int? value) => values['role_id'] = value; - int? get userId { - return (values['user_id'] as int?); + set roleId(int value) => values['role_id'] = value; + int get userId { + return (values['user_id'] as int); } - set userId(int? value) => values['user_id'] = value; + set userId(int value) => values['user_id'] = value; void copyFrom(RoleUser model) { if (model.role != null) { - values['role_id'] = model.role!.id; + values['role_id'] = model.role?.id; } if (model.user != null) { - values['user_id'] = model.user!.id; + values['user_id'] = model.user?.id; } } } @@ -476,8 +479,8 @@ class RoleQuery extends Query { @override bool canCompile(trampoline) { - return (!(trampoline.contains('roles') == true && - trampoline.contains('role_users') == true)); + return (!(trampoline.contains('roles') && + trampoline.contains('role_users'))); } @override @@ -492,7 +495,8 @@ class RoleQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - users: List<_User>.from(l.users)..addAll(model.users)); + users: List<_User>.from(l.users ?? []) + ..addAll(model.users ?? [])); } }); }); @@ -510,7 +514,8 @@ class RoleQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - users: List<_User>.from(l.users)..addAll(model.users)); + users: List<_User>.from(l.users ?? []) + ..addAll(model.users ?? [])); } }); }); @@ -528,7 +533,8 @@ class RoleQuery extends Query { var l = out[idx]; return out ..[idx] = l.copyWith( - users: List<_User>.from(l.users)..addAll(model.users)); + users: List<_User>.from(l.users ?? []) + ..addAll(model.users ?? [])); } }); }); @@ -618,16 +624,16 @@ class User extends _User { DateTime? updatedAt; @override - final String? username; + String? username; @override - final String? password; + String? password; @override - final String? email; + String? email; @override - final List<_Role> roles; + List<_Role> roles; User copyWith( {String? id, @@ -636,7 +642,7 @@ class User extends _User { String? username, String? password, String? email, - List<_Role> roles = const []}) { + List<_Role>? roles}) { return User( id: id ?? this.id, createdAt: createdAt ?? this.createdAt, @@ -644,7 +650,7 @@ class User extends _User { username: username ?? this.username, password: password ?? this.password, email: email ?? this.email, - roles: roles); + roles: roles ?? this.roles); } @override @@ -671,20 +677,20 @@ class User extends _User { return 'User(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, username=$username, password=$password, email=$email, roles=$roles)'; } - Map? toJson() { + Map toJson() { return UserSerializer.toMap(this); } } @generatedSerializable class RoleUser implements _RoleUser { - const RoleUser({this.role, this.user}); + RoleUser({this.role, this.user}); @override - final _Role? role; + _Role? role; @override - final _User? user; + _User? user; RoleUser copyWith({_Role? role, _User? user}) { return RoleUser(role: role ?? this.role, user: user ?? this.user); @@ -713,8 +719,12 @@ class RoleUser implements _RoleUser { @generatedSerializable class Role extends _Role { Role( - {this.id, this.createdAt, this.updatedAt, this.name, List<_User?>? users}) - : users = List.unmodifiable(users ?? []); + {this.id, + this.createdAt, + this.updatedAt, + this.name, + List<_User> users = const []}) + : users = List.unmodifiable(users); /// A unique identifier corresponding to this item. @override @@ -732,14 +742,14 @@ class Role extends _Role { String? name; @override - final List<_User> users; + List<_User> users; Role copyWith( {String? id, DateTime? createdAt, DateTime? updatedAt, String? name, - List<_User?>? users}) { + List<_User>? users}) { return Role( id: id ?? this.id, createdAt: createdAt ?? this.createdAt, @@ -769,7 +779,7 @@ class Role extends _Role { return 'Role(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, name=$name, users=$users)'; } - Map? toJson() { + Map toJson() { return RoleSerializer.toMap(this); } } @@ -780,11 +790,11 @@ class Role extends _Role { const UserSerializer userSerializer = UserSerializer(); -class UserEncoder extends Converter { +class UserEncoder extends Converter { const UserEncoder(); @override - Map? convert(User model) => UserSerializer.toMap(model); + Map convert(User model) => UserSerializer.toMap(model); } class UserDecoder extends Converter { @@ -794,7 +804,7 @@ class UserDecoder extends Converter { User convert(Map map) => UserSerializer.fromMap(map); } -class UserSerializer extends Codec { +class UserSerializer extends Codec { const UserSerializer(); @override @@ -806,12 +816,12 @@ class UserSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, username: map['username'] as String?, @@ -823,9 +833,9 @@ class UserSerializer extends Codec { : []); } - static Map? toMap(_User? model) { + static Map toMap(_User? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, @@ -898,7 +908,10 @@ class RoleUserSerializer extends Codec { : null); } - static Map toMap(_RoleUser model) { + static Map toMap(_RoleUser? model) { + if (model == null) { + return {}; + } return { 'role': RoleSerializer.toMap(model.role), 'user': UserSerializer.toMap(model.user) @@ -916,11 +929,11 @@ abstract class RoleUserFields { const RoleSerializer roleSerializer = RoleSerializer(); -class RoleEncoder extends Converter { +class RoleEncoder extends Converter { const RoleEncoder(); @override - Map? convert(Role model) => RoleSerializer.toMap(model); + Map convert(Role model) => RoleSerializer.toMap(model); } class RoleDecoder extends Converter { @@ -930,7 +943,7 @@ class RoleDecoder extends Converter { Role convert(Map map) => RoleSerializer.fromMap(map); } -class RoleSerializer extends Codec { +class RoleSerializer extends Codec { const RoleSerializer(); @override @@ -942,24 +955,24 @@ class RoleSerializer extends Codec { id: map['id'] as String?, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime - ? (map['created_at'] as DateTime?) + ? (map['created_at'] as DateTime) : DateTime.parse(map['created_at'].toString())) : null, updatedAt: map['updated_at'] != null ? (map['updated_at'] is DateTime - ? (map['updated_at'] as DateTime?) + ? (map['updated_at'] as DateTime) : DateTime.parse(map['updated_at'].toString())) : null, name: map['name'] as String?, users: map['users'] is Iterable ? List.unmodifiable(((map['users'] as Iterable).whereType()) .map(UserSerializer.fromMap)) - : null); + : []); } - static Map? toMap(_Role? model) { + static Map toMap(_Role? model) { if (model == null) { - return null; + return {}; } return { 'id': model.id, diff --git a/packages/orm/angel_orm_test/lib/src/models/world.dart b/packages/orm/angel_orm_test/lib/src/models/world.dart index b7505a4e..31376268 100644 --- a/packages/orm/angel_orm_test/lib/src/models/world.dart +++ b/packages/orm/angel_orm_test/lib/src/models/world.dart @@ -1,5 +1,4 @@ import 'package:angel3_migration/angel3_migration.dart'; -//import 'package:angel3_model/angel3_model.dart'; import 'package:angel3_serialize/angel3_serialize.dart'; import 'package:angel3_orm/angel3_orm.dart'; import 'package:optional/optional.dart'; @@ -9,6 +8,7 @@ part 'world.g.dart'; @serializable @Orm(tableName: 'world') abstract class _World { + @primaryKey int? id; @Column() diff --git a/packages/orm/angel_orm_test/lib/src/models/world.g.dart b/packages/orm/angel_orm_test/lib/src/models/world.g.dart index d6d442ee..674c883d 100644 --- a/packages/orm/angel_orm_test/lib/src/models/world.g.dart +++ b/packages/orm/angel_orm_test/lib/src/models/world.g.dart @@ -10,8 +10,8 @@ class WorldMigration extends Migration { @override void up(Schema schema) { schema.create('world', (table) { - table.integer('id'); - table.integer('randomNumber'); + table.integer('id').primaryKey(); + table.integer('random_number'); }); } @@ -49,7 +49,7 @@ class WorldQuery extends Query { @override List get fields { - return const ['id', 'randomNumber']; + return const ['id', 'random_number']; } @override @@ -62,24 +62,24 @@ class WorldQuery extends Query { return WorldQueryWhere(this); } - static World? parseRow(List row) { + static Optional parseRow(List row) { if (row.every((x) => x == null)) { - return null; + return Optional.empty(); } var model = World(id: (row[0] as int?), randomNumber: (row[1] as int?)); - return model; + return Optional.of(model); } @override Optional deserialize(List row) { - return Optional.ofNullable(parseRow(row)); + return parseRow(row); } } class WorldQueryWhere extends QueryWhere { WorldQueryWhere(WorldQuery query) : id = NumericSqlExpressionBuilder(query, 'id'), - randomNumber = NumericSqlExpressionBuilder(query, 'randomNumber'); + randomNumber = NumericSqlExpressionBuilder(query, 'random_number'); final NumericSqlExpressionBuilder id; @@ -103,10 +103,10 @@ class WorldQueryValues extends MapQueryValues { set id(int? value) => values['id'] = value; int? get randomNumber { - return (values['randomNumber'] as int?); + return (values['random_number'] as int?); } - set randomNumber(int? value) => values['randomNumber'] = value; + set randomNumber(int? value) => values['random_number'] = value; void copyFrom(World model) { id = model.id; randomNumber = model.randomNumber; @@ -183,14 +183,14 @@ class WorldSerializer extends Codec { WorldDecoder get decoder => const WorldDecoder(); static World fromMap(Map map) { return World( - id: map['id'] as int?, randomNumber: map['randomNumber'] as int?); + id: map['id'] as int?, randomNumber: map['random_number'] as int?); } static Map toMap(_World? model) { if (model == null) { return {}; } - return {'id': model.id, 'randomNumber': model.randomNumber}; + return {'id': model.id, 'random_number': model.randomNumber}; } } @@ -199,5 +199,5 @@ abstract class WorldFields { static const String id = 'id'; - static const String randomNumber = 'randomNumber'; + static const String randomNumber = 'random_number'; } diff --git a/packages/orm/angel_orm_test/pubspec.yaml b/packages/orm/angel_orm_test/pubspec.yaml index 58bcf062..f7e599b2 100644 --- a/packages/orm/angel_orm_test/pubspec.yaml +++ b/packages/orm/angel_orm_test/pubspec.yaml @@ -19,12 +19,12 @@ dev_dependencies: angel3_framework: ^4.2.0 build_runner: ^2.0.1 lints: ^1.0.0 -#dependency_overrides: +dependency_overrides: # angel3_migration_runner: # path: ../angel_migration_runner -# angel3_orm: -# path: ../angel_orm + angel3_orm: + path: ../angel_orm # angel3_migration: # path: ..//angel_migration -# angel3_orm_generator: -# path: ../angel_orm_generator + angel3_orm_generator: + path: ../angel_orm_generator diff --git a/packages/orm/orm_builder/analysis_options.yaml b/packages/orm/orm_builder/analysis_options.yaml new file mode 100644 index 00000000..ea2c9e94 --- /dev/null +++ b/packages/orm/orm_builder/analysis_options.yaml @@ -0,0 +1 @@ +include: package:lints/recommended.yaml \ No newline at end of file diff --git a/packages/orm/orm_builder/lib/src/belongs_to_test.dart b/packages/orm/orm_builder/lib/src/belongs_to_test.dart new file mode 100644 index 00000000..73d1fd52 --- /dev/null +++ b/packages/orm/orm_builder/lib/src/belongs_to_test.dart @@ -0,0 +1,175 @@ +import 'dart:async'; +import 'package:angel3_orm/angel3_orm.dart'; +import 'package:test/test.dart'; +import 'models/book.dart'; + +import 'util.dart'; + +void belongsToTests(FutureOr Function() createExecutor, + {FutureOr Function(QueryExecutor)? close}) { + late QueryExecutor executor; + Author? jkRowling; + Author? jameson; + Book? deathlyHallows; + close ??= (_) => null; + + setUp(() async { + executor = await createExecutor(); + + // Insert an author + var query = AuthorQuery()..values.name = 'J.K. Rowling'; + jkRowling = (await query.insert(executor)).value; + + query.values.name = 'J.K. Jameson'; + jameson = (await query.insert(executor)).value; + + // And a book + var bookQuery = BookQuery(); + bookQuery.values + ..authorId = jkRowling!.idAsInt + ..partnerAuthorId = jameson!.idAsInt + ..name = 'Deathly Hallows'; + + deathlyHallows = (await bookQuery.insert(executor)).value; + }); + + tearDown(() => close!(executor)); + + group('selects', () { + test('select all', () async { + var query = BookQuery(); + var books = await query.get(executor); + expect(books, hasLength(1)); + + var book = books.first; + //print(book.toJson()); + expect(book.id, deathlyHallows!.id); + expect(book.name, deathlyHallows!.name); + + var author = book.author!; + //print(AuthorSerializer.toMap(author)); + expect(author.id, jkRowling!.id); + expect(author.name, jkRowling!.name); + }); + + test('select one', () async { + var query = BookQuery(); + query.where!.id.equals(int.parse(deathlyHallows!.id!)); + //print(query.compile({})); + + var bookOpt = await query.getOne(executor); + expect(bookOpt.isPresent, true); + bookOpt.ifPresent((book) { + //print(book.toJson()); + expect(book.id, deathlyHallows!.id); + expect(book.name, deathlyHallows!.name); + + var author = book.author!; + //print(AuthorSerializer.toMap(author)); + expect(author.id, jkRowling!.id); + expect(author.name, jkRowling!.name); + }); + }); + + test('where clause', () async { + var query = BookQuery() + ..where!.name.equals('Goblet of Fire') + ..orWhere((w) => w.authorId.equals(jkRowling!.idAsInt)); + //print(query.compile({})); + + var books = await query.get(executor); + expect(books, hasLength(1)); + + var book = books.first; + //print(book.toJson()); + expect(book.id, deathlyHallows!.id); + expect(book.name, deathlyHallows!.name); + + var author = book.author!; + //print(AuthorSerializer.toMap(author)); + expect(author.id, jkRowling!.id); + expect(author.name, jkRowling!.name); + }); + + test('union', () async { + var query1 = BookQuery()..where!.name.like('Deathly%'); + var query2 = BookQuery()..where!.authorId.equals(-1); + var query3 = BookQuery() + ..where!.name.isIn(['Goblet of Fire', 'Order of the Phoenix']); + query1 + ..union(query2) + ..unionAll(query3); + //print(query1.compile({})); + + var books = await query1.get(executor); + expect(books, hasLength(1)); + + var book = books.first; + //print(book.toJson()); + expect(book.id, deathlyHallows!.id); + expect(book.name, deathlyHallows!.name); + + var author = book.author!; + //print(AuthorSerializer.toMap(author)); + expect(author.id, jkRowling!.id); + expect(author.name, jkRowling!.name); + }); + + test('order by', () async { + var query = AuthorQuery()..orderBy(AuthorFields.name, descending: true); + var authors = await query.get(executor); + expect(authors, [jkRowling, jameson]); + }); + }); + + test('insert sets relationship', () { + expect(deathlyHallows!.author, jkRowling); + //expect(deathlyHallows.author, isNotNull); + //expect(deathlyHallows.author.name, rowling.name); + }); + + test('delete stream', () async { + //printSeparator('Delete stream test'); + var query = BookQuery()..where!.name.equals(deathlyHallows!.name!); + //print(query.compile({}, preamble: 'DELETE', withFields: false)); + var books = await query.delete(executor); + expect(books, hasLength(1)); + + var book = books.first; + expect(book.id, deathlyHallows?.id); + expect(book.author, isNotNull); + expect(book.author!.name, jkRowling!.name); + }); + + test('update book', () async { + var cloned = deathlyHallows!.copyWith(name: "Sorcerer's Stone"); + var query = BookQuery() + ..where?.id.equals(int.parse(cloned.id!)) + ..values.copyFrom(cloned); + var bookOpt = await (query.updateOne(executor)); + expect(bookOpt.isPresent, true); + bookOpt.ifPresent((book) { + //print(book.toJson()); + expect(book.name, cloned.name); + expect(book.author, isNotNull); + expect(book.author!.name, jkRowling!.name); + }); + }); + + group('joined subquery', () { + // To verify that the joined subquery is correct, + // we test both a query that return empty, and one + // that should return correctly. + test('returns empty on false subquery', () async { + printSeparator('False subquery test'); + var query = BookQuery()..author.where!.name.equals('Billie Jean'); + expect(await query.get(executor), isEmpty); + }); + + test('returns values on true subquery', () async { + printSeparator('True subquery test'); + var query = BookQuery()..author.where!.name.like('%Rowling%'); + expect(await query.get(executor), [deathlyHallows]); + }); + }); +} diff --git a/packages/orm/orm_builder/lib/src/models/book.dart b/packages/orm/orm_builder/lib/src/models/book.dart new file mode 100644 index 00000000..30a0c5c1 --- /dev/null +++ b/packages/orm/orm_builder/lib/src/models/book.dart @@ -0,0 +1,28 @@ +library angel_orm3.generator.models.book; + +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 'book.g.dart'; + +@serializable +@orm +class _Book extends Model { + @BelongsTo(joinType: JoinType.inner) + _Author? author; + + @BelongsTo(localKey: 'partner_author_id', joinType: JoinType.inner) + _Author? partnerAuthor; + + String? name; +} + +@serializable +@orm +abstract class _Author extends Model { + @Column(length: 255, indexType: IndexType.unique) + @SerializableField(defaultValue: 'Tobe Osakwe') + String? get name; +} diff --git a/packages/orm/orm_builder/lib/src/models/book.g.dart b/packages/orm/orm_builder/lib/src/models/book.g.dart new file mode 100644 index 00000000..27c20d09 --- /dev/null +++ b/packages/orm/orm_builder/lib/src/models/book.g.dart @@ -0,0 +1,617 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of angel_orm3.generator.models.book; + +// ************************************************************************** +// MigrationGenerator +// ************************************************************************** + +class BookMigration extends Migration { + @override + void up(Schema schema) { + schema.create('books', (table) { + table.serial('id').primaryKey(); + table.timeStamp('created_at'); + table.timeStamp('updated_at'); + table.varChar('name', length: 255); + table.declare('author_id', ColumnType('int')).references('authors', 'id'); + table + .declare('partner_author_id', ColumnType('int')) + .references('authors', 'id'); + }); + } + + @override + void down(Schema schema) { + schema.drop('books'); + } +} + +class AuthorMigration extends Migration { + @override + void up(Schema schema) { + schema.create('authors', (table) { + table.serial('id').primaryKey(); + table.timeStamp('created_at'); + table.timeStamp('updated_at'); + table.varChar('name', length: 255) + ..defaultsTo('Tobe Osakwe') + ..unique(); + }); + } + + @override + void down(Schema schema) { + schema.drop('authors'); + } +} + +// ************************************************************************** +// OrmGenerator +// ************************************************************************** + +class BookQuery extends Query { + BookQuery({Query? parent, Set? trampoline}) : super(parent: parent) { + trampoline ??= {}; + trampoline.add(tableName); + _where = BookQueryWhere(this); + join(_author = AuthorQuery(trampoline: trampoline, parent: this), + 'author_id', 'id', + additionalFields: const ['id', 'created_at', 'updated_at', 'name'], + trampoline: trampoline); + join(_partnerAuthor = AuthorQuery(trampoline: trampoline, parent: this), + 'partner_author_id', 'id', + additionalFields: const ['id', 'created_at', 'updated_at', 'name'], + trampoline: trampoline); + } + + @override + final BookQueryValues values = BookQueryValues(); + + BookQueryWhere? _where; + + late AuthorQuery _author; + + late AuthorQuery _partnerAuthor; + + @override + Map get casts { + return {}; + } + + @override + String get tableName { + return 'books'; + } + + @override + List get fields { + return const [ + 'id', + 'created_at', + 'updated_at', + 'author_id', + 'partner_author_id', + 'name' + ]; + } + + @override + BookQueryWhere? get where { + return _where; + } + + @override + BookQueryWhere newWhereClause() { + return BookQueryWhere(this); + } + + static Optional parseRow(List row) { + if (row.every((x) => x == null)) { + return Optional.empty(); + } + var model = Book( + id: row[0].toString(), + createdAt: (row[1] as DateTime?), + updatedAt: (row[2] as DateTime?), + name: (row[5] as String?)); + if (row.length > 6) { + var modelOpt = AuthorQuery.parseRow(row.skip(6).take(4).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(author: m); + }); + } + if (row.length > 10) { + var modelOpt = AuthorQuery.parseRow(row.skip(10).take(4).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(partnerAuthor: m); + }); + } + return Optional.of(model); + } + + @override + Optional deserialize(List row) { + return parseRow(row); + } + + AuthorQuery get author { + return _author; + } + + AuthorQuery get partnerAuthor { + return _partnerAuthor; + } +} + +class BookQueryWhere extends QueryWhere { + BookQueryWhere(BookQuery query) + : id = NumericSqlExpressionBuilder(query, 'id'), + createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'), + updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at'), + authorId = NumericSqlExpressionBuilder(query, 'author_id'), + partnerAuthorId = + NumericSqlExpressionBuilder(query, 'partner_author_id'), + name = StringSqlExpressionBuilder(query, 'name'); + + final NumericSqlExpressionBuilder id; + + final DateTimeSqlExpressionBuilder createdAt; + + final DateTimeSqlExpressionBuilder updatedAt; + + final NumericSqlExpressionBuilder authorId; + + final NumericSqlExpressionBuilder partnerAuthorId; + + final StringSqlExpressionBuilder name; + + @override + List get expressionBuilders { + return [id, createdAt, updatedAt, authorId, partnerAuthorId, name]; + } +} + +class BookQueryValues extends MapQueryValues { + @override + Map get casts { + return {}; + } + + String? get id { + return (values['id'] as String?); + } + + set id(String? value) => values['id'] = value; + DateTime? get createdAt { + return (values['created_at'] as DateTime?); + } + + set createdAt(DateTime? value) => values['created_at'] = value; + DateTime? get updatedAt { + return (values['updated_at'] as DateTime?); + } + + set updatedAt(DateTime? value) => values['updated_at'] = value; + int get authorId { + return (values['author_id'] as int); + } + + set authorId(int value) => values['author_id'] = value; + int get partnerAuthorId { + return (values['partner_author_id'] as int); + } + + set partnerAuthorId(int value) => values['partner_author_id'] = value; + String? get name { + return (values['name'] as String?); + } + + set name(String? value) => values['name'] = value; + void copyFrom(Book model) { + createdAt = model.createdAt; + updatedAt = model.updatedAt; + name = model.name; + if (model.author != null) { + values['author_id'] = model.author?.id; + } + if (model.partnerAuthor != null) { + values['partner_author_id'] = model.partnerAuthor?.id; + } + } +} + +class AuthorQuery extends Query { + AuthorQuery({Query? parent, Set? trampoline}) + : super(parent: parent) { + trampoline ??= {}; + trampoline.add(tableName); + _where = AuthorQueryWhere(this); + } + + @override + final AuthorQueryValues values = AuthorQueryValues(); + + AuthorQueryWhere? _where; + + @override + Map get casts { + return {}; + } + + @override + String get tableName { + return 'authors'; + } + + @override + List get fields { + return const ['id', 'created_at', 'updated_at', 'name']; + } + + @override + AuthorQueryWhere? get where { + return _where; + } + + @override + AuthorQueryWhere newWhereClause() { + return AuthorQueryWhere(this); + } + + static Optional parseRow(List row) { + if (row.every((x) => x == null)) { + return Optional.empty(); + } + var model = Author( + id: row[0].toString(), + createdAt: (row[1] as DateTime?), + updatedAt: (row[2] as DateTime?), + name: (row[3] as String?)); + return Optional.of(model); + } + + @override + Optional deserialize(List row) { + return parseRow(row); + } +} + +class AuthorQueryWhere extends QueryWhere { + AuthorQueryWhere(AuthorQuery query) + : id = NumericSqlExpressionBuilder(query, 'id'), + createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'), + updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at'), + name = StringSqlExpressionBuilder(query, 'name'); + + final NumericSqlExpressionBuilder id; + + final DateTimeSqlExpressionBuilder createdAt; + + final DateTimeSqlExpressionBuilder updatedAt; + + final StringSqlExpressionBuilder name; + + @override + List get expressionBuilders { + return [id, createdAt, updatedAt, name]; + } +} + +class AuthorQueryValues extends MapQueryValues { + @override + Map get casts { + return {}; + } + + String? get id { + return (values['id'] as String?); + } + + set id(String? value) => values['id'] = value; + DateTime? get createdAt { + return (values['created_at'] as DateTime?); + } + + set createdAt(DateTime? value) => values['created_at'] = value; + DateTime? get updatedAt { + return (values['updated_at'] as DateTime?); + } + + set updatedAt(DateTime? value) => values['updated_at'] = value; + String? get name { + return (values['name'] as String?); + } + + set name(String? value) => values['name'] = value; + void copyFrom(Author model) { + createdAt = model.createdAt; + updatedAt = model.updatedAt; + name = model.name; + } +} + +// ************************************************************************** +// JsonModelGenerator +// ************************************************************************** + +@generatedSerializable +class Book extends _Book { + Book( + {this.id, + this.createdAt, + this.updatedAt, + this.author, + this.partnerAuthor, + this.name}); + + /// A unique identifier corresponding to this item. + @override + String? id; + + /// The time at which this item was created. + @override + DateTime? createdAt; + + /// The last time at which this item was updated. + @override + DateTime? updatedAt; + + @override + _Author? author; + + @override + _Author? partnerAuthor; + + @override + String? name; + + Book copyWith( + {String? id, + DateTime? createdAt, + DateTime? updatedAt, + _Author? author, + _Author? partnerAuthor, + String? name}) { + return Book( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + author: author ?? this.author, + partnerAuthor: partnerAuthor ?? this.partnerAuthor, + name: name ?? this.name); + } + + @override + bool operator ==(other) { + return other is _Book && + other.id == id && + other.createdAt == createdAt && + other.updatedAt == updatedAt && + other.author == author && + other.partnerAuthor == partnerAuthor && + other.name == name; + } + + @override + int get hashCode { + return hashObjects([id, createdAt, updatedAt, author, partnerAuthor, name]); + } + + @override + String toString() { + return 'Book(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, author=$author, partnerAuthor=$partnerAuthor, name=$name)'; + } + + Map toJson() { + return BookSerializer.toMap(this); + } +} + +@generatedSerializable +class Author extends _Author { + Author({this.id, this.createdAt, this.updatedAt, this.name = 'Tobe Osakwe'}); + + /// A unique identifier corresponding to this item. + @override + String? id; + + /// The time at which this item was created. + @override + DateTime? createdAt; + + /// The last time at which this item was updated. + @override + DateTime? updatedAt; + + @override + String? name; + + Author copyWith( + {String? id, DateTime? createdAt, DateTime? updatedAt, String? name}) { + return Author( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + name: name ?? this.name); + } + + @override + bool operator ==(other) { + return other is _Author && + other.id == id && + other.createdAt == createdAt && + other.updatedAt == updatedAt && + other.name == name; + } + + @override + int get hashCode { + return hashObjects([id, createdAt, updatedAt, name]); + } + + @override + String toString() { + return 'Author(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, name=$name)'; + } + + Map toJson() { + return AuthorSerializer.toMap(this); + } +} + +// ************************************************************************** +// SerializerGenerator +// ************************************************************************** + +const BookSerializer bookSerializer = BookSerializer(); + +class BookEncoder extends Converter { + const BookEncoder(); + + @override + Map convert(Book model) => BookSerializer.toMap(model); +} + +class BookDecoder extends Converter { + const BookDecoder(); + + @override + Book convert(Map map) => BookSerializer.fromMap(map); +} + +class BookSerializer extends Codec { + const BookSerializer(); + + @override + BookEncoder get encoder => const BookEncoder(); + @override + BookDecoder get decoder => const BookDecoder(); + static Book fromMap(Map map) { + return Book( + id: map['id'] as String?, + createdAt: map['created_at'] != null + ? (map['created_at'] is DateTime + ? (map['created_at'] as DateTime) + : DateTime.parse(map['created_at'].toString())) + : null, + updatedAt: map['updated_at'] != null + ? (map['updated_at'] is DateTime + ? (map['updated_at'] as DateTime) + : DateTime.parse(map['updated_at'].toString())) + : null, + author: map['author'] != null + ? AuthorSerializer.fromMap(map['author'] as Map) + : null, + partnerAuthor: map['partner_author'] != null + ? AuthorSerializer.fromMap(map['partner_author'] as Map) + : null, + name: map['name'] as String?); + } + + static Map toMap(_Book? model) { + if (model == null) { + return {}; + } + return { + 'id': model.id, + 'created_at': model.createdAt?.toIso8601String(), + 'updated_at': model.updatedAt?.toIso8601String(), + 'author': AuthorSerializer.toMap(model.author), + 'partner_author': AuthorSerializer.toMap(model.partnerAuthor), + 'name': model.name + }; + } +} + +abstract class BookFields { + static const List allFields = [ + id, + createdAt, + updatedAt, + author, + partnerAuthor, + name + ]; + + static const String id = 'id'; + + static const String createdAt = 'created_at'; + + static const String updatedAt = 'updated_at'; + + static const String author = 'author'; + + static const String partnerAuthor = 'partner_author'; + + static const String name = 'name'; +} + +const AuthorSerializer authorSerializer = AuthorSerializer(); + +class AuthorEncoder extends Converter { + const AuthorEncoder(); + + @override + Map convert(Author model) => AuthorSerializer.toMap(model); +} + +class AuthorDecoder extends Converter { + const AuthorDecoder(); + + @override + Author convert(Map map) => AuthorSerializer.fromMap(map); +} + +class AuthorSerializer extends Codec { + const AuthorSerializer(); + + @override + AuthorEncoder get encoder => const AuthorEncoder(); + @override + AuthorDecoder get decoder => const AuthorDecoder(); + static Author fromMap(Map map) { + return Author( + id: map['id'] as String?, + createdAt: map['created_at'] != null + ? (map['created_at'] is DateTime + ? (map['created_at'] as DateTime) + : DateTime.parse(map['created_at'].toString())) + : null, + updatedAt: map['updated_at'] != null + ? (map['updated_at'] is DateTime + ? (map['updated_at'] as DateTime) + : DateTime.parse(map['updated_at'].toString())) + : null, + name: map['name'] as String? ?? 'Tobe Osakwe'); + } + + static Map toMap(_Author? model) { + if (model == null) { + return {}; + } + return { + 'id': model.id, + 'created_at': model.createdAt?.toIso8601String(), + 'updated_at': model.updatedAt?.toIso8601String(), + 'name': model.name + }; + } +} + +abstract class AuthorFields { + static const List allFields = [ + id, + createdAt, + updatedAt, + name + ]; + + static const String id = 'id'; + + static const String createdAt = 'created_at'; + + static const String updatedAt = 'updated_at'; + + static const String name = 'name'; +} diff --git a/packages/orm/orm_builder/lib/src/models/user.dart b/packages/orm/orm_builder/lib/src/models/user.dart new file mode 100644 index 00000000..52bb257e --- /dev/null +++ b/packages/orm/orm_builder/lib/src/models/user.dart @@ -0,0 +1,38 @@ +library angel3_orm_generator.test.models.user; + +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 'user.g.dart'; + +@serializable +@orm +abstract class _User extends Model { + String? get username; + String? get password; + String? get email; + + @ManyToMany(_RoleUser) + List<_Role> get roles; +} + +@serializable +@orm +abstract class _RoleUser { + @belongsTo + _Role? get role; + + @belongsTo + _User? get user; +} + +@serializable +@orm +abstract class _Role extends Model { + String? name; + + @ManyToMany(_RoleUser) + List<_User>? get users; +} diff --git a/packages/orm/orm_builder/lib/src/models/user.g.dart b/packages/orm/orm_builder/lib/src/models/user.g.dart new file mode 100644 index 00000000..514c1b5f --- /dev/null +++ b/packages/orm/orm_builder/lib/src/models/user.g.dart @@ -0,0 +1,1002 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of angel3_orm_generator.test.models.user; + +// ************************************************************************** +// MigrationGenerator +// ************************************************************************** + +class UserMigration extends Migration { + @override + void up(Schema schema) { + schema.create('users', (table) { + table.serial('id').primaryKey(); + table.timeStamp('created_at'); + table.timeStamp('updated_at'); + table.varChar('username', length: 255); + table.varChar('password', length: 255); + table.varChar('email', length: 255); + }); + } + + @override + void down(Schema schema) { + schema.drop('users', cascade: true); + } +} + +class RoleUserMigration extends Migration { + @override + void up(Schema schema) { + schema.create('role_users', (table) { + table.declare('role_id', ColumnType('int')).references('roles', 'id'); + table.declare('user_id', ColumnType('int')).references('users', 'id'); + }); + } + + @override + void down(Schema schema) { + schema.drop('role_users'); + } +} + +class RoleMigration extends Migration { + @override + void up(Schema schema) { + schema.create('roles', (table) { + table.serial('id').primaryKey(); + table.timeStamp('created_at'); + table.timeStamp('updated_at'); + table.varChar('name', length: 255); + }); + } + + @override + void down(Schema schema) { + schema.drop('roles', cascade: true); + } +} + +// ************************************************************************** +// OrmGenerator +// ************************************************************************** + +class UserQuery extends Query { + UserQuery({Query? parent, Set? trampoline}) : super(parent: parent) { + trampoline ??= {}; + trampoline.add(tableName); + _where = UserQueryWhere(this); + leftJoin( + '(SELECT role_users.user_id, roles.id, roles.created_at, roles.updated_at, roles.name FROM roles LEFT JOIN role_users ON role_users.role_id=roles.id)', + 'id', + 'user_id', + additionalFields: const ['id', 'created_at', 'updated_at', 'name'], + trampoline: trampoline); + } + + @override + final UserQueryValues values = UserQueryValues(); + + UserQueryWhere? _where; + + @override + Map get casts { + return {}; + } + + @override + String get tableName { + return 'users'; + } + + @override + List get fields { + return const [ + 'id', + 'created_at', + 'updated_at', + 'username', + 'password', + 'email' + ]; + } + + @override + UserQueryWhere? get where { + return _where; + } + + @override + UserQueryWhere newWhereClause() { + return UserQueryWhere(this); + } + + static Optional parseRow(List row) { + if (row.every((x) => x == null)) { + return Optional.empty(); + } + var model = User( + id: row[0].toString(), + createdAt: (row[1] as DateTime?), + updatedAt: (row[2] as DateTime?), + username: (row[3] as String?), + password: (row[4] as String?), + email: (row[5] as String?)); + if (row.length > 6) { + var modelOpt = RoleQuery.parseRow(row.skip(6).take(4).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(roles: [m]); + }); + } + return Optional.of(model); + } + + @override + Optional deserialize(List row) { + return parseRow(row); + } + + @override + bool canCompile(trampoline) { + return (!(trampoline.contains('users') && + trampoline.contains('role_users'))); + } + + @override + Future> get(QueryExecutor executor) { + return super.get(executor).then((result) { + return result.fold>([], (out, model) { + var idx = out.indexWhere((m) => m.id == model.id); + + if (idx == -1) { + return out..add(model); + } else { + var l = out[idx]; + return out + ..[idx] = l.copyWith( + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); + } + }); + }); + } + + @override + Future> update(QueryExecutor executor) { + return super.update(executor).then((result) { + return result.fold>([], (out, model) { + var idx = out.indexWhere((m) => m.id == model.id); + + if (idx == -1) { + return out..add(model); + } else { + var l = out[idx]; + return out + ..[idx] = l.copyWith( + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); + } + }); + }); + } + + @override + Future> delete(QueryExecutor executor) { + return super.delete(executor).then((result) { + return result.fold>([], (out, model) { + var idx = out.indexWhere((m) => m.id == model.id); + + if (idx == -1) { + return out..add(model); + } else { + var l = out[idx]; + return out + ..[idx] = l.copyWith( + roles: List<_Role>.from(l.roles ?? []) + ..addAll(model.roles ?? [])); + } + }); + }); + } +} + +class UserQueryWhere extends QueryWhere { + UserQueryWhere(UserQuery query) + : id = NumericSqlExpressionBuilder(query, 'id'), + createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'), + updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at'), + username = StringSqlExpressionBuilder(query, 'username'), + password = StringSqlExpressionBuilder(query, 'password'), + email = StringSqlExpressionBuilder(query, 'email'); + + final NumericSqlExpressionBuilder id; + + final DateTimeSqlExpressionBuilder createdAt; + + final DateTimeSqlExpressionBuilder updatedAt; + + final StringSqlExpressionBuilder username; + + final StringSqlExpressionBuilder password; + + final StringSqlExpressionBuilder email; + + @override + List get expressionBuilders { + return [id, createdAt, updatedAt, username, password, email]; + } +} + +class UserQueryValues extends MapQueryValues { + @override + Map get casts { + return {}; + } + + String? get id { + return (values['id'] as String?); + } + + set id(String? value) => values['id'] = value; + DateTime? get createdAt { + return (values['created_at'] as DateTime?); + } + + set createdAt(DateTime? value) => values['created_at'] = value; + DateTime? get updatedAt { + return (values['updated_at'] as DateTime?); + } + + set updatedAt(DateTime? value) => values['updated_at'] = value; + String? get username { + return (values['username'] as String?); + } + + set username(String? value) => values['username'] = value; + String? get password { + return (values['password'] as String?); + } + + set password(String? value) => values['password'] = value; + String? get email { + return (values['email'] as String?); + } + + set email(String? value) => values['email'] = value; + void copyFrom(User model) { + createdAt = model.createdAt; + updatedAt = model.updatedAt; + username = model.username; + password = model.password; + email = model.email; + } +} + +class RoleUserQuery extends Query { + RoleUserQuery({Query? parent, Set? trampoline}) + : super(parent: parent) { + trampoline ??= {}; + trampoline.add(tableName); + _where = RoleUserQueryWhere(this); + leftJoin(_role = RoleQuery(trampoline: trampoline, parent: this), 'role_id', + 'id', + additionalFields: const ['id', 'created_at', 'updated_at', 'name'], + trampoline: trampoline); + leftJoin(_user = UserQuery(trampoline: trampoline, parent: this), 'user_id', + 'id', + additionalFields: const [ + 'id', + 'created_at', + 'updated_at', + 'username', + 'password', + 'email' + ], + trampoline: trampoline); + } + + @override + final RoleUserQueryValues values = RoleUserQueryValues(); + + RoleUserQueryWhere? _where; + + late RoleQuery _role; + + late UserQuery _user; + + @override + Map get casts { + return {}; + } + + @override + String get tableName { + return 'role_users'; + } + + @override + List get fields { + return const ['role_id', 'user_id']; + } + + @override + RoleUserQueryWhere? get where { + return _where; + } + + @override + RoleUserQueryWhere newWhereClause() { + return RoleUserQueryWhere(this); + } + + static Optional parseRow(List row) { + if (row.every((x) => x == null)) { + return Optional.empty(); + } + var model = RoleUser(); + if (row.length > 2) { + var modelOpt = RoleQuery.parseRow(row.skip(2).take(4).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(role: m); + }); + } + if (row.length > 6) { + var modelOpt = UserQuery.parseRow(row.skip(6).take(6).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(user: m); + }); + } + return Optional.of(model); + } + + @override + Optional deserialize(List row) { + return parseRow(row); + } + + RoleQuery get role { + return _role; + } + + UserQuery get user { + return _user; + } +} + +class RoleUserQueryWhere extends QueryWhere { + RoleUserQueryWhere(RoleUserQuery query) + : roleId = NumericSqlExpressionBuilder(query, 'role_id'), + userId = NumericSqlExpressionBuilder(query, 'user_id'); + + final NumericSqlExpressionBuilder roleId; + + final NumericSqlExpressionBuilder userId; + + @override + List get expressionBuilders { + return [roleId, userId]; + } +} + +class RoleUserQueryValues extends MapQueryValues { + @override + Map get casts { + return {}; + } + + int get roleId { + return (values['role_id'] as int); + } + + set roleId(int value) => values['role_id'] = value; + int get userId { + return (values['user_id'] as int); + } + + set userId(int value) => values['user_id'] = value; + void copyFrom(RoleUser model) { + if (model.role != null) { + values['role_id'] = model.role?.id; + } + if (model.user != null) { + values['user_id'] = model.user?.id; + } + } +} + +class RoleQuery extends Query { + RoleQuery({Query? parent, Set? trampoline}) : super(parent: parent) { + trampoline ??= {}; + trampoline.add(tableName); + _where = RoleQueryWhere(this); + leftJoin( + '(SELECT role_users.role_id, users.id, users.created_at, users.updated_at, users.username, users.password, users.email FROM users LEFT JOIN role_users ON role_users.user_id=users.id)', + 'id', + 'role_id', + additionalFields: const [ + 'id', + 'created_at', + 'updated_at', + 'username', + 'password', + 'email' + ], + trampoline: trampoline); + } + + @override + final RoleQueryValues values = RoleQueryValues(); + + RoleQueryWhere? _where; + + @override + Map get casts { + return {}; + } + + @override + String get tableName { + return 'roles'; + } + + @override + List get fields { + return const ['id', 'created_at', 'updated_at', 'name']; + } + + @override + RoleQueryWhere? get where { + return _where; + } + + @override + RoleQueryWhere newWhereClause() { + return RoleQueryWhere(this); + } + + static Optional parseRow(List row) { + if (row.every((x) => x == null)) { + return Optional.empty(); + } + var model = Role( + id: row[0].toString(), + createdAt: (row[1] as DateTime?), + updatedAt: (row[2] as DateTime?), + name: (row[3] as String?)); + if (row.length > 4) { + var modelOpt = UserQuery.parseRow(row.skip(4).take(6).toList()); + modelOpt.ifPresent((m) { + model = model.copyWith(users: [m]); + }); + } + return Optional.of(model); + } + + @override + Optional deserialize(List row) { + return parseRow(row); + } + + @override + bool canCompile(trampoline) { + return (!(trampoline.contains('roles') && + trampoline.contains('role_users'))); + } + + @override + Future> get(QueryExecutor executor) { + return super.get(executor).then((result) { + return result.fold>([], (out, model) { + var idx = out.indexWhere((m) => m.id == model.id); + + if (idx == -1) { + return out..add(model); + } else { + var l = out[idx]; + return out + ..[idx] = l.copyWith( + users: List<_User>.from(l.users)..addAll(model.users)); + } + }); + }); + } + + @override + Future> update(QueryExecutor executor) { + return super.update(executor).then((result) { + return result.fold>([], (out, model) { + var idx = out.indexWhere((m) => m.id == model.id); + + if (idx == -1) { + return out..add(model); + } else { + var l = out[idx]; + return out + ..[idx] = l.copyWith( + users: List<_User>.from(l.users)..addAll(model.users)); + } + }); + }); + } + + @override + Future> delete(QueryExecutor executor) { + return super.delete(executor).then((result) { + return result.fold>([], (out, model) { + var idx = out.indexWhere((m) => m.id == model.id); + + if (idx == -1) { + return out..add(model); + } else { + var l = out[idx]; + return out + ..[idx] = l.copyWith( + users: List<_User>.from(l.users)..addAll(model.users)); + } + }); + }); + } +} + +class RoleQueryWhere extends QueryWhere { + RoleQueryWhere(RoleQuery query) + : id = NumericSqlExpressionBuilder(query, 'id'), + createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'), + updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at'), + name = StringSqlExpressionBuilder(query, 'name'); + + final NumericSqlExpressionBuilder id; + + final DateTimeSqlExpressionBuilder createdAt; + + final DateTimeSqlExpressionBuilder updatedAt; + + final StringSqlExpressionBuilder name; + + @override + List get expressionBuilders { + return [id, createdAt, updatedAt, name]; + } +} + +class RoleQueryValues extends MapQueryValues { + @override + Map get casts { + return {}; + } + + String? get id { + return (values['id'] as String?); + } + + set id(String? value) => values['id'] = value; + DateTime? get createdAt { + return (values['created_at'] as DateTime?); + } + + set createdAt(DateTime? value) => values['created_at'] = value; + DateTime? get updatedAt { + return (values['updated_at'] as DateTime?); + } + + set updatedAt(DateTime? value) => values['updated_at'] = value; + String? get name { + return (values['name'] as String?); + } + + set name(String? value) => values['name'] = value; + void copyFrom(Role model) { + createdAt = model.createdAt; + updatedAt = model.updatedAt; + name = model.name; + } +} + +// ************************************************************************** +// JsonModelGenerator +// ************************************************************************** + +@generatedSerializable +class User extends _User { + User( + {this.id, + this.createdAt, + this.updatedAt, + this.username, + this.password, + this.email, + List<_Role> roles = const []}) + : roles = List.unmodifiable(roles); + + /// A unique identifier corresponding to this item. + @override + String? id; + + /// The time at which this item was created. + @override + DateTime? createdAt; + + /// The last time at which this item was updated. + @override + DateTime? updatedAt; + + @override + String? username; + + @override + String? password; + + @override + String? email; + + @override + List<_Role> roles; + + User copyWith( + {String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? username, + String? password, + String? email, + List<_Role>? roles}) { + return User( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + username: username ?? this.username, + password: password ?? this.password, + email: email ?? this.email, + roles: roles ?? this.roles); + } + + @override + bool operator ==(other) { + return other is _User && + other.id == id && + other.createdAt == createdAt && + other.updatedAt == updatedAt && + other.username == username && + other.password == password && + other.email == email && + ListEquality<_Role>(DefaultEquality<_Role>()) + .equals(other.roles, roles); + } + + @override + int get hashCode { + return hashObjects( + [id, createdAt, updatedAt, username, password, email, roles]); + } + + @override + String toString() { + return 'User(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, username=$username, password=$password, email=$email, roles=$roles)'; + } + + Map toJson() { + return UserSerializer.toMap(this); + } +} + +@generatedSerializable +class RoleUser implements _RoleUser { + RoleUser({this.role, this.user}); + + @override + _Role? role; + + @override + _User? user; + + RoleUser copyWith({_Role? role, _User? user}) { + return RoleUser(role: role ?? this.role, user: user ?? this.user); + } + + @override + bool operator ==(other) { + return other is _RoleUser && other.role == role && other.user == user; + } + + @override + int get hashCode { + return hashObjects([role, user]); + } + + @override + String toString() { + return 'RoleUser(role=$role, user=$user)'; + } + + Map toJson() { + return RoleUserSerializer.toMap(this); + } +} + +@generatedSerializable +class Role extends _Role { + Role( + {this.id, + this.createdAt, + this.updatedAt, + this.name, + List<_User>? users = const []}) + : users = List.unmodifiable(users ?? []); + + /// A unique identifier corresponding to this item. + @override + String? id; + + /// The time at which this item was created. + @override + DateTime? createdAt; + + /// The last time at which this item was updated. + @override + DateTime? updatedAt; + + @override + String? name; + + @override + List<_User>? users; + + Role copyWith( + {String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? name, + List<_User>? users}) { + return Role( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + name: name ?? this.name, + users: users ?? this.users); + } + + @override + bool operator ==(other) { + return other is _Role && + other.id == id && + other.createdAt == createdAt && + other.updatedAt == updatedAt && + other.name == name && + ListEquality<_User>(DefaultEquality<_User>()) + .equals(other.users, users); + } + + @override + int get hashCode { + return hashObjects([id, createdAt, updatedAt, name, users]); + } + + @override + String toString() { + return 'Role(id=$id, createdAt=$createdAt, updatedAt=$updatedAt, name=$name, users=$users)'; + } + + Map toJson() { + return RoleSerializer.toMap(this); + } +} + +// ************************************************************************** +// SerializerGenerator +// ************************************************************************** + +const UserSerializer userSerializer = UserSerializer(); + +class UserEncoder extends Converter { + const UserEncoder(); + + @override + Map convert(User model) => UserSerializer.toMap(model); +} + +class UserDecoder extends Converter { + const UserDecoder(); + + @override + User convert(Map map) => UserSerializer.fromMap(map); +} + +class UserSerializer extends Codec { + const UserSerializer(); + + @override + UserEncoder get encoder => const UserEncoder(); + @override + UserDecoder get decoder => const UserDecoder(); + static User fromMap(Map map) { + return User( + id: map['id'] as String?, + createdAt: map['created_at'] != null + ? (map['created_at'] is DateTime + ? (map['created_at'] as DateTime) + : DateTime.parse(map['created_at'].toString())) + : null, + updatedAt: map['updated_at'] != null + ? (map['updated_at'] is DateTime + ? (map['updated_at'] as DateTime) + : DateTime.parse(map['updated_at'].toString())) + : null, + username: map['username'] as String?, + password: map['password'] as String?, + email: map['email'] as String?, + roles: map['roles'] is Iterable + ? List.unmodifiable(((map['roles'] as Iterable).whereType()) + .map(RoleSerializer.fromMap)) + : []); + } + + static Map toMap(_User? model) { + if (model == null) { + return {}; + } + return { + 'id': model.id, + 'created_at': model.createdAt?.toIso8601String(), + 'updated_at': model.updatedAt?.toIso8601String(), + 'username': model.username, + 'password': model.password, + 'email': model.email, + 'roles': model.roles.map((m) => RoleSerializer.toMap(m)).toList() + }; + } +} + +abstract class UserFields { + static const List allFields = [ + id, + createdAt, + updatedAt, + username, + password, + email, + roles + ]; + + static const String id = 'id'; + + static const String createdAt = 'created_at'; + + static const String updatedAt = 'updated_at'; + + static const String username = 'username'; + + static const String password = 'password'; + + static const String email = 'email'; + + static const String roles = 'roles'; +} + +const RoleUserSerializer roleUserSerializer = RoleUserSerializer(); + +class RoleUserEncoder extends Converter { + const RoleUserEncoder(); + + @override + Map convert(RoleUser model) => RoleUserSerializer.toMap(model); +} + +class RoleUserDecoder extends Converter { + const RoleUserDecoder(); + + @override + RoleUser convert(Map map) => RoleUserSerializer.fromMap(map); +} + +class RoleUserSerializer extends Codec { + const RoleUserSerializer(); + + @override + RoleUserEncoder get encoder => const RoleUserEncoder(); + @override + RoleUserDecoder get decoder => const RoleUserDecoder(); + static RoleUser fromMap(Map map) { + return RoleUser( + role: map['role'] != null + ? RoleSerializer.fromMap(map['role'] as Map) + : null, + user: map['user'] != null + ? UserSerializer.fromMap(map['user'] as Map) + : null); + } + + static Map toMap(_RoleUser? model) { + if (model == null) { + return {}; + } + return { + 'role': RoleSerializer.toMap(model.role), + 'user': UserSerializer.toMap(model.user) + }; + } +} + +abstract class RoleUserFields { + static const List allFields = [role, user]; + + static const String role = 'role'; + + static const String user = 'user'; +} + +const RoleSerializer roleSerializer = RoleSerializer(); + +class RoleEncoder extends Converter { + const RoleEncoder(); + + @override + Map convert(Role model) => RoleSerializer.toMap(model); +} + +class RoleDecoder extends Converter { + const RoleDecoder(); + + @override + Role convert(Map map) => RoleSerializer.fromMap(map); +} + +class RoleSerializer extends Codec { + const RoleSerializer(); + + @override + RoleEncoder get encoder => const RoleEncoder(); + @override + RoleDecoder get decoder => const RoleDecoder(); + static Role fromMap(Map map) { + return Role( + id: map['id'] as String?, + createdAt: map['created_at'] != null + ? (map['created_at'] is DateTime + ? (map['created_at'] as DateTime) + : DateTime.parse(map['created_at'].toString())) + : null, + updatedAt: map['updated_at'] != null + ? (map['updated_at'] is DateTime + ? (map['updated_at'] as DateTime) + : DateTime.parse(map['updated_at'].toString())) + : null, + name: map['name'] as String?, + users: map['users'] is Iterable + ? List.unmodifiable(((map['users'] as Iterable).whereType()) + .map(UserSerializer.fromMap)) + : []); + } + + static Map toMap(_Role? model) { + if (model == null) { + return {}; + } + return { + 'id': model.id, + 'created_at': model.createdAt?.toIso8601String(), + 'updated_at': model.updatedAt?.toIso8601String(), + 'name': model.name, + 'users': model.users?.map((m) => UserSerializer.toMap(m)).toList() + }; + } +} + +abstract class RoleFields { + static const List allFields = [ + id, + createdAt, + updatedAt, + name, + users + ]; + + static const String id = 'id'; + + static const String createdAt = 'created_at'; + + static const String updatedAt = 'updated_at'; + + static const String name = 'name'; + + static const String users = 'users'; +} diff --git a/packages/orm/orm_builder/lib/src/util.dart b/packages/orm/orm_builder/lib/src/util.dart new file mode 100644 index 00000000..897050af --- /dev/null +++ b/packages/orm/orm_builder/lib/src/util.dart @@ -0,0 +1,12 @@ +import 'dart:io'; +import 'package:io/ansi.dart'; + +void printSeparator(String title) { + var b = StringBuffer('===' + title.toUpperCase()); + for (var i = b.length; i < stdout.terminalColumns - 3; i++) { + b.write('='); + } + for (var i = 0; i < 3; i++) { + print(magenta.wrap(b.toString())); + } +} diff --git a/packages/orm/orm_builder/pubspec.yaml b/packages/orm/orm_builder/pubspec.yaml new file mode 100644 index 00000000..d54b2bbe --- /dev/null +++ b/packages/orm/orm_builder/pubspec.yaml @@ -0,0 +1,31 @@ +name: orm_builder +version: 1.0.0 +description: ORM Builder Testing +published_to: none +environment: + sdk: '>=2.12.0 <3.0.0' +dependencies: + angel3_migration: ^4.0.0 + angel3_model: ^3.1.0 + angel3_orm: ^4.0.0 + angel3_serialize: ^4.1.0 + io: ^1.0.0 + test: ^1.17.4 + collection: ^1.15.0 + optional: ^6.0.0 +dev_dependencies: + angel3_orm_generator: ^4.1.0 + angel3_framework: ^4.2.0 + build_runner: ^2.0.1 + lints: ^1.0.0 +dependency_overrides: +# angel3_migration_runner: +# path: ../angel_migration_runner + angel3_orm: + path: ../angel_orm + angel3_migration: + path: ../angel_migration + angel3_orm_generator: + path: ../angel_orm_generator + angel3_serialize: + path: ../../serialize/angel_serialize