2.0.0-dev.9
This commit is contained in:
parent
83eb36c4a7
commit
207cd50afe
18 changed files with 526 additions and 67 deletions
|
@ -1,3 +1,13 @@
|
|||
# 2.0.0-dev.9
|
||||
* Permanent preamble fix
|
||||
|
||||
# 2.0.0-dev.8
|
||||
* Escapes
|
||||
|
||||
# 2.0.0-dev.7
|
||||
* Update `toSql`
|
||||
* Add `isTrue` and `isFalse`
|
||||
|
||||
# 2.0.0-dev.6
|
||||
* Add `delete`, `insert` and `update` methods to `Query`.
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class _FakeExecutor extends QueryExecutor {
|
|||
const _FakeExecutor();
|
||||
|
||||
@override
|
||||
Future<List<List>> query(String query, returningFields) async {
|
||||
Future<List<List>> query(String query, [returningFields]) async {
|
||||
var now = new DateTime.now();
|
||||
print('_FakeExecutor received query: $query');
|
||||
return [
|
||||
|
|
|
@ -223,6 +223,10 @@ class BooleanSqlExpressionBuilder implements SqlExpressionBuilder<bool> {
|
|||
return '$_op $v';
|
||||
}
|
||||
|
||||
Null get isTrue => equals(true);
|
||||
|
||||
Null get isFalse => equals(false);
|
||||
|
||||
void equals(bool value) {
|
||||
_change('=', value);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import 'dart:async';
|
||||
import 'package:charcode/ascii.dart';
|
||||
import 'annotations.dart';
|
||||
import 'builder.dart';
|
||||
|
||||
bool isAscii(int ch) => ch >= $nul && ch <= $del;
|
||||
|
||||
/// A base class for objects that compile to SQL queries, typically within an ORM.
|
||||
abstract class QueryBase<T> {
|
||||
/// The list of fields returned by this query.
|
||||
|
@ -18,9 +21,7 @@ abstract class QueryBase<T> {
|
|||
|
||||
Future<List<T>> get(QueryExecutor executor) async {
|
||||
var sql = compile();
|
||||
return executor
|
||||
.query(sql, fields)
|
||||
.then((it) => it.map(deserialize).toList());
|
||||
return executor.query(sql).then((it) => it.map(deserialize).toList());
|
||||
}
|
||||
|
||||
Future<T> getOne(QueryExecutor executor) {
|
||||
|
@ -47,14 +48,33 @@ class OrderBy {
|
|||
|
||||
String toSql(Object obj) {
|
||||
if (obj is DateTime) {
|
||||
return dateYmdHms.format(obj);
|
||||
return "'${dateYmdHms.format(obj)}'";
|
||||
} else if (obj is bool) {
|
||||
return obj ? 'TRUE' : 'FALSE';
|
||||
} else if (obj == null) {
|
||||
return 'NULL';
|
||||
} else if (obj is String) {
|
||||
// TODO: Proper escapes
|
||||
return obj;
|
||||
var b = new StringBuffer();
|
||||
var it = obj.runes.iterator;
|
||||
|
||||
while (it.moveNext()) {
|
||||
if (it.current == $nul)
|
||||
continue; // Skip null byte
|
||||
else if (isAscii(it.current)) {
|
||||
b.writeCharCode(it.current);
|
||||
} else if (it.currentSize == 1) {
|
||||
b.write('\\u');
|
||||
b.write(it.current.toRadixString(16).padLeft(4, '0'));
|
||||
} else if (it.currentSize == 2) {
|
||||
b.write('\\U');
|
||||
b.write(it.current.toRadixString(16).padLeft(8, '0'));
|
||||
} else {
|
||||
throw new UnsupportedError(
|
||||
'toSql() cannot encode a rune of size (${it.currentSize})');
|
||||
}
|
||||
}
|
||||
|
||||
return "'$b'";
|
||||
} else {
|
||||
return obj.toString();
|
||||
}
|
||||
|
@ -174,7 +194,8 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
|||
|
||||
@override
|
||||
String compile({bool includeTableName: false, String preamble}) {
|
||||
var b = new StringBuffer(preamble ?? 'SELECT ');
|
||||
var b = new StringBuffer(preamble ?? 'SELECT');
|
||||
b.write(' ');
|
||||
var f = fields ?? ['*'];
|
||||
if (includeTableName) f = f.map((s) => '$tableName.$s').toList();
|
||||
b.write(f.join(', '));
|
||||
|
@ -210,21 +231,19 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
|||
}
|
||||
|
||||
Future<T> insert(QueryExecutor executor) {
|
||||
var sql = new StringBuffer('INSERT INTO $tableName ($fieldSet)');
|
||||
var valuesClause = values.compileForInsert();
|
||||
var sql = values.compileInsert(tableName);
|
||||
|
||||
if (valuesClause == null) {
|
||||
if (sql == null) {
|
||||
throw new StateError('No values have been specified for update.');
|
||||
} else {
|
||||
sql.write(' $valuesClause');
|
||||
return executor
|
||||
.query(sql.toString(), fields)
|
||||
.query(sql, fields)
|
||||
.then((it) => it.isEmpty ? null : deserialize(it.first));
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<T>> update(QueryExecutor executor) async {
|
||||
var sql = new StringBuffer('UPDATE $tableName');
|
||||
var sql = new StringBuffer('UPDATE $tableName ');
|
||||
var valuesClause = values.compileForUpdate();
|
||||
|
||||
if (valuesClause == null) {
|
||||
|
@ -249,10 +268,12 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
|||
abstract class QueryValues {
|
||||
Map<String, dynamic> toMap();
|
||||
|
||||
String compileForInsert() {
|
||||
String compileInsert(String tableName) {
|
||||
var data = toMap();
|
||||
if (data.isEmpty) return null;
|
||||
var b = new StringBuffer('VALUES (');
|
||||
|
||||
var fieldSet = data.keys.join(', ');
|
||||
var b = new StringBuffer('INSERT INTO $tableName ($fieldSet) VALUES (');
|
||||
int i = 0;
|
||||
|
||||
for (var entry in data.entries) {
|
||||
|
@ -318,7 +339,12 @@ abstract class QueryWhere {
|
|||
if (tableName != null) key = '$tableName.$key';
|
||||
if (builder.hasValue) {
|
||||
if (i++ > 0) b.write(' AND ');
|
||||
b.write('$key ${builder.compile()}');
|
||||
if (builder is DateTimeSqlExpressionBuilder) {
|
||||
if (tableName != null) b.write('$tableName.');
|
||||
b.write(builder.compile());
|
||||
} else {
|
||||
b.write('$key ${builder.compile()}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,5 +437,5 @@ class JoinOn {
|
|||
abstract class QueryExecutor {
|
||||
const QueryExecutor();
|
||||
|
||||
Future<List<List>> query(String query, List<String> returningFields);
|
||||
Future<List<List>> query(String query, [List<String> returningFields]);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
name: angel_orm
|
||||
version: 2.0.0-dev.6
|
||||
version: 2.0.0-dev.9
|
||||
description: Runtime support for Angel's ORM. Includes base classes for queries.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/orm
|
||||
environment:
|
||||
sdk: '>=2.0.0-dev.1.2 <3.0.0'
|
||||
dependencies:
|
||||
charcode: ^1.0.0
|
||||
intl: ^0.15.7
|
||||
meta: ^1.0.0
|
||||
string_scanner: ^1.0.0
|
||||
|
@ -13,4 +14,5 @@ dev_dependencies:
|
|||
angel_model: ^1.0.0
|
||||
angel_serialize: ^2.0.0
|
||||
angel_serialize_generator: ^2.0.0
|
||||
build_runner: ^1.0.0
|
||||
build_runner: ^1.0.0
|
||||
test: ^1.0.0
|
17
angel_orm/test/to_sql_test.dart
Normal file
17
angel_orm/test/to_sql_test.dart
Normal file
|
@ -0,0 +1,17 @@
|
|||
import 'package:angel_orm/angel_orm.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('simple', () {
|
||||
expect(toSql('ABC _!'), "'ABC _!'");
|
||||
});
|
||||
|
||||
test('ignores null byte', () {
|
||||
expect(toSql('a\x00bc'), "'abc'");
|
||||
});
|
||||
|
||||
test('unicode', () {
|
||||
expect(toSql('東'), r"'\u6771'");
|
||||
expect(toSql('𐐀'), r"'\U00010400'");
|
||||
});
|
||||
}
|
|
@ -48,6 +48,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
// Create `FooQueryWhere` class
|
||||
lib.body.add(buildQueryClass(ctx));
|
||||
lib.body.add(buildWhereClass(ctx));
|
||||
lib.body.add(buildValuesClass(ctx));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -68,6 +69,17 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
]);
|
||||
});
|
||||
|
||||
// Add values
|
||||
clazz.fields.add(new Field((b) {
|
||||
var type = refer('${rc.pascalCase}QueryValues');
|
||||
b
|
||||
..name = 'values'
|
||||
..modifier = FieldModifier.final$
|
||||
..annotations.add(refer('override'))
|
||||
..type = type
|
||||
..assignment = type.newInstance([]).code;
|
||||
}));
|
||||
|
||||
// Add tableName
|
||||
clazz.methods.add(new Method((m) {
|
||||
m
|
||||
|
@ -101,6 +113,15 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..assignment = queryWhereType.newInstance([]).code;
|
||||
}));
|
||||
|
||||
clazz.methods.add(new Method((b) {
|
||||
b
|
||||
..name = 'newWhereClause'
|
||||
..annotations.add(refer('override'))
|
||||
..returns = queryWhereType
|
||||
..body = new Block(
|
||||
(b) => b.addExpression(queryWhereType.newInstance([]).returned));
|
||||
}));
|
||||
|
||||
// Add deserialize()
|
||||
clazz.methods.add(new Method((m) {
|
||||
m
|
||||
|
@ -193,4 +214,66 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
Class buildValuesClass(OrmBuildContext ctx) {
|
||||
return new Class((clazz) {
|
||||
var rc = ctx.buildContext.modelClassNameRecase;
|
||||
clazz
|
||||
..name = '${rc.pascalCase}QueryValues'
|
||||
..extend = refer('MapQueryValues');
|
||||
|
||||
// Each field generates a getter for setter
|
||||
for (var field in ctx.buildContext.fields) {
|
||||
var name = ctx.buildContext.resolveFieldName(field.name);
|
||||
var type = isSpecialId(field)
|
||||
? refer('int')
|
||||
: convertTypeReference(field.type);
|
||||
|
||||
clazz.methods.add(new Method((b) {
|
||||
b
|
||||
..name = field.name
|
||||
..type = MethodType.getter
|
||||
..returns = type
|
||||
..body = new Block((b) => b.addExpression(
|
||||
refer('values').index(literalString(name)).asA(type).returned));
|
||||
}));
|
||||
|
||||
clazz.methods.add(new Method((b) {
|
||||
b
|
||||
..name = field.name
|
||||
..type = MethodType.setter
|
||||
..returns = refer('void')
|
||||
..requiredParameters.add(new Parameter((b) => b
|
||||
..name = 'value'
|
||||
..type = type))
|
||||
..body = refer('values')
|
||||
.index(literalString(name))
|
||||
.assign(refer('value'))
|
||||
.code;
|
||||
}));
|
||||
}
|
||||
|
||||
// Add an copyFrom(model)
|
||||
clazz.methods.add(new Method((b) {
|
||||
b
|
||||
..name = 'copyFrom'
|
||||
..returns = refer('void')
|
||||
..requiredParameters.add(new Parameter((b) => b
|
||||
..name = 'model'
|
||||
..type = ctx.buildContext.modelClassType))
|
||||
..body = new Block((b) {
|
||||
var args = <String, Expression>{};
|
||||
|
||||
for (var field in ctx.buildContext.fields) {
|
||||
if (isSpecialId(field)) continue;
|
||||
args[ctx.buildContext.resolveFieldName(field.name)] =
|
||||
refer('model').property(field.name);
|
||||
}
|
||||
|
||||
b.addExpression(
|
||||
refer('values').property('addAll').call([literalMap(args)]));
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: angel_orm_generator
|
||||
version: 2.0.0-dev
|
||||
description: Code generators for Angel's ORM.
|
||||
version: 2.0.0-alpha
|
||||
description: Code generators for Angel's ORM. Generates query builder classes.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/orm
|
||||
environment:
|
||||
|
|
|
@ -10,8 +10,7 @@ Future<PostgresExecutor> connectToPostgres(Iterable<String> schemas) async {
|
|||
await conn.open();
|
||||
|
||||
for (var s in schemas)
|
||||
await conn
|
||||
.execute(await new File('test/models/$s.up.g.sql').readAsString());
|
||||
await conn.execute(await new File('test/migrations/$s.sql').readAsString());
|
||||
|
||||
return new PostgresExecutor(conn);
|
||||
}
|
||||
|
@ -24,9 +23,14 @@ class PostgresExecutor extends QueryExecutor {
|
|||
Future close() => connection.close();
|
||||
|
||||
@override
|
||||
Future<List<List>> query(String query, List<String> returningFields) {
|
||||
var fields = returningFields.join(', ');
|
||||
var returning = 'RETURNING ($fields)';
|
||||
return connection.query('$query $returning');
|
||||
Future<List<List>> query(String query, [List<String> returningFields]) {
|
||||
if (returningFields != null) {
|
||||
var fields = returningFields.join(', ');
|
||||
var returning = 'RETURNING $fields';
|
||||
query = '$query $returning';
|
||||
}
|
||||
|
||||
print('Running: $query');
|
||||
return connection.query(query);
|
||||
}
|
||||
}
|
||||
|
|
9
angel_orm_generator/test/migrations/car.sql
Normal file
9
angel_orm_generator/test/migrations/car.sql
Normal file
|
@ -0,0 +1,9 @@
|
|||
CREATE TEMPORARY TABLE "cars" (
|
||||
id serial PRIMARY KEY,
|
||||
make varchar(255) NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
family_friendly BOOLEAN NOT NULL,
|
||||
recalled_at timestamp,
|
||||
created_at timestamp,
|
||||
updated_at timestamp
|
||||
);
|
|
@ -7,6 +7,9 @@ part of angel_orm.generator.models.author;
|
|||
// **************************************************************************
|
||||
|
||||
class AuthorQuery extends Query<Author, AuthorQueryWhere> {
|
||||
@override
|
||||
final AuthorQueryValues values = new AuthorQueryValues();
|
||||
|
||||
@override
|
||||
final AuthorQueryWhere where = new AuthorQueryWhere();
|
||||
|
||||
|
@ -20,6 +23,11 @@ class AuthorQuery extends Query<Author, AuthorQueryWhere> {
|
|||
return AuthorFields.allFields;
|
||||
}
|
||||
|
||||
@override
|
||||
AuthorQueryWhere newWhereClause() {
|
||||
return new AuthorQueryWhere();
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return new Author(
|
||||
|
@ -49,6 +57,36 @@ class AuthorQueryWhere extends QueryWhere {
|
|||
}
|
||||
}
|
||||
|
||||
class AuthorQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
String get name {
|
||||
return (values['name'] as String);
|
||||
}
|
||||
|
||||
void set name(String value) => values['name'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Author model) {
|
||||
values.addAll({
|
||||
'name': model.name,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -7,6 +7,9 @@ part of angel_orm.generator.models.car;
|
|||
// **************************************************************************
|
||||
|
||||
class CarQuery extends Query<Car, CarQueryWhere> {
|
||||
@override
|
||||
final CarQueryValues values = new CarQueryValues();
|
||||
|
||||
@override
|
||||
final CarQueryWhere where = new CarQueryWhere();
|
||||
|
||||
|
@ -20,6 +23,11 @@ class CarQuery extends Query<Car, CarQueryWhere> {
|
|||
return CarFields.allFields;
|
||||
}
|
||||
|
||||
@override
|
||||
CarQueryWhere newWhereClause() {
|
||||
return new CarQueryWhere();
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return new Car(
|
||||
|
@ -69,6 +77,54 @@ class CarQueryWhere extends QueryWhere {
|
|||
}
|
||||
}
|
||||
|
||||
class CarQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
String get make {
|
||||
return (values['make'] as String);
|
||||
}
|
||||
|
||||
void set make(String value) => values['make'] = value;
|
||||
String get description {
|
||||
return (values['description'] as String);
|
||||
}
|
||||
|
||||
void set description(String value) => values['description'] = value;
|
||||
bool get familyFriendly {
|
||||
return (values['family_friendly'] as bool);
|
||||
}
|
||||
|
||||
void set familyFriendly(bool value) => values['family_friendly'] = value;
|
||||
DateTime get recalledAt {
|
||||
return (values['recalled_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set recalledAt(DateTime value) => values['recalled_at'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Car model) {
|
||||
values.addAll({
|
||||
'make': model.make,
|
||||
'description': model.description,
|
||||
'family_friendly': model.familyFriendly,
|
||||
'recalled_at': model.recalledAt,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -7,6 +7,9 @@ part of angel_orm_generator.test.models.customer;
|
|||
// **************************************************************************
|
||||
|
||||
class CustomerQuery extends Query<Customer, CustomerQueryWhere> {
|
||||
@override
|
||||
final CustomerQueryValues values = new CustomerQueryValues();
|
||||
|
||||
@override
|
||||
final CustomerQueryWhere where = new CustomerQueryWhere();
|
||||
|
||||
|
@ -20,6 +23,11 @@ class CustomerQuery extends Query<Customer, CustomerQueryWhere> {
|
|||
return CustomerFields.allFields;
|
||||
}
|
||||
|
||||
@override
|
||||
CustomerQueryWhere newWhereClause() {
|
||||
return new CustomerQueryWhere();
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return new Customer(
|
||||
|
@ -45,6 +53,28 @@ class CustomerQueryWhere extends QueryWhere {
|
|||
}
|
||||
}
|
||||
|
||||
class CustomerQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Customer model) {
|
||||
values
|
||||
.addAll({'created_at': model.createdAt, 'updated_at': model.updatedAt});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -7,6 +7,9 @@ part of angel_orm_generator.test.models.foot;
|
|||
// **************************************************************************
|
||||
|
||||
class FootQuery extends Query<Foot, FootQueryWhere> {
|
||||
@override
|
||||
final FootQueryValues values = new FootQueryValues();
|
||||
|
||||
@override
|
||||
final FootQueryWhere where = new FootQueryWhere();
|
||||
|
||||
|
@ -20,6 +23,11 @@ class FootQuery extends Query<Foot, FootQueryWhere> {
|
|||
return FootFields.allFields;
|
||||
}
|
||||
|
||||
@override
|
||||
FootQueryWhere newWhereClause() {
|
||||
return new FootQueryWhere();
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return new Foot(
|
||||
|
@ -53,6 +61,42 @@ class FootQueryWhere extends QueryWhere {
|
|||
}
|
||||
}
|
||||
|
||||
class FootQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
int get legId {
|
||||
return (values['leg_id'] as int);
|
||||
}
|
||||
|
||||
void set legId(int value) => values['leg_id'] = value;
|
||||
int get nToes {
|
||||
return (values['n_toes'] as int);
|
||||
}
|
||||
|
||||
void set nToes(int value) => values['n_toes'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Foot model) {
|
||||
values.addAll({
|
||||
'leg_id': model.legId,
|
||||
'n_toes': model.nToes,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -7,6 +7,9 @@ part of angel_orm_generator.test.models.fruit;
|
|||
// **************************************************************************
|
||||
|
||||
class FruitQuery extends Query<Fruit, FruitQueryWhere> {
|
||||
@override
|
||||
final FruitQueryValues values = new FruitQueryValues();
|
||||
|
||||
@override
|
||||
final FruitQueryWhere where = new FruitQueryWhere();
|
||||
|
||||
|
@ -20,6 +23,11 @@ class FruitQuery extends Query<Fruit, FruitQueryWhere> {
|
|||
return FruitFields.allFields;
|
||||
}
|
||||
|
||||
@override
|
||||
FruitQueryWhere newWhereClause() {
|
||||
return new FruitQueryWhere();
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return new Fruit(
|
||||
|
@ -53,6 +61,42 @@ class FruitQueryWhere extends QueryWhere {
|
|||
}
|
||||
}
|
||||
|
||||
class FruitQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
int get treeId {
|
||||
return (values['tree_id'] as int);
|
||||
}
|
||||
|
||||
void set treeId(int value) => values['tree_id'] = value;
|
||||
String get commonName {
|
||||
return (values['common_name'] as String);
|
||||
}
|
||||
|
||||
void set commonName(String value) => values['common_name'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Fruit model) {
|
||||
values.addAll({
|
||||
'tree_id': model.treeId,
|
||||
'common_name': model.commonName,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -7,6 +7,9 @@ part of angel_orm_generator.test.models.order;
|
|||
// **************************************************************************
|
||||
|
||||
class OrderQuery extends Query<Order, OrderQueryWhere> {
|
||||
@override
|
||||
final OrderQueryValues values = new OrderQueryValues();
|
||||
|
||||
@override
|
||||
final OrderQueryWhere where = new OrderQueryWhere();
|
||||
|
||||
|
@ -20,6 +23,11 @@ class OrderQuery extends Query<Order, OrderQueryWhere> {
|
|||
return OrderFields.allFields;
|
||||
}
|
||||
|
||||
@override
|
||||
OrderQueryWhere newWhereClause() {
|
||||
return new OrderQueryWhere();
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return new Order(
|
||||
|
@ -69,6 +77,54 @@ class OrderQueryWhere extends QueryWhere {
|
|||
}
|
||||
}
|
||||
|
||||
class OrderQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
int get customerId {
|
||||
return (values['customer_id'] as int);
|
||||
}
|
||||
|
||||
void set customerId(int value) => values['customer_id'] = value;
|
||||
int get employeeId {
|
||||
return (values['employee_id'] as int);
|
||||
}
|
||||
|
||||
void set employeeId(int value) => values['employee_id'] = value;
|
||||
DateTime get orderDate {
|
||||
return (values['order_date'] as DateTime);
|
||||
}
|
||||
|
||||
void set orderDate(DateTime value) => values['order_date'] = value;
|
||||
int get shipperId {
|
||||
return (values['shipper_id'] as int);
|
||||
}
|
||||
|
||||
void set shipperId(int value) => values['shipper_id'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Order model) {
|
||||
values.addAll({
|
||||
'customer_id': model.customerId,
|
||||
'employee_id': model.employeeId,
|
||||
'order_date': model.orderDate,
|
||||
'shipper_id': model.shipperId,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -7,6 +7,9 @@ part of angel_orm_generator.test.models.role;
|
|||
// **************************************************************************
|
||||
|
||||
class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||
@override
|
||||
final RoleQueryValues values = new RoleQueryValues();
|
||||
|
||||
@override
|
||||
final RoleQueryWhere where = new RoleQueryWhere();
|
||||
|
||||
|
@ -20,6 +23,11 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
|||
return RoleFields.allFields;
|
||||
}
|
||||
|
||||
@override
|
||||
RoleQueryWhere newWhereClause() {
|
||||
return new RoleQueryWhere();
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(List row) {
|
||||
return new Role(
|
||||
|
@ -49,6 +57,36 @@ class RoleQueryWhere extends QueryWhere {
|
|||
}
|
||||
}
|
||||
|
||||
class RoleQueryValues extends MapQueryValues {
|
||||
int get id {
|
||||
return (values['id'] as int);
|
||||
}
|
||||
|
||||
void set id(int value) => values['id'] = value;
|
||||
String get name {
|
||||
return (values['name'] as String);
|
||||
}
|
||||
|
||||
void set name(String value) => values['name'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
}
|
||||
|
||||
void set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
void copyFrom(Role model) {
|
||||
values.addAll({
|
||||
'name': model.name,
|
||||
'created_at': model.createdAt,
|
||||
'updated_at': model.updatedAt
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonModelGenerator
|
||||
// **************************************************************************
|
||||
|
|
|
@ -12,24 +12,16 @@ main() {
|
|||
test('to where', () {
|
||||
var query = new CarQuery();
|
||||
query.where
|
||||
..familyFriendly.equals(true)
|
||||
..familyFriendly.isTrue
|
||||
..recalledAt.lessThanOrEqualTo(y2k, includeTime: false);
|
||||
var whereClause = query.where.compile(tableName: 'cars');
|
||||
print('Where clause: $whereClause');
|
||||
expect(whereClause,
|
||||
'WHERE cars.family_friendly = TRUE AND cars.recalled_at <= \'2000-01-01\'');
|
||||
'cars.family_friendly = TRUE AND cars.recalled_at <= \'2000-01-01\'');
|
||||
});
|
||||
|
||||
test('parseRow', () {
|
||||
var row = [
|
||||
0,
|
||||
'Mazda',
|
||||
'CX9',
|
||||
true,
|
||||
dateYmdHms.format(y2k),
|
||||
dateYmdHms.format(y2k),
|
||||
dateYmdHms.format(y2k)
|
||||
];
|
||||
var row = [0, 'Mazda', 'CX9', true, y2k, y2k, y2k];
|
||||
print(row);
|
||||
var car = new CarQuery().deserialize(row);
|
||||
print(car.toJson());
|
||||
|
@ -59,20 +51,22 @@ main() {
|
|||
Car ferrari;
|
||||
|
||||
setUp(() async {
|
||||
ferrari = await CarQuery.insert(connection,
|
||||
make: 'Ferrari',
|
||||
description: 'Vroom vroom!',
|
||||
familyFriendly: false);
|
||||
var query = new CarQuery();
|
||||
query.values
|
||||
..make = 'Ferrari東'
|
||||
..description = 'Vroom vroom!'
|
||||
..familyFriendly = false;
|
||||
ferrari = await query.insert(connection);
|
||||
});
|
||||
|
||||
tearDown(() => connection.close());
|
||||
|
||||
test('where clause is applied', () async {
|
||||
var query = new CarQuery()..where.familyFriendly.equals(true);
|
||||
var query = new CarQuery()..where.familyFriendly.isTrue;
|
||||
var cars = await query.get(connection);
|
||||
expect(cars, isEmpty);
|
||||
|
||||
var sportsCars = new CarQuery()..where.familyFriendly.notEquals(true);
|
||||
var sportsCars = new CarQuery()..where.familyFriendly.isFalse;
|
||||
cars = await sportsCars.get(connection);
|
||||
print(cars.map((c) => c.toJson()));
|
||||
|
||||
|
@ -85,22 +79,20 @@ main() {
|
|||
|
||||
test('union', () async {
|
||||
var query1 = new CarQuery()..where.make.like('%Fer%');
|
||||
var query2 = new CarQuery()..where.familyFriendly.equals(true);
|
||||
var query2 = new CarQuery()..where.familyFriendly.isTrue;
|
||||
var query3 = new CarQuery()..where.description.equals('Submarine');
|
||||
query1
|
||||
..union(query2)
|
||||
..unionAll(query3);
|
||||
print(query1.compile());
|
||||
|
||||
var cars = await query1.get(connection);
|
||||
var union = query1.union(query2).unionAll(query3);
|
||||
print(union.compile());
|
||||
var cars = await union.get(connection);
|
||||
expect(cars, hasLength(1));
|
||||
});
|
||||
|
||||
test('or clause', () async {
|
||||
var query = new CarQuery()
|
||||
..where.make.like('Fer%')
|
||||
..orWhere((where) =>
|
||||
where..familyFriendly.equals(true)..make.equals('Honda'));
|
||||
..orWhere((where) => where
|
||||
..familyFriendly.isTrue
|
||||
..make.equals('Honda'));
|
||||
print(query.compile());
|
||||
var cars = await query.get(connection);
|
||||
expect(cars, hasLength(1));
|
||||
|
@ -132,25 +124,28 @@ main() {
|
|||
|
||||
test('delete stream', () async {
|
||||
var query = new CarQuery()
|
||||
..where.make.equals('Ferrari')
|
||||
..orWhere((w) => w.familyFriendly.equals(true));
|
||||
|
||||
..where.make.equals('Ferrari東')
|
||||
..orWhere((w) => w.familyFriendly.isTrue);
|
||||
print(query.compile(preamble: 'DELETE FROM "cars"'));
|
||||
var cars = await query.get(connection);
|
||||
|
||||
var cars = await query.delete(connection);
|
||||
expect(cars, hasLength(1));
|
||||
expect(cars.first.toJson(), ferrari.toJson());
|
||||
});
|
||||
|
||||
test('update', () async {
|
||||
var query = new CarQuery()..where.id.equals(int.parse(ferrari.id));
|
||||
var cars = await query.update(connection, make: 'Hyundai');
|
||||
var query = new CarQuery()
|
||||
..where.id.equals(int.parse(ferrari.id))
|
||||
..values.make = 'Hyundai';
|
||||
var cars = await query.update(connection);
|
||||
expect(cars, hasLength(1));
|
||||
expect(cars.first.make, 'Hyundai');
|
||||
});
|
||||
|
||||
test('update car', () async {
|
||||
var cloned = ferrari.copyWith(make: 'Angel');
|
||||
var car = await CarQuery.updateCar(connection, cloned);
|
||||
var query = new CarQuery()..values.copyFrom(cloned);
|
||||
var car = await query.updateOne(connection);
|
||||
print(car.toJson());
|
||||
expect(car.toJson(), cloned.toJson());
|
||||
});
|
||||
|
@ -159,11 +154,13 @@ main() {
|
|||
|
||||
test('insert', () async {
|
||||
var recalledAt = new DateTime.now();
|
||||
var car = await CarQuery.insert(connection,
|
||||
make: 'Honda',
|
||||
description: 'Hello',
|
||||
familyFriendly: true,
|
||||
recalledAt: recalledAt);
|
||||
var query = new CarQuery();
|
||||
query.values
|
||||
..make = 'Honda'
|
||||
..description = 'Hello'
|
||||
..familyFriendly = true
|
||||
..recalledAt = recalledAt;
|
||||
var car = await query.insert(connection);
|
||||
expect(car.id, isNotNull);
|
||||
expect(car.make, 'Honda');
|
||||
expect(car.description, 'Hello');
|
||||
|
@ -179,7 +176,8 @@ main() {
|
|||
description: 'Herbie',
|
||||
familyFriendly: true,
|
||||
recalledAt: recalledAt);
|
||||
var car = await CarQuery.insertCar(connection, beetle);
|
||||
var query = new CarQuery()..values.copyFrom(beetle);
|
||||
var car = await query.insert(connection);
|
||||
print(car.toJson());
|
||||
expect(car.make, beetle.make);
|
||||
expect(car.description, beetle.description);
|
||||
|
|
Loading…
Reference in a new issue