ORM gen updates
This commit is contained in:
parent
e95c4d8c6b
commit
432bac7512
30 changed files with 639 additions and 595 deletions
|
@ -3,14 +3,10 @@ builders:
|
||||||
import: "package:angel_orm_generator/angel_orm_generator.dart"
|
import: "package:angel_orm_generator/angel_orm_generator.dart"
|
||||||
builder_factories:
|
builder_factories:
|
||||||
- ormBuilder
|
- ormBuilder
|
||||||
#- mongoDBOrmBuilder
|
|
||||||
- postgreSqlOrmBuilder
|
|
||||||
auto_apply: root_package
|
auto_apply: root_package
|
||||||
build_to: source
|
build_to: source
|
||||||
build_extensions:
|
build_extensions:
|
||||||
.dart:
|
.dart:
|
||||||
- ".orm.g.dart"
|
- ".angel_orm.g.part"
|
||||||
- ".mongodb.orm.g.dart"
|
applies_builders:
|
||||||
- ".mysql.orm.g.dart"
|
["source_gen|combining_builder", "source_gen|part_cleanup"]
|
||||||
- ".rethinkdb.orm.g.dart"
|
|
||||||
- ".postgresql.orm.g.dart"
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//export 'src/mongodb_orm_generator.dart';
|
//export 'src/mongodb_orm_generator.dart';
|
||||||
export 'src/orm_build_context.dart';
|
export 'src/orm_build_context.dart';
|
||||||
export 'src/orm_generator.dart';
|
export 'src/orm_generator.dart';
|
||||||
export 'src/postgresql_orm_generator.dart';
|
|
||||||
export 'src/readers.dart';
|
export 'src/readers.dart';
|
|
@ -1,45 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
|
||||||
import 'package:angel_orm/angel_orm.dart';
|
|
||||||
import 'package:build/build.dart';
|
|
||||||
import 'package:code_builder/code_builder.dart' hide LibraryBuilder;
|
|
||||||
import 'package:path/path.dart' as p;
|
|
||||||
import 'package:source_gen/source_gen.dart';
|
|
||||||
|
|
||||||
import 'orm_build_context.dart';
|
|
||||||
|
|
||||||
Builder mongoDBOrmBuilder(_) {
|
|
||||||
return new LibraryBuilder(new MongoDBOrmGenerator(),
|
|
||||||
generatedExtension: '.mongodb.orm.g.dart');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builder that generates `.orm.g.dart`, with an abstract `FooOrm` class.
|
|
||||||
class MongoDBOrmGenerator extends GeneratorForAnnotation<Orm> {
|
|
||||||
final bool autoSnakeCaseNames;
|
|
||||||
final bool autoIdAndDateFields;
|
|
||||||
|
|
||||||
MongoDBOrmGenerator({this.autoSnakeCaseNames, this.autoIdAndDateFields});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<String> generateForAnnotatedElement(
|
|
||||||
Element element, ConstantReader annotation, BuildStep buildStep) async {
|
|
||||||
if (element is ClassElement) {
|
|
||||||
var ctx = await buildOrmContext(element, annotation, buildStep,
|
|
||||||
buildStep.resolver, autoSnakeCaseNames, autoIdAndDateFields);
|
|
||||||
var lib = buildOrmLibrary(buildStep.inputId, ctx);
|
|
||||||
return lib.accept(new DartEmitter()).toString();
|
|
||||||
} else {
|
|
||||||
throw 'The @Orm() annotation can only be applied to classes.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Library buildOrmLibrary(AssetId inputId, OrmBuildContext ctx) {
|
|
||||||
return new Library((lib) {
|
|
||||||
// Add part of
|
|
||||||
var libFile =
|
|
||||||
p.setExtension(p.basename(inputId.uri.path), '.orm.g.dart');
|
|
||||||
lib.body.add(new Code("part of '$libFile';"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +1,19 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:collection';
|
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:angel_orm/angel_orm.dart';
|
import 'package:angel_orm/angel_orm.dart';
|
||||||
|
import 'package:angel_serialize_generator/angel_serialize_generator.dart';
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
import 'package:code_builder/code_builder.dart' hide LibraryBuilder;
|
import 'package:code_builder/code_builder.dart' hide LibraryBuilder;
|
||||||
import 'package:path/path.dart' as p;
|
|
||||||
import 'package:recase/recase.dart';
|
|
||||||
import 'package:source_gen/source_gen.dart';
|
import 'package:source_gen/source_gen.dart';
|
||||||
|
|
||||||
import 'orm_build_context.dart';
|
import 'orm_build_context.dart';
|
||||||
|
|
||||||
Builder ormBuilder(_) {
|
Builder ormBuilder(BuilderOptions options) {
|
||||||
return new LibraryBuilder(new OrmGenerator(),
|
return new SharedPartBuilder([
|
||||||
generatedExtension: '.orm.g.dart');
|
new OrmGenerator(
|
||||||
|
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false,
|
||||||
|
autoIdAndDateFields: options.config['auto_id_and_date_fields'] != false)
|
||||||
|
], 'angel_orm');
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeReference futureOf(String type) {
|
TypeReference futureOf(String type) {
|
||||||
|
@ -34,156 +35,151 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
if (element is ClassElement) {
|
if (element is ClassElement) {
|
||||||
var ctx = await buildOrmContext(element, annotation, buildStep,
|
var ctx = await buildOrmContext(element, annotation, buildStep,
|
||||||
buildStep.resolver, autoSnakeCaseNames, autoIdAndDateFields);
|
buildStep.resolver, autoSnakeCaseNames, autoIdAndDateFields);
|
||||||
var lib = buildOrmBaseLibrary(buildStep.inputId, ctx);
|
var lib = buildOrmLibrary(buildStep.inputId, ctx);
|
||||||
return lib.accept(new DartEmitter()).toString();
|
return lib.accept(new DartEmitter()).toString();
|
||||||
} else {
|
} else {
|
||||||
throw 'The @Orm() annotation can only be applied to classes.';
|
throw 'The @Orm() annotation can only be applied to classes.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Library buildOrmBaseLibrary(AssetId inputId, OrmBuildContext ctx) {
|
Library buildOrmLibrary(AssetId inputId, OrmBuildContext ctx) {
|
||||||
return new Library((lib) {
|
return new Library((lib) {
|
||||||
// Necessary imports
|
// Create `FooQuery` class
|
||||||
var imports = new SplayTreeSet<String>.from(
|
// Create `FooQueryWhere` class
|
||||||
['dart:async', p.basename(inputId.uri.path)]);
|
lib.body.add(buildQueryClass(ctx));
|
||||||
|
lib.body.add(buildWhereClass(ctx));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
switch (ctx.ormAnnotation.type) {
|
Class buildQueryClass(OrmBuildContext ctx) {
|
||||||
// case OrmType.mongoDB:
|
// TODO: Handle relations
|
||||||
// imports.add('package:mongo_dart/mongo_dart.dart');
|
|
||||||
// break;
|
|
||||||
case OrmType.postgreSql:
|
|
||||||
imports.add('package:postgres/postgres.dart');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lib.directives.addAll(imports.map((url) => new Directive.import(url)));
|
return new Class((clazz) {
|
||||||
|
|
||||||
// Add the corresponding `part`
|
|
||||||
String dbExtension;
|
|
||||||
|
|
||||||
switch (ctx.ormAnnotation.type) {
|
|
||||||
// case OrmType.mongoDB:
|
|
||||||
// dbExtension = 'mongodb';
|
|
||||||
// break;
|
|
||||||
case OrmType.rethinkDB:
|
|
||||||
dbExtension = 'rethinkdb';
|
|
||||||
break;
|
|
||||||
case OrmType.mySql:
|
|
||||||
dbExtension = 'mysql';
|
|
||||||
break;
|
|
||||||
case OrmType.postgreSql:
|
|
||||||
dbExtension = 'postgresql';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw 'Unsupported ORM type: ${ctx.ormAnnotation.type}';
|
|
||||||
}
|
|
||||||
|
|
||||||
var dbFile = p.setExtension(
|
|
||||||
p.basename(inputId.uri.path), '.$dbExtension.orm.g.dart');
|
|
||||||
|
|
||||||
lib.body.add(new Code("part '$dbFile';"));
|
|
||||||
|
|
||||||
// Create `FooOrm` abstract class
|
|
||||||
var rc = ctx.buildContext.modelClassNameRecase;
|
var rc = ctx.buildContext.modelClassNameRecase;
|
||||||
|
var queryWhereType = refer('${rc.pascalCase}QueryWhere');
|
||||||
|
clazz
|
||||||
|
..name = '${rc.pascalCase}Query'
|
||||||
|
..extend = new TypeReference((b) {
|
||||||
|
b
|
||||||
|
..symbol = 'Query'
|
||||||
|
..types.addAll([
|
||||||
|
ctx.buildContext.modelClassType,
|
||||||
|
queryWhereType,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
lib.body.add(new Class((clazz) {
|
// Add tableName
|
||||||
clazz
|
clazz.methods.add(new Method((m) {
|
||||||
..name = '${rc.pascalCase}Orm'
|
m
|
||||||
..abstract = true;
|
..name = 'tableName'
|
||||||
|
..annotations.add(refer('override'))
|
||||||
// Add factory constructors.
|
..type = MethodType.getter
|
||||||
switch (ctx.ormAnnotation.type) {
|
..body = new Block((b) {
|
||||||
case OrmType.postgreSql:
|
b.addExpression(literalString(ctx.tableName).returned);
|
||||||
clazz.constructors.add(new Constructor((b) {
|
});
|
||||||
b
|
|
||||||
..name = 'postgreSql'
|
|
||||||
..factory = true
|
|
||||||
..redirect = refer('PostgreSql${rc.pascalCase}Orm')
|
|
||||||
..requiredParameters.add(new Parameter((b) {
|
|
||||||
b
|
|
||||||
..name = 'connection'
|
|
||||||
..type = refer('PostgreSQLConnection');
|
|
||||||
}));
|
|
||||||
}));
|
|
||||||
dbExtension = 'postgresql';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, add method stubs.
|
|
||||||
// * getAll
|
|
||||||
// * getById
|
|
||||||
// * deleteById
|
|
||||||
// * updateX()
|
|
||||||
// * createX()
|
|
||||||
// * query()
|
|
||||||
|
|
||||||
// getAll
|
|
||||||
clazz.methods.add(new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'getAll'
|
|
||||||
..returns = new TypeReference((b) => b
|
|
||||||
..symbol = 'Future'
|
|
||||||
..types.add(new TypeReference((b) => b
|
|
||||||
..symbol = 'List'
|
|
||||||
..types.add(ctx.buildContext.modelClassType))));
|
|
||||||
}));
|
|
||||||
|
|
||||||
// getById
|
|
||||||
clazz.methods.add(new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'getById'
|
|
||||||
..returns = futureOf(ctx.buildContext.modelClassName)
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'id'
|
|
||||||
..type = refer('String')));
|
|
||||||
}));
|
|
||||||
|
|
||||||
// deleteById
|
|
||||||
clazz.methods.add(new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'deleteById'
|
|
||||||
..returns = futureOf(ctx.buildContext.modelClassName)
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'id'
|
|
||||||
..type = refer('String')));
|
|
||||||
}));
|
|
||||||
|
|
||||||
// createX()
|
|
||||||
clazz.methods.add(new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'create${ctx.buildContext.modelClassName}'
|
|
||||||
..returns = futureOf(ctx.buildContext.modelClassName)
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'model'
|
|
||||||
..type = ctx.buildContext.modelClassType));
|
|
||||||
}));
|
|
||||||
|
|
||||||
// updateX()
|
|
||||||
clazz.methods.add(new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'update${ctx.buildContext.modelClassName}'
|
|
||||||
..returns = futureOf(ctx.buildContext.modelClassName)
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'model'
|
|
||||||
..type = ctx.buildContext.modelClassType));
|
|
||||||
}));
|
|
||||||
|
|
||||||
// query()
|
|
||||||
clazz.methods.add(new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'query'
|
|
||||||
..returns = refer('${rc.pascalCase}Query');
|
|
||||||
}));
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Create `FooQuery` class
|
// Add fields getter
|
||||||
lib.body.add(new Class((clazz) {
|
clazz.methods.add(new Method((m) {
|
||||||
clazz..name = '${rc.pascalCase}Query';
|
m
|
||||||
|
..name = 'fields'
|
||||||
|
..annotations.add(refer('override'))
|
||||||
|
..type = MethodType.getter
|
||||||
|
..body = new Block((b) {
|
||||||
|
var names = ctx.buildContext.fields
|
||||||
|
.map((f) => literalString(f.name))
|
||||||
|
.toList();
|
||||||
|
b.addExpression(literalConstList(names).returned);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Add where member
|
||||||
|
clazz.fields.add(new Field((b) {
|
||||||
|
b
|
||||||
|
..annotations.add(refer('override'))
|
||||||
|
..name = 'where'
|
||||||
|
..modifier = FieldModifier.final$
|
||||||
|
..type = queryWhereType
|
||||||
|
..assignment = queryWhereType.newInstance([]).code;
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Add deserialize()
|
||||||
|
clazz.methods.add(new Method((m) {
|
||||||
|
m
|
||||||
|
..name = 'deserialize'
|
||||||
|
..annotations.add(refer('override'))
|
||||||
|
..requiredParameters.add(new Parameter((b) => b
|
||||||
|
..name = 'row'
|
||||||
|
..type = refer('List')))
|
||||||
|
..body = new Block((b) {
|
||||||
|
int i = 0;
|
||||||
|
var args = <String, Expression>{};
|
||||||
|
|
||||||
|
for (var field in ctx.buildContext.fields) {
|
||||||
|
var type = convertTypeReference(field.type);
|
||||||
|
args[field.name] = (refer('row').index(literalNum(i))).asA(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
b.addExpression(
|
||||||
|
ctx.buildContext.modelClassType.newInstance([], args).returned);
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Class buildWhereClass(OrmBuildContext ctx) {
|
||||||
|
return new Class((clazz) {
|
||||||
|
var rc = ctx.buildContext.modelClassNameRecase;
|
||||||
|
clazz
|
||||||
|
..name = '${rc.pascalCase}QueryWhere'
|
||||||
|
..extend = refer('QueryWhere');
|
||||||
|
|
||||||
|
// Build expressionBuilders getter
|
||||||
|
clazz.methods.add(new Method((m) {
|
||||||
|
m
|
||||||
|
..name = 'expressionBuilders'
|
||||||
|
..annotations.add(refer('override'))
|
||||||
|
..type = MethodType.getter
|
||||||
|
..body = new Block((b) {
|
||||||
|
var references = ctx.buildContext.fields.map((f) => refer(f.name));
|
||||||
|
b.addExpression(literalList(references).returned);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Add builders for each field
|
||||||
|
for (var field in ctx.buildContext.fields) {
|
||||||
|
// TODO: Handle fields with relations
|
||||||
|
Reference builderType;
|
||||||
|
|
||||||
|
if (const TypeChecker.fromRuntime(String).isExactlyType(field.type)) {
|
||||||
|
builderType = refer('StringSqlExpressionBuilder');
|
||||||
|
} else if (const TypeChecker.fromRuntime(bool)
|
||||||
|
.isExactlyType(field.type)) {
|
||||||
|
builderType = refer('BooleanSqlExpressionBuilder');
|
||||||
|
} else if (const TypeChecker.fromRuntime(DateTime)
|
||||||
|
.isExactlyType(field.type)) {
|
||||||
|
builderType = refer('DateTimeSqlExpressionBuilder');
|
||||||
|
} else if (const TypeChecker.fromRuntime(int)
|
||||||
|
.isExactlyType(field.type) ||
|
||||||
|
const TypeChecker.fromRuntime(double).isExactlyType(field.type)) {
|
||||||
|
builderType = new TypeReference((b) => b
|
||||||
|
..symbol = 'NumericSqlExpressionBuilder'
|
||||||
|
..types.add(refer(field.type.name)));
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedError(
|
||||||
|
'Cannot generate ORM code for field of type ${field.type.name}.');
|
||||||
|
}
|
||||||
|
|
||||||
|
clazz.fields.add(new Field((b) {
|
||||||
|
b
|
||||||
|
..name = field.name
|
||||||
|
..modifier = FieldModifier.final$
|
||||||
|
..type = builderType
|
||||||
|
..assignment = builderType.newInstance([
|
||||||
|
literalString(ctx.buildContext.resolveFieldName(field.name))
|
||||||
|
]).code;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,348 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
|
||||||
import 'package:angel_orm/angel_orm.dart';
|
|
||||||
import 'package:angel_serialize_generator/angel_serialize_generator.dart';
|
|
||||||
import 'package:angel_serialize_generator/build_context.dart';
|
|
||||||
import 'package:build/build.dart';
|
|
||||||
import 'package:code_builder/code_builder.dart' hide LibraryBuilder;
|
|
||||||
import 'package:path/path.dart' as p;
|
|
||||||
import 'package:source_gen/source_gen.dart';
|
|
||||||
|
|
||||||
import 'orm_build_context.dart';
|
|
||||||
|
|
||||||
Builder postgreSqlOrmBuilder(_) {
|
|
||||||
return new LibraryBuilder(new PostgreSqlOrmGenerator(),
|
|
||||||
generatedExtension: '.postgresql.orm.g.dart');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builder that generates `.orm.g.dart`, with an abstract `FooOrm` class.
|
|
||||||
class PostgreSqlOrmGenerator extends GeneratorForAnnotation<Orm> {
|
|
||||||
final bool autoSnakeCaseNames;
|
|
||||||
final bool autoIdAndDateFields;
|
|
||||||
|
|
||||||
PostgreSqlOrmGenerator({this.autoSnakeCaseNames, this.autoIdAndDateFields});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<String> generateForAnnotatedElement(
|
|
||||||
Element element, ConstantReader annotation, BuildStep buildStep) async {
|
|
||||||
if (element is ClassElement) {
|
|
||||||
var ctx = await buildOrmContext(element, annotation, buildStep,
|
|
||||||
buildStep.resolver, autoSnakeCaseNames, autoIdAndDateFields);
|
|
||||||
var lib = buildOrmLibrary(buildStep.inputId, ctx);
|
|
||||||
return lib.accept(new DartEmitter()).toString();
|
|
||||||
} else {
|
|
||||||
throw 'The @Orm() annotation can only be applied to classes.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Library buildOrmLibrary(AssetId inputId, OrmBuildContext ctx) {
|
|
||||||
return new Library((lib) {
|
|
||||||
// Add part of
|
|
||||||
var libFile = p.setExtension(p.basename(inputId.uri.path), '.orm.g.dart');
|
|
||||||
lib.body.add(new Code("part of '$libFile';"));
|
|
||||||
|
|
||||||
// Add _PostgresqlFooOrmImpl
|
|
||||||
lib.body.add(buildOrmClass(ctx));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Class buildOrmClass(OrmBuildContext ctx) {
|
|
||||||
return new Class((clazz) {
|
|
||||||
var rc = ctx.buildContext.modelClassNameRecase;
|
|
||||||
clazz
|
|
||||||
..name = 'PostgreSql${rc.pascalCase}Orm'
|
|
||||||
..implements.add(refer('${rc.pascalCase}Orm'))
|
|
||||||
|
|
||||||
// final PostgreSQLConnection connection;
|
|
||||||
..fields.add(new Field((b) {
|
|
||||||
b
|
|
||||||
..modifier = FieldModifier.final$
|
|
||||||
..name = 'connection'
|
|
||||||
..type = refer('PostgreSQLConnection');
|
|
||||||
}))
|
|
||||||
|
|
||||||
// _PostgresqlFooOrmImpl(this.connection);
|
|
||||||
..constructors.add(new Constructor((b) {
|
|
||||||
b
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'connection'
|
|
||||||
..toThis = true));
|
|
||||||
}))
|
|
||||||
..methods.add(buildParseRowMethod(ctx))
|
|
||||||
..methods.add(buildGetById(ctx))
|
|
||||||
..methods.add(buildDeleteById(ctx))
|
|
||||||
..methods.add(buildGetAll(ctx))
|
|
||||||
..methods.add(buildCreate(ctx))
|
|
||||||
..methods.add(buildUpdate(ctx))
|
|
||||||
..methods.add(buildQuery(ctx));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Method buildQuery(OrmBuildContext ctx) {
|
|
||||||
return new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'query'
|
|
||||||
..returns = refer('${ctx.buildContext.modelClassName}Query')
|
|
||||||
..body = new Block((b) => b.addExpression(literalNull.returned));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Method buildParseRowMethod(OrmBuildContext ctx) {
|
|
||||||
return new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'parseRow'
|
|
||||||
..static = true
|
|
||||||
..returns = ctx.buildContext.modelClassType
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'row'
|
|
||||||
..type = refer('List')))
|
|
||||||
..body = new Block((b) {
|
|
||||||
var args = <String, Expression>{};
|
|
||||||
|
|
||||||
for (int i = 0; i < ctx.buildContext.fields.length; i++) {
|
|
||||||
var field = ctx.buildContext.fields[i];
|
|
||||||
args[field.name] = refer('row')
|
|
||||||
.index(literalNum(i))
|
|
||||||
.asA(convertTypeReference(field.type));
|
|
||||||
}
|
|
||||||
|
|
||||||
var returnValue =
|
|
||||||
ctx.buildContext.modelClassType.newInstance([], args);
|
|
||||||
b.addExpression(returnValue.returned);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
String buildFieldString(OrmBuildContext ctx) {
|
|
||||||
var queryString = new StringBuffer();
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (var field in ctx.buildContext.fields) {
|
|
||||||
if (i++ > 0) queryString.write(',');
|
|
||||||
queryString.write(' ' + ctx.buildContext.resolveFieldName(field.name));
|
|
||||||
}
|
|
||||||
return queryString.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
String buildQuotedFieldString(OrmBuildContext ctx) {
|
|
||||||
var queryString = new StringBuffer();
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (var field in ctx.buildContext.fields) {
|
|
||||||
if (i++ > 0) queryString.write(',');
|
|
||||||
queryString
|
|
||||||
.write(' "' + ctx.buildContext.resolveFieldName(field.name) + '"');
|
|
||||||
}
|
|
||||||
return queryString.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
String buildInsertionValueString(OrmBuildContext ctx) {
|
|
||||||
var buf = new StringBuffer('(');
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (var field in ctx.buildContext.fields) {
|
|
||||||
if (i++ > 0) buf.write(',');
|
|
||||||
if (dateTimeTypeChecker.isAssignableFromType(field.type))
|
|
||||||
buf.write(
|
|
||||||
'CAST (@${field.name} AS ${ctx.columns[field.name].type.name})');
|
|
||||||
else
|
|
||||||
buf.write('@${field.name}');
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.toString() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression buildSubstitutionValues(OrmBuildContext ctx) {
|
|
||||||
var values = <Expression, Expression>{};
|
|
||||||
|
|
||||||
for (var field in ctx.buildContext.fields) {
|
|
||||||
values[literalString(field.name)] = refer('model').property(field.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return literalMap(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
void applyQuery(
|
|
||||||
BlockBuilder b, String queryString, Expression substitutionValues) {
|
|
||||||
b.statements.add(refer('connection')
|
|
||||||
.property('query')
|
|
||||||
.call(
|
|
||||||
[literalString(queryString)],
|
|
||||||
substitutionValues == null
|
|
||||||
? {}
|
|
||||||
: {'substitutionValues': substitutionValues})
|
|
||||||
.awaited
|
|
||||||
.assignVar('r')
|
|
||||||
.statement);
|
|
||||||
}
|
|
||||||
|
|
||||||
void applyQueryAndReturnOne(
|
|
||||||
BlockBuilder b, String queryString, Expression substitutionValues) {
|
|
||||||
applyQuery(b, queryString, substitutionValues);
|
|
||||||
b.addExpression(
|
|
||||||
(refer('parseRow').call([refer('r').property('first')])).returned);
|
|
||||||
}
|
|
||||||
|
|
||||||
void applyQueryAndReturnList(
|
|
||||||
BlockBuilder b, String queryString, Expression substitutionValues) {
|
|
||||||
applyQuery(b, queryString, substitutionValues);
|
|
||||||
b.statements.add(new Code('return r.map(parseRow).toList();'));
|
|
||||||
}
|
|
||||||
|
|
||||||
Method buildGetById(OrmBuildContext ctx) {
|
|
||||||
/*
|
|
||||||
@override
|
|
||||||
Future<Author> getById(id) async {
|
|
||||||
var r = await connection.query('');
|
|
||||||
return parseRow(r.first);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'getById'
|
|
||||||
..annotations.add(refer('override'))
|
|
||||||
..modifier = MethodModifier.async
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'id'
|
|
||||||
..type = refer('String')))
|
|
||||||
..returns = new TypeReference((b) => b
|
|
||||||
..symbol = 'Future'
|
|
||||||
..types.add(ctx.buildContext.modelClassType))
|
|
||||||
..body = new Block((b) {
|
|
||||||
var fields = buildFieldString(ctx);
|
|
||||||
var queryString =
|
|
||||||
'SELECT $fields FROM "${ctx.tableName}" WHERE id = @id LIMIT 1;';
|
|
||||||
applyQueryAndReturnOne(
|
|
||||||
b,
|
|
||||||
queryString,
|
|
||||||
literalMap({
|
|
||||||
'id': refer('int').property('parse').call([refer('id')])
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Method buildDeleteById(OrmBuildContext ctx) {
|
|
||||||
/*
|
|
||||||
@override
|
|
||||||
Future<Author> getById(id) async {
|
|
||||||
var r = await connection.query('');
|
|
||||||
return parseRow(r.first);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return new Method((m) {
|
|
||||||
m
|
|
||||||
..name = 'deleteById'
|
|
||||||
..annotations.add(refer('override'))
|
|
||||||
..modifier = MethodModifier.async
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'id'
|
|
||||||
..type = refer('String')))
|
|
||||||
..returns = new TypeReference((b) => b
|
|
||||||
..symbol = 'Future'
|
|
||||||
..types.add(ctx.buildContext.modelClassType))
|
|
||||||
..body = new Block((b) {
|
|
||||||
var fields = buildQuotedFieldString(ctx);
|
|
||||||
var queryString =
|
|
||||||
'DELETE FROM "${ctx.tableName}" WHERE id = @id RETURNING $fields;';
|
|
||||||
applyQueryAndReturnOne(
|
|
||||||
b,
|
|
||||||
queryString,
|
|
||||||
literalMap({
|
|
||||||
'id': refer('int').property('parse').call([refer('id')])
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Method buildGetAll(OrmBuildContext ctx) {
|
|
||||||
/*
|
|
||||||
@override
|
|
||||||
Future<List<Author>> getAll() async {
|
|
||||||
var r = await connection
|
|
||||||
.query('SELECT id, name, created_at, updated_at FROM "authors";');
|
|
||||||
return r.map(parseRow).toList();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return new Method((method) {
|
|
||||||
method
|
|
||||||
..name = 'getAll'
|
|
||||||
..modifier = MethodModifier.async
|
|
||||||
..returns = refer('Future<List<${ctx.buildContext.modelClassName}>>')
|
|
||||||
..annotations.add(refer('override'))
|
|
||||||
..body = new Block((block) {
|
|
||||||
var fields = buildFieldString(ctx);
|
|
||||||
var queryString = 'SELECT $fields FROM "${ctx.tableName}";';
|
|
||||||
applyQueryAndReturnList(block, queryString, null);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Method buildCreate(OrmBuildContext ctx) {
|
|
||||||
/*
|
|
||||||
@override
|
|
||||||
Future<Author> createAuthor(Author model) async {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return new Method((method) {
|
|
||||||
method
|
|
||||||
..name = 'create${ctx.buildContext.modelClassName}'
|
|
||||||
..modifier = MethodModifier.async
|
|
||||||
..annotations.add(refer('override'))
|
|
||||||
..returns = refer('Future<${ctx.buildContext.modelClassName}>')
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'model'
|
|
||||||
..type = ctx.buildContext.modelClassType))
|
|
||||||
..body = new Block((block) {
|
|
||||||
if (ctx.buildContext.autoIdAndDateFields != false) {
|
|
||||||
// If we are auto-managing created+updated at, do so now
|
|
||||||
block.statements.add(new Code(
|
|
||||||
'model = model.copyWith(createdAt: new DateTime.now(), updatedAt: new DateTime.now());'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var fields = buildQuotedFieldString(ctx);
|
|
||||||
var fieldSet = buildInsertionValueString(ctx);
|
|
||||||
var queryString =
|
|
||||||
'INSERT INTO "${ctx.tableName}" ($fields) VALUES $fieldSet RETURNING $fields;';
|
|
||||||
applyQueryAndReturnOne(
|
|
||||||
block, queryString, buildSubstitutionValues(ctx));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Method buildUpdate(OrmBuildContext ctx) {
|
|
||||||
/*
|
|
||||||
@override
|
|
||||||
Future<Author> updateAuthor(Author model) async {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return new Method((method) {
|
|
||||||
method
|
|
||||||
..name = 'update${ctx.buildContext.modelClassName}'
|
|
||||||
..modifier = MethodModifier.async
|
|
||||||
..annotations.add(refer('override'))
|
|
||||||
..returns = refer('Future<${ctx.buildContext.modelClassName}>')
|
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
|
||||||
..name = 'model'
|
|
||||||
..type = ctx.buildContext.modelClassType))
|
|
||||||
..body = new Block((block) {
|
|
||||||
if (ctx.buildContext.autoIdAndDateFields != false) {
|
|
||||||
// If we are auto-managing created+updated at, do so now
|
|
||||||
block.statements.add(new Code(
|
|
||||||
'model = model.copyWith(updatedAt: new DateTime.now());'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var fields = buildQuotedFieldString(ctx);
|
|
||||||
var fieldSet = buildInsertionValueString(ctx);
|
|
||||||
var queryString =
|
|
||||||
'UPDATE "${ctx.tableName}" SET ($fields) = $fieldSet RETURNING $fields;';
|
|
||||||
applyQueryAndReturnOne(
|
|
||||||
block, queryString, buildSubstitutionValues(ctx));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,10 +5,7 @@ import 'package:source_gen/source_gen.dart';
|
||||||
const TypeChecker columnTypeChecker = const TypeChecker.fromRuntime(Column);
|
const TypeChecker columnTypeChecker = const TypeChecker.fromRuntime(Column);
|
||||||
|
|
||||||
Orm reviveORMAnnotation(ConstantReader reader) {
|
Orm reviveORMAnnotation(ConstantReader reader) {
|
||||||
return Orm(
|
return Orm(tableName: reader.peek('tableName')?.stringValue);
|
||||||
OrmType.values[reader.read('type').objectValue.getField('index').toIntValue()],
|
|
||||||
tableName: reader.peek('tableName')?.stringValue,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ColumnReader {
|
class ColumnReader {
|
||||||
|
|
|
@ -8,7 +8,7 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
angel_orm: ^2.0.0-dev
|
angel_orm: ^2.0.0-dev
|
||||||
angel_serialize_generator: ^2.0.0
|
angel_serialize_generator: ^2.0.0
|
||||||
build: ^0.12.0
|
build: ">=0.12.0 <2.0.0"
|
||||||
build_config: ^0.3.0
|
build_config: ^0.3.0
|
||||||
code_builder: ^3.0.0
|
code_builder: ^3.0.0
|
||||||
inflection:
|
inflection:
|
||||||
|
@ -23,6 +23,6 @@ dev_dependencies:
|
||||||
angel_framework: ^2.0.0-alpha
|
angel_framework: ^2.0.0-alpha
|
||||||
#angel_migration: ^1.0.0-alpha
|
#angel_migration: ^1.0.0-alpha
|
||||||
#angel_test: ^1.0.0
|
#angel_test: ^1.0.0
|
||||||
build_runner: ^0.10.0
|
build_runner: ^1.0.0
|
||||||
postgres: ^1.0.0
|
postgres: ^1.0.0
|
||||||
test: ^1.0.0
|
test: ^1.0.0
|
||||||
|
|
|
@ -9,7 +9,7 @@ part 'author.g.dart';
|
||||||
part 'author.serializer.g.dart';
|
part 'author.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Author extends Model {
|
class _Author extends Model {
|
||||||
@Column(length: 255, indexType: IndexType.unique, defaultValue: 'Tobe Osakwe')
|
@Column(length: 255, indexType: IndexType.unique, defaultValue: 'Tobe Osakwe')
|
||||||
String name;
|
String name;
|
||||||
|
|
|
@ -2,6 +2,52 @@
|
||||||
|
|
||||||
part of angel_orm.generator.models.author;
|
part of angel_orm.generator.models.author;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// OrmGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class AuthorQuery extends Query<Author, AuthorQueryWhere> {
|
||||||
|
@override
|
||||||
|
final AuthorQueryWhere where = new AuthorQueryWhere();
|
||||||
|
|
||||||
|
@override
|
||||||
|
get tableName {
|
||||||
|
return 'authors';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
get fields {
|
||||||
|
return const ['id', 'name', 'createdAt', 'updatedAt'];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(List row) {
|
||||||
|
return new Author(
|
||||||
|
id: (row[0] as String),
|
||||||
|
name: (row[0] as String),
|
||||||
|
createdAt: (row[0] as DateTime),
|
||||||
|
updatedAt: (row[0] as DateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AuthorQueryWhere extends QueryWhere {
|
||||||
|
final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id');
|
||||||
|
|
||||||
|
final StringSqlExpressionBuilder name =
|
||||||
|
new StringSqlExpressionBuilder('name');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('updated_at');
|
||||||
|
|
||||||
|
@override
|
||||||
|
get expressionBuilders {
|
||||||
|
return [id, name, createdAt, updatedAt];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonModelGenerator
|
// JsonModelGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -39,6 +85,11 @@ class Author extends _Author {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([id, name, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return AuthorSerializer.toMap(this);
|
return AuthorSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ part 'book.g.dart';
|
||||||
part 'book.serializer.g.dart';
|
part 'book.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Book extends Model {
|
class _Book extends Model {
|
||||||
@belongsTo
|
@belongsTo
|
||||||
Author author;
|
Author author;
|
||||||
|
|
|
@ -67,6 +67,12 @@ class Book extends _Book {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects(
|
||||||
|
[id, author, partnerAuthor, authorId, name, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return BookSerializer.toMap(this);
|
return BookSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ part 'car.g.dart';
|
||||||
part 'car.serializer.g.dart';
|
part 'car.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Car extends Model {
|
class _Car extends Model {
|
||||||
String make;
|
String make;
|
||||||
String description;
|
String description;
|
||||||
|
|
|
@ -2,6 +2,80 @@
|
||||||
|
|
||||||
part of angel_orm.generator.models.car;
|
part of angel_orm.generator.models.car;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// OrmGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class CarQuery extends Query<Car, CarQueryWhere> {
|
||||||
|
@override
|
||||||
|
final CarQueryWhere where = new CarQueryWhere();
|
||||||
|
|
||||||
|
@override
|
||||||
|
get tableName {
|
||||||
|
return 'cars';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
get fields {
|
||||||
|
return const [
|
||||||
|
'id',
|
||||||
|
'make',
|
||||||
|
'description',
|
||||||
|
'familyFriendly',
|
||||||
|
'recalledAt',
|
||||||
|
'createdAt',
|
||||||
|
'updatedAt'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(List row) {
|
||||||
|
return new Car(
|
||||||
|
id: (row[0] as String),
|
||||||
|
make: (row[0] as String),
|
||||||
|
description: (row[0] as String),
|
||||||
|
familyFriendly: (row[0] as bool),
|
||||||
|
recalledAt: (row[0] as DateTime),
|
||||||
|
createdAt: (row[0] as DateTime),
|
||||||
|
updatedAt: (row[0] as DateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CarQueryWhere extends QueryWhere {
|
||||||
|
final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id');
|
||||||
|
|
||||||
|
final StringSqlExpressionBuilder make =
|
||||||
|
new StringSqlExpressionBuilder('make');
|
||||||
|
|
||||||
|
final StringSqlExpressionBuilder description =
|
||||||
|
new StringSqlExpressionBuilder('description');
|
||||||
|
|
||||||
|
final BooleanSqlExpressionBuilder familyFriendly =
|
||||||
|
new BooleanSqlExpressionBuilder('family_friendly');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder recalledAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('recalled_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('updated_at');
|
||||||
|
|
||||||
|
@override
|
||||||
|
get expressionBuilders {
|
||||||
|
return [
|
||||||
|
id,
|
||||||
|
make,
|
||||||
|
description,
|
||||||
|
familyFriendly,
|
||||||
|
recalledAt,
|
||||||
|
createdAt,
|
||||||
|
updatedAt
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonModelGenerator
|
// JsonModelGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -67,6 +141,19 @@ class Car extends _Car {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([
|
||||||
|
id,
|
||||||
|
make,
|
||||||
|
description,
|
||||||
|
familyFriendly,
|
||||||
|
recalledAt,
|
||||||
|
createdAt,
|
||||||
|
updatedAt
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return CarSerializer.toMap(this);
|
return CarSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import 'package:angel_serialize/angel_serialize.dart';
|
||||||
part 'customer.g.dart';
|
part 'customer.g.dart';
|
||||||
part 'customer.serializer.g.dart';
|
part 'customer.serializer.g.dart';
|
||||||
|
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
@serializable
|
@serializable
|
||||||
class _Customer extends Model {
|
class _Customer extends Model {
|
||||||
}
|
}
|
|
@ -2,6 +2,48 @@
|
||||||
|
|
||||||
part of angel_orm_generator.test.models.customer;
|
part of angel_orm_generator.test.models.customer;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// OrmGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class CustomerQuery extends Query<Customer, CustomerQueryWhere> {
|
||||||
|
@override
|
||||||
|
final CustomerQueryWhere where = new CustomerQueryWhere();
|
||||||
|
|
||||||
|
@override
|
||||||
|
get tableName {
|
||||||
|
return 'customers';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
get fields {
|
||||||
|
return const ['id', 'createdAt', 'updatedAt'];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(List row) {
|
||||||
|
return new Customer(
|
||||||
|
id: (row[0] as String),
|
||||||
|
createdAt: (row[0] as DateTime),
|
||||||
|
updatedAt: (row[0] as DateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomerQueryWhere extends QueryWhere {
|
||||||
|
final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('updated_at');
|
||||||
|
|
||||||
|
@override
|
||||||
|
get expressionBuilders {
|
||||||
|
return [id, createdAt, updatedAt];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonModelGenerator
|
// JsonModelGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -33,6 +75,11 @@ class Customer extends _Customer {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([id, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return CustomerSerializer.toMap(this);
|
return CustomerSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ part 'foot.g.dart';
|
||||||
part 'foot.serializer.g.dart';
|
part 'foot.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Foot extends Model {
|
class _Foot extends Model {
|
||||||
int legId, nToes;
|
int legId, nToes;
|
||||||
}
|
}
|
|
@ -2,6 +2,56 @@
|
||||||
|
|
||||||
part of angel_orm_generator.test.models.foot;
|
part of angel_orm_generator.test.models.foot;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// OrmGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class FootQuery extends Query<Foot, FootQueryWhere> {
|
||||||
|
@override
|
||||||
|
final FootQueryWhere where = new FootQueryWhere();
|
||||||
|
|
||||||
|
@override
|
||||||
|
get tableName {
|
||||||
|
return 'foots';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
get fields {
|
||||||
|
return const ['id', 'legId', 'nToes', 'createdAt', 'updatedAt'];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(List row) {
|
||||||
|
return new Foot(
|
||||||
|
id: (row[0] as String),
|
||||||
|
legId: (row[0] as int),
|
||||||
|
nToes: (row[0] as int),
|
||||||
|
createdAt: (row[0] as DateTime),
|
||||||
|
updatedAt: (row[0] as DateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FootQueryWhere extends QueryWhere {
|
||||||
|
final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id');
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> legId =
|
||||||
|
new NumericSqlExpressionBuilder<int>('leg_id');
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> nToes =
|
||||||
|
new NumericSqlExpressionBuilder<int>('n_toes');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('updated_at');
|
||||||
|
|
||||||
|
@override
|
||||||
|
get expressionBuilders {
|
||||||
|
return [id, legId, nToes, createdAt, updatedAt];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonModelGenerator
|
// JsonModelGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -48,6 +98,11 @@ class Foot extends _Foot {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([id, legId, nToes, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return FootSerializer.toMap(this);
|
return FootSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ part 'fruit.g.dart';
|
||||||
part 'fruit.serializer.g.dart';
|
part 'fruit.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Fruit extends Model {
|
class _Fruit extends Model {
|
||||||
int treeId;
|
int treeId;
|
||||||
String commonName;
|
String commonName;
|
||||||
|
|
|
@ -2,6 +2,56 @@
|
||||||
|
|
||||||
part of angel_orm_generator.test.models.fruit;
|
part of angel_orm_generator.test.models.fruit;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// OrmGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class FruitQuery extends Query<Fruit, FruitQueryWhere> {
|
||||||
|
@override
|
||||||
|
final FruitQueryWhere where = new FruitQueryWhere();
|
||||||
|
|
||||||
|
@override
|
||||||
|
get tableName {
|
||||||
|
return 'fruits';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
get fields {
|
||||||
|
return const ['id', 'treeId', 'commonName', 'createdAt', 'updatedAt'];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(List row) {
|
||||||
|
return new Fruit(
|
||||||
|
id: (row[0] as String),
|
||||||
|
treeId: (row[0] as int),
|
||||||
|
commonName: (row[0] as String),
|
||||||
|
createdAt: (row[0] as DateTime),
|
||||||
|
updatedAt: (row[0] as DateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FruitQueryWhere extends QueryWhere {
|
||||||
|
final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id');
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> treeId =
|
||||||
|
new NumericSqlExpressionBuilder<int>('tree_id');
|
||||||
|
|
||||||
|
final StringSqlExpressionBuilder commonName =
|
||||||
|
new StringSqlExpressionBuilder('common_name');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('updated_at');
|
||||||
|
|
||||||
|
@override
|
||||||
|
get expressionBuilders {
|
||||||
|
return [id, treeId, commonName, createdAt, updatedAt];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonModelGenerator
|
// JsonModelGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -49,6 +99,11 @@ class Fruit extends _Fruit {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([id, treeId, commonName, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return FruitSerializer.toMap(this);
|
return FruitSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ part 'leg.g.dart';
|
||||||
part 'leg.serializer.g.dart';
|
part 'leg.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Leg extends Model {
|
class _Leg extends Model {
|
||||||
@hasOne
|
@hasOne
|
||||||
Foot foot;
|
Foot foot;
|
||||||
|
|
|
@ -48,6 +48,11 @@ class Leg extends _Leg {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([id, foot, name, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return LegSerializer.toMap(this);
|
return LegSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import 'customer.dart';
|
||||||
part 'order.g.dart';
|
part 'order.g.dart';
|
||||||
part 'order.serializer.g.dart';
|
part 'order.serializer.g.dart';
|
||||||
|
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
@serializable
|
@serializable
|
||||||
class _Order extends Model {
|
class _Order extends Model {
|
||||||
@Join(Customer, CustomerFields.id)
|
@Join(Customer, CustomerFields.id)
|
||||||
|
|
|
@ -2,6 +2,80 @@
|
||||||
|
|
||||||
part of angel_orm_generator.test.models.order;
|
part of angel_orm_generator.test.models.order;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// OrmGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class OrderQuery extends Query<Order, OrderQueryWhere> {
|
||||||
|
@override
|
||||||
|
final OrderQueryWhere where = new OrderQueryWhere();
|
||||||
|
|
||||||
|
@override
|
||||||
|
get tableName {
|
||||||
|
return 'orders';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
get fields {
|
||||||
|
return const [
|
||||||
|
'id',
|
||||||
|
'customerId',
|
||||||
|
'employeeId',
|
||||||
|
'orderDate',
|
||||||
|
'shipperId',
|
||||||
|
'createdAt',
|
||||||
|
'updatedAt'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(List row) {
|
||||||
|
return new Order(
|
||||||
|
id: (row[0] as String),
|
||||||
|
customerId: (row[0] as int),
|
||||||
|
employeeId: (row[0] as int),
|
||||||
|
orderDate: (row[0] as DateTime),
|
||||||
|
shipperId: (row[0] as int),
|
||||||
|
createdAt: (row[0] as DateTime),
|
||||||
|
updatedAt: (row[0] as DateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OrderQueryWhere extends QueryWhere {
|
||||||
|
final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id');
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> customerId =
|
||||||
|
new NumericSqlExpressionBuilder<int>('customer_id');
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> employeeId =
|
||||||
|
new NumericSqlExpressionBuilder<int>('employee_id');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder orderDate =
|
||||||
|
new DateTimeSqlExpressionBuilder('order_date');
|
||||||
|
|
||||||
|
final NumericSqlExpressionBuilder<int> shipperId =
|
||||||
|
new NumericSqlExpressionBuilder<int>('shipper_id');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('updated_at');
|
||||||
|
|
||||||
|
@override
|
||||||
|
get expressionBuilders {
|
||||||
|
return [
|
||||||
|
id,
|
||||||
|
customerId,
|
||||||
|
employeeId,
|
||||||
|
orderDate,
|
||||||
|
shipperId,
|
||||||
|
createdAt,
|
||||||
|
updatedAt
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonModelGenerator
|
// JsonModelGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -67,6 +141,19 @@ class Order extends _Order {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([
|
||||||
|
id,
|
||||||
|
customerId,
|
||||||
|
employeeId,
|
||||||
|
orderDate,
|
||||||
|
shipperId,
|
||||||
|
createdAt,
|
||||||
|
updatedAt
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return OrderSerializer.toMap(this);
|
return OrderSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ part 'role.g.dart';
|
||||||
part 'role.serializer.g.dart';
|
part 'role.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Role extends Model {
|
class _Role extends Model {
|
||||||
String name;
|
String name;
|
||||||
}
|
}
|
|
@ -2,6 +2,52 @@
|
||||||
|
|
||||||
part of angel_orm_generator.test.models.role;
|
part of angel_orm_generator.test.models.role;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// OrmGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
|
@override
|
||||||
|
final RoleQueryWhere where = new RoleQueryWhere();
|
||||||
|
|
||||||
|
@override
|
||||||
|
get tableName {
|
||||||
|
return 'roles';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
get fields {
|
||||||
|
return const ['id', 'name', 'createdAt', 'updatedAt'];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(List row) {
|
||||||
|
return new Role(
|
||||||
|
id: (row[0] as String),
|
||||||
|
name: (row[0] as String),
|
||||||
|
createdAt: (row[0] as DateTime),
|
||||||
|
updatedAt: (row[0] as DateTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoleQueryWhere extends QueryWhere {
|
||||||
|
final StringSqlExpressionBuilder id = new StringSqlExpressionBuilder('id');
|
||||||
|
|
||||||
|
final StringSqlExpressionBuilder name =
|
||||||
|
new StringSqlExpressionBuilder('name');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder createdAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('created_at');
|
||||||
|
|
||||||
|
final DateTimeSqlExpressionBuilder updatedAt =
|
||||||
|
new DateTimeSqlExpressionBuilder('updated_at');
|
||||||
|
|
||||||
|
@override
|
||||||
|
get expressionBuilders {
|
||||||
|
return [id, name, createdAt, updatedAt];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonModelGenerator
|
// JsonModelGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
@ -39,6 +85,11 @@ class Role extends _Role {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([id, name, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return RoleSerializer.toMap(this);
|
return RoleSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ part 'tree.g.dart';
|
||||||
part 'tree.serializer.g.dart';
|
part 'tree.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _Tree extends Model {
|
class _Tree extends Model {
|
||||||
@Column(indexType: IndexType.unique, type: ColumnType.smallInt)
|
@Column(indexType: IndexType.unique, type: ColumnType.smallInt)
|
||||||
int rings;
|
int rings;
|
||||||
|
|
|
@ -55,6 +55,11 @@ class Tree extends _Tree {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects([id, rings, fruits, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return TreeSerializer.toMap(this);
|
return TreeSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ part 'user.g.dart';
|
||||||
part 'user.serializer.g.dart';
|
part 'user.serializer.g.dart';
|
||||||
|
|
||||||
@serializable
|
@serializable
|
||||||
@postgreSqlOrm
|
@orm
|
||||||
class _User extends Model {
|
class _User extends Model {
|
||||||
String username, password, email;
|
String username, password, email;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,12 @@ class User extends _User {
|
||||||
other.updatedAt == updatedAt;
|
other.updatedAt == updatedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashObjects(
|
||||||
|
[id, username, password, email, roles, createdAt, updatedAt]);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return UserSerializer.toMap(this);
|
return UserSerializer.toMap(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,18 +5,17 @@ import 'package:angel_orm/angel_orm.dart';
|
||||||
import 'package:postgres/postgres.dart';
|
import 'package:postgres/postgres.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'models/car.dart';
|
import 'models/car.dart';
|
||||||
import 'models/car.orm.g.dart';
|
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
|
|
||||||
final DateTime MILENNIUM = new DateTime.utc(2000, 1, 1);
|
final DateTime y2k = new DateTime.utc(2000, 1, 1);
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
test('to where', () {
|
test('to where', () {
|
||||||
var query = new CarQuery();
|
var query = new CarQuery();
|
||||||
query.where
|
query.where
|
||||||
..familyFriendly.equals(true)
|
..familyFriendly.equals(true)
|
||||||
..recalledAt.lessThanOrEqualTo(MILENNIUM, includeTime: false);
|
..recalledAt.lessThanOrEqualTo(y2k, includeTime: false);
|
||||||
var whereClause = query.where.toWhereClause();
|
var whereClause = query.where.compile(tableName: 'cars');
|
||||||
print('Where clause: $whereClause');
|
print('Where clause: $whereClause');
|
||||||
expect(whereClause,
|
expect(whereClause,
|
||||||
'WHERE cars.family_friendly = TRUE AND cars.recalled_at <= \'2000-01-01\'');
|
'WHERE cars.family_friendly = TRUE AND cars.recalled_at <= \'2000-01-01\'');
|
||||||
|
@ -28,23 +27,20 @@ main() {
|
||||||
'Mazda',
|
'Mazda',
|
||||||
'CX9',
|
'CX9',
|
||||||
true,
|
true,
|
||||||
dateYmdHms.format(MILENNIUM),
|
dateYmdHms.format(y2k),
|
||||||
dateYmdHms.format(MILENNIUM),
|
dateYmdHms.format(y2k),
|
||||||
dateYmdHms.format(MILENNIUM)
|
dateYmdHms.format(y2k)
|
||||||
];
|
];
|
||||||
print(row);
|
print(row);
|
||||||
var car = PostgreSqlCarOrm.parseRow(row);
|
var car = new CarQuery().deserialize(row);
|
||||||
print(car.toJson());
|
print(car.toJson());
|
||||||
expect(car.id, '0');
|
expect(car.id, '0');
|
||||||
expect(car.make, 'Mazda');
|
expect(car.make, 'Mazda');
|
||||||
expect(car.description, 'CX9');
|
expect(car.description, 'CX9');
|
||||||
expect(car.familyFriendly, true);
|
expect(car.familyFriendly, true);
|
||||||
expect(MILENNIUM.toIso8601String(),
|
expect(y2k.toIso8601String(), startsWith(car.recalledAt.toIso8601String()));
|
||||||
startsWith(car.recalledAt.toIso8601String()));
|
expect(y2k.toIso8601String(), startsWith(car.createdAt.toIso8601String()));
|
||||||
expect(MILENNIUM.toIso8601String(),
|
expect(y2k.toIso8601String(), startsWith(car.updatedAt.toIso8601String()));
|
||||||
startsWith(car.createdAt.toIso8601String()));
|
|
||||||
expect(MILENNIUM.toIso8601String(),
|
|
||||||
startsWith(car.updatedAt.toIso8601String()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group('queries', () {
|
group('queries', () {
|
||||||
|
@ -56,7 +52,7 @@ main() {
|
||||||
|
|
||||||
group('selects', () {
|
group('selects', () {
|
||||||
test('select all', () async {
|
test('select all', () async {
|
||||||
var cars = await CarQuery.getAll(connection).toList();
|
var cars = await CarQuery.getAll(connection);
|
||||||
expect(cars, []);
|
expect(cars, []);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -72,12 +68,12 @@ main() {
|
||||||
|
|
||||||
test('where clause is applied', () async {
|
test('where clause is applied', () async {
|
||||||
var query = new CarQuery()..where.familyFriendly.equals(true);
|
var query = new CarQuery()..where.familyFriendly.equals(true);
|
||||||
var cars = await query.get(connection).toList();
|
var cars = await query.get(connection);
|
||||||
expect(cars, isEmpty);
|
expect(cars, isEmpty);
|
||||||
|
|
||||||
var sportsCars = new CarQuery()..where.familyFriendly.notEquals(true);
|
var sportsCars = new CarQuery()..where.familyFriendly.notEquals(true);
|
||||||
cars = await sportsCars.get(connection).toList();
|
cars = await sportsCars.get(connection);
|
||||||
print(cars.map((c) => c.toJson()).toList());
|
print(cars.map((c) => c.toJson()));
|
||||||
|
|
||||||
var car = cars.first;
|
var car = cars.first;
|
||||||
expect(car.make, ferrari.make);
|
expect(car.make, ferrari.make);
|
||||||
|
@ -93,27 +89,26 @@ main() {
|
||||||
query1
|
query1
|
||||||
..union(query2)
|
..union(query2)
|
||||||
..unionAll(query3);
|
..unionAll(query3);
|
||||||
print(query1.toSql());
|
print(query1.compile());
|
||||||
|
|
||||||
var cars = await query1.get(connection).toList();
|
var cars = await query1.get(connection);
|
||||||
expect(cars, hasLength(1));
|
expect(cars, hasLength(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('or clause', () async {
|
test('or clause', () async {
|
||||||
var query = new CarQuery()
|
var query = new CarQuery()
|
||||||
..where.make.like('Fer%')
|
..where.make.like('Fer%')
|
||||||
..or(new CarQueryWhere()
|
..orWhere((where) =>
|
||||||
..familyFriendly.equals(true)
|
where..familyFriendly.equals(true)..make.equals('Honda'));
|
||||||
..make.equals('Honda'));
|
print(query.compile());
|
||||||
print(query.toSql());
|
var cars = await query.get(connection);
|
||||||
var cars = await query.get(connection).toList();
|
|
||||||
expect(cars, hasLength(1));
|
expect(cars, hasLength(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('limit obeyed', () async {
|
test('limit obeyed', () async {
|
||||||
var query = new CarQuery()..limit = 0;
|
var query = new CarQuery()..limit(0);
|
||||||
print(query.toSql());
|
print(query.compile());
|
||||||
var cars = await query.get(connection).toList();
|
var cars = await query.get(connection);
|
||||||
expect(cars, isEmpty);
|
expect(cars, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -126,28 +121,28 @@ main() {
|
||||||
var car = await CarQuery.deleteOne(int.parse(ferrari.id), connection);
|
var car = await CarQuery.deleteOne(int.parse(ferrari.id), connection);
|
||||||
expect(car.toJson(), ferrari.toJson());
|
expect(car.toJson(), ferrari.toJson());
|
||||||
|
|
||||||
var cars = await CarQuery.getAll(connection).toList();
|
var cars = await CarQuery.getAll(connection);
|
||||||
expect(cars, isEmpty);
|
expect(cars, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('delete stream', () async {
|
test('delete stream', () async {
|
||||||
var query = new CarQuery()..where.make.equals('Ferrari');
|
var query = new CarQuery()..where.make.equals('Ferrari');
|
||||||
query.or(new CarQueryWhere()..familyFriendly.equals(true));
|
query.or(new CarQueryWhere()..familyFriendly.equals(true));
|
||||||
print(query.toSql('DELETE FROM "cars"'));
|
print(query.compile('DELETE FROM "cars"'));
|
||||||
var cars = await query.delete(connection).toList();
|
var cars = await query.delete(connection);
|
||||||
expect(cars, hasLength(1));
|
expect(cars, hasLength(1));
|
||||||
expect(cars.first.toJson(), ferrari.toJson());
|
expect(cars.first.toJson(), ferrari.toJson());
|
||||||
});
|
});
|
||||||
|
|
||||||
test('update', () async {
|
test('update', () async {
|
||||||
var query = new CarQuery()..where.id.equals(int.parse(ferrari.id));
|
var query = new CarQuery()..where.id.equals(int.parse(ferrari.id));
|
||||||
var cars = await query.update(connection, make: 'Hyundai').toList();
|
var cars = await query.update(connection, make: 'Hyundai');
|
||||||
expect(cars, hasLength(1));
|
expect(cars, hasLength(1));
|
||||||
expect(cars.first.make, 'Hyundai');
|
expect(cars.first.make, 'Hyundai');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('update car', () async {
|
test('update car', () async {
|
||||||
var cloned = ferrari.clone()..make = 'Angel';
|
var cloned = ferrari.copyWith(make: 'Angel');
|
||||||
var car = await CarQuery.updateCar(connection, cloned);
|
var car = await CarQuery.updateCar(connection, cloned);
|
||||||
print(car.toJson());
|
print(car.toJson());
|
||||||
expect(car.toJson(), cloned.toJson());
|
expect(car.toJson(), cloned.toJson());
|
||||||
|
@ -166,8 +161,7 @@ main() {
|
||||||
expect(car.make, 'Honda');
|
expect(car.make, 'Honda');
|
||||||
expect(car.description, 'Hello');
|
expect(car.description, 'Hello');
|
||||||
expect(car.familyFriendly, isTrue);
|
expect(car.familyFriendly, isTrue);
|
||||||
expect(
|
expect(dateYmdHms.format(car.recalledAt), dateYmdHms.format(recalledAt));
|
||||||
dateYmdHms.format(car.recalledAt), dateYmdHms.format(recalledAt));
|
|
||||||
expect(car.createdAt, allOf(isNotNull, equals(car.updatedAt)));
|
expect(car.createdAt, allOf(isNotNull, equals(car.updatedAt)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue