@hasOne Done
This commit is contained in:
parent
fa3ce3abc8
commit
62a4c15a2b
25 changed files with 850 additions and 93 deletions
.idea/runConfigurations
angel_orm_generator
lib/src/builder/postgres
pubspec.yamltest
belongs_to_many_test.dartbelongs_to_test.dartcommon.darthas_one_test.dart
models
author.orm.g.dartbook.orm.g.dartcar.orm.g.dartfoot.dartfoot.down.g.sqlfoot.g.dartfoot.orm.g.dartfoot.up.g.sqlleg.dartleg.down.g.sqlleg.g.dartleg.orm.g.dartleg.up.g.sqlrole.orm.g.dartuser.orm.g.dart
standalone_test.darttool
6
.idea/runConfigurations/tests_in_has_one_test.xml
Normal file
6
.idea/runConfigurations/tests_in_has_one_test.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="tests in has_one_test" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="leg" singleton="true">
|
||||||
|
<option name="filePath" value="$PROJECT_DIR$/angel_orm_generator/test/has_one_test.dart" />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
|
@ -35,11 +35,17 @@ class PostgresORMGenerator extends GeneratorForAnnotation<ORM> {
|
||||||
@override
|
@override
|
||||||
Future<String> generateForAnnotatedElement(
|
Future<String> generateForAnnotatedElement(
|
||||||
Element element, ORM annotation, BuildStep buildStep) async {
|
Element element, ORM annotation, BuildStep buildStep) async {
|
||||||
|
if (buildStep.inputId.path.contains('.orm.g.dart')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (element is! ClassElement)
|
if (element is! ClassElement)
|
||||||
throw 'Only classes can be annotated with @serializable.';
|
throw 'Only classes can be annotated with @ORM().';
|
||||||
var resolver = await buildStep.resolver;
|
var resolver = await buildStep.resolver;
|
||||||
return prettyToSource(
|
var lib =
|
||||||
generateOrmLibrary(element.library, resolver, buildStep).buildAst());
|
generateOrmLibrary(element.library, resolver, buildStep).buildAst();
|
||||||
|
if (lib == null) return null;
|
||||||
|
return prettyToSource(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibraryBuilder generateOrmLibrary(
|
LibraryBuilder generateOrmLibrary(
|
||||||
|
@ -91,6 +97,8 @@ class PostgresORMGenerator extends GeneratorForAnnotation<ORM> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (contexts.isEmpty) return null;
|
||||||
|
|
||||||
done.clear();
|
done.clear();
|
||||||
for (var element in contexts.keys) {
|
for (var element in contexts.keys) {
|
||||||
if (!done.contains(element.name)) {
|
if (!done.contains(element.name)) {
|
||||||
|
@ -252,12 +260,10 @@ class PostgresORMGenerator extends GeneratorForAnnotation<ORM> {
|
||||||
ctx.relationships.forEach((name, r) {
|
ctx.relationships.forEach((name, r) {
|
||||||
var relationship = ctx.populateRelationship(name);
|
var relationship = ctx.populateRelationship(name);
|
||||||
|
|
||||||
// TODO: Has one, has many
|
// TODO: Belongs to many, has many
|
||||||
if (relationship.isBelongsTo) {
|
if (relationship.isSingular) {
|
||||||
var b = new StringBuffer(
|
String b = ' LEFT OUTER JOIN ${relationship.foreignTable} ON ${ctx.tableName}.${relationship.localKey} = ${relationship.foreignTable}.${relationship.foreignKey}';
|
||||||
' INNER JOIN ${relationship.foreignTable} ON ${ctx.tableName}.${relationship.localKey} = ${relationship.foreignTable}.${relationship.foreignKey}');
|
relationsIfThen.addStatement(buf.invoke('write', [literal(b)]));
|
||||||
relationsIfThen
|
|
||||||
.addStatement(buf.invoke('write', [literal(b.toString())]));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -559,11 +565,8 @@ class PostgresORMGenerator extends GeneratorForAnnotation<ORM> {
|
||||||
meth.addStatement(varField('whereClause',
|
meth.addStatement(varField('whereClause',
|
||||||
value: reference('where').invoke('toWhereClause', [])));
|
value: reference('where').invoke('toWhereClause', [])));
|
||||||
|
|
||||||
meth.addStatement(ifThen(whereClause.equals(literal(null)), [
|
meth.addStatement(ifThen(whereClause.notEquals(literal(null)), [
|
||||||
$buf.invoke('write', [literal('WHERE "id" = @id')]),
|
$buf.invoke('write', [whereClause])
|
||||||
elseThen([
|
|
||||||
$buf.invoke('write', [whereClause])
|
|
||||||
])
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
var buf2 = new StringBuffer();
|
var buf2 = new StringBuffer();
|
||||||
|
@ -690,38 +693,37 @@ class PostgresORMGenerator extends GeneratorForAnnotation<ORM> {
|
||||||
void _applyRelationshipsToOutput(PostgresBuildContext ctx,
|
void _applyRelationshipsToOutput(PostgresBuildContext ctx,
|
||||||
ExpressionBuilder output, ExpressionBuilder row, MethodBuilder meth) {
|
ExpressionBuilder output, ExpressionBuilder row, MethodBuilder meth) {
|
||||||
// Every relationship should fill itself in with a query
|
// Every relationship should fill itself in with a query
|
||||||
// TODO: Has one, has many, belongs to many
|
|
||||||
ctx.relationships.forEach((name, r) {
|
ctx.relationships.forEach((name, r) {
|
||||||
var relationship = ctx.populateRelationship(name);
|
var relationship = ctx.populateRelationship(name);
|
||||||
|
|
||||||
if (relationship.isBelongsTo) {
|
var rc = new ReCase(relationship.isList
|
||||||
var rc = new ReCase(relationship.isList
|
? relationship.modelType.name
|
||||||
? relationship.modelType.name
|
: relationship.dartType.name);
|
||||||
: relationship.dartType.name);
|
var type = new TypeBuilder('${rc.pascalCase}Query');
|
||||||
var type = new TypeBuilder('${rc.pascalCase}Query');
|
|
||||||
|
|
||||||
// Resolve index within row...
|
// Resolve index within row...
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
for (var field in ctx.fields) {
|
for (var field in ctx.fields) {
|
||||||
if (field is RelationshipConstraintField &&
|
if (field is RelationshipConstraintField &&
|
||||||
field.originalName == name) {
|
field.originalName == name) {
|
||||||
matched = true;
|
matched = true;
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matched) {
|
if (!matched) {
|
||||||
matched = ctx.resolveRelationshipField(name) != null;
|
matched = ctx.resolveRelationshipField(name) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matched)
|
if (!matched)
|
||||||
throw 'Couldn\'t resolve row index for relationship "${name}".';
|
throw 'Couldn\'t resolve row index for relationship "${name}".';
|
||||||
|
|
||||||
var idAsInt = row[literal(col)];
|
var idAsInt = row[literal(col)];
|
||||||
|
|
||||||
if (relationship.isSingular) {
|
if (relationship.isSingular) {
|
||||||
|
if (relationship.isBelongsTo) {
|
||||||
meth.addStatement(type
|
meth.addStatement(type
|
||||||
.invoke('getOne', [idAsInt, reference('connection')])
|
.invoke('getOne', [idAsInt, reference('connection')])
|
||||||
.asAwait()
|
.asAwait()
|
||||||
|
@ -730,20 +732,38 @@ class PostgresORMGenerator extends GeneratorForAnnotation<ORM> {
|
||||||
var query = reference('${rc.camelCase}Query');
|
var query = reference('${rc.camelCase}Query');
|
||||||
meth.addStatement(
|
meth.addStatement(
|
||||||
varField('${rc.camelCase}Query', value: type.newInstance([])));
|
varField('${rc.camelCase}Query', value: type.newInstance([])));
|
||||||
ExpressionBuilder fetched;
|
// Set id to row[0]
|
||||||
|
meth.addStatement(query
|
||||||
// TODO: HasMany
|
.property('where')
|
||||||
if (relationship.isBelongsTo) {
|
.property('id')
|
||||||
meth.addStatement(query
|
.invoke('equals', [row[literal(0)]]));
|
||||||
.property('where')
|
var fetched = query
|
||||||
.property('id')
|
.invoke('get', [reference('connection')])
|
||||||
.invoke('equals', [idAsInt]));
|
.property('first')
|
||||||
fetched = query.invoke('get', [reference('connection')]).invoke(
|
.invoke('catchError', [
|
||||||
'toList', []).asAwait();
|
new MethodBuilder.closure(returns: literal(null))
|
||||||
}
|
..addPositional(parameter('_'))
|
||||||
|
])
|
||||||
meth.addStatement(output.property(name).invoke('addAll', [fetched]));
|
.asAwait();
|
||||||
|
meth.addStatement(fetched.asAssign(output.property(name)));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
var query = reference('${rc.camelCase}Query');
|
||||||
|
meth.addStatement(
|
||||||
|
varField('${rc.camelCase}Query', value: type.newInstance([])));
|
||||||
|
ExpressionBuilder fetched;
|
||||||
|
|
||||||
|
// TODO: HasMany
|
||||||
|
if (relationship.isBelongsTo) {
|
||||||
|
meth.addStatement(query
|
||||||
|
.property('where')
|
||||||
|
.property('id')
|
||||||
|
.invoke('equals', [idAsInt]));
|
||||||
|
fetched = query.invoke('get', [reference('connection')]).invoke(
|
||||||
|
'toList', []).asAwait();
|
||||||
|
}
|
||||||
|
|
||||||
|
meth.addStatement(output.property(name).invoke('addAll', [fetched]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,11 +109,12 @@ class PostgresBuildContext extends BuildContext {
|
||||||
|
|
||||||
if (relationship.type == RelationshipType.HAS_ONE ||
|
if (relationship.type == RelationshipType.HAS_ONE ||
|
||||||
relationship.type == RelationshipType.HAS_MANY) {
|
relationship.type == RelationshipType.HAS_MANY) {
|
||||||
var foreignKey = relationship.localKey ??
|
var single = singularize(tableName);
|
||||||
|
var foreignKey = relationship.foreignTable ??
|
||||||
(autoSnakeCaseNames != false
|
(autoSnakeCaseNames != false
|
||||||
? '${rc.snakeCase}_id'
|
? '${single}_id'
|
||||||
: '${typeName}Id');
|
: '${single}Id');
|
||||||
var localKey = relationship.foreignKey ?? 'id';
|
var localKey = relationship.localKey ?? 'id';
|
||||||
var foreignTable = relationship.foreignTable ??
|
var foreignTable = relationship.foreignTable ??
|
||||||
(autoSnakeCaseNames != false
|
(autoSnakeCaseNames != false
|
||||||
? pluralize(rc.snakeCase)
|
? pluralize(rc.snakeCase)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_orm_generator
|
name: angel_orm_generator
|
||||||
version: 1.0.0-alpha+2
|
version: 1.0.0-alpha+3
|
||||||
description: Code generators for Angel's ORM.
|
description: Code generators for Angel's ORM.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/orm
|
homepage: https://github.com/angel-dart/orm
|
||||||
|
|
|
@ -12,7 +12,7 @@ main() {
|
||||||
User john;
|
User john;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
connection = await connectToPostgres();
|
connection = await connectToPostgres(['user', 'role']);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,7 @@ main() {
|
||||||
Book deathlyHallows;
|
Book deathlyHallows;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
connection = await connectToPostgres();
|
connection = await connectToPostgres(['author', 'book']);
|
||||||
|
|
||||||
// Insert an author
|
// Insert an author
|
||||||
rowling = await AuthorQuery.insert(connection, name: 'J.K. Rowling');
|
rowling = await AuthorQuery.insert(connection, name: 'J.K. Rowling');
|
||||||
|
|
|
@ -2,22 +2,15 @@ import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:postgres/postgres.dart';
|
import 'package:postgres/postgres.dart';
|
||||||
|
|
||||||
Future<PostgreSQLConnection> connectToPostgres() async {
|
Future<PostgreSQLConnection> connectToPostgres(Iterable<String> schemas) async {
|
||||||
var conn = new PostgreSQLConnection('127.0.0.1', 5432, 'angel_orm_test',
|
var conn = new PostgreSQLConnection('127.0.0.1', 5432, 'angel_orm_test',
|
||||||
username: Platform.environment['POSTGRES_USERNAME'] ?? 'postgres',
|
username: Platform.environment['POSTGRES_USERNAME'] ?? 'postgres',
|
||||||
password: Platform.environment['POSTGRES_PASSWORD'] ?? 'password');
|
password: Platform.environment['POSTGRES_PASSWORD'] ?? 'password');
|
||||||
await conn.open();
|
await conn.open();
|
||||||
|
|
||||||
var query = await new File('test/models/car.up.g.sql').readAsString();
|
for (var s in schemas)
|
||||||
await conn.execute(query);
|
await conn
|
||||||
query = await new File('test/models/author.up.g.sql').readAsString();
|
.execute(await new File('test/models/$s.up.g.sql').readAsString());
|
||||||
await conn.execute(query);
|
|
||||||
query = await new File('test/models/book.up.g.sql').readAsString();
|
|
||||||
await conn.execute(query);
|
|
||||||
query = await new File('test/models/role.up.g.sql').readAsString();
|
|
||||||
await conn.execute(query);
|
|
||||||
query = await new File('test/models/user.up.g.sql').readAsString();
|
|
||||||
await conn.execute(query);
|
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
73
angel_orm_generator/test/has_one_test.dart
Normal file
73
angel_orm_generator/test/has_one_test.dart
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/// Tests for @hasOne...
|
||||||
|
library angel_orm_generator.test.has_one_test;
|
||||||
|
|
||||||
|
import 'package:postgres/postgres.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'models/foot.orm.g.dart';
|
||||||
|
import 'models/leg.dart';
|
||||||
|
import 'models/leg.orm.g.dart';
|
||||||
|
import 'common.dart';
|
||||||
|
|
||||||
|
main() {
|
||||||
|
PostgreSQLConnection connection;
|
||||||
|
Leg originalLeg;
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
connection = await connectToPostgres(['leg', 'foot']);
|
||||||
|
originalLeg = await LegQuery.insert(connection, name: 'Left');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sets to null if no child', () async {
|
||||||
|
var leg = await LegQuery.getOne(int.parse(originalLeg.id), connection);
|
||||||
|
expect(leg.name, originalLeg.name);
|
||||||
|
expect(leg.id, originalLeg.id);
|
||||||
|
expect(leg.foot, isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('can fetch one foot', () async {
|
||||||
|
var foot = await FootQuery.insert(connection,
|
||||||
|
legId: int.parse(originalLeg.id), nToes: 5);
|
||||||
|
var leg = await LegQuery.getOne(int.parse(originalLeg.id), connection);
|
||||||
|
expect(leg.name, originalLeg.name);
|
||||||
|
expect(leg.id, originalLeg.id);
|
||||||
|
expect(leg.foot, isNotNull);
|
||||||
|
expect(leg.foot.id, foot.id);
|
||||||
|
expect(leg.foot.nToes, foot.nToes);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('only fetches one foot even if there are multiple', () async {
|
||||||
|
var foot = await FootQuery.insert(connection,
|
||||||
|
legId: int.parse(originalLeg.id), nToes: 5);
|
||||||
|
await FootQuery.insert(connection,
|
||||||
|
legId: int.parse(originalLeg.id), nToes: 24);
|
||||||
|
var leg = await LegQuery.getOne(int.parse(originalLeg.id), connection);
|
||||||
|
expect(leg.name, originalLeg.name);
|
||||||
|
expect(leg.id, originalLeg.id);
|
||||||
|
expect(leg.foot, isNotNull);
|
||||||
|
expect(leg.foot.id, foot.id);
|
||||||
|
expect(leg.foot.nToes, foot.nToes);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sets foot on update', () async {
|
||||||
|
var foot = await FootQuery.insert(connection,
|
||||||
|
legId: int.parse(originalLeg.id), nToes: 5);
|
||||||
|
var leg = await LegQuery.updateLeg(
|
||||||
|
connection, originalLeg.clone()..name = 'Right');
|
||||||
|
print(leg.toJson());
|
||||||
|
expect(leg.name, 'Right');
|
||||||
|
expect(leg.foot, isNotNull);
|
||||||
|
expect(leg.foot.id, foot.id);
|
||||||
|
expect(leg.foot.nToes, foot.nToes);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sets foot on delete', () async {
|
||||||
|
var foot = await FootQuery.insert(connection,
|
||||||
|
legId: int.parse(originalLeg.id), nToes: 5);
|
||||||
|
var leg = await LegQuery.deleteOne(int.parse(originalLeg.id), connection);
|
||||||
|
print(leg.toJson());
|
||||||
|
expect(leg.name, originalLeg.name);
|
||||||
|
expect(leg.foot, isNotNull);
|
||||||
|
expect(leg.foot.id, foot.id);
|
||||||
|
expect(leg.foot.nToes, foot.nToes);
|
||||||
|
});
|
||||||
|
}
|
|
@ -125,9 +125,7 @@ class AuthorQuery {
|
||||||
var buf = new StringBuffer(
|
var buf = new StringBuffer(
|
||||||
'UPDATE "authors" SET ("name", "created_at", "updated_at") = (@name, @createdAt, @updatedAt) ');
|
'UPDATE "authors" SET ("name", "created_at", "updated_at") = (@name, @createdAt, @updatedAt) ');
|
||||||
var whereClause = where.toWhereClause();
|
var whereClause = where.toWhereClause();
|
||||||
if (whereClause == null) {
|
if (whereClause != null) {
|
||||||
buf.write('WHERE "id" = @id');
|
|
||||||
} else {
|
|
||||||
buf.write(whereClause);
|
buf.write(whereClause);
|
||||||
}
|
}
|
||||||
var __ormNow__ = new DateTime.now();
|
var __ormNow__ = new DateTime.now();
|
||||||
|
|
|
@ -54,7 +54,7 @@ class BookQuery {
|
||||||
? prefix
|
? prefix
|
||||||
: 'SELECT books.id, books.name, books.created_at, books.updated_at, books.author_id, authors.id, authors.name, authors.created_at, authors.updated_at FROM "books"');
|
: 'SELECT books.id, books.name, books.created_at, books.updated_at, books.author_id, authors.id, authors.name, authors.created_at, authors.updated_at FROM "books"');
|
||||||
if (prefix == null) {
|
if (prefix == null) {
|
||||||
buf.write(' INNER JOIN authors ON books.author_id = authors.id');
|
buf.write(' LEFT OUTER JOIN authors ON books.author_id = authors.id');
|
||||||
}
|
}
|
||||||
var whereClause = where.toWhereClause();
|
var whereClause = where.toWhereClause();
|
||||||
if (whereClause != null) {
|
if (whereClause != null) {
|
||||||
|
@ -133,9 +133,7 @@ class BookQuery {
|
||||||
var buf = new StringBuffer(
|
var buf = new StringBuffer(
|
||||||
'UPDATE "books" SET ("name", "created_at", "updated_at", "author_id") = (@name, @createdAt, @updatedAt, @authorId) ');
|
'UPDATE "books" SET ("name", "created_at", "updated_at", "author_id") = (@name, @createdAt, @updatedAt, @authorId) ');
|
||||||
var whereClause = where.toWhereClause();
|
var whereClause = where.toWhereClause();
|
||||||
if (whereClause == null) {
|
if (whereClause != null) {
|
||||||
buf.write('WHERE "id" = @id');
|
|
||||||
} else {
|
|
||||||
buf.write(whereClause);
|
buf.write(whereClause);
|
||||||
}
|
}
|
||||||
var __ormNow__ = new DateTime.now();
|
var __ormNow__ = new DateTime.now();
|
||||||
|
|
|
@ -133,9 +133,7 @@ class CarQuery {
|
||||||
var buf = new StringBuffer(
|
var buf = new StringBuffer(
|
||||||
'UPDATE "cars" SET ("make", "description", "family_friendly", "recalled_at", "created_at", "updated_at") = (@make, @description, @familyFriendly, @recalledAt, @createdAt, @updatedAt) ');
|
'UPDATE "cars" SET ("make", "description", "family_friendly", "recalled_at", "created_at", "updated_at") = (@make, @description, @familyFriendly, @recalledAt, @createdAt, @updatedAt) ');
|
||||||
var whereClause = where.toWhereClause();
|
var whereClause = where.toWhereClause();
|
||||||
if (whereClause == null) {
|
if (whereClause != null) {
|
||||||
buf.write('WHERE "id" = @id');
|
|
||||||
} else {
|
|
||||||
buf.write(whereClause);
|
buf.write(whereClause);
|
||||||
}
|
}
|
||||||
var __ormNow__ = new DateTime.now();
|
var __ormNow__ = new DateTime.now();
|
||||||
|
|
12
angel_orm_generator/test/models/foot.dart
Normal file
12
angel_orm_generator/test/models/foot.dart
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
library angel_orm_generator.test.models.foot;
|
||||||
|
|
||||||
|
import 'package:angel_model/angel_model.dart';
|
||||||
|
import 'package:angel_orm/angel_orm.dart';
|
||||||
|
import 'package:angel_serialize/angel_serialize.dart';
|
||||||
|
part 'foot.g.dart';
|
||||||
|
|
||||||
|
@serializable
|
||||||
|
@orm
|
||||||
|
class _Foot extends Model {
|
||||||
|
int legId, nToes;
|
||||||
|
}
|
1
angel_orm_generator/test/models/foot.down.g.sql
Normal file
1
angel_orm_generator/test/models/foot.down.g.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
DROP TABLE "foots";
|
58
angel_orm_generator/test/models/foot.g.dart
Normal file
58
angel_orm_generator/test/models/foot.g.dart
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of angel_orm_generator.test.models.foot;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// Generator: JsonModelGenerator
|
||||||
|
// Target: class _Foot
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class Foot extends _Foot {
|
||||||
|
@override
|
||||||
|
String id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int legId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int nToes;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime createdAt;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime updatedAt;
|
||||||
|
|
||||||
|
Foot({this.id, this.legId, this.nToes, this.createdAt, this.updatedAt});
|
||||||
|
|
||||||
|
factory Foot.fromJson(Map data) {
|
||||||
|
return new Foot(
|
||||||
|
id: data['id'],
|
||||||
|
legId: data['leg_id'],
|
||||||
|
nToes: data['n_toes'],
|
||||||
|
createdAt: data['created_at'] is DateTime
|
||||||
|
? data['created_at']
|
||||||
|
: (data['created_at'] is String
|
||||||
|
? DateTime.parse(data['created_at'])
|
||||||
|
: null),
|
||||||
|
updatedAt: data['updated_at'] is DateTime
|
||||||
|
? data['updated_at']
|
||||||
|
: (data['updated_at'] is String
|
||||||
|
? DateTime.parse(data['updated_at'])
|
||||||
|
: null));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'id': id,
|
||||||
|
'leg_id': legId,
|
||||||
|
'n_toes': nToes,
|
||||||
|
'created_at': createdAt == null ? null : createdAt.toIso8601String(),
|
||||||
|
'updated_at': updatedAt == null ? null : updatedAt.toIso8601String()
|
||||||
|
};
|
||||||
|
|
||||||
|
static Foot parse(Map map) => new Foot.fromJson(map);
|
||||||
|
|
||||||
|
Foot clone() {
|
||||||
|
return new Foot.fromJson(toJson());
|
||||||
|
}
|
||||||
|
}
|
253
angel_orm_generator/test/models/foot.orm.g.dart
Normal file
253
angel_orm_generator/test/models/foot.orm.g.dart
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// Generator: PostgresORMGenerator
|
||||||
|
// Target: class _Foot
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:angel_orm/angel_orm.dart';
|
||||||
|
import 'package:postgres/postgres.dart';
|
||||||
|
import 'foot.dart';
|
||||||
|
|
||||||
|
class FootQuery {
|
||||||
|
final Map<FootQuery, bool> _unions = {};
|
||||||
|
|
||||||
|
String _sortKey;
|
||||||
|
|
||||||
|
String _sortMode;
|
||||||
|
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
final List<FootQueryWhere> _or = [];
|
||||||
|
|
||||||
|
final FootQueryWhere where = new FootQueryWhere();
|
||||||
|
|
||||||
|
void union(FootQuery query) {
|
||||||
|
_unions[query] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unionAll(FootQuery query) {
|
||||||
|
_unions[query] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sortDescending(String key) {
|
||||||
|
_sortMode = 'Descending';
|
||||||
|
_sortKey = ('' + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sortAscending(String key) {
|
||||||
|
_sortMode = 'Ascending';
|
||||||
|
_sortKey = ('' + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void or(FootQueryWhere selector) {
|
||||||
|
_or.add(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toSql([String prefix]) {
|
||||||
|
var buf = new StringBuffer();
|
||||||
|
buf.write(prefix != null
|
||||||
|
? prefix
|
||||||
|
: 'SELECT id, leg_id, n_toes, created_at, updated_at FROM "foots"');
|
||||||
|
if (prefix == null) {}
|
||||||
|
var whereClause = where.toWhereClause();
|
||||||
|
if (whereClause != null) {
|
||||||
|
buf.write(' ' + whereClause);
|
||||||
|
}
|
||||||
|
_or.forEach((x) {
|
||||||
|
var whereClause = x.toWhereClause(keyword: false);
|
||||||
|
if (whereClause != null) {
|
||||||
|
buf.write(' OR (' + whereClause + ')');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (prefix == null) {
|
||||||
|
if (limit != null) {
|
||||||
|
buf.write(' LIMIT ' + limit.toString());
|
||||||
|
}
|
||||||
|
if (offset != null) {
|
||||||
|
buf.write(' OFFSET ' + offset.toString());
|
||||||
|
}
|
||||||
|
if (_sortMode == 'Descending') {
|
||||||
|
buf.write(' ORDER BY "' + _sortKey + '" DESC');
|
||||||
|
}
|
||||||
|
if (_sortMode == 'Ascending') {
|
||||||
|
buf.write(' ORDER BY "' + _sortKey + '" ASC');
|
||||||
|
}
|
||||||
|
_unions.forEach((query, all) {
|
||||||
|
buf.write(' UNION');
|
||||||
|
if (all) {
|
||||||
|
buf.write(' ALL');
|
||||||
|
}
|
||||||
|
buf.write(' (');
|
||||||
|
var sql = query.toSql().replaceAll(';', '');
|
||||||
|
buf.write(sql + ')');
|
||||||
|
});
|
||||||
|
buf.write(';');
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Foot parseRow(List row) {
|
||||||
|
var result = new Foot.fromJson({
|
||||||
|
'id': row[0].toString(),
|
||||||
|
'leg_id': row[1],
|
||||||
|
'n_toes': row[2],
|
||||||
|
'created_at': row[3],
|
||||||
|
'updated_at': row[4]
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Foot> get(PostgreSQLConnection connection) {
|
||||||
|
StreamController<Foot> ctrl = new StreamController<Foot>();
|
||||||
|
connection.query(toSql()).then((rows) async {
|
||||||
|
var futures = rows.map((row) async {
|
||||||
|
var parsed = parseRow(row);
|
||||||
|
return parsed;
|
||||||
|
});
|
||||||
|
var output = await Future.wait(futures);
|
||||||
|
output.forEach(ctrl.add);
|
||||||
|
ctrl.close();
|
||||||
|
}).catchError(ctrl.addError);
|
||||||
|
return ctrl.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Foot> getOne(int id, PostgreSQLConnection connection) {
|
||||||
|
var query = new FootQuery();
|
||||||
|
query.where.id.equals(id);
|
||||||
|
return query.get(connection).first.catchError((_) => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Foot> update(PostgreSQLConnection connection,
|
||||||
|
{int legId, int nToes, DateTime createdAt, DateTime updatedAt}) {
|
||||||
|
var buf = new StringBuffer(
|
||||||
|
'UPDATE "foots" SET ("leg_id", "n_toes", "created_at", "updated_at") = (@legId, @nToes, @createdAt, @updatedAt) ');
|
||||||
|
var whereClause = where.toWhereClause();
|
||||||
|
if (whereClause != null) {
|
||||||
|
buf.write(whereClause);
|
||||||
|
}
|
||||||
|
var __ormNow__ = new DateTime.now();
|
||||||
|
var ctrl = new StreamController<Foot>();
|
||||||
|
connection.query(
|
||||||
|
buf.toString() +
|
||||||
|
' RETURNING "id", "leg_id", "n_toes", "created_at", "updated_at";',
|
||||||
|
substitutionValues: {
|
||||||
|
'legId': legId,
|
||||||
|
'nToes': nToes,
|
||||||
|
'createdAt': createdAt != null ? createdAt : __ormNow__,
|
||||||
|
'updatedAt': updatedAt != null ? updatedAt : __ormNow__
|
||||||
|
}).then((rows) async {
|
||||||
|
var futures = rows.map((row) async {
|
||||||
|
var parsed = parseRow(row);
|
||||||
|
return parsed;
|
||||||
|
});
|
||||||
|
var output = await Future.wait(futures);
|
||||||
|
output.forEach(ctrl.add);
|
||||||
|
ctrl.close();
|
||||||
|
}).catchError(ctrl.addError);
|
||||||
|
return ctrl.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Foot> delete(PostgreSQLConnection connection) {
|
||||||
|
StreamController<Foot> ctrl = new StreamController<Foot>();
|
||||||
|
connection
|
||||||
|
.query(toSql('DELETE FROM "foots"') +
|
||||||
|
' RETURNING "id", "leg_id", "n_toes", "created_at", "updated_at";')
|
||||||
|
.then((rows) async {
|
||||||
|
var futures = rows.map((row) async {
|
||||||
|
var parsed = parseRow(row);
|
||||||
|
return parsed;
|
||||||
|
});
|
||||||
|
var output = await Future.wait(futures);
|
||||||
|
output.forEach(ctrl.add);
|
||||||
|
ctrl.close();
|
||||||
|
}).catchError(ctrl.addError);
|
||||||
|
return ctrl.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Foot> deleteOne(int id, PostgreSQLConnection connection) {
|
||||||
|
var query = new FootQuery();
|
||||||
|
query.where.id.equals(id);
|
||||||
|
return query.delete(connection).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Foot> insert(PostgreSQLConnection connection,
|
||||||
|
{int legId, int nToes, DateTime createdAt, DateTime updatedAt}) async {
|
||||||
|
var __ormNow__ = new DateTime.now();
|
||||||
|
var result = await connection.query(
|
||||||
|
'INSERT INTO "foots" ("leg_id", "n_toes", "created_at", "updated_at") VALUES (@legId, @nToes, @createdAt, @updatedAt) RETURNING "id", "leg_id", "n_toes", "created_at", "updated_at";',
|
||||||
|
substitutionValues: {
|
||||||
|
'legId': legId,
|
||||||
|
'nToes': nToes,
|
||||||
|
'createdAt': createdAt != null ? createdAt : __ormNow__,
|
||||||
|
'updatedAt': updatedAt != null ? updatedAt : __ormNow__
|
||||||
|
});
|
||||||
|
var output = parseRow(result[0]);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Foot> insertFoot(PostgreSQLConnection connection, Foot foot) {
|
||||||
|
return FootQuery.insert(connection,
|
||||||
|
legId: foot.legId,
|
||||||
|
nToes: foot.nToes,
|
||||||
|
createdAt: foot.createdAt,
|
||||||
|
updatedAt: foot.updatedAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Foot> updateFoot(PostgreSQLConnection connection, Foot foot) {
|
||||||
|
var query = new FootQuery();
|
||||||
|
query.where.id.equals(int.parse(foot.id));
|
||||||
|
return query
|
||||||
|
.update(connection,
|
||||||
|
legId: foot.legId,
|
||||||
|
nToes: foot.nToes,
|
||||||
|
createdAt: foot.createdAt,
|
||||||
|
updatedAt: foot.updatedAt)
|
||||||
|
.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Foot> getAll(PostgreSQLConnection connection) =>
|
||||||
|
new FootQuery().get(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FootQueryWhere {
|
||||||
|
final NumericSqlExpressionBuilder<int> id =
|
||||||
|
new NumericSqlExpressionBuilder<int>();
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> legId =
|
||||||
|
new NumericSqlExpressionBuilder<int>();
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> nToes =
|
||||||
|
new NumericSqlExpressionBuilder<int>();
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('foots.created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('foots.updated_at');
|
||||||
|
|
||||||
|
String toWhereClause({bool keyword}) {
|
||||||
|
final List<String> expressions = [];
|
||||||
|
if (id.hasValue) {
|
||||||
|
expressions.add('foots.id ' + id.compile());
|
||||||
|
}
|
||||||
|
if (legId.hasValue) {
|
||||||
|
expressions.add('foots.leg_id ' + legId.compile());
|
||||||
|
}
|
||||||
|
if (nToes.hasValue) {
|
||||||
|
expressions.add('foots.n_toes ' + nToes.compile());
|
||||||
|
}
|
||||||
|
if (createdAt.hasValue) {
|
||||||
|
expressions.add(createdAt.compile());
|
||||||
|
}
|
||||||
|
if (updatedAt.hasValue) {
|
||||||
|
expressions.add(updatedAt.compile());
|
||||||
|
}
|
||||||
|
return expressions.isEmpty
|
||||||
|
? null
|
||||||
|
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||||
|
}
|
||||||
|
}
|
8
angel_orm_generator/test/models/foot.up.g.sql
Normal file
8
angel_orm_generator/test/models/foot.up.g.sql
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
CREATE TEMPORARY TABLE "foots" (
|
||||||
|
"id" serial,
|
||||||
|
"leg_id" int,
|
||||||
|
"n_toes" int,
|
||||||
|
"created_at" timestamp,
|
||||||
|
"updated_at" timestamp,
|
||||||
|
PRIMARY KEY(id)
|
||||||
|
);
|
16
angel_orm_generator/test/models/leg.dart
Normal file
16
angel_orm_generator/test/models/leg.dart
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
library angel_orm_generator.test.models.leg;
|
||||||
|
|
||||||
|
import 'package:angel_model/angel_model.dart';
|
||||||
|
import 'package:angel_orm/angel_orm.dart';
|
||||||
|
import 'package:angel_serialize/angel_serialize.dart';
|
||||||
|
import 'foot.dart';
|
||||||
|
part 'leg.g.dart';
|
||||||
|
|
||||||
|
@serializable
|
||||||
|
@orm
|
||||||
|
class _Leg extends Model {
|
||||||
|
@hasOne
|
||||||
|
Foot foot;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
}
|
1
angel_orm_generator/test/models/leg.down.g.sql
Normal file
1
angel_orm_generator/test/models/leg.down.g.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
DROP TABLE "legs";
|
58
angel_orm_generator/test/models/leg.g.dart
Normal file
58
angel_orm_generator/test/models/leg.g.dart
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of angel_orm_generator.test.models.leg;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// Generator: JsonModelGenerator
|
||||||
|
// Target: class _Leg
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class Leg extends _Leg {
|
||||||
|
@override
|
||||||
|
String id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
dynamic foot;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime createdAt;
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime updatedAt;
|
||||||
|
|
||||||
|
Leg({this.id, this.foot, this.name, this.createdAt, this.updatedAt});
|
||||||
|
|
||||||
|
factory Leg.fromJson(Map data) {
|
||||||
|
return new Leg(
|
||||||
|
id: data['id'],
|
||||||
|
foot: data['foot'],
|
||||||
|
name: data['name'],
|
||||||
|
createdAt: data['created_at'] is DateTime
|
||||||
|
? data['created_at']
|
||||||
|
: (data['created_at'] is String
|
||||||
|
? DateTime.parse(data['created_at'])
|
||||||
|
: null),
|
||||||
|
updatedAt: data['updated_at'] is DateTime
|
||||||
|
? data['updated_at']
|
||||||
|
: (data['updated_at'] is String
|
||||||
|
? DateTime.parse(data['updated_at'])
|
||||||
|
: null));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'id': id,
|
||||||
|
'foot': foot,
|
||||||
|
'name': name,
|
||||||
|
'created_at': createdAt == null ? null : createdAt.toIso8601String(),
|
||||||
|
'updated_at': updatedAt == null ? null : updatedAt.toIso8601String()
|
||||||
|
};
|
||||||
|
|
||||||
|
static Leg parse(Map map) => new Leg.fromJson(map);
|
||||||
|
|
||||||
|
Leg clone() {
|
||||||
|
return new Leg.fromJson(toJson());
|
||||||
|
}
|
||||||
|
}
|
258
angel_orm_generator/test/models/leg.orm.g.dart
Normal file
258
angel_orm_generator/test/models/leg.orm.g.dart
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// Generator: PostgresORMGenerator
|
||||||
|
// Target: class _Leg
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:angel_orm/angel_orm.dart';
|
||||||
|
import 'package:postgres/postgres.dart';
|
||||||
|
import 'leg.dart';
|
||||||
|
import 'foot.orm.g.dart';
|
||||||
|
|
||||||
|
class LegQuery {
|
||||||
|
final Map<LegQuery, bool> _unions = {};
|
||||||
|
|
||||||
|
String _sortKey;
|
||||||
|
|
||||||
|
String _sortMode;
|
||||||
|
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
final List<LegQueryWhere> _or = [];
|
||||||
|
|
||||||
|
final LegQueryWhere where = new LegQueryWhere();
|
||||||
|
|
||||||
|
void union(LegQuery query) {
|
||||||
|
_unions[query] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unionAll(LegQuery query) {
|
||||||
|
_unions[query] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sortDescending(String key) {
|
||||||
|
_sortMode = 'Descending';
|
||||||
|
_sortKey = ('legs.' + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sortAscending(String key) {
|
||||||
|
_sortMode = 'Ascending';
|
||||||
|
_sortKey = ('legs.' + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void or(LegQueryWhere selector) {
|
||||||
|
_or.add(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toSql([String prefix]) {
|
||||||
|
var buf = new StringBuffer();
|
||||||
|
buf.write(prefix != null
|
||||||
|
? prefix
|
||||||
|
: 'SELECT legs.id, legs.name, legs.created_at, legs.updated_at, foots.id, foots.leg_id, foots.n_toes, foots.created_at, foots.updated_at FROM "legs"');
|
||||||
|
if (prefix == null) {
|
||||||
|
buf.write(' LEFT OUTER JOIN foots ON legs.id = foots.leg_id');
|
||||||
|
}
|
||||||
|
var whereClause = where.toWhereClause();
|
||||||
|
if (whereClause != null) {
|
||||||
|
buf.write(' ' + whereClause);
|
||||||
|
}
|
||||||
|
_or.forEach((x) {
|
||||||
|
var whereClause = x.toWhereClause(keyword: false);
|
||||||
|
if (whereClause != null) {
|
||||||
|
buf.write(' OR (' + whereClause + ')');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (prefix == null) {
|
||||||
|
if (limit != null) {
|
||||||
|
buf.write(' LIMIT ' + limit.toString());
|
||||||
|
}
|
||||||
|
if (offset != null) {
|
||||||
|
buf.write(' OFFSET ' + offset.toString());
|
||||||
|
}
|
||||||
|
if (_sortMode == 'Descending') {
|
||||||
|
buf.write(' ORDER BY "' + _sortKey + '" DESC');
|
||||||
|
}
|
||||||
|
if (_sortMode == 'Ascending') {
|
||||||
|
buf.write(' ORDER BY "' + _sortKey + '" ASC');
|
||||||
|
}
|
||||||
|
_unions.forEach((query, all) {
|
||||||
|
buf.write(' UNION');
|
||||||
|
if (all) {
|
||||||
|
buf.write(' ALL');
|
||||||
|
}
|
||||||
|
buf.write(' (');
|
||||||
|
var sql = query.toSql().replaceAll(';', '');
|
||||||
|
buf.write(sql + ')');
|
||||||
|
});
|
||||||
|
buf.write(';');
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Leg parseRow(List row) {
|
||||||
|
var result = new Leg.fromJson({
|
||||||
|
'id': row[0].toString(),
|
||||||
|
'name': row[1],
|
||||||
|
'created_at': row[2],
|
||||||
|
'updated_at': row[3]
|
||||||
|
});
|
||||||
|
if (row.length > 4) {
|
||||||
|
result.foot =
|
||||||
|
FootQuery.parseRow([row[4], row[5], row[6], row[7], row[8]]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Leg> get(PostgreSQLConnection connection) {
|
||||||
|
StreamController<Leg> ctrl = new StreamController<Leg>();
|
||||||
|
connection.query(toSql()).then((rows) async {
|
||||||
|
var futures = rows.map((row) async {
|
||||||
|
var parsed = parseRow(row);
|
||||||
|
var footQuery = new FootQuery();
|
||||||
|
footQuery.where.id.equals(row[0]);
|
||||||
|
parsed.foot =
|
||||||
|
await footQuery.get(connection).first.catchError((_) => null);
|
||||||
|
return parsed;
|
||||||
|
});
|
||||||
|
var output = await Future.wait(futures);
|
||||||
|
output.forEach(ctrl.add);
|
||||||
|
ctrl.close();
|
||||||
|
}).catchError(ctrl.addError);
|
||||||
|
return ctrl.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Leg> getOne(int id, PostgreSQLConnection connection) {
|
||||||
|
var query = new LegQuery();
|
||||||
|
query.where.id.equals(id);
|
||||||
|
return query.get(connection).first.catchError((_) => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Leg> update(PostgreSQLConnection connection,
|
||||||
|
{String name, DateTime createdAt, DateTime updatedAt}) {
|
||||||
|
var buf = new StringBuffer(
|
||||||
|
'UPDATE "legs" SET ("name", "created_at", "updated_at") = (@name, @createdAt, @updatedAt) ');
|
||||||
|
var whereClause = where.toWhereClause();
|
||||||
|
if (whereClause != null) {
|
||||||
|
buf.write(whereClause);
|
||||||
|
}
|
||||||
|
var __ormNow__ = new DateTime.now();
|
||||||
|
var ctrl = new StreamController<Leg>();
|
||||||
|
connection.query(
|
||||||
|
buf.toString() + ' RETURNING "id", "name", "created_at", "updated_at";',
|
||||||
|
substitutionValues: {
|
||||||
|
'name': name,
|
||||||
|
'createdAt': createdAt != null ? createdAt : __ormNow__,
|
||||||
|
'updatedAt': updatedAt != null ? updatedAt : __ormNow__
|
||||||
|
}).then((rows) async {
|
||||||
|
var futures = rows.map((row) async {
|
||||||
|
var parsed = parseRow(row);
|
||||||
|
var footQuery = new FootQuery();
|
||||||
|
footQuery.where.id.equals(row[0]);
|
||||||
|
parsed.foot =
|
||||||
|
await footQuery.get(connection).first.catchError((_) => null);
|
||||||
|
return parsed;
|
||||||
|
});
|
||||||
|
var output = await Future.wait(futures);
|
||||||
|
output.forEach(ctrl.add);
|
||||||
|
ctrl.close();
|
||||||
|
}).catchError(ctrl.addError);
|
||||||
|
return ctrl.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<Leg> delete(PostgreSQLConnection connection) {
|
||||||
|
StreamController<Leg> ctrl = new StreamController<Leg>();
|
||||||
|
connection
|
||||||
|
.query(toSql('DELETE FROM "legs"') +
|
||||||
|
' RETURNING "id", "name", "created_at", "updated_at";')
|
||||||
|
.then((rows) async {
|
||||||
|
var futures = rows.map((row) async {
|
||||||
|
var parsed = parseRow(row);
|
||||||
|
var footQuery = new FootQuery();
|
||||||
|
footQuery.where.id.equals(row[0]);
|
||||||
|
parsed.foot =
|
||||||
|
await footQuery.get(connection).first.catchError((_) => null);
|
||||||
|
return parsed;
|
||||||
|
});
|
||||||
|
var output = await Future.wait(futures);
|
||||||
|
output.forEach(ctrl.add);
|
||||||
|
ctrl.close();
|
||||||
|
}).catchError(ctrl.addError);
|
||||||
|
return ctrl.stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Leg> deleteOne(int id, PostgreSQLConnection connection) {
|
||||||
|
var query = new LegQuery();
|
||||||
|
query.where.id.equals(id);
|
||||||
|
return query.delete(connection).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Leg> insert(PostgreSQLConnection connection,
|
||||||
|
{String name, DateTime createdAt, DateTime updatedAt}) async {
|
||||||
|
var __ormNow__ = new DateTime.now();
|
||||||
|
var result = await connection.query(
|
||||||
|
'INSERT INTO "legs" ("name", "created_at", "updated_at") VALUES (@name, @createdAt, @updatedAt) RETURNING "id", "name", "created_at", "updated_at";',
|
||||||
|
substitutionValues: {
|
||||||
|
'name': name,
|
||||||
|
'createdAt': createdAt != null ? createdAt : __ormNow__,
|
||||||
|
'updatedAt': updatedAt != null ? updatedAt : __ormNow__
|
||||||
|
});
|
||||||
|
var output = parseRow(result[0]);
|
||||||
|
var footQuery = new FootQuery();
|
||||||
|
footQuery.where.id.equals(result[0][0]);
|
||||||
|
output.foot = await footQuery.get(connection).first.catchError((_) => null);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Leg> insertLeg(PostgreSQLConnection connection, Leg leg) {
|
||||||
|
return LegQuery.insert(connection,
|
||||||
|
name: leg.name, createdAt: leg.createdAt, updatedAt: leg.updatedAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Leg> updateLeg(PostgreSQLConnection connection, Leg leg) {
|
||||||
|
var query = new LegQuery();
|
||||||
|
query.where.id.equals(int.parse(leg.id));
|
||||||
|
return query
|
||||||
|
.update(connection,
|
||||||
|
name: leg.name, createdAt: leg.createdAt, updatedAt: leg.updatedAt)
|
||||||
|
.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Leg> getAll(PostgreSQLConnection connection) =>
|
||||||
|
new LegQuery().get(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LegQueryWhere {
|
||||||
|
final NumericSqlExpressionBuilder<int> id =
|
||||||
|
new NumericSqlExpressionBuilder<int>();
|
||||||
|
|
||||||
|
final StringSqlExpressionBuilder name = new StringSqlExpressionBuilder();
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('legs.created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('legs.updated_at');
|
||||||
|
|
||||||
|
String toWhereClause({bool keyword}) {
|
||||||
|
final List<String> expressions = [];
|
||||||
|
if (id.hasValue) {
|
||||||
|
expressions.add('legs.id ' + id.compile());
|
||||||
|
}
|
||||||
|
if (name.hasValue) {
|
||||||
|
expressions.add('legs.name ' + name.compile());
|
||||||
|
}
|
||||||
|
if (createdAt.hasValue) {
|
||||||
|
expressions.add(createdAt.compile());
|
||||||
|
}
|
||||||
|
if (updatedAt.hasValue) {
|
||||||
|
expressions.add(updatedAt.compile());
|
||||||
|
}
|
||||||
|
return expressions.isEmpty
|
||||||
|
? null
|
||||||
|
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||||
|
}
|
||||||
|
}
|
7
angel_orm_generator/test/models/leg.up.g.sql
Normal file
7
angel_orm_generator/test/models/leg.up.g.sql
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TEMPORARY TABLE "legs" (
|
||||||
|
"id" serial,
|
||||||
|
"name" varchar,
|
||||||
|
"created_at" timestamp,
|
||||||
|
"updated_at" timestamp,
|
||||||
|
PRIMARY KEY(id)
|
||||||
|
);
|
|
@ -125,9 +125,7 @@ class RoleQuery {
|
||||||
var buf = new StringBuffer(
|
var buf = new StringBuffer(
|
||||||
'UPDATE "roles" SET ("name", "created_at", "updated_at") = (@name, @createdAt, @updatedAt) ');
|
'UPDATE "roles" SET ("name", "created_at", "updated_at") = (@name, @createdAt, @updatedAt) ');
|
||||||
var whereClause = where.toWhereClause();
|
var whereClause = where.toWhereClause();
|
||||||
if (whereClause == null) {
|
if (whereClause != null) {
|
||||||
buf.write('WHERE "id" = @id');
|
|
||||||
} else {
|
|
||||||
buf.write(whereClause);
|
buf.write(whereClause);
|
||||||
}
|
}
|
||||||
var __ormNow__ = new DateTime.now();
|
var __ormNow__ = new DateTime.now();
|
||||||
|
|
|
@ -53,9 +53,7 @@ class UserQuery {
|
||||||
buf.write(prefix != null
|
buf.write(prefix != null
|
||||||
? prefix
|
? prefix
|
||||||
: 'SELECT users.id, users.username, users.password, users.email, users.created_at, users.updated_at, roles.id, roles.name, roles.created_at, roles.updated_at FROM "users"');
|
: 'SELECT users.id, users.username, users.password, users.email, users.created_at, users.updated_at, roles.id, roles.name, roles.created_at, roles.updated_at FROM "users"');
|
||||||
if (prefix == null) {
|
if (prefix == null) {}
|
||||||
buf.write(' INNER JOIN roles ON users.role_id = roles.id');
|
|
||||||
}
|
|
||||||
var whereClause = where.toWhereClause();
|
var whereClause = where.toWhereClause();
|
||||||
if (whereClause != null) {
|
if (whereClause != null) {
|
||||||
buf.write(' ' + whereClause);
|
buf.write(' ' + whereClause);
|
||||||
|
@ -140,9 +138,7 @@ class UserQuery {
|
||||||
var buf = new StringBuffer(
|
var buf = new StringBuffer(
|
||||||
'UPDATE "users" SET ("username", "password", "email", "created_at", "updated_at") = (@username, @password, @email, @createdAt, @updatedAt) ');
|
'UPDATE "users" SET ("username", "password", "email", "created_at", "updated_at") = (@username, @password, @email, @createdAt, @updatedAt) ');
|
||||||
var whereClause = where.toWhereClause();
|
var whereClause = where.toWhereClause();
|
||||||
if (whereClause == null) {
|
if (whereClause != null) {
|
||||||
buf.write('WHERE "id" = @id');
|
|
||||||
} else {
|
|
||||||
buf.write(whereClause);
|
buf.write(whereClause);
|
||||||
}
|
}
|
||||||
var __ormNow__ = new DateTime.now();
|
var __ormNow__ = new DateTime.now();
|
||||||
|
|
|
@ -51,7 +51,7 @@ main() {
|
||||||
PostgreSQLConnection connection;
|
PostgreSQLConnection connection;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
connection = await connectToPostgres();
|
connection = await connectToPostgres(['car']);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('selects', () {
|
group('selects', () {
|
||||||
|
|
|
@ -6,12 +6,16 @@ import 'package:angel_serialize_generator/angel_serialize_generator.dart';
|
||||||
final InputSet ALL_MODELS =
|
final InputSet ALL_MODELS =
|
||||||
new InputSet('angel_orm_generator', const ['test/models/*.dart']);
|
new InputSet('angel_orm_generator', const ['test/models/*.dart']);
|
||||||
final InputSet STANDALONE_MODELS = new InputSet('angel_orm_generator', const [
|
final InputSet STANDALONE_MODELS = new InputSet('angel_orm_generator', const [
|
||||||
'test/models/car.dart',
|
|
||||||
'test/models/author.dart',
|
'test/models/author.dart',
|
||||||
|
'test/models/car.dart',
|
||||||
|
'test/models/foot.dart',
|
||||||
'test/models/role.dart'
|
'test/models/role.dart'
|
||||||
]);
|
]);
|
||||||
final InputSet DEPENDENT_MODELS = new InputSet('angel_orm_generator',
|
final InputSet DEPENDENT_MODELS = new InputSet('angel_orm_generator', const [
|
||||||
const ['test/models/book.dart', 'test/models/user.dart']);
|
'test/models/book.dart',
|
||||||
|
'test/models/leg.dart',
|
||||||
|
'test/models/user.dart'
|
||||||
|
]);
|
||||||
|
|
||||||
final PhaseGroup PHASES = new PhaseGroup()
|
final PhaseGroup PHASES = new PhaseGroup()
|
||||||
..addPhase(new Phase()
|
..addPhase(new Phase()
|
||||||
|
|
Loading…
Reference in a new issue