diff --git a/angel_orm/CHANGELOG.md b/angel_orm/CHANGELOG.md index f3c6674c..428d192f 100644 --- a/angel_orm/CHANGELOG.md +++ b/angel_orm/CHANGELOG.md @@ -1,3 +1,6 @@ +# 2.0.0-dev.6 +* Add `delete`, `insert` and `update` methods to `Query`. + # 2.0.0-dev.4 * Add more querying methods. * Add preamble to `Query.compile`. diff --git a/angel_orm/example/main.dart b/angel_orm/example/main.dart index a857d41c..be3c28ad 100644 --- a/angel_orm/example/main.dart +++ b/angel_orm/example/main.dart @@ -39,6 +39,9 @@ abstract class _Employee extends Model { } class EmployeeQuery extends Query { + @override + final QueryValues values = new MapQueryValues(); + @override final EmployeeQueryWhere where = new EmployeeQueryWhere(); diff --git a/angel_orm/lib/angel_orm.dart b/angel_orm/lib/angel_orm.dart index 3ba225e9..b7931d80 100644 --- a/angel_orm/lib/angel_orm.dart +++ b/angel_orm/lib/angel_orm.dart @@ -2,4 +2,4 @@ export 'src/annotations.dart'; export 'src/builder.dart'; export 'src/migration.dart'; export 'src/relations.dart'; -export 'src/query.dart'; \ No newline at end of file +export 'src/query.dart'; diff --git a/angel_orm/lib/src/migration.dart b/angel_orm/lib/src/migration.dart index d3b50736..d34d8e0e 100644 --- a/angel_orm/lib/src/migration.dart +++ b/angel_orm/lib/src/migration.dart @@ -40,7 +40,8 @@ class Column { class PrimaryKey extends Column { const PrimaryKey({ColumnType columnType}) : super( - type: columnType ?? ColumnType.serial, indexType: IndexType.primaryKey); + type: columnType ?? ColumnType.serial, + indexType: IndexType.primaryKey); } const Column primaryKey = const PrimaryKey(); diff --git a/angel_orm/lib/src/query.dart b/angel_orm/lib/src/query.dart index bd235313..38b9e589 100644 --- a/angel_orm/lib/src/query.dart +++ b/angel_orm/lib/src/query.dart @@ -9,6 +9,9 @@ abstract class QueryBase { /// If it's `null`, then this query will perform a `SELECT *`. List get fields; + /// A String of all [fields], joined by a comma (`,`). + String get fieldSet => fields.join(', '); + String compile({bool includeTableName: false, String preamble}); T deserialize(List row); @@ -42,6 +45,21 @@ class OrderBy { String compile() => descending ? '$key DESC' : '$key ASC'; } +String toSql(Object obj) { + if (obj is DateTime) { + return dateYmdHms.format(obj); + } else if (obj is bool) { + return obj ? 'TRUE' : 'FALSE'; + } else if (obj == null) { + return 'NULL'; + } else if (obj is String) { + // TODO: Proper escapes + return obj; + } else { + return obj.toString(); + } +} + /// A SQL `SELECT` query builder. abstract class Query extends QueryBase { final List _orderBy = []; @@ -54,9 +72,14 @@ abstract class Query extends QueryBase { /// A reference to an abstract query builder. /// - /// This is often a generated class. + /// This is usually a generated class. Where get where; + /// A set of values, for an insertion or update. + /// + /// This is usually a generated class. + QueryValues get values; + /// Makes a new [Where] clause. Where newWhereClause() { throw new UnsupportedError( @@ -168,6 +191,12 @@ abstract class Query extends QueryBase { return b.toString(); } + @override + Future getOne(QueryExecutor executor) { + limit(1); + return super.getOne(executor); + } + Future> delete(QueryExecutor executor) async { var sql = compile(preamble: 'DELETE FROM $tableName'); return executor @@ -176,8 +205,88 @@ abstract class Query extends QueryBase { } Future deleteOne(QueryExecutor executor) { + limit(1); return delete(executor).then((it) => it.isEmpty ? null : it.first); } + + Future insert(QueryExecutor executor) { + var sql = new StringBuffer('INSERT INTO $tableName ($fieldSet)'); + var valuesClause = values.compileForInsert(); + + if (valuesClause == null) { + throw new StateError('No values have been specified for update.'); + } else { + sql.write(' $valuesClause'); + return executor + .query(sql.toString(), fields) + .then((it) => it.isEmpty ? null : deserialize(it.first)); + } + } + + Future> update(QueryExecutor executor) async { + var sql = new StringBuffer('UPDATE $tableName'); + var valuesClause = values.compileForUpdate(); + + if (valuesClause == null) { + throw new StateError('No values have been specified for update.'); + } else { + sql.write(' $valuesClause'); + var whereClause = where.compile(); + if (whereClause.isNotEmpty) sql.write(' WHERE $whereClause'); + if (_limit != null) sql.write(' LIMIT $_limit'); + return executor + .query(sql.toString(), fields) + .then((it) => it.map(deserialize).toList()); + } + } + + Future updateOne(QueryExecutor executor) { + limit(1); + return update(executor).then((it) => it.isEmpty ? null : it.first); + } +} + +abstract class QueryValues { + Map toMap(); + + String compileForInsert() { + var data = toMap(); + if (data.isEmpty) return null; + var b = new StringBuffer('VALUES ('); + int i = 0; + + for (var entry in data.entries) { + if (i++ > 0) b.write(', '); + b.write(toSql(entry.value)); + } + + b.write(')'); + return b.toString(); + } + + String compileForUpdate() { + var data = toMap(); + if (data.isEmpty) return null; + var b = new StringBuffer('SET'); + int i = 0; + + for (var entry in data.entries) { + if (i++ > 0) b.write(','); + b.write(' '); + b.write(entry.key); + b.write('='); + b.write(toSql(entry.value)); + } + return b.toString(); + } +} + +/// A [QueryValues] implementation that simply writes to a [Map]. +class MapQueryValues extends QueryValues { + final Map values = {}; + + @override + Map toMap() => values; } /// Builds a SQL `WHERE` clause. diff --git a/angel_orm/pubspec.yaml b/angel_orm/pubspec.yaml index a19546dd..5021ed1b 100644 --- a/angel_orm/pubspec.yaml +++ b/angel_orm/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_orm -version: 2.0.0-dev.5 +version: 2.0.0-dev.6 description: Runtime support for Angel's ORM. author: Tobe O homepage: https://github.com/angel-dart/orm diff --git a/angel_orm_generator/build.yaml b/angel_orm_generator/build.yaml index cc8cac74..41b9c97e 100644 --- a/angel_orm_generator/build.yaml +++ b/angel_orm_generator/build.yaml @@ -10,3 +10,21 @@ builders: - ".angel_orm.g.part" applies_builders: ["source_gen|combining_builder", "source_gen|part_cleanup"] +targets: + _standalone: + sources: + - test/models/author.dart + - test/models/car.dart + - test/models/customer.dart + - test/models/foot.dart + - test/models/fruit.dart + - test/models/role.dart + $default: + dependencies: + - :_standalone + sources: + - test/models/book.dart + - test/models/leg.dart + - test/models/order.dart + - test/models/tree.dart + - test/models/user.dart \ No newline at end of file diff --git a/angel_orm_generator/lib/angel_orm_generator.dart b/angel_orm_generator/lib/angel_orm_generator.dart index a9d1dca9..3774cb96 100644 --- a/angel_orm_generator/lib/angel_orm_generator.dart +++ b/angel_orm_generator/lib/angel_orm_generator.dart @@ -1,4 +1,4 @@ //export 'src/mongodb_orm_generator.dart'; export 'src/orm_build_context.dart'; export 'src/orm_generator.dart'; -export 'src/readers.dart'; \ No newline at end of file +export 'src/readers.dart'; diff --git a/angel_orm_generator/lib/src/orm_generator.dart b/angel_orm_generator/lib/src/orm_generator.dart index 85824d4f..a2713f35 100644 --- a/angel_orm_generator/lib/src/orm_generator.dart +++ b/angel_orm_generator/lib/src/orm_generator.dart @@ -86,10 +86,8 @@ class OrmGenerator extends GeneratorForAnnotation { ..annotations.add(refer('override')) ..type = MethodType.getter ..body = new Block((b) { - var names = ctx.buildContext.fields - .map((f) => literalString(f.name)) - .toList(); - b.addExpression(literalConstList(names).returned); + b.addExpression( + refer('${rc.pascalCase}Fields').property('allFields').returned); }); })); @@ -116,8 +114,16 @@ class OrmGenerator extends GeneratorForAnnotation { var args = {}; for (var field in ctx.buildContext.fields) { - var type = convertTypeReference(field.type); - args[field.name] = (refer('row').index(literalNum(i))).asA(type); + Reference type = convertTypeReference(field.type); + if (isSpecialId(field)) type = refer('int'); + + var expr = (refer('row').index(literalNum(i++))); + if (isSpecialId(field)) + expr = expr.property('toString').call([]); + else + expr = expr.asA(type); + + args[field.name] = expr; } b.addExpression( @@ -127,6 +133,10 @@ class OrmGenerator extends GeneratorForAnnotation { }); } + bool isSpecialId(FieldElement field) { + return (field.name == 'id' && autoIdAndDateFields); + } + Class buildWhereClass(OrmBuildContext ctx) { return new Class((clazz) { var rc = ctx.buildContext.modelClassNameRecase; @@ -151,7 +161,14 @@ class OrmGenerator extends GeneratorForAnnotation { // TODO: Handle fields with relations Reference builderType; - if (const TypeChecker.fromRuntime(String).isExactlyType(field.type)) { + if (const TypeChecker.fromRuntime(int).isExactlyType(field.type) || + const TypeChecker.fromRuntime(double).isExactlyType(field.type) || + isSpecialId(field)) { + builderType = new TypeReference((b) => b + ..symbol = 'NumericSqlExpressionBuilder' + ..types.add(refer(isSpecialId(field) ? 'int' : field.type.name))); + } else if (const TypeChecker.fromRuntime(String) + .isExactlyType(field.type)) { builderType = refer('StringSqlExpressionBuilder'); } else if (const TypeChecker.fromRuntime(bool) .isExactlyType(field.type)) { @@ -159,12 +176,6 @@ class OrmGenerator extends GeneratorForAnnotation { } else if (const TypeChecker.fromRuntime(DateTime) .isExactlyType(field.type)) { builderType = refer('DateTimeSqlExpressionBuilder'); - } else if (const TypeChecker.fromRuntime(int) - .isExactlyType(field.type) || - const TypeChecker.fromRuntime(double).isExactlyType(field.type)) { - builderType = new TypeReference((b) => b - ..symbol = 'NumericSqlExpressionBuilder' - ..types.add(refer(field.type.name))); } else { throw new UnsupportedError( 'Cannot generate ORM code for field of type ${field.type.name}.'); diff --git a/angel_orm_generator/pubspec.yaml b/angel_orm_generator/pubspec.yaml index ccba3d07..1b3ae2d6 100644 --- a/angel_orm_generator/pubspec.yaml +++ b/angel_orm_generator/pubspec.yaml @@ -24,5 +24,6 @@ dev_dependencies: #angel_migration: ^1.0.0-alpha #angel_test: ^1.0.0 build_runner: ^1.0.0 + collection: ^1.0.0 postgres: ^1.0.0 test: ^1.0.0 diff --git a/angel_orm_generator/test/belongs_to_test.dart b/angel_orm_generator/test/belongs_to_test.dart index f6d090e4..da942ee7 100644 --- a/angel_orm_generator/test/belongs_to_test.dart +++ b/angel_orm_generator/test/belongs_to_test.dart @@ -1,16 +1,13 @@ /// Tests for @belongsTo... library angel_orm_generator.test.book_test; -import 'package:postgres/postgres.dart'; import 'package:test/test.dart'; import 'models/author.dart'; -import 'models/author.orm.g.dart'; import 'models/book.dart'; -import 'models/book.orm.g.dart'; import 'common.dart'; main() { - PostgreSQLConnection connection; + PostgresExecutor connection; Author rowling; Author jameson; Book deathlyHallows; @@ -24,13 +21,14 @@ main() { // And a book deathlyHallows = await BookQuery.insert(connection, - authorId: int.parse(rowling.id), name: 'Deathly Hallows', partnerAuthorId: int.parse(jameson.id)); + authorId: int.parse(rowling.id), + name: 'Deathly Hallows', + partnerAuthorId: int.parse(jameson.id)); }); tearDown(() => connection.close()); - group('selects', () - { + group('selects', () { test('select all', () async { var query = new BookQuery(); var books = await query.get(connection).toList(); @@ -52,8 +50,8 @@ main() { query.where.id.equals(int.parse(deathlyHallows.id)); print(query.toSql()); - var book = await BookQuery.getOne( - int.parse(deathlyHallows.id), connection); + var book = + await BookQuery.getOne(int.parse(deathlyHallows.id), connection); print(book.toJson()); expect(book.id, deathlyHallows.id); expect(book.name, deathlyHallows.name); @@ -85,10 +83,8 @@ main() { }); test('union', () async { - var query1 = new BookQuery() - ..where.name.like('Deathly%'); - var query2 = new BookQuery() - ..where.authorId.equals(-1); + var query1 = new BookQuery()..where.name.like('Deathly%'); + var query2 = new BookQuery()..where.authorId.equals(-1); var query3 = new BookQuery() ..where.name.isIn(['Goblet of Fire', 'Order of the Phoenix']); query1 diff --git a/angel_orm_generator/test/common.dart b/angel_orm_generator/test/common.dart index 306c57f0..ebcd5353 100644 --- a/angel_orm_generator/test/common.dart +++ b/angel_orm_generator/test/common.dart @@ -1,8 +1,9 @@ import 'dart:async'; import 'dart:io'; +import 'package:angel_orm/angel_orm.dart'; import 'package:postgres/postgres.dart'; -Future connectToPostgres(Iterable schemas) async { +Future connectToPostgres(Iterable schemas) async { var conn = new PostgreSQLConnection('127.0.0.1', 5432, 'angel_orm_test', username: Platform.environment['POSTGRES_USERNAME'] ?? 'postgres', password: Platform.environment['POSTGRES_PASSWORD'] ?? 'password'); @@ -12,5 +13,20 @@ Future connectToPostgres(Iterable schemas) async { await conn .execute(await new File('test/models/$s.up.g.sql').readAsString()); - return conn; + return new PostgresExecutor(conn); +} + +class PostgresExecutor extends QueryExecutor { + final PostgreSQLConnection connection; + + PostgresExecutor(this.connection); + + Future close() => connection.close(); + + @override + Future> query(String query, List returningFields) { + var fields = returningFields.join(', '); + var returning = 'RETURNING ($fields)'; + return connection.query('$query $returning'); + } } diff --git a/angel_orm_generator/test/example/car_controller.dart b/angel_orm_generator/test/example/car_controller.dart index 0919e30a..063491f5 100644 --- a/angel_orm_generator/test/example/car_controller.dart +++ b/angel_orm_generator/test/example/car_controller.dart @@ -1,13 +1,12 @@ import 'dart:async'; import 'package:angel_framework/angel_framework.dart'; -import 'package:postgres/postgres.dart'; +import 'package:angel_orm/angel_orm.dart'; import '../models/car.dart'; -import '../models/car.orm.g.dart'; @Expose('/api/cars') class CarController extends Controller { @Expose('/luxury') - Stream getLuxuryCars(PostgreSQLConnection connection) { + Future> getLuxuryCars(QueryExecutor connection) { var query = new CarQuery(); query.where ..familyFriendly.equals(false) diff --git a/angel_orm_generator/test/has_one_test.dart b/angel_orm_generator/test/has_one_test.dart index 2494c063..02e916eb 100644 --- a/angel_orm_generator/test/has_one_test.dart +++ b/angel_orm_generator/test/has_one_test.dart @@ -1,7 +1,7 @@ /// Tests for @hasOne... library angel_orm_generator.test.has_one_test; -import 'package:postgres/postgres.dart'; +import 'package:angel_orm/angel_orm.dart'; import 'package:test/test.dart'; import 'models/foot.orm.g.dart'; import 'models/leg.dart'; @@ -9,7 +9,7 @@ import 'models/leg.orm.g.dart'; import 'common.dart'; main() { - PostgreSQLConnection connection; + QueryExecutor connection; Leg originalLeg; setUp(() async { diff --git a/angel_orm_generator/test/models/author.g.dart b/angel_orm_generator/test/models/author.g.dart index 6111e407..3de90385 100644 --- a/angel_orm_generator/test/models/author.g.dart +++ b/angel_orm_generator/test/models/author.g.dart @@ -17,21 +17,22 @@ class AuthorQuery extends Query { @override get fields { - return const ['id', 'name', 'createdAt', 'updatedAt']; + return AuthorFields.allFields; } @override deserialize(List row) { return new Author( - id: (row[0] as String), - name: (row[0] as String), - createdAt: (row[0] as DateTime), - updatedAt: (row[0] as DateTime)); + id: row[0].toString(), + name: (row[1] as String), + createdAt: (row[2] as DateTime), + updatedAt: (row[3] as DateTime)); } } class AuthorQueryWhere extends QueryWhere { - final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id'); + final NumericSqlExpressionBuilder id = + new NumericSqlExpressionBuilder('id'); final StringSqlExpressionBuilder name = new StringSqlExpressionBuilder('name'); diff --git a/angel_orm_generator/test/models/author.orm.g.dart b/angel_orm_generator/test/models/author.orm.g.dart deleted file mode 100644 index 757f8223..00000000 --- a/angel_orm_generator/test/models/author.orm.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -import 'author.dart'; -import 'dart:async'; -import 'package:postgres/postgres.dart'; -part 'author.postgresql.orm.g.dart'; - -abstract class AuthorOrm { - factory AuthorOrm.postgreSql(PostgreSQLConnection connection) = - PostgreSqlAuthorOrm; - - Future> getAll(); - Future getById(String id); - Future deleteById(String id); - Future createAuthor(Author model); - Future updateAuthor(Author model); - AuthorQuery query(); -} - -class AuthorQuery {} diff --git a/angel_orm_generator/test/models/author.postgresql.orm.g.dart b/angel_orm_generator/test/models/author.postgresql.orm.g.dart deleted file mode 100644 index f9b04d22..00000000 --- a/angel_orm_generator/test/models/author.postgresql.orm.g.dart +++ /dev/null @@ -1,77 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -part of 'author.orm.g.dart'; - -class PostgreSqlAuthorOrm implements AuthorOrm { - PostgreSqlAuthorOrm(this.connection); - - final PostgreSQLConnection connection; - - static Author parseRow(List row) { - return new Author( - id: (row[0] as String), - name: (row[1] as String), - createdAt: (row[2] as DateTime), - updatedAt: (row[3] as DateTime)); - } - - @override - Future getById(String id) async { - var r = await connection.query( - 'SELECT id, name, created_at, updated_at FROM "authors" WHERE id = @id LIMIT 1;', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future deleteById(String id) async { - var r = await connection.query( - 'DELETE FROM "authors" WHERE id = @id RETURNING "id", "name", "created_at", "updated_at";', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future> getAll() async { - var r = await connection - .query('SELECT id, name, created_at, updated_at FROM "authors";'); - return r.map(parseRow).toList(); - } - - @override - Future createAuthor(Author model) async { - model = model.copyWith( - createdAt: new DateTime.now(), updatedAt: new DateTime.now()); - var r = await connection.query( - 'INSERT INTO "authors" ( "id", "name", "created_at", "updated_at") VALUES (@id,@name,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "name", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'name': model.name, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - @override - Future updateAuthor(Author model) async { - model = model.copyWith(updatedAt: new DateTime.now()); - var r = await connection.query( - 'UPDATE "authors" SET ( "id", "name", "created_at", "updated_at") = (@id,@name,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "name", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'name': model.name, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - AuthorQuery query() { - return null; - } -} diff --git a/angel_orm_generator/test/models/book.g.dart b/angel_orm_generator/test/models/book.g.dart index e9f59c6f..affb5339 100644 --- a/angel_orm_generator/test/models/book.g.dart +++ b/angel_orm_generator/test/models/book.g.dart @@ -21,10 +21,10 @@ class Book extends _Book { final String id; @override - final dynamic author; + final Author author; @override - final dynamic partnerAuthor; + final Author partnerAuthor; @override final int authorId; @@ -40,8 +40,8 @@ class Book extends _Book { Book copyWith( {String id, - dynamic author, - dynamic partnerAuthor, + Author author, + Author partnerAuthor, int authorId, String name, DateTime createdAt, diff --git a/angel_orm_generator/test/models/book.orm.g.dart b/angel_orm_generator/test/models/book.orm.g.dart deleted file mode 100644 index 80e27846..00000000 --- a/angel_orm_generator/test/models/book.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "author" with type "Author". diff --git a/angel_orm_generator/test/models/book.postgresql.orm.g.dart b/angel_orm_generator/test/models/book.postgresql.orm.g.dart deleted file mode 100644 index f62dfee3..00000000 --- a/angel_orm_generator/test/models/book.postgresql.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "author" with type "Author". diff --git a/angel_orm_generator/test/models/book.serializer.g.dart b/angel_orm_generator/test/models/book.serializer.g.dart index 1fd8e599..1e34c2d8 100644 --- a/angel_orm_generator/test/models/book.serializer.g.dart +++ b/angel_orm_generator/test/models/book.serializer.g.dart @@ -10,8 +10,12 @@ abstract class BookSerializer { static Book fromMap(Map map) { return new Book( id: map['id'] as String, - author: map['author'] as dynamic, - partnerAuthor: map['partner_author'] as dynamic, + author: map['author'] != null + ? AuthorSerializer.fromMap(map['author'] as Map) + : null, + partnerAuthor: map['partner_author'] != null + ? AuthorSerializer.fromMap(map['partner_author'] as Map) + : null, authorId: map['author_id'] as int, name: map['name'] as String, createdAt: map['created_at'] != null @@ -32,8 +36,8 @@ abstract class BookSerializer { } return { 'id': model.id, - 'author': model.author, - 'partner_author': model.partnerAuthor, + 'author': AuthorSerializer.toMap(model.author), + 'partner_author': AuthorSerializer.toMap(model.partnerAuthor), 'author_id': model.authorId, 'name': model.name, 'created_at': model.createdAt?.toIso8601String(), diff --git a/angel_orm_generator/test/models/car.g.dart b/angel_orm_generator/test/models/car.g.dart index 021a386d..61d33adb 100644 --- a/angel_orm_generator/test/models/car.g.dart +++ b/angel_orm_generator/test/models/car.g.dart @@ -17,32 +17,25 @@ class CarQuery extends Query { @override get fields { - return const [ - 'id', - 'make', - 'description', - 'familyFriendly', - 'recalledAt', - 'createdAt', - 'updatedAt' - ]; + return CarFields.allFields; } @override deserialize(List row) { return new Car( - id: (row[0] as String), - make: (row[0] as String), - description: (row[0] as String), - familyFriendly: (row[0] as bool), - recalledAt: (row[0] as DateTime), - createdAt: (row[0] as DateTime), - updatedAt: (row[0] as DateTime)); + id: row[0].toString(), + make: (row[1] as String), + description: (row[2] as String), + familyFriendly: (row[3] as bool), + recalledAt: (row[4] as DateTime), + createdAt: (row[5] as DateTime), + updatedAt: (row[6] as DateTime)); } } class CarQueryWhere extends QueryWhere { - final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id'); + final NumericSqlExpressionBuilder id = + new NumericSqlExpressionBuilder('id'); final StringSqlExpressionBuilder make = new StringSqlExpressionBuilder('make'); diff --git a/angel_orm_generator/test/models/car.orm.g.dart b/angel_orm_generator/test/models/car.orm.g.dart deleted file mode 100644 index 3a5a96bc..00000000 --- a/angel_orm_generator/test/models/car.orm.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -import 'car.dart'; -import 'dart:async'; -import 'package:postgres/postgres.dart'; -part 'car.postgresql.orm.g.dart'; - -abstract class CarOrm { - factory CarOrm.postgreSql(PostgreSQLConnection connection) = PostgreSqlCarOrm; - - Future> getAll(); - Future getById(String id); - Future deleteById(String id); - Future createCar(Car model); - Future updateCar(Car model); - CarQuery query(); -} - -class CarQuery {} diff --git a/angel_orm_generator/test/models/car.postgresql.orm.g.dart b/angel_orm_generator/test/models/car.postgresql.orm.g.dart deleted file mode 100644 index 128f44ae..00000000 --- a/angel_orm_generator/test/models/car.postgresql.orm.g.dart +++ /dev/null @@ -1,86 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -part of 'car.orm.g.dart'; - -class PostgreSqlCarOrm implements CarOrm { - PostgreSqlCarOrm(this.connection); - - final PostgreSQLConnection connection; - - static Car parseRow(List row) { - return new Car( - id: (row[0] as String), - make: (row[1] as String), - description: (row[2] as String), - familyFriendly: (row[3] as bool), - recalledAt: (row[4] as DateTime), - createdAt: (row[5] as DateTime), - updatedAt: (row[6] as DateTime)); - } - - @override - Future getById(String id) async { - var r = await connection.query( - 'SELECT id, make, description, family_friendly, recalled_at, created_at, updated_at FROM "cars" WHERE id = @id LIMIT 1;', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future deleteById(String id) async { - var r = await connection.query( - 'DELETE FROM "cars" WHERE id = @id RETURNING "id", "make", "description", "family_friendly", "recalled_at", "created_at", "updated_at";', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future> getAll() async { - var r = await connection.query( - 'SELECT id, make, description, family_friendly, recalled_at, created_at, updated_at FROM "cars";'); - return r.map(parseRow).toList(); - } - - @override - Future createCar(Car model) async { - model = model.copyWith( - createdAt: new DateTime.now(), updatedAt: new DateTime.now()); - var r = await connection.query( - 'INSERT INTO "cars" ( "id", "make", "description", "family_friendly", "recalled_at", "created_at", "updated_at") VALUES (@id,@make,@description,@familyFriendly,CAST (@recalledAt AS timestamp),CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "make", "description", "family_friendly", "recalled_at", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'make': model.make, - 'description': model.description, - 'familyFriendly': model.familyFriendly, - 'recalledAt': model.recalledAt, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - @override - Future updateCar(Car model) async { - model = model.copyWith(updatedAt: new DateTime.now()); - var r = await connection.query( - 'UPDATE "cars" SET ( "id", "make", "description", "family_friendly", "recalled_at", "created_at", "updated_at") = (@id,@make,@description,@familyFriendly,CAST (@recalledAt AS timestamp),CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "make", "description", "family_friendly", "recalled_at", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'make': model.make, - 'description': model.description, - 'familyFriendly': model.familyFriendly, - 'recalledAt': model.recalledAt, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - CarQuery query() { - return null; - } -} diff --git a/angel_orm_generator/test/models/customer.dart b/angel_orm_generator/test/models/customer.dart index 0808bdfa..1852b590 100644 --- a/angel_orm_generator/test/models/customer.dart +++ b/angel_orm_generator/test/models/customer.dart @@ -8,5 +8,4 @@ part 'customer.serializer.g.dart'; @orm @serializable -class _Customer extends Model { -} \ No newline at end of file +class _Customer extends Model {} diff --git a/angel_orm_generator/test/models/customer.g.dart b/angel_orm_generator/test/models/customer.g.dart index c97ac796..07958111 100644 --- a/angel_orm_generator/test/models/customer.g.dart +++ b/angel_orm_generator/test/models/customer.g.dart @@ -17,20 +17,21 @@ class CustomerQuery extends Query { @override get fields { - return const ['id', 'createdAt', 'updatedAt']; + return CustomerFields.allFields; } @override deserialize(List row) { return new Customer( - id: (row[0] as String), - createdAt: (row[0] as DateTime), - updatedAt: (row[0] as DateTime)); + id: row[0].toString(), + createdAt: (row[1] as DateTime), + updatedAt: (row[2] as DateTime)); } } class CustomerQueryWhere extends QueryWhere { - final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id'); + final NumericSqlExpressionBuilder id = + new NumericSqlExpressionBuilder('id'); final DateTimeSqlExpressionBuilder createdAt = new DateTimeSqlExpressionBuilder('created_at'); diff --git a/angel_orm_generator/test/models/customer.orm.g.dart b/angel_orm_generator/test/models/customer.orm.g.dart deleted file mode 100644 index 26136da0..00000000 --- a/angel_orm_generator/test/models/customer.orm.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -import 'customer.dart'; -import 'dart:async'; -import 'package:postgres/postgres.dart'; -part 'customer.postgresql.orm.g.dart'; - -abstract class CustomerOrm { - factory CustomerOrm.postgreSql(PostgreSQLConnection connection) = - PostgreSqlCustomerOrm; - - Future> getAll(); - Future getById(String id); - Future deleteById(String id); - Future createCustomer(Customer model); - Future updateCustomer(Customer model); - CustomerQuery query(); -} - -class CustomerQuery {} diff --git a/angel_orm_generator/test/models/customer.postgresql.orm.g.dart b/angel_orm_generator/test/models/customer.postgresql.orm.g.dart deleted file mode 100644 index f7174a0c..00000000 --- a/angel_orm_generator/test/models/customer.postgresql.orm.g.dart +++ /dev/null @@ -1,74 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -part of 'customer.orm.g.dart'; - -class PostgreSqlCustomerOrm implements CustomerOrm { - PostgreSqlCustomerOrm(this.connection); - - final PostgreSQLConnection connection; - - static Customer parseRow(List row) { - return new Customer( - id: (row[0] as String), - createdAt: (row[1] as DateTime), - updatedAt: (row[2] as DateTime)); - } - - @override - Future getById(String id) async { - var r = await connection.query( - 'SELECT id, created_at, updated_at FROM "customers" WHERE id = @id LIMIT 1;', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future deleteById(String id) async { - var r = await connection.query( - 'DELETE FROM "customers" WHERE id = @id RETURNING "id", "created_at", "updated_at";', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future> getAll() async { - var r = await connection - .query('SELECT id, created_at, updated_at FROM "customers";'); - return r.map(parseRow).toList(); - } - - @override - Future createCustomer(Customer model) async { - model = model.copyWith( - createdAt: new DateTime.now(), updatedAt: new DateTime.now()); - var r = await connection.query( - 'INSERT INTO "customers" ( "id", "created_at", "updated_at") VALUES (@id,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - @override - Future updateCustomer(Customer model) async { - model = model.copyWith(updatedAt: new DateTime.now()); - var r = await connection.query( - 'UPDATE "customers" SET ( "id", "created_at", "updated_at") = (@id,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - CustomerQuery query() { - return null; - } -} diff --git a/angel_orm_generator/test/models/foot.dart b/angel_orm_generator/test/models/foot.dart index 39c57947..d25d6489 100644 --- a/angel_orm_generator/test/models/foot.dart +++ b/angel_orm_generator/test/models/foot.dart @@ -10,4 +10,4 @@ part 'foot.serializer.g.dart'; @orm class _Foot extends Model { int legId, nToes; -} \ No newline at end of file +} diff --git a/angel_orm_generator/test/models/foot.g.dart b/angel_orm_generator/test/models/foot.g.dart index e7f01d0a..0ec36497 100644 --- a/angel_orm_generator/test/models/foot.g.dart +++ b/angel_orm_generator/test/models/foot.g.dart @@ -17,22 +17,23 @@ class FootQuery extends Query { @override get fields { - return const ['id', 'legId', 'nToes', 'createdAt', 'updatedAt']; + return FootFields.allFields; } @override deserialize(List row) { return new Foot( - id: (row[0] as String), - legId: (row[0] as int), - nToes: (row[0] as int), - createdAt: (row[0] as DateTime), - updatedAt: (row[0] as DateTime)); + id: row[0].toString(), + legId: (row[1] as int), + nToes: (row[2] as int), + createdAt: (row[3] as DateTime), + updatedAt: (row[4] as DateTime)); } } class FootQueryWhere extends QueryWhere { - final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id'); + final NumericSqlExpressionBuilder id = + new NumericSqlExpressionBuilder('id'); final NumericSqlExpressionBuilder legId = new NumericSqlExpressionBuilder('leg_id'); diff --git a/angel_orm_generator/test/models/foot.orm.g.dart b/angel_orm_generator/test/models/foot.orm.g.dart deleted file mode 100644 index bd3b456c..00000000 --- a/angel_orm_generator/test/models/foot.orm.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -import 'dart:async'; -import 'foot.dart'; -import 'package:postgres/postgres.dart'; -part 'foot.postgresql.orm.g.dart'; - -abstract class FootOrm { - factory FootOrm.postgreSql(PostgreSQLConnection connection) = - PostgreSqlFootOrm; - - Future> getAll(); - Future getById(String id); - Future deleteById(String id); - Future createFoot(Foot model); - Future updateFoot(Foot model); - FootQuery query(); -} - -class FootQuery {} diff --git a/angel_orm_generator/test/models/foot.postgresql.orm.g.dart b/angel_orm_generator/test/models/foot.postgresql.orm.g.dart deleted file mode 100644 index 40579c51..00000000 --- a/angel_orm_generator/test/models/foot.postgresql.orm.g.dart +++ /dev/null @@ -1,80 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -part of 'foot.orm.g.dart'; - -class PostgreSqlFootOrm implements FootOrm { - PostgreSqlFootOrm(this.connection); - - final PostgreSQLConnection connection; - - static Foot parseRow(List row) { - return new Foot( - id: (row[0] as String), - legId: (row[1] as int), - nToes: (row[2] as int), - createdAt: (row[3] as DateTime), - updatedAt: (row[4] as DateTime)); - } - - @override - Future getById(String id) async { - var r = await connection.query( - 'SELECT id, leg_id, n_toes, created_at, updated_at FROM "foots" WHERE id = @id LIMIT 1;', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future deleteById(String id) async { - var r = await connection.query( - 'DELETE FROM "foots" WHERE id = @id RETURNING "id", "leg_id", "n_toes", "created_at", "updated_at";', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future> getAll() async { - var r = await connection.query( - 'SELECT id, leg_id, n_toes, created_at, updated_at FROM "foots";'); - return r.map(parseRow).toList(); - } - - @override - Future createFoot(Foot model) async { - model = model.copyWith( - createdAt: new DateTime.now(), updatedAt: new DateTime.now()); - var r = await connection.query( - 'INSERT INTO "foots" ( "id", "leg_id", "n_toes", "created_at", "updated_at") VALUES (@id,@legId,@nToes,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "leg_id", "n_toes", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'legId': model.legId, - 'nToes': model.nToes, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - @override - Future updateFoot(Foot model) async { - model = model.copyWith(updatedAt: new DateTime.now()); - var r = await connection.query( - 'UPDATE "foots" SET ( "id", "leg_id", "n_toes", "created_at", "updated_at") = (@id,@legId,@nToes,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "leg_id", "n_toes", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'legId': model.legId, - 'nToes': model.nToes, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - FootQuery query() { - return null; - } -} diff --git a/angel_orm_generator/test/models/fruit.dart b/angel_orm_generator/test/models/fruit.dart index 3af538ed..1bd9bce5 100644 --- a/angel_orm_generator/test/models/fruit.dart +++ b/angel_orm_generator/test/models/fruit.dart @@ -11,4 +11,4 @@ part 'fruit.serializer.g.dart'; class _Fruit extends Model { int treeId; String commonName; -} \ No newline at end of file +} diff --git a/angel_orm_generator/test/models/fruit.g.dart b/angel_orm_generator/test/models/fruit.g.dart index 613bb016..45159c4f 100644 --- a/angel_orm_generator/test/models/fruit.g.dart +++ b/angel_orm_generator/test/models/fruit.g.dart @@ -17,22 +17,23 @@ class FruitQuery extends Query { @override get fields { - return const ['id', 'treeId', 'commonName', 'createdAt', 'updatedAt']; + return FruitFields.allFields; } @override deserialize(List row) { return new Fruit( - id: (row[0] as String), - treeId: (row[0] as int), - commonName: (row[0] as String), - createdAt: (row[0] as DateTime), - updatedAt: (row[0] as DateTime)); + id: row[0].toString(), + treeId: (row[1] as int), + commonName: (row[2] as String), + createdAt: (row[3] as DateTime), + updatedAt: (row[4] as DateTime)); } } class FruitQueryWhere extends QueryWhere { - final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id'); + final NumericSqlExpressionBuilder id = + new NumericSqlExpressionBuilder('id'); final NumericSqlExpressionBuilder treeId = new NumericSqlExpressionBuilder('tree_id'); diff --git a/angel_orm_generator/test/models/fruit.orm.g.dart b/angel_orm_generator/test/models/fruit.orm.g.dart deleted file mode 100644 index 6ca4a8d6..00000000 --- a/angel_orm_generator/test/models/fruit.orm.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -import 'dart:async'; -import 'fruit.dart'; -import 'package:postgres/postgres.dart'; -part 'fruit.postgresql.orm.g.dart'; - -abstract class FruitOrm { - factory FruitOrm.postgreSql(PostgreSQLConnection connection) = - PostgreSqlFruitOrm; - - Future> getAll(); - Future getById(String id); - Future deleteById(String id); - Future createFruit(Fruit model); - Future updateFruit(Fruit model); - FruitQuery query(); -} - -class FruitQuery {} diff --git a/angel_orm_generator/test/models/fruit.postgresql.orm.g.dart b/angel_orm_generator/test/models/fruit.postgresql.orm.g.dart deleted file mode 100644 index fc9b9621..00000000 --- a/angel_orm_generator/test/models/fruit.postgresql.orm.g.dart +++ /dev/null @@ -1,80 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -part of 'fruit.orm.g.dart'; - -class PostgreSqlFruitOrm implements FruitOrm { - PostgreSqlFruitOrm(this.connection); - - final PostgreSQLConnection connection; - - static Fruit parseRow(List row) { - return new Fruit( - id: (row[0] as String), - treeId: (row[1] as int), - commonName: (row[2] as String), - createdAt: (row[3] as DateTime), - updatedAt: (row[4] as DateTime)); - } - - @override - Future getById(String id) async { - var r = await connection.query( - 'SELECT id, tree_id, common_name, created_at, updated_at FROM "fruits" WHERE id = @id LIMIT 1;', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future deleteById(String id) async { - var r = await connection.query( - 'DELETE FROM "fruits" WHERE id = @id RETURNING "id", "tree_id", "common_name", "created_at", "updated_at";', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future> getAll() async { - var r = await connection.query( - 'SELECT id, tree_id, common_name, created_at, updated_at FROM "fruits";'); - return r.map(parseRow).toList(); - } - - @override - Future createFruit(Fruit model) async { - model = model.copyWith( - createdAt: new DateTime.now(), updatedAt: new DateTime.now()); - var r = await connection.query( - 'INSERT INTO "fruits" ( "id", "tree_id", "common_name", "created_at", "updated_at") VALUES (@id,@treeId,@commonName,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "tree_id", "common_name", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'treeId': model.treeId, - 'commonName': model.commonName, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - @override - Future updateFruit(Fruit model) async { - model = model.copyWith(updatedAt: new DateTime.now()); - var r = await connection.query( - 'UPDATE "fruits" SET ( "id", "tree_id", "common_name", "created_at", "updated_at") = (@id,@treeId,@commonName,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "tree_id", "common_name", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'treeId': model.treeId, - 'commonName': model.commonName, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - FruitQuery query() { - return null; - } -} diff --git a/angel_orm_generator/test/models/leg.dart b/angel_orm_generator/test/models/leg.dart index 365fa357..7b86ae32 100644 --- a/angel_orm_generator/test/models/leg.dart +++ b/angel_orm_generator/test/models/leg.dart @@ -14,4 +14,4 @@ class _Leg extends Model { Foot foot; String name; -} \ No newline at end of file +} diff --git a/angel_orm_generator/test/models/leg.g.dart b/angel_orm_generator/test/models/leg.g.dart index 0d7916d6..a7b52302 100644 --- a/angel_orm_generator/test/models/leg.g.dart +++ b/angel_orm_generator/test/models/leg.g.dart @@ -14,7 +14,7 @@ class Leg extends _Leg { final String id; @override - final dynamic foot; + final Foot foot; @override final String name; @@ -27,7 +27,7 @@ class Leg extends _Leg { Leg copyWith( {String id, - dynamic foot, + Foot foot, String name, DateTime createdAt, DateTime updatedAt}) { diff --git a/angel_orm_generator/test/models/leg.orm.g.dart b/angel_orm_generator/test/models/leg.orm.g.dart deleted file mode 100644 index 92e118f3..00000000 --- a/angel_orm_generator/test/models/leg.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "foot" with type "Foot". diff --git a/angel_orm_generator/test/models/leg.postgresql.orm.g.dart b/angel_orm_generator/test/models/leg.postgresql.orm.g.dart deleted file mode 100644 index 34839103..00000000 --- a/angel_orm_generator/test/models/leg.postgresql.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "foot" with type "Foot". diff --git a/angel_orm_generator/test/models/leg.serializer.g.dart b/angel_orm_generator/test/models/leg.serializer.g.dart index 8f2c0732..2707e671 100644 --- a/angel_orm_generator/test/models/leg.serializer.g.dart +++ b/angel_orm_generator/test/models/leg.serializer.g.dart @@ -10,7 +10,9 @@ abstract class LegSerializer { static Leg fromMap(Map map) { return new Leg( id: map['id'] as String, - foot: map['foot'] as dynamic, + foot: map['foot'] != null + ? FootSerializer.fromMap(map['foot'] as Map) + : null, name: map['name'] as String, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime @@ -30,7 +32,7 @@ abstract class LegSerializer { } return { 'id': model.id, - 'foot': model.foot, + 'foot': FootSerializer.toMap(model.foot), 'name': model.name, 'created_at': model.createdAt?.toIso8601String(), 'updated_at': model.updatedAt?.toIso8601String() diff --git a/angel_orm_generator/test/models/order.g.dart b/angel_orm_generator/test/models/order.g.dart index 7c95f97b..7a8d030d 100644 --- a/angel_orm_generator/test/models/order.g.dart +++ b/angel_orm_generator/test/models/order.g.dart @@ -17,32 +17,25 @@ class OrderQuery extends Query { @override get fields { - return const [ - 'id', - 'customerId', - 'employeeId', - 'orderDate', - 'shipperId', - 'createdAt', - 'updatedAt' - ]; + return OrderFields.allFields; } @override deserialize(List row) { return new Order( - id: (row[0] as String), - customerId: (row[0] as int), - employeeId: (row[0] as int), - orderDate: (row[0] as DateTime), - shipperId: (row[0] as int), - createdAt: (row[0] as DateTime), - updatedAt: (row[0] as DateTime)); + id: row[0].toString(), + customerId: (row[1] as int), + employeeId: (row[2] as int), + orderDate: (row[3] as DateTime), + shipperId: (row[4] as int), + createdAt: (row[5] as DateTime), + updatedAt: (row[6] as DateTime)); } } class OrderQueryWhere extends QueryWhere { - final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id'); + final NumericSqlExpressionBuilder id = + new NumericSqlExpressionBuilder('id'); final NumericSqlExpressionBuilder customerId = new NumericSqlExpressionBuilder('customer_id'); diff --git a/angel_orm_generator/test/models/order.orm.g.dart b/angel_orm_generator/test/models/order.orm.g.dart deleted file mode 100644 index a12fd7a1..00000000 --- a/angel_orm_generator/test/models/order.orm.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -import 'dart:async'; -import 'order.dart'; -import 'package:postgres/postgres.dart'; -part 'order.postgresql.orm.g.dart'; - -abstract class OrderOrm { - factory OrderOrm.postgreSql(PostgreSQLConnection connection) = - PostgreSqlOrderOrm; - - Future> getAll(); - Future getById(String id); - Future deleteById(String id); - Future createOrder(Order model); - Future updateOrder(Order model); - OrderQuery query(); -} - -class OrderQuery {} diff --git a/angel_orm_generator/test/models/order.postgresql.orm.g.dart b/angel_orm_generator/test/models/order.postgresql.orm.g.dart deleted file mode 100644 index dcc8e569..00000000 --- a/angel_orm_generator/test/models/order.postgresql.orm.g.dart +++ /dev/null @@ -1,86 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -part of 'order.orm.g.dart'; - -class PostgreSqlOrderOrm implements OrderOrm { - PostgreSqlOrderOrm(this.connection); - - final PostgreSQLConnection connection; - - static Order parseRow(List row) { - return new Order( - id: (row[0] as String), - customerId: (row[1] as int), - employeeId: (row[2] as int), - orderDate: (row[3] as DateTime), - shipperId: (row[4] as int), - createdAt: (row[5] as DateTime), - updatedAt: (row[6] as DateTime)); - } - - @override - Future getById(String id) async { - var r = await connection.query( - 'SELECT id, customer_id, employee_id, order_date, shipper_id, created_at, updated_at FROM "orders" WHERE id = @id LIMIT 1;', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future deleteById(String id) async { - var r = await connection.query( - 'DELETE FROM "orders" WHERE id = @id RETURNING "id", "customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at";', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future> getAll() async { - var r = await connection.query( - 'SELECT id, customer_id, employee_id, order_date, shipper_id, created_at, updated_at FROM "orders";'); - return r.map(parseRow).toList(); - } - - @override - Future createOrder(Order model) async { - model = model.copyWith( - createdAt: new DateTime.now(), updatedAt: new DateTime.now()); - var r = await connection.query( - 'INSERT INTO "orders" ( "id", "customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at") VALUES (@id,@customerId,@employeeId,CAST (@orderDate AS timestamp),@shipperId,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'customerId': model.customerId, - 'employeeId': model.employeeId, - 'orderDate': model.orderDate, - 'shipperId': model.shipperId, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - @override - Future updateOrder(Order model) async { - model = model.copyWith(updatedAt: new DateTime.now()); - var r = await connection.query( - 'UPDATE "orders" SET ( "id", "customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at") = (@id,@customerId,@employeeId,CAST (@orderDate AS timestamp),@shipperId,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'customerId': model.customerId, - 'employeeId': model.employeeId, - 'orderDate': model.orderDate, - 'shipperId': model.shipperId, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - OrderQuery query() { - return null; - } -} diff --git a/angel_orm_generator/test/models/role.dart b/angel_orm_generator/test/models/role.dart index ae27ec7a..b68d32f6 100644 --- a/angel_orm_generator/test/models/role.dart +++ b/angel_orm_generator/test/models/role.dart @@ -10,4 +10,4 @@ part 'role.serializer.g.dart'; @orm class _Role extends Model { String name; -} \ No newline at end of file +} diff --git a/angel_orm_generator/test/models/role.g.dart b/angel_orm_generator/test/models/role.g.dart index a7f339df..5b9de74a 100644 --- a/angel_orm_generator/test/models/role.g.dart +++ b/angel_orm_generator/test/models/role.g.dart @@ -17,21 +17,22 @@ class RoleQuery extends Query { @override get fields { - return const ['id', 'name', 'createdAt', 'updatedAt']; + return RoleFields.allFields; } @override deserialize(List row) { return new Role( - id: (row[0] as String), - name: (row[0] as String), - createdAt: (row[0] as DateTime), - updatedAt: (row[0] as DateTime)); + id: row[0].toString(), + name: (row[1] as String), + createdAt: (row[2] as DateTime), + updatedAt: (row[3] as DateTime)); } } class RoleQueryWhere extends QueryWhere { - final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id'); + final NumericSqlExpressionBuilder id = + new NumericSqlExpressionBuilder('id'); final StringSqlExpressionBuilder name = new StringSqlExpressionBuilder('name'); diff --git a/angel_orm_generator/test/models/role.orm.g.dart b/angel_orm_generator/test/models/role.orm.g.dart deleted file mode 100644 index 3040e8d4..00000000 --- a/angel_orm_generator/test/models/role.orm.g.dart +++ /dev/null @@ -1,24 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -import 'dart:async'; -import 'package:postgres/postgres.dart'; -import 'role.dart'; -part 'role.postgresql.orm.g.dart'; - -abstract class RoleOrm { - factory RoleOrm.postgreSql(PostgreSQLConnection connection) = - PostgreSqlRoleOrm; - - Future> getAll(); - Future getById(String id); - Future deleteById(String id); - Future createRole(Role model); - Future updateRole(Role model); - RoleQuery query(); -} - -class RoleQuery {} diff --git a/angel_orm_generator/test/models/role.postgresql.orm.g.dart b/angel_orm_generator/test/models/role.postgresql.orm.g.dart deleted file mode 100644 index 9fe62351..00000000 --- a/angel_orm_generator/test/models/role.postgresql.orm.g.dart +++ /dev/null @@ -1,77 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -part of 'role.orm.g.dart'; - -class PostgreSqlRoleOrm implements RoleOrm { - PostgreSqlRoleOrm(this.connection); - - final PostgreSQLConnection connection; - - static Role parseRow(List row) { - return new Role( - id: (row[0] as String), - name: (row[1] as String), - createdAt: (row[2] as DateTime), - updatedAt: (row[3] as DateTime)); - } - - @override - Future getById(String id) async { - var r = await connection.query( - 'SELECT id, name, created_at, updated_at FROM "roles" WHERE id = @id LIMIT 1;', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future deleteById(String id) async { - var r = await connection.query( - 'DELETE FROM "roles" WHERE id = @id RETURNING "id", "name", "created_at", "updated_at";', - substitutionValues: {'id': int.parse(id)}); - return parseRow(r.first); - } - - @override - Future> getAll() async { - var r = await connection - .query('SELECT id, name, created_at, updated_at FROM "roles";'); - return r.map(parseRow).toList(); - } - - @override - Future createRole(Role model) async { - model = model.copyWith( - createdAt: new DateTime.now(), updatedAt: new DateTime.now()); - var r = await connection.query( - 'INSERT INTO "roles" ( "id", "name", "created_at", "updated_at") VALUES (@id,@name,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "name", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'name': model.name, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - @override - Future updateRole(Role model) async { - model = model.copyWith(updatedAt: new DateTime.now()); - var r = await connection.query( - 'UPDATE "roles" SET ( "id", "name", "created_at", "updated_at") = (@id,@name,CAST (@createdAt AS timestamp),CAST (@updatedAt AS timestamp)) RETURNING "id", "name", "created_at", "updated_at";', - substitutionValues: { - 'id': model.id, - 'name': model.name, - 'createdAt': model.createdAt, - 'updatedAt': model.updatedAt - }); - return parseRow(r.first); - } - - RoleQuery query() { - return null; - } -} diff --git a/angel_orm_generator/test/models/tree.g.dart b/angel_orm_generator/test/models/tree.g.dart index 5cf2a90a..4fd63935 100644 --- a/angel_orm_generator/test/models/tree.g.dart +++ b/angel_orm_generator/test/models/tree.g.dart @@ -9,11 +9,7 @@ part of angel_orm_generator.test.models.tree; @generatedSerializable class Tree extends _Tree { Tree( - {this.id, - this.rings, - List fruits, - this.createdAt, - this.updatedAt}) + {this.id, this.rings, List fruits, this.createdAt, this.updatedAt}) : this.fruits = new List.unmodifiable(fruits ?? []); @override @@ -23,7 +19,7 @@ class Tree extends _Tree { final int rings; @override - final List fruits; + final List fruits; @override final DateTime createdAt; @@ -34,7 +30,7 @@ class Tree extends _Tree { Tree copyWith( {String id, int rings, - List fruits, + List fruits, DateTime createdAt, DateTime updatedAt}) { return new Tree( @@ -49,7 +45,7 @@ class Tree extends _Tree { return other is _Tree && other.id == id && other.rings == rings && - const ListEquality(const DefaultEquality()) + const ListEquality(const DefaultEquality()) .equals(other.fruits, fruits) && other.createdAt == createdAt && other.updatedAt == updatedAt; diff --git a/angel_orm_generator/test/models/tree.orm.g.dart b/angel_orm_generator/test/models/tree.orm.g.dart deleted file mode 100644 index 61166847..00000000 --- a/angel_orm_generator/test/models/tree.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "fruits" with type "List". diff --git a/angel_orm_generator/test/models/tree.postgresql.orm.g.dart b/angel_orm_generator/test/models/tree.postgresql.orm.g.dart deleted file mode 100644 index d8da15ee..00000000 --- a/angel_orm_generator/test/models/tree.postgresql.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "fruits" with type "List". diff --git a/angel_orm_generator/test/models/tree.serializer.g.dart b/angel_orm_generator/test/models/tree.serializer.g.dart index bca42347..90211f04 100644 --- a/angel_orm_generator/test/models/tree.serializer.g.dart +++ b/angel_orm_generator/test/models/tree.serializer.g.dart @@ -11,7 +11,11 @@ abstract class TreeSerializer { return new Tree( id: map['id'] as String, rings: map['rings'] as int, - fruits: map['fruits'] as List, + fruits: map['fruits'] is Iterable + ? new List.unmodifiable(((map['fruits'] as Iterable) + .where((x) => x is Map) as Iterable) + .map(FruitSerializer.fromMap)) + : null, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime ? (map['created_at'] as DateTime) @@ -31,7 +35,7 @@ abstract class TreeSerializer { return { 'id': model.id, 'rings': model.rings, - 'fruits': model.fruits, + 'fruits': model.fruits?.map((m) => m.toJson())?.toList(), 'created_at': model.createdAt?.toIso8601String(), 'updated_at': model.updatedAt?.toIso8601String() }; diff --git a/angel_orm_generator/test/models/user.dart b/angel_orm_generator/test/models/user.dart index 7588cf62..22181c00 100644 --- a/angel_orm_generator/test/models/user.dart +++ b/angel_orm_generator/test/models/user.dart @@ -3,6 +3,7 @@ library angel_orm_generator.test.models.user; import 'package:angel_model/angel_model.dart'; import 'package:angel_orm/angel_orm.dart'; import 'package:angel_serialize/angel_serialize.dart'; +import 'package:collection/collection.dart'; import 'role.dart'; part 'user.g.dart'; part 'user.serializer.g.dart'; @@ -14,4 +15,4 @@ class _User extends Model { @belongsToMany List roles; -} \ No newline at end of file +} diff --git a/angel_orm_generator/test/models/user.g.dart b/angel_orm_generator/test/models/user.g.dart index ec880b55..584bbb45 100644 --- a/angel_orm_generator/test/models/user.g.dart +++ b/angel_orm_generator/test/models/user.g.dart @@ -13,7 +13,7 @@ class User extends _User { this.username, this.password, this.email, - List roles, + List roles, this.createdAt, this.updatedAt}) : this.roles = new List.unmodifiable(roles ?? []); @@ -31,7 +31,7 @@ class User extends _User { final String email; @override - final List roles; + final List roles; @override final DateTime createdAt; @@ -44,7 +44,7 @@ class User extends _User { String username, String password, String email, - List roles, + List roles, DateTime createdAt, DateTime updatedAt}) { return new User( @@ -63,7 +63,7 @@ class User extends _User { other.username == username && other.password == password && other.email == email && - const ListEquality(const DefaultEquality()) + const ListEquality(const DefaultEquality()) .equals(other.roles, roles) && other.createdAt == createdAt && other.updatedAt == updatedAt; diff --git a/angel_orm_generator/test/models/user.orm.g.dart b/angel_orm_generator/test/models/user.orm.g.dart deleted file mode 100644 index fd82a00f..00000000 --- a/angel_orm_generator/test/models/user.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// OrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "roles" with type "List". diff --git a/angel_orm_generator/test/models/user.postgresql.orm.g.dart b/angel_orm_generator/test/models/user.postgresql.orm.g.dart deleted file mode 100644 index 5c66fa10..00000000 --- a/angel_orm_generator/test/models/user.postgresql.orm.g.dart +++ /dev/null @@ -1,7 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// PostgreSqlOrmGenerator -// ************************************************************************** - -// Error: Cannot infer SQL column type for field "roles" with type "List". diff --git a/angel_orm_generator/test/models/user.serializer.g.dart b/angel_orm_generator/test/models/user.serializer.g.dart index f5bfa44d..7e5998fa 100644 --- a/angel_orm_generator/test/models/user.serializer.g.dart +++ b/angel_orm_generator/test/models/user.serializer.g.dart @@ -13,7 +13,11 @@ abstract class UserSerializer { username: map['username'] as String, password: map['password'] as String, email: map['email'] as String, - roles: map['roles'] as List, + roles: map['roles'] is Iterable + ? new List.unmodifiable(((map['roles'] as Iterable) + .where((x) => x is Map) as Iterable) + .map(RoleSerializer.fromMap)) + : null, createdAt: map['created_at'] != null ? (map['created_at'] is DateTime ? (map['created_at'] as DateTime) @@ -35,7 +39,7 @@ abstract class UserSerializer { 'username': model.username, 'password': model.password, 'email': model.email, - 'roles': model.roles, + 'roles': model.roles?.map((m) => m.toJson())?.toList(), 'created_at': model.createdAt?.toIso8601String(), 'updated_at': model.updatedAt?.toIso8601String() }; diff --git a/angel_orm_generator/test/standalone_test.dart b/angel_orm_generator/test/standalone_test.dart index 7114af5f..f0cf74bc 100644 --- a/angel_orm_generator/test/standalone_test.dart +++ b/angel_orm_generator/test/standalone_test.dart @@ -2,7 +2,6 @@ library angel_orm_generator.test.car_test; import 'package:angel_orm/angel_orm.dart'; -import 'package:postgres/postgres.dart'; import 'package:test/test.dart'; import 'models/car.dart'; import 'common.dart'; @@ -44,7 +43,7 @@ main() { }); group('queries', () { - PostgreSQLConnection connection; + PostgresExecutor connection; setUp(() async { connection = await connectToPostgres(['car']); @@ -52,7 +51,7 @@ main() { group('selects', () { test('select all', () async { - var cars = await CarQuery.getAll(connection); + var cars = await new CarQuery().get(connection); expect(cars, []); }); @@ -66,6 +65,8 @@ main() { familyFriendly: false); }); + tearDown(() => connection.close()); + test('where clause is applied', () async { var query = new CarQuery()..where.familyFriendly.equals(true); var cars = await query.get(connection); @@ -113,23 +114,29 @@ main() { }); test('get one', () async { - var car = await CarQuery.getOne(int.parse(ferrari.id), connection); - expect(car.toJson(), ferrari.toJson()); + var id = int.parse(ferrari.id); + var query = new CarQuery()..where.id.equals(id); + var car = await query.getOne(connection); + expect(car, ferrari); }); test('delete one', () async { - var car = await CarQuery.deleteOne(int.parse(ferrari.id), connection); + var id = int.parse(ferrari.id); + var query = new CarQuery()..where.id.equals(id); + var car = await query.deleteOne(connection); expect(car.toJson(), ferrari.toJson()); - var cars = await CarQuery.getAll(connection); + var cars = await new CarQuery().get(connection); expect(cars, isEmpty); }); test('delete stream', () async { - var query = new CarQuery()..where.make.equals('Ferrari'); - query.or(new CarQueryWhere()..familyFriendly.equals(true)); - print(query.compile('DELETE FROM "cars"')); - var cars = await query.delete(connection); + var query = new CarQuery() + ..where.make.equals('Ferrari') + ..orWhere((w) => w.familyFriendly.equals(true)); + + print(query.compile(preamble: 'DELETE FROM "cars"')); + var cars = await query.get(connection); expect(cars, hasLength(1)); expect(cars.first.toJson(), ferrari.toJson()); });