Joins in the works
This commit is contained in:
parent
d097f6bb35
commit
ba0fb80448
30 changed files with 1346 additions and 10 deletions
|
@ -1,6 +1,12 @@
|
|||
const ORM orm = const ORM();
|
||||
|
||||
class ORM {
|
||||
final String tableName;
|
||||
const ORM([this.tableName]);
|
||||
}
|
||||
|
||||
const ORM orm = const ORM();
|
||||
class CanJoin {
|
||||
final Type type;
|
||||
final String foreignKey;
|
||||
const CanJoin(this.type, this.foreignKey);
|
||||
}
|
|
@ -21,7 +21,8 @@ String sanitizeExpression(String unsafe) {
|
|||
continue;
|
||||
|
||||
// Otherwise, add the next char, unless it's a null byte.
|
||||
else if ((ch = scanner.readChar()) != 0 && ch != null) buf.writeCharCode(ch);
|
||||
else if ((ch = scanner.readChar()) != 0 && ch != null)
|
||||
buf.writeCharCode(ch);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: angel_orm
|
||||
version: 1.0.0-alpha+10
|
||||
version: 1.0.0-alpha+12
|
||||
description: Runtime support for Angel's ORM.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/orm
|
||||
|
|
|
@ -99,7 +99,7 @@ Future<PostgresBuildContext> buildContext(
|
|||
var raw = await serialize.buildContext(clazz, null, buildStep, resolver,
|
||||
autoSnakeCaseNames != false, autoIdAndDateFields != false);
|
||||
var ctx = await PostgresBuildContext.create(
|
||||
raw, annotation, resolver, buildStep,
|
||||
clazz, raw, annotation, resolver, buildStep,
|
||||
tableName: (annotation.tableName?.isNotEmpty == true)
|
||||
? annotation.tableName
|
||||
: pluralize(new ReCase(clazz.name).snakeCase),
|
||||
|
@ -110,6 +110,19 @@ Future<PostgresBuildContext> buildContext(
|
|||
|
||||
for (var field in raw.fields) {
|
||||
fieldNames.add(field.name);
|
||||
|
||||
// Check for joins.
|
||||
var canJoins = canJoinTypeChecker.annotationsOf(field);
|
||||
|
||||
for (var ann in canJoins) {
|
||||
var cr = new ConstantReader(ann);
|
||||
ctx.joins[field.name] ??= [];
|
||||
ctx.joins[field.name].add(new JoinContext(
|
||||
resolveModelAncestor(cr.read('type').typeValue),
|
||||
cr.read('foreignKey').stringValue,
|
||||
));
|
||||
}
|
||||
|
||||
// Check for relationship. If so, skip.
|
||||
var relationshipAnnotation =
|
||||
relationshipTypeChecker.firstAnnotationOf(field);
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:build/build.dart';
|
|||
import 'package:code_builder/dart/async.dart';
|
||||
import 'package:code_builder/dart/core.dart';
|
||||
import 'package:code_builder/code_builder.dart';
|
||||
import 'package:inflection/inflection.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
|
||||
|
@ -100,8 +101,12 @@ class PostgresOrmGenerator extends GeneratorForAnnotation<ORM> {
|
|||
for (var element in contexts.keys) {
|
||||
if (!done.contains(element.name)) {
|
||||
var ctx = contexts[element];
|
||||
lib.addMember(await buildQueryClass(ctx));
|
||||
var queryClass = await buildQueryClass(ctx);
|
||||
if (ctx.joins.isNotEmpty)
|
||||
await buildJoins(queryClass, lib, ctx, resolver, buildStep);
|
||||
lib.addMember(queryClass);
|
||||
lib.addMember(buildWhereClass(ctx));
|
||||
lib.addMember(buildFieldClass(ctx));
|
||||
done.add(element.name);
|
||||
}
|
||||
}
|
||||
|
@ -252,8 +257,10 @@ class PostgresOrmGenerator extends GeneratorForAnnotation<ORM> {
|
|||
// Write prefix, or default to SELECT
|
||||
var prefix = reference('prefix');
|
||||
meth.addStatement(buf.invoke('write', [
|
||||
prefix.notEquals(literal(null)).ternary(prefix,
|
||||
literal('SELECT ${await computeSelector(ctx)} FROM "${ctx.tableName}"'))
|
||||
prefix.notEquals(literal(null)).ternary(
|
||||
prefix,
|
||||
literal(
|
||||
'SELECT ${await computeSelector(ctx)} FROM "${ctx.tableName}"'))
|
||||
]));
|
||||
|
||||
var relationsIfThen = ifThen(prefix.equals(literal(null)));
|
||||
|
@ -966,4 +973,70 @@ class PostgresOrmGenerator extends GeneratorForAnnotation<ORM> {
|
|||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
ClassBuilder buildFieldClass(PostgresBuildContext ctx) {
|
||||
var clazz = new ClassBuilder(ctx.reCase.pascalCase + 'Fields');
|
||||
|
||||
for (var field in ctx.fields) {
|
||||
clazz.addField(
|
||||
varConst(field.name,
|
||||
value: literal(ctx.resolveFieldName(field.name))),
|
||||
asStatic: true);
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
Future buildJoins(ClassBuilder queryClass, LibraryBuilder lib,
|
||||
PostgresBuildContext ctx, Resolver resolver, BuildStep buildStep) async {
|
||||
Map<int, PostgresBuildContext> contexts = {};
|
||||
Map<PostgresBuildContext, Map<String, JoinContext>> targets = {};
|
||||
|
||||
for (var fieldName in ctx.joins.keys) {
|
||||
print('${ctx.originalClassName}:$fieldName');
|
||||
var joins = ctx.joins[fieldName];
|
||||
|
||||
for (var join in joins) {
|
||||
PostgresBuildContext refType;
|
||||
|
||||
if (contexts.containsKey(join.type.hashCode))
|
||||
refType = contexts[join.type.hashCode];
|
||||
else {
|
||||
var clazz = join.type.element as ClassElement;
|
||||
var annotation = ormTypeChecker.firstAnnotationOf(join.type.element);
|
||||
var ctx = await buildContext(
|
||||
clazz,
|
||||
reviveOrm(new ConstantReader(annotation)),
|
||||
buildStep,
|
||||
resolver,
|
||||
autoSnakeCaseNames,
|
||||
autoIdAndDateFields,
|
||||
);
|
||||
contexts[join.type.hashCode] = refType = ctx;
|
||||
}
|
||||
|
||||
var targetMap = targets.putIfAbsent(refType, () => {});
|
||||
var localFieldName = ctx.resolveFieldName(fieldName);
|
||||
targetMap.putIfAbsent(localFieldName, () => join);
|
||||
}
|
||||
}
|
||||
|
||||
if (targets.isNotEmpty) {
|
||||
/*
|
||||
var result = await OrderQuery.joinCustomers(
|
||||
connection,
|
||||
OrderQueryFields.customerId
|
||||
);
|
||||
*/
|
||||
|
||||
for (var refType in targets.keys) {
|
||||
var refTypeRc = new ReCase(pluralize(refType.modelClassName));
|
||||
var refTypePlural = refTypeRc.pascalCase;
|
||||
var joinMethod = new MethodBuilder('join$refTypePlural');
|
||||
queryClass.addMethod(joinMethod, asStatic: true);
|
||||
joinMethod.addPositional(
|
||||
parameter('connection', [ctx.postgreSQLConnectionBuilder]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:analyzer/dart/constant/value.dart';
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:analyzer/src/generated/resolver.dart';
|
||||
import 'package:angel_model/angel_model.dart';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:angel_serialize_generator/context.dart';
|
||||
import 'package:build/build.dart';
|
||||
|
@ -12,6 +13,33 @@ import 'package:recase/recase.dart';
|
|||
import 'package:source_gen/source_gen.dart';
|
||||
import 'build_context.dart';
|
||||
|
||||
const TypeChecker canJoinTypeChecker = const TypeChecker.fromRuntime(CanJoin);
|
||||
|
||||
DartType resolveModelAncestor(DartType type) {
|
||||
DartType refType = type;
|
||||
|
||||
while (refType != null) {
|
||||
if (!const TypeChecker.fromRuntime(Model).isAssignableFromType(refType)) {
|
||||
var parent = (refType.element as ClassElement).allSupertypes[0];
|
||||
if (parent != refType)
|
||||
refType = parent;
|
||||
else
|
||||
refType = null;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
if (refType != null) return refType;
|
||||
|
||||
throw '${type.name} does not extend Model.';
|
||||
}
|
||||
|
||||
class JoinContext {
|
||||
final DartType type;
|
||||
final String foreignKey;
|
||||
JoinContext(this.type, this.foreignKey);
|
||||
}
|
||||
|
||||
class PostgresBuildContext extends BuildContext {
|
||||
LibraryElement _libraryCache;
|
||||
TypeProvider _typeProviderCache;
|
||||
|
@ -23,28 +51,36 @@ class PostgresBuildContext extends BuildContext {
|
|||
final Map<String, Relationship> _populatedRelationships = {};
|
||||
final Map<String, Column> columnInfo = {};
|
||||
final Map<String, IndexType> indices = {};
|
||||
final Map<String, List<JoinContext>> joins = {};
|
||||
final Map<String, Relationship> relationships = {};
|
||||
final bool autoSnakeCaseNames, autoIdAndDateFields;
|
||||
final String tableName;
|
||||
final ORM ormAnnotation;
|
||||
final ClassElement element;
|
||||
final BuildContext raw;
|
||||
final Resolver resolver;
|
||||
final BuildStep buildStep;
|
||||
ReCase _reCase;
|
||||
String primaryKeyName = 'id';
|
||||
|
||||
PostgresBuildContext._(
|
||||
this.raw, this.ormAnnotation, this.resolver, this.buildStep,
|
||||
this.element, this.raw, this.ormAnnotation, this.resolver, this.buildStep,
|
||||
{this.tableName, this.autoSnakeCaseNames, this.autoIdAndDateFields})
|
||||
: super(raw.annotation,
|
||||
originalClassName: raw.originalClassName,
|
||||
sourceFilename: raw.sourceFilename);
|
||||
|
||||
static Future<PostgresBuildContext> create(BuildContext raw,
|
||||
ORM ormAnnotation, Resolver resolver, BuildStep buildStep,
|
||||
static Future<PostgresBuildContext> create(
|
||||
ClassElement element,
|
||||
BuildContext raw,
|
||||
ORM ormAnnotation,
|
||||
Resolver resolver,
|
||||
BuildStep buildStep,
|
||||
{String tableName,
|
||||
bool autoSnakeCaseNames,
|
||||
bool autoIdAndDateFields}) async {
|
||||
var ctx = new PostgresBuildContext._(
|
||||
element,
|
||||
raw,
|
||||
ormAnnotation,
|
||||
resolver,
|
||||
|
@ -62,6 +98,8 @@ class PostgresBuildContext extends BuildContext {
|
|||
|
||||
final List<FieldElement> fields = [], relationshipFields = [];
|
||||
|
||||
ReCase get reCase => _reCase ?? new ReCase(modelClassName);
|
||||
|
||||
TypeBuilder get modelClassBuilder =>
|
||||
_modelClassBuilder ??= new TypeBuilder(modelClassName);
|
||||
|
||||
|
@ -179,6 +217,11 @@ class PostgresBuildContext extends BuildContext {
|
|||
'Invalid relationship type: ${relationship.type}');
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PostgresBuildContext: $originalClassName';
|
||||
}
|
||||
}
|
||||
|
||||
class PopulatedRelationship extends Relationship {
|
||||
|
|
|
@ -241,3 +241,13 @@ class AuthorQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class AuthorFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const name = 'name';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
|
@ -263,3 +263,15 @@ class BookQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class BookFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const name = 'name';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
|
||||
static const authorId = 'author_id';
|
||||
}
|
||||
|
|
|
@ -281,3 +281,19 @@ class CarQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class CarFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const make = 'make';
|
||||
|
||||
static const description = 'description';
|
||||
|
||||
static const familyFriendly = 'family_friendly';
|
||||
|
||||
static const recalledAt = 'recalled_at';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
11
angel_orm_generator/test/models/customer.dart
Normal file
11
angel_orm_generator/test/models/customer.dart
Normal file
|
@ -0,0 +1,11 @@
|
|||
library angel_orm_generator.test.models.customer;
|
||||
|
||||
import 'package:angel_model/angel_model.dart';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:angel_serialize/angel_serialize.dart';
|
||||
part 'customer.g.dart';
|
||||
|
||||
@orm
|
||||
@serializable
|
||||
class _Customer extends Model {
|
||||
}
|
1
angel_orm_generator/test/models/customer.down.g.sql
Normal file
1
angel_orm_generator/test/models/customer.down.g.sql
Normal file
|
@ -0,0 +1 @@
|
|||
DROP TABLE "customers";
|
47
angel_orm_generator/test/models/customer.g.dart
Normal file
47
angel_orm_generator/test/models/customer.g.dart
Normal file
|
@ -0,0 +1,47 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of angel_orm_generator.test.models.customer;
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class Customer extends _Customer {
|
||||
@override
|
||||
String id;
|
||||
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
Customer({this.id, this.createdAt, this.updatedAt});
|
||||
|
||||
factory Customer.fromJson(Map data) {
|
||||
return new Customer(
|
||||
id: data['id'],
|
||||
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,
|
||||
'created_at': createdAt == null ? null : createdAt.toIso8601String(),
|
||||
'updated_at': updatedAt == null ? null : updatedAt.toIso8601String()
|
||||
};
|
||||
|
||||
static Customer parse(Map map) => new Customer.fromJson(map);
|
||||
|
||||
Customer clone() {
|
||||
return new Customer.fromJson(toJson());
|
||||
}
|
||||
}
|
23
angel_orm_generator/test/models/customer.migration.g.dart
Normal file
23
angel_orm_generator/test/models/customer.migration.g.dart
Normal file
|
@ -0,0 +1,23 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: MigrationGenerator
|
||||
// **************************************************************************
|
||||
|
||||
import 'package:angel_migration/angel_migration.dart';
|
||||
|
||||
class CustomerMigration extends Migration {
|
||||
@override
|
||||
up(Schema schema) {
|
||||
schema.create('customers', (table) {
|
||||
table.serial('id')..primaryKey();
|
||||
table.timeStamp('created_at');
|
||||
table.timeStamp('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
down(Schema schema) {
|
||||
schema.drop('customers');
|
||||
}
|
||||
}
|
234
angel_orm_generator/test/models/customer.orm.g.dart
Normal file
234
angel_orm_generator/test/models/customer.orm.g.dart
Normal file
|
@ -0,0 +1,234 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: PostgresOrmGenerator
|
||||
// **************************************************************************
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:postgres/postgres.dart';
|
||||
import 'customer.dart';
|
||||
|
||||
class CustomerQuery {
|
||||
final Map<CustomerQuery, bool> _unions = {};
|
||||
|
||||
String _sortKey;
|
||||
|
||||
String _sortMode;
|
||||
|
||||
int limit;
|
||||
|
||||
int offset;
|
||||
|
||||
final List<CustomerQueryWhere> _or = [];
|
||||
|
||||
final CustomerQueryWhere where = new CustomerQueryWhere();
|
||||
|
||||
void union(CustomerQuery query) {
|
||||
_unions[query] = false;
|
||||
}
|
||||
|
||||
void unionAll(CustomerQuery query) {
|
||||
_unions[query] = true;
|
||||
}
|
||||
|
||||
void sortDescending(String key) {
|
||||
_sortMode = 'Descending';
|
||||
_sortKey = ('' + key);
|
||||
}
|
||||
|
||||
void sortAscending(String key) {
|
||||
_sortMode = 'Ascending';
|
||||
_sortKey = ('' + key);
|
||||
}
|
||||
|
||||
void or(CustomerQueryWhere selector) {
|
||||
_or.add(selector);
|
||||
}
|
||||
|
||||
String toSql([String prefix]) {
|
||||
var buf = new StringBuffer();
|
||||
buf.write(prefix != null
|
||||
? prefix
|
||||
: 'SELECT id, created_at, updated_at FROM "customers"');
|
||||
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 Customer parseRow(List row) {
|
||||
var result = new Customer.fromJson(
|
||||
{'id': row[0].toString(), 'created_at': row[1], 'updated_at': row[2]});
|
||||
return result;
|
||||
}
|
||||
|
||||
Stream<Customer> get(PostgreSQLConnection connection) {
|
||||
StreamController<Customer> ctrl = new StreamController<Customer>();
|
||||
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<Customer> getOne(int id, PostgreSQLConnection connection) {
|
||||
var query = new CustomerQuery();
|
||||
query.where.id.equals(id);
|
||||
return query.get(connection).first.catchError((_) => null);
|
||||
}
|
||||
|
||||
Stream<Customer> update(PostgreSQLConnection connection,
|
||||
{DateTime createdAt, DateTime updatedAt}) {
|
||||
var buf = new StringBuffer(
|
||||
'UPDATE "customers" SET ("created_at", "updated_at") = (@createdAt, @updatedAt) ');
|
||||
var whereClause = where.toWhereClause();
|
||||
if (whereClause != null) {
|
||||
buf.write(whereClause);
|
||||
}
|
||||
var __ormNow__ = new DateTime.now();
|
||||
var ctrl = new StreamController<Customer>();
|
||||
connection.query(
|
||||
buf.toString() + ' RETURNING "id", "created_at", "updated_at";',
|
||||
substitutionValues: {
|
||||
'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<Customer> delete(PostgreSQLConnection connection) {
|
||||
StreamController<Customer> ctrl = new StreamController<Customer>();
|
||||
connection
|
||||
.query(toSql('DELETE FROM "customers"') +
|
||||
' RETURNING "id", "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<Customer> deleteOne(int id, PostgreSQLConnection connection) {
|
||||
var query = new CustomerQuery();
|
||||
query.where.id.equals(id);
|
||||
return query.delete(connection).first;
|
||||
}
|
||||
|
||||
static Future<Customer> insert(PostgreSQLConnection connection,
|
||||
{DateTime createdAt, DateTime updatedAt}) async {
|
||||
var __ormNow__ = new DateTime.now();
|
||||
var result = await connection.query(
|
||||
'INSERT INTO "customers" ("created_at", "updated_at") VALUES (@createdAt, @updatedAt) RETURNING "id", "created_at", "updated_at";',
|
||||
substitutionValues: {
|
||||
'createdAt': createdAt != null ? createdAt : __ormNow__,
|
||||
'updatedAt': updatedAt != null ? updatedAt : __ormNow__
|
||||
});
|
||||
var output = parseRow(result[0]);
|
||||
return output;
|
||||
}
|
||||
|
||||
static Future<Customer> insertCustomer(
|
||||
PostgreSQLConnection connection, Customer customer) {
|
||||
return CustomerQuery.insert(connection,
|
||||
createdAt: customer.createdAt, updatedAt: customer.updatedAt);
|
||||
}
|
||||
|
||||
static Future<Customer> updateCustomer(
|
||||
PostgreSQLConnection connection, Customer customer) {
|
||||
var query = new CustomerQuery();
|
||||
query.where.id.equals(int.parse(customer.id));
|
||||
return query
|
||||
.update(connection,
|
||||
createdAt: customer.createdAt, updatedAt: customer.updatedAt)
|
||||
.first;
|
||||
}
|
||||
|
||||
static Stream<Customer> getAll(PostgreSQLConnection connection) =>
|
||||
new CustomerQuery().get(connection);
|
||||
}
|
||||
|
||||
class CustomerQueryWhere {
|
||||
final NumericSqlExpressionBuilder<int> id =
|
||||
new NumericSqlExpressionBuilder<int>();
|
||||
|
||||
final DateTimeSqlExpressionBuilder createdAt =
|
||||
new DateTimeSqlExpressionBuilder('customers.created_at');
|
||||
|
||||
final DateTimeSqlExpressionBuilder updatedAt =
|
||||
new DateTimeSqlExpressionBuilder('customers.updated_at');
|
||||
|
||||
String toWhereClause({bool keyword}) {
|
||||
final List<String> expressions = [];
|
||||
if (id.hasValue) {
|
||||
expressions.add('customers.id ' + id.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 '));
|
||||
}
|
||||
}
|
||||
|
||||
class CustomerFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
143
angel_orm_generator/test/models/customer.service.g.dart
Normal file
143
angel_orm_generator/test/models/customer.service.g.dart
Normal file
|
@ -0,0 +1,143 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: PostgresServiceGenerator
|
||||
// **************************************************************************
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:postgres/postgres.dart';
|
||||
import 'customer.dart';
|
||||
import 'customer.orm.g.dart';
|
||||
|
||||
class CustomerService extends Service {
|
||||
final PostgreSQLConnection connection;
|
||||
|
||||
final bool allowRemoveAll;
|
||||
|
||||
final bool allowQuery;
|
||||
|
||||
CustomerService(this.connection,
|
||||
{this.allowRemoveAll: false, this.allowQuery: false});
|
||||
|
||||
CustomerQuery buildQuery(Map params) {
|
||||
var query = new CustomerQuery();
|
||||
if (params['query'] is Map) {
|
||||
query.where.id.equals(params['query']['id']);
|
||||
query.where.createdAt.equals(params['query']['created_at'] is String
|
||||
? DateTime.parse(params['query']['created_at'])
|
||||
: params['query']['created_at'] != null
|
||||
? params['query']['created_at'] is String
|
||||
? DateTime.parse(params['query']['created_at'])
|
||||
: params['query']['created_at']
|
||||
: new DateTime.now());
|
||||
query.where.updatedAt.equals(params['query']['updated_at'] is String
|
||||
? DateTime.parse(params['query']['updated_at'])
|
||||
: params['query']['updated_at'] != null
|
||||
? params['query']['updated_at'] is String
|
||||
? DateTime.parse(params['query']['updated_at'])
|
||||
: params['query']['updated_at']
|
||||
: new DateTime.now());
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
int toId(id) {
|
||||
if (id is int) {
|
||||
return id;
|
||||
} else {
|
||||
if (id == 'null' || id == null) {
|
||||
return null;
|
||||
} else {
|
||||
return int.parse(id.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Customer applyData(data) {
|
||||
if (data is Customer || data == null) {
|
||||
return data;
|
||||
}
|
||||
if (data is Map) {
|
||||
var query = new Customer();
|
||||
if (data.containsKey('created_at')) {
|
||||
query.createdAt = data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at'] != null
|
||||
? data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
if (data.containsKey('updated_at')) {
|
||||
query.updatedAt = data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at'] != null
|
||||
? data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
return query;
|
||||
} else
|
||||
throw new AngelHttpException.badRequest(message: 'Invalid data.');
|
||||
}
|
||||
|
||||
Future<List<Customer>> index([Map params]) {
|
||||
return buildQuery(params).get(connection).toList();
|
||||
}
|
||||
|
||||
Future<Customer> create(data, [Map params]) {
|
||||
return CustomerQuery.insertCustomer(connection, applyData(data));
|
||||
}
|
||||
|
||||
Future<Customer> read(id, [Map params]) {
|
||||
var query = buildQuery(params);
|
||||
query.where.id.equals(toId(id));
|
||||
return query.get(connection).first.catchError((_) {
|
||||
new AngelHttpException.notFound(
|
||||
message: 'No record found for ID ' + id.toString());
|
||||
});
|
||||
}
|
||||
|
||||
Future<Customer> remove(id, [Map params]) {
|
||||
var query = buildQuery(params);
|
||||
query.where.id.equals(toId(id));
|
||||
return query.delete(connection).first.catchError((_) {
|
||||
new AngelHttpException.notFound(
|
||||
message: 'No record found for ID ' + id.toString());
|
||||
});
|
||||
}
|
||||
|
||||
Future<Customer> update(id, data, [Map params]) {
|
||||
return CustomerQuery.updateCustomer(connection, applyData(data));
|
||||
}
|
||||
|
||||
Future<Customer> modify(id, data, [Map params]) async {
|
||||
var query = await read(toId(id), params);
|
||||
if (data is Customer) {
|
||||
query = data;
|
||||
}
|
||||
if (data is Map) {
|
||||
if (data.containsKey('created_at')) {
|
||||
query.createdAt = data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at'] != null
|
||||
? data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
if (data.containsKey('updated_at')) {
|
||||
query.updatedAt = data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at'] != null
|
||||
? data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
}
|
||||
return await CustomerQuery.updateCustomer(connection, query);
|
||||
}
|
||||
}
|
6
angel_orm_generator/test/models/customer.up.g.sql
Normal file
6
angel_orm_generator/test/models/customer.up.g.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
CREATE TEMPORARY TABLE "customers" (
|
||||
"id" serial,
|
||||
"created_at" timestamp,
|
||||
"updated_at" timestamp,
|
||||
PRIMARY KEY(id)
|
||||
);
|
|
@ -250,3 +250,15 @@ class FootQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class FootFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const legId = 'leg_id';
|
||||
|
||||
static const nToes = 'n_toes';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
|
@ -255,3 +255,15 @@ class FruitQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class FruitFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const treeId = 'tree_id';
|
||||
|
||||
static const commonName = 'common_name';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
|
@ -255,3 +255,13 @@ class LegQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class LegFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const name = 'name';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
17
angel_orm_generator/test/models/order.dart
Normal file
17
angel_orm_generator/test/models/order.dart
Normal file
|
@ -0,0 +1,17 @@
|
|||
library angel_orm_generator.test.models.order;
|
||||
|
||||
import 'package:angel_model/angel_model.dart';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:angel_serialize/angel_serialize.dart';
|
||||
import 'customer.dart';
|
||||
part 'order.g.dart';
|
||||
|
||||
@orm
|
||||
@serializable
|
||||
class _Order extends Model {
|
||||
@CanJoin(Customer, 'id')
|
||||
int customerId;
|
||||
int employeeId;
|
||||
DateTime orderDate;
|
||||
int shipperId;
|
||||
}
|
1
angel_orm_generator/test/models/order.down.g.sql
Normal file
1
angel_orm_generator/test/models/order.down.g.sql
Normal file
|
@ -0,0 +1 @@
|
|||
DROP TABLE "orders";
|
78
angel_orm_generator/test/models/order.g.dart
Normal file
78
angel_orm_generator/test/models/order.g.dart
Normal file
|
@ -0,0 +1,78 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of angel_orm_generator.test.models.order;
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class Order extends _Order {
|
||||
@override
|
||||
String id;
|
||||
|
||||
@override
|
||||
int customerId;
|
||||
|
||||
@override
|
||||
int employeeId;
|
||||
|
||||
@override
|
||||
DateTime orderDate;
|
||||
|
||||
@override
|
||||
int shipperId;
|
||||
|
||||
@override
|
||||
DateTime createdAt;
|
||||
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
|
||||
Order(
|
||||
{this.id,
|
||||
this.customerId,
|
||||
this.employeeId,
|
||||
this.orderDate,
|
||||
this.shipperId,
|
||||
this.createdAt,
|
||||
this.updatedAt});
|
||||
|
||||
factory Order.fromJson(Map data) {
|
||||
return new Order(
|
||||
id: data['id'],
|
||||
customerId: data['customer_id'],
|
||||
employeeId: data['employee_id'],
|
||||
orderDate: data['order_date'] is DateTime
|
||||
? data['order_date']
|
||||
: (data['order_date'] is String
|
||||
? DateTime.parse(data['order_date'])
|
||||
: null),
|
||||
shipperId: data['shipper_id'],
|
||||
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,
|
||||
'customer_id': customerId,
|
||||
'employee_id': employeeId,
|
||||
'order_date': orderDate == null ? null : orderDate.toIso8601String(),
|
||||
'shipper_id': shipperId,
|
||||
'created_at': createdAt == null ? null : createdAt.toIso8601String(),
|
||||
'updated_at': updatedAt == null ? null : updatedAt.toIso8601String()
|
||||
};
|
||||
|
||||
static Order parse(Map map) => new Order.fromJson(map);
|
||||
|
||||
Order clone() {
|
||||
return new Order.fromJson(toJson());
|
||||
}
|
||||
}
|
27
angel_orm_generator/test/models/order.migration.g.dart
Normal file
27
angel_orm_generator/test/models/order.migration.g.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: MigrationGenerator
|
||||
// **************************************************************************
|
||||
|
||||
import 'package:angel_migration/angel_migration.dart';
|
||||
|
||||
class OrderMigration extends Migration {
|
||||
@override
|
||||
up(Schema schema) {
|
||||
schema.create('orders', (table) {
|
||||
table.serial('id')..primaryKey();
|
||||
table.integer('customer_id');
|
||||
table.integer('employee_id');
|
||||
table.timeStamp('order_date');
|
||||
table.integer('shipper_id');
|
||||
table.timeStamp('created_at');
|
||||
table.timeStamp('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
down(Schema schema) {
|
||||
schema.drop('orders');
|
||||
}
|
||||
}
|
305
angel_orm_generator/test/models/order.orm.g.dart
Normal file
305
angel_orm_generator/test/models/order.orm.g.dart
Normal file
|
@ -0,0 +1,305 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: PostgresOrmGenerator
|
||||
// **************************************************************************
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:postgres/postgres.dart';
|
||||
import 'order.dart';
|
||||
|
||||
class OrderQuery {
|
||||
final Map<OrderQuery, bool> _unions = {};
|
||||
|
||||
String _sortKey;
|
||||
|
||||
String _sortMode;
|
||||
|
||||
int limit;
|
||||
|
||||
int offset;
|
||||
|
||||
final List<OrderQueryWhere> _or = [];
|
||||
|
||||
final OrderQueryWhere where = new OrderQueryWhere();
|
||||
|
||||
void union(OrderQuery query) {
|
||||
_unions[query] = false;
|
||||
}
|
||||
|
||||
void unionAll(OrderQuery query) {
|
||||
_unions[query] = true;
|
||||
}
|
||||
|
||||
void sortDescending(String key) {
|
||||
_sortMode = 'Descending';
|
||||
_sortKey = ('' + key);
|
||||
}
|
||||
|
||||
void sortAscending(String key) {
|
||||
_sortMode = 'Ascending';
|
||||
_sortKey = ('' + key);
|
||||
}
|
||||
|
||||
void or(OrderQueryWhere selector) {
|
||||
_or.add(selector);
|
||||
}
|
||||
|
||||
String toSql([String prefix]) {
|
||||
var buf = new StringBuffer();
|
||||
buf.write(prefix != null
|
||||
? prefix
|
||||
: 'SELECT id, customer_id, employee_id, order_date, shipper_id, created_at, updated_at FROM "orders"');
|
||||
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 Order parseRow(List row) {
|
||||
var result = new Order.fromJson({
|
||||
'id': row[0].toString(),
|
||||
'customer_id': row[1],
|
||||
'employee_id': row[2],
|
||||
'order_date': row[3],
|
||||
'shipper_id': row[4],
|
||||
'created_at': row[5],
|
||||
'updated_at': row[6]
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
Stream<Order> get(PostgreSQLConnection connection) {
|
||||
StreamController<Order> ctrl = new StreamController<Order>();
|
||||
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<Order> getOne(int id, PostgreSQLConnection connection) {
|
||||
var query = new OrderQuery();
|
||||
query.where.id.equals(id);
|
||||
return query.get(connection).first.catchError((_) => null);
|
||||
}
|
||||
|
||||
Stream<Order> update(PostgreSQLConnection connection,
|
||||
{int customerId,
|
||||
int employeeId,
|
||||
DateTime orderDate,
|
||||
int shipperId,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt}) {
|
||||
var buf = new StringBuffer(
|
||||
'UPDATE "orders" SET ("customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at") = (@customerId, @employeeId, @orderDate, @shipperId, @createdAt, @updatedAt) ');
|
||||
var whereClause = where.toWhereClause();
|
||||
if (whereClause != null) {
|
||||
buf.write(whereClause);
|
||||
}
|
||||
var __ormNow__ = new DateTime.now();
|
||||
var ctrl = new StreamController<Order>();
|
||||
connection.query(
|
||||
buf.toString() +
|
||||
' RETURNING "id", "customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at";',
|
||||
substitutionValues: {
|
||||
'customerId': customerId,
|
||||
'employeeId': employeeId,
|
||||
'orderDate': orderDate,
|
||||
'shipperId': shipperId,
|
||||
'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<Order> delete(PostgreSQLConnection connection) {
|
||||
StreamController<Order> ctrl = new StreamController<Order>();
|
||||
connection
|
||||
.query(toSql('DELETE FROM "orders"') +
|
||||
' RETURNING "id", "customer_id", "employee_id", "order_date", "shipper_id", "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<Order> deleteOne(int id, PostgreSQLConnection connection) {
|
||||
var query = new OrderQuery();
|
||||
query.where.id.equals(id);
|
||||
return query.delete(connection).first;
|
||||
}
|
||||
|
||||
static Future<Order> insert(PostgreSQLConnection connection,
|
||||
{int customerId,
|
||||
int employeeId,
|
||||
DateTime orderDate,
|
||||
int shipperId,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt}) async {
|
||||
var __ormNow__ = new DateTime.now();
|
||||
var result = await connection.query(
|
||||
'INSERT INTO "orders" ("customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at") VALUES (@customerId, @employeeId, @orderDate, @shipperId, @createdAt, @updatedAt) RETURNING "id", "customer_id", "employee_id", "order_date", "shipper_id", "created_at", "updated_at";',
|
||||
substitutionValues: {
|
||||
'customerId': customerId,
|
||||
'employeeId': employeeId,
|
||||
'orderDate': orderDate,
|
||||
'shipperId': shipperId,
|
||||
'createdAt': createdAt != null ? createdAt : __ormNow__,
|
||||
'updatedAt': updatedAt != null ? updatedAt : __ormNow__
|
||||
});
|
||||
var output = parseRow(result[0]);
|
||||
return output;
|
||||
}
|
||||
|
||||
static Future<Order> insertOrder(
|
||||
PostgreSQLConnection connection, Order order) {
|
||||
return OrderQuery.insert(connection,
|
||||
customerId: order.customerId,
|
||||
employeeId: order.employeeId,
|
||||
orderDate: order.orderDate,
|
||||
shipperId: order.shipperId,
|
||||
createdAt: order.createdAt,
|
||||
updatedAt: order.updatedAt);
|
||||
}
|
||||
|
||||
static Future<Order> updateOrder(
|
||||
PostgreSQLConnection connection, Order order) {
|
||||
var query = new OrderQuery();
|
||||
query.where.id.equals(int.parse(order.id));
|
||||
return query
|
||||
.update(connection,
|
||||
customerId: order.customerId,
|
||||
employeeId: order.employeeId,
|
||||
orderDate: order.orderDate,
|
||||
shipperId: order.shipperId,
|
||||
createdAt: order.createdAt,
|
||||
updatedAt: order.updatedAt)
|
||||
.first;
|
||||
}
|
||||
|
||||
static Stream<Order> getAll(PostgreSQLConnection connection) =>
|
||||
new OrderQuery().get(connection);
|
||||
|
||||
static joinCustomers(PostgreSQLConnection connection) {
|
||||
}
|
||||
}
|
||||
|
||||
class OrderQueryWhere {
|
||||
final NumericSqlExpressionBuilder<int> id =
|
||||
new NumericSqlExpressionBuilder<int>();
|
||||
|
||||
final NumericSqlExpressionBuilder<int> customerId =
|
||||
new NumericSqlExpressionBuilder<int>();
|
||||
|
||||
final NumericSqlExpressionBuilder<int> employeeId =
|
||||
new NumericSqlExpressionBuilder<int>();
|
||||
|
||||
final DateTimeSqlExpressionBuilder orderDate =
|
||||
new DateTimeSqlExpressionBuilder('orders.order_date');
|
||||
|
||||
final NumericSqlExpressionBuilder<int> shipperId =
|
||||
new NumericSqlExpressionBuilder<int>();
|
||||
|
||||
final DateTimeSqlExpressionBuilder createdAt =
|
||||
new DateTimeSqlExpressionBuilder('orders.created_at');
|
||||
|
||||
final DateTimeSqlExpressionBuilder updatedAt =
|
||||
new DateTimeSqlExpressionBuilder('orders.updated_at');
|
||||
|
||||
String toWhereClause({bool keyword}) {
|
||||
final List<String> expressions = [];
|
||||
if (id.hasValue) {
|
||||
expressions.add('orders.id ' + id.compile());
|
||||
}
|
||||
if (customerId.hasValue) {
|
||||
expressions.add('orders.customer_id ' + customerId.compile());
|
||||
}
|
||||
if (employeeId.hasValue) {
|
||||
expressions.add('orders.employee_id ' + employeeId.compile());
|
||||
}
|
||||
if (orderDate.hasValue) {
|
||||
expressions.add(orderDate.compile());
|
||||
}
|
||||
if (shipperId.hasValue) {
|
||||
expressions.add('orders.shipper_id ' + shipperId.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 '));
|
||||
}
|
||||
}
|
||||
|
||||
class OrderFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const customerId = 'customer_id';
|
||||
|
||||
static const employeeId = 'employee_id';
|
||||
|
||||
static const orderDate = 'order_date';
|
||||
|
||||
static const shipperId = 'shipper_id';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
189
angel_orm_generator/test/models/order.service.g.dart
Normal file
189
angel_orm_generator/test/models/order.service.g.dart
Normal file
|
@ -0,0 +1,189 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
// **************************************************************************
|
||||
// Generator: PostgresServiceGenerator
|
||||
// **************************************************************************
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:postgres/postgres.dart';
|
||||
import 'order.dart';
|
||||
import 'order.orm.g.dart';
|
||||
|
||||
class OrderService extends Service {
|
||||
final PostgreSQLConnection connection;
|
||||
|
||||
final bool allowRemoveAll;
|
||||
|
||||
final bool allowQuery;
|
||||
|
||||
OrderService(this.connection,
|
||||
{this.allowRemoveAll: false, this.allowQuery: false});
|
||||
|
||||
OrderQuery buildQuery(Map params) {
|
||||
var query = new OrderQuery();
|
||||
if (params['query'] is Map) {
|
||||
query.where.id.equals(params['query']['id']);
|
||||
query.where.customerId.equals(params['query']['customer_id']);
|
||||
query.where.employeeId.equals(params['query']['employee_id']);
|
||||
query.where.orderDate.equals(params['query']['order_date'] is String
|
||||
? DateTime.parse(params['query']['order_date'])
|
||||
: params['query']['order_date'] != null
|
||||
? params['query']['order_date'] is String
|
||||
? DateTime.parse(params['query']['order_date'])
|
||||
: params['query']['order_date']
|
||||
: new DateTime.now());
|
||||
query.where.shipperId.equals(params['query']['shipper_id']);
|
||||
query.where.createdAt.equals(params['query']['created_at'] is String
|
||||
? DateTime.parse(params['query']['created_at'])
|
||||
: params['query']['created_at'] != null
|
||||
? params['query']['created_at'] is String
|
||||
? DateTime.parse(params['query']['created_at'])
|
||||
: params['query']['created_at']
|
||||
: new DateTime.now());
|
||||
query.where.updatedAt.equals(params['query']['updated_at'] is String
|
||||
? DateTime.parse(params['query']['updated_at'])
|
||||
: params['query']['updated_at'] != null
|
||||
? params['query']['updated_at'] is String
|
||||
? DateTime.parse(params['query']['updated_at'])
|
||||
: params['query']['updated_at']
|
||||
: new DateTime.now());
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
int toId(id) {
|
||||
if (id is int) {
|
||||
return id;
|
||||
} else {
|
||||
if (id == 'null' || id == null) {
|
||||
return null;
|
||||
} else {
|
||||
return int.parse(id.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Order applyData(data) {
|
||||
if (data is Order || data == null) {
|
||||
return data;
|
||||
}
|
||||
if (data is Map) {
|
||||
var query = new Order();
|
||||
if (data.containsKey('customer_id')) {
|
||||
query.customerId = data['customer_id'];
|
||||
}
|
||||
if (data.containsKey('employee_id')) {
|
||||
query.employeeId = data['employee_id'];
|
||||
}
|
||||
if (data.containsKey('order_date')) {
|
||||
query.orderDate = data['order_date'] is String
|
||||
? DateTime.parse(data['order_date'])
|
||||
: data['order_date'] != null
|
||||
? data['order_date'] is String
|
||||
? DateTime.parse(data['order_date'])
|
||||
: data['order_date']
|
||||
: new DateTime.now();
|
||||
}
|
||||
if (data.containsKey('shipper_id')) {
|
||||
query.shipperId = data['shipper_id'];
|
||||
}
|
||||
if (data.containsKey('created_at')) {
|
||||
query.createdAt = data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at'] != null
|
||||
? data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
if (data.containsKey('updated_at')) {
|
||||
query.updatedAt = data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at'] != null
|
||||
? data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
return query;
|
||||
} else
|
||||
throw new AngelHttpException.badRequest(message: 'Invalid data.');
|
||||
}
|
||||
|
||||
Future<List<Order>> index([Map params]) {
|
||||
return buildQuery(params).get(connection).toList();
|
||||
}
|
||||
|
||||
Future<Order> create(data, [Map params]) {
|
||||
return OrderQuery.insertOrder(connection, applyData(data));
|
||||
}
|
||||
|
||||
Future<Order> read(id, [Map params]) {
|
||||
var query = buildQuery(params);
|
||||
query.where.id.equals(toId(id));
|
||||
return query.get(connection).first.catchError((_) {
|
||||
new AngelHttpException.notFound(
|
||||
message: 'No record found for ID ' + id.toString());
|
||||
});
|
||||
}
|
||||
|
||||
Future<Order> remove(id, [Map params]) {
|
||||
var query = buildQuery(params);
|
||||
query.where.id.equals(toId(id));
|
||||
return query.delete(connection).first.catchError((_) {
|
||||
new AngelHttpException.notFound(
|
||||
message: 'No record found for ID ' + id.toString());
|
||||
});
|
||||
}
|
||||
|
||||
Future<Order> update(id, data, [Map params]) {
|
||||
return OrderQuery.updateOrder(connection, applyData(data));
|
||||
}
|
||||
|
||||
Future<Order> modify(id, data, [Map params]) async {
|
||||
var query = await read(toId(id), params);
|
||||
if (data is Order) {
|
||||
query = data;
|
||||
}
|
||||
if (data is Map) {
|
||||
if (data.containsKey('customer_id')) {
|
||||
query.customerId = data['customer_id'];
|
||||
}
|
||||
if (data.containsKey('employee_id')) {
|
||||
query.employeeId = data['employee_id'];
|
||||
}
|
||||
if (data.containsKey('order_date')) {
|
||||
query.orderDate = data['order_date'] is String
|
||||
? DateTime.parse(data['order_date'])
|
||||
: data['order_date'] != null
|
||||
? data['order_date'] is String
|
||||
? DateTime.parse(data['order_date'])
|
||||
: data['order_date']
|
||||
: new DateTime.now();
|
||||
}
|
||||
if (data.containsKey('shipper_id')) {
|
||||
query.shipperId = data['shipper_id'];
|
||||
}
|
||||
if (data.containsKey('created_at')) {
|
||||
query.createdAt = data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at'] != null
|
||||
? data['created_at'] is String
|
||||
? DateTime.parse(data['created_at'])
|
||||
: data['created_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
if (data.containsKey('updated_at')) {
|
||||
query.updatedAt = data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at'] != null
|
||||
? data['updated_at'] is String
|
||||
? DateTime.parse(data['updated_at'])
|
||||
: data['updated_at']
|
||||
: new DateTime.now();
|
||||
}
|
||||
}
|
||||
return await OrderQuery.updateOrder(connection, query);
|
||||
}
|
||||
}
|
10
angel_orm_generator/test/models/order.up.g.sql
Normal file
10
angel_orm_generator/test/models/order.up.g.sql
Normal file
|
@ -0,0 +1,10 @@
|
|||
CREATE TEMPORARY TABLE "orders" (
|
||||
"id" serial,
|
||||
"customer_id" int,
|
||||
"employee_id" int,
|
||||
"order_date" timestamp,
|
||||
"shipper_id" int,
|
||||
"created_at" timestamp,
|
||||
"updated_at" timestamp,
|
||||
PRIMARY KEY(id)
|
||||
);
|
|
@ -235,3 +235,13 @@ class RoleQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class RoleFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const name = 'name';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
|
@ -260,3 +260,13 @@ class TreeQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class TreeFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const rings = 'rings';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
|
@ -283,3 +283,17 @@ class UserQueryWhere {
|
|||
: ((keyword != false ? 'WHERE ' : '') + expressions.join(' AND '));
|
||||
}
|
||||
}
|
||||
|
||||
class UserFields {
|
||||
static const id = 'id';
|
||||
|
||||
static const username = 'username';
|
||||
|
||||
static const password = 'password';
|
||||
|
||||
static const email = 'email';
|
||||
|
||||
static const createdAt = 'created_at';
|
||||
|
||||
static const updatedAt = 'updated_at';
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@ const List<String> standaloneModels = const [
|
|||
'test/models/car.dart',
|
||||
'test/models/foot.dart',
|
||||
'test/models/fruit.dart',
|
||||
'test/models/order.dart',
|
||||
'test/models/role.dart'
|
||||
];
|
||||
const List<String> dependentModels = const [
|
||||
'test/models/book.dart',
|
||||
'test/models/customer.dart',
|
||||
'test/models/leg.dart',
|
||||
'test/models/tree.dart',
|
||||
'test/models/user.dart'
|
||||
|
|
Loading…
Reference in a new issue