orm_service preview

This commit is contained in:
Tobe O 2019-04-20 14:45:41 -04:00
parent 0f9c4adfe0
commit 9f98a3350e
30 changed files with 1432 additions and 1001 deletions

View file

@ -214,6 +214,8 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
var skipToList = refer('row')
.property('skip')
.call([literalNum(i)])
.property('take')
.call([literalNum(relation.foreign.effectiveFields.length)])
.property('toList')
.call([]);
var parsed = refer(

View file

@ -0,0 +1,4 @@
include: package:pedantic/analysis_options.yaml
analyzer:
strong-mode:
implicit-casts: false

View file

@ -0,0 +1,14 @@
import 'dart:async';
import 'dart:io';
import 'package:angel_orm_postgres/angel_orm_postgres.dart';
import 'package:postgres/postgres.dart';
final conn = PostgreSQLConnection('localhost', 5432, 'angel_orm_service_test',
username: Platform.environment['POSTGRES_USERNAME'] ?? 'postgres',
password: Platform.environment['POSTGRES_PASSWORD'] ?? 'password');
Future<PostgreSqlExecutor> connect() async {
var executor = PostgreSqlExecutor(conn);
await conn.open();
return executor;
}

View file

@ -0,0 +1,38 @@
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/http.dart';
import 'package:angel_orm_service/angel_orm_service.dart';
import 'package:logging/logging.dart';
import 'connect.dart';
import 'todo.dart';
main() async {
// Logging, connection setup.
hierarchicalLoggingEnabled = true;
var app = Angel(logger: Logger.detached('orm_service'));
var http = AngelHttp(app);
var executor = await connect();
app.logger.onRecord.listen((rec) {
print(rec);
if (rec.error != null) print(rec.error);
if (rec.stackTrace != null) print(rec.stackTrace);
});
// Create an ORM-backed service.
var todoService = OrmService<int, Todo, TodoQuery>(
executor, () => TodoQuery(),
readData: (req, res) => todoSerializer.decode(req.bodyAsMap));
// Because we provided `readData`, the todoService can face the Web.
// **IMPORTANT: Providing the type arguments is an ABSOLUTE MUST, if your
// model has `int` ID's (this is the case when using `angel_orm_generator` and `Model`).
// **
app.use<int, Todo, OrmService<int, Todo, TodoQuery>>(
'/api/todos', todoService);
// Clean up when we are done.
app.shutdownHooks.add((_) => executor.close());
await http.startServer('127.0.0.1', 3000);
print('Listening at ${http.uri}');
print('Todos API: ${http.uri}/api/todos');
}

View file

@ -0,0 +1,11 @@
import 'package:angel_migration_runner/angel_migration_runner.dart';
import 'package:angel_migration_runner/postgres.dart';
import 'connect.dart';
import 'todo.dart';
main(List<String> args) {
var runner = PostgresMigrationRunner(conn, migrations: [
TodoMigration(),
]);
return runMigrations(runner, args);
}

View file

@ -1,11 +1,14 @@
library angel_orm_generator.test.models.customer;
import 'package:angel_migration/angel_migration.dart';
import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
part 'customer.g.dart';
import 'package:angel_orm/angel_orm.dart';
part 'todo.g.dart';
@orm
@serializable
class _Customer extends Model {}
@orm
abstract class _Todo extends Model {
@notNull
String get text;
@DefaultsTo(false)
bool isComplete;
}

View file

@ -1,18 +1,18 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of angel_orm_generator.test.models.fruit;
part of 'todo.dart';
// **************************************************************************
// MigrationGenerator
// **************************************************************************
class FruitMigration extends Migration {
class TodoMigration extends Migration {
@override
up(Schema schema) {
schema.create('fruits', (table) {
schema.create('todos', (table) {
table.serial('id')..primaryKey();
table.integer('tree_id');
table.varChar('common_name');
table.boolean('is_complete')..defaultsTo(false);
table.varChar('text');
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
@ -20,7 +20,7 @@ class FruitMigration extends Migration {
@override
down(Schema schema) {
schema.drop('fruits');
schema.drop('todos');
}
}
@ -28,17 +28,17 @@ class FruitMigration extends Migration {
// OrmGenerator
// **************************************************************************
class FruitQuery extends Query<Fruit, FruitQueryWhere> {
FruitQuery({Set<String> trampoline}) {
class TodoQuery extends Query<Todo, TodoQueryWhere> {
TodoQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = FruitQueryWhere(this);
_where = TodoQueryWhere(this);
}
@override
final FruitQueryValues values = FruitQueryValues();
final TodoQueryValues values = TodoQueryValues();
FruitQueryWhere _where;
TodoQueryWhere _where;
@override
get casts {
@ -47,30 +47,30 @@ class FruitQuery extends Query<Fruit, FruitQueryWhere> {
@override
get tableName {
return 'fruits';
return 'todos';
}
@override
get fields {
return const ['id', 'tree_id', 'common_name', 'created_at', 'updated_at'];
return const ['id', 'is_complete', 'text', 'created_at', 'updated_at'];
}
@override
FruitQueryWhere get where {
TodoQueryWhere get where {
return _where;
}
@override
FruitQueryWhere newWhereClause() {
return FruitQueryWhere(this);
TodoQueryWhere newWhereClause() {
return TodoQueryWhere(this);
}
static Fruit parseRow(List row) {
static Todo parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Fruit(
var model = Todo(
id: row[0].toString(),
treeId: (row[1] as int),
commonName: (row[2] as String),
isComplete: (row[1] as bool),
text: (row[2] as String),
createdAt: (row[3] as DateTime),
updatedAt: (row[4] as DateTime));
return model;
@ -82,19 +82,19 @@ class FruitQuery extends Query<Fruit, FruitQueryWhere> {
}
}
class FruitQueryWhere extends QueryWhere {
FruitQueryWhere(FruitQuery query)
class TodoQueryWhere extends QueryWhere {
TodoQueryWhere(TodoQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
treeId = NumericSqlExpressionBuilder<int>(query, 'tree_id'),
commonName = StringSqlExpressionBuilder(query, 'common_name'),
isComplete = BooleanSqlExpressionBuilder(query, 'is_complete'),
text = StringSqlExpressionBuilder(query, 'text'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final NumericSqlExpressionBuilder<int> treeId;
final BooleanSqlExpressionBuilder isComplete;
final StringSqlExpressionBuilder commonName;
final StringSqlExpressionBuilder text;
final DateTimeSqlExpressionBuilder createdAt;
@ -102,11 +102,11 @@ class FruitQueryWhere extends QueryWhere {
@override
get expressionBuilders {
return [id, treeId, commonName, createdAt, updatedAt];
return [id, isComplete, text, createdAt, updatedAt];
}
}
class FruitQueryValues extends MapQueryValues {
class TodoQueryValues extends MapQueryValues {
@override
get casts {
return {};
@ -117,16 +117,16 @@ class FruitQueryValues extends MapQueryValues {
}
set id(String value) => values['id'] = value;
int get treeId {
return (values['tree_id'] as int);
bool get isComplete {
return (values['is_complete'] as bool);
}
set treeId(int value) => values['tree_id'] = value;
String get commonName {
return (values['common_name'] as String);
set isComplete(bool value) => values['is_complete'] = value;
String get text {
return (values['text'] as String);
}
set commonName(String value) => values['common_name'] = value;
set text(String value) => values['text'] = value;
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
@ -137,9 +137,9 @@ class FruitQueryValues extends MapQueryValues {
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Fruit model) {
treeId = model.treeId;
commonName = model.commonName;
void copyFrom(Todo model) {
isComplete = model.isComplete;
text = model.text;
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
@ -150,18 +150,22 @@ class FruitQueryValues extends MapQueryValues {
// **************************************************************************
@generatedSerializable
class Fruit extends _Fruit {
Fruit(
{this.id, this.treeId, this.commonName, this.createdAt, this.updatedAt});
class Todo extends _Todo {
Todo(
{this.id,
this.isComplete = false,
@required this.text,
this.createdAt,
this.updatedAt});
@override
final String id;
@override
final int treeId;
final bool isComplete;
@override
final String commonName;
final String text;
@override
final DateTime createdAt;
@ -169,41 +173,41 @@ class Fruit extends _Fruit {
@override
final DateTime updatedAt;
Fruit copyWith(
Todo copyWith(
{String id,
int treeId,
String commonName,
bool isComplete,
String text,
DateTime createdAt,
DateTime updatedAt}) {
return new Fruit(
return new Todo(
id: id ?? this.id,
treeId: treeId ?? this.treeId,
commonName: commonName ?? this.commonName,
isComplete: isComplete ?? this.isComplete,
text: text ?? this.text,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Fruit &&
return other is _Todo &&
other.id == id &&
other.treeId == treeId &&
other.commonName == commonName &&
other.isComplete == isComplete &&
other.text == text &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, treeId, commonName, createdAt, updatedAt]);
return hashObjects([id, isComplete, text, createdAt, updatedAt]);
}
@override
String toString() {
return "Fruit(id=$id, treeId=$treeId, commonName=$commonName, createdAt=$createdAt, updatedAt=$updatedAt)";
return "Todo(id=$id, isComplete=$isComplete, text=$text, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return FruitSerializer.toMap(this);
return TodoSerializer.toMap(this);
}
}
@ -211,34 +215,38 @@ class Fruit extends _Fruit {
// SerializerGenerator
// **************************************************************************
const FruitSerializer fruitSerializer = const FruitSerializer();
const TodoSerializer todoSerializer = const TodoSerializer();
class FruitEncoder extends Converter<Fruit, Map> {
const FruitEncoder();
class TodoEncoder extends Converter<Todo, Map> {
const TodoEncoder();
@override
Map convert(Fruit model) => FruitSerializer.toMap(model);
Map convert(Todo model) => TodoSerializer.toMap(model);
}
class FruitDecoder extends Converter<Map, Fruit> {
const FruitDecoder();
class TodoDecoder extends Converter<Map, Todo> {
const TodoDecoder();
@override
Fruit convert(Map map) => FruitSerializer.fromMap(map);
Todo convert(Map map) => TodoSerializer.fromMap(map);
}
class FruitSerializer extends Codec<Fruit, Map> {
const FruitSerializer();
class TodoSerializer extends Codec<Todo, Map> {
const TodoSerializer();
@override
get encoder => const FruitEncoder();
get encoder => const TodoEncoder();
@override
get decoder => const FruitDecoder();
static Fruit fromMap(Map map) {
return new Fruit(
get decoder => const TodoDecoder();
static Todo fromMap(Map map) {
if (map['text'] == null) {
throw new FormatException("Missing required field 'text' on Todo.");
}
return new Todo(
id: map['id'] as String,
treeId: map['tree_id'] as int,
commonName: map['common_name'] as String,
isComplete: map['is_complete'] as bool ?? false,
text: map['text'] as String,
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
@ -251,34 +259,38 @@ class FruitSerializer extends Codec<Fruit, Map> {
: null);
}
static Map<String, dynamic> toMap(_Fruit model) {
static Map<String, dynamic> toMap(_Todo model) {
if (model == null) {
return null;
}
if (model.text == null) {
throw new FormatException("Missing required field 'text' on Todo.");
}
return {
'id': model.id,
'tree_id': model.treeId,
'common_name': model.commonName,
'is_complete': model.isComplete,
'text': model.text,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class FruitFields {
abstract class TodoFields {
static const List<String> allFields = <String>[
id,
treeId,
commonName,
isComplete,
text,
createdAt,
updatedAt
];
static const String id = 'id';
static const String treeId = 'tree_id';
static const String isComplete = 'is_complete';
static const String commonName = 'common_name';
static const String text = 'text';
static const String createdAt = 'created_at';

View file

@ -0,0 +1,176 @@
import 'dart:async';
import 'package:angel_framework/angel_framework.dart' hide Query;
import 'package:angel_orm/angel_orm.dart';
/// A [Service] implementation that wraps over a [Query] class generated
/// via the Angel ORM.
class OrmService<Id, Data, TQuery extends Query<Data, QueryWhere>>
extends Service<Id, Data> {
/// The [QueryExecutor] used to communicate with a database.
final QueryExecutor executor;
/// A callback that produces an instance of [TQuery].
final FutureOr<TQuery> Function() queryCreator;
/// The name of the primary key in the database table.
///
/// Defaults to `'id'`.
final String idField;
/// If set to `true`, clients can remove all items by passing a `null` `id` to `remove`.
///
/// `false` by default.
final bool allowRemoveAll;
/// If set to `true`, parameters in `req.queryParameters` are applied to the database query.
final bool allowQuery;
/// In most cases, you will want to provide [readData].
///
/// Note that you won't need to call `RequestContext.parseBody`, as by the time
/// `readData` is invoked, the body will have already been parsed.
OrmService(this.executor, this.queryCreator,
{this.idField = 'id',
this.allowRemoveAll = false,
this.allowQuery = true,
FutureOr<Data> Function(RequestContext, ResponseContext) readData})
: super(readData: readData);
SqlExpressionBuilder _findBuilder(TQuery query, String name) {
return query.where.expressionBuilders.firstWhere(
(b) => b.columnName == name,
orElse: () => throw ArgumentError(
'${query.where.runtimeType} has no expression builder for a column named "$name".'));
}
void _apply(TQuery query, String name, dynamic value) {
var builder = _findBuilder(query, name);
try {
(builder as dynamic).equals(value);
} on NoSuchMethodError {
throw UnsupportedError(
'${builder.runtimeType} has no `equals` method, so it cannot be given a value from the dynamic query parameter "$name".');
}
}
Future<void> _applyQuery(TQuery query, Map<String, dynamic> params) async {
if (params == null || params.isEmpty) return;
if (allowQuery || !params.containsKey('provider')) {
var queryObj = params['query'];
if (queryObj is Function(TQuery)) {
await queryObj(query);
} else if (queryObj is Map) {
queryObj.forEach((k, v) {
if (k is String && v is! RequestContext && v is! ResponseContext) {
_apply(query, k, v);
}
});
}
}
}
@override
Future<List<Data>> readMany(List<Id> ids,
[Map<String, dynamic> params]) async {
var query = await queryCreator();
var builder = _findBuilder(query, idField);
try {
(builder as dynamic).isIn(ids);
} on NoSuchMethodError {
throw UnsupportedError(
'${builder.runtimeType} `$idField` has no `isIn` method, and therefore does not support `readMany`.');
}
await _applyQuery(query, params);
return await query.get(executor);
}
@override
Future<List<Data>> index([Map<String, dynamic> params]) async {
var query = await queryCreator();
await _applyQuery(query, params);
return await query.get(executor);
}
@override
Future<Data> read(Id id, [Map<String, dynamic> params]) async {
var query = await queryCreator();
_apply(query, idField, id);
await _applyQuery(query, params);
var result = await query.getOne(executor);
if (result != null) return result;
throw new AngelHttpException.notFound(
message: 'No record found for ID $id');
}
@override
Future<Data> findOne(
[Map<String, dynamic> params,
String errorMessage =
'No record was found matching the given query.']) async {
var query = await queryCreator();
await _applyQuery(query, params);
var result = await query.getOne(executor);
if (result != null) return result;
throw new AngelHttpException.notFound(message: errorMessage);
}
@override
Future<Data> create(Data data, [Map<String, dynamic> params]) async {
var query = await queryCreator();
try {
(query.values as dynamic).copyFrom(data);
} on NoSuchMethodError {
throw UnsupportedError(
'${query.values.runtimeType} has no `copyFrom` method, but OrmService requires this for insertions.');
}
return await query.insert(executor);
}
@override
Future<Data> modify(Id id, Data data, [Map<String, dynamic> params]) {
// TODO: Is there any way to make this an actual modify, and not an update?
return update(id, data, params);
}
@override
Future<Data> update(Id id, Data data, [Map<String, dynamic> params]) async {
var query = await queryCreator();
_apply(query, idField, id);
await _applyQuery(query, params);
try {
(query.values as dynamic).copyFrom(data);
} on NoSuchMethodError {
throw UnsupportedError(
'${query.values.runtimeType} has no `copyFrom` method, but OrmService requires this for updates.');
}
return await query.updateOne(executor);
}
@override
Future<Data> remove(Id id, [Map<String, dynamic> params]) async {
var query = await queryCreator();
if (id == null || id == 'null') {
// Remove everything...
if (!(allowRemoveAll == true ||
params?.containsKey('provider') != true)) {
throw AngelHttpException.forbidden(
message: 'Clients are not allowed to delete all items.');
}
} else {
_apply(query, idField, id);
await _applyQuery(query, params);
}
var deleted = await query.delete(executor);
return deleted.isEmpty ? null : deleted.first;
}
}

View file

View file

@ -0,0 +1,18 @@
name: angel_orm_service
dependencies:
angel_framework: ^2.0.0-alpha
angel_orm: ^2.0.0
angel_migration: ^2.0.0-alpha
dev_dependencies:
angel_migration_runner:
path: ../angel_migration_runner
angel_orm_generator:
path: ../angel_orm_generator
angel_orm_postgres:
path: ../angel_orm_postgres
angel_orm_test:
path: ../angel_orm_test
build_runner: ^1.0.0
logging: ^0.11.0
pedantic: ^1.0.0
postgres: ^1.0.0

View file

@ -1,42 +0,0 @@
builders:
angel_orm:
import: "package:angel_orm_generator/angel_orm_generator.dart"
builder_factories:
- migrationBuilder
- ormBuilder
auto_apply: root_package
build_to: cache
build_extensions:
.dart:
- ".angel_migration.g.part"
- ".angel_orm.g.part"
required_inputs:
- angel_serialize.g.part
- angel_serialize_serializer.g.part
applies_builders:
- angel_serialize_generator|angel_serialize
- source_gen|combining_builder
- source_gen|part_cleanup"
targets:
_standalone:
sources:
- lib/src/models/author.dart
- lib/src/models/car.dart
- lib/src/models/customer.dart
- lib/src/models/foot.dart
- lib/src/models/fruit.dart
- lib/src/models/has_map.dart
- lib/src/models/role.dart
- lib/src/models/unorthodox.dart
$default:
dependencies:
- angel_serialize_generator
- :_standalone
sources:
- lib/src/models/book.dart
- lib/src/models/has_car.dart
- lib/src/models/leg.dart
- lib/src/models/order.dart
- lib/src/models/tree.dart
- lib/src/models/user.dart

View file

@ -1,7 +1,6 @@
import 'dart:async';
import 'package:angel_orm/angel_orm.dart';
import 'package:test/test.dart';
import 'models/author.dart';
import 'models/book.dart';
belongsToTests(FutureOr<QueryExecutor> Function() createExecutor,
@ -46,7 +45,7 @@ belongsToTests(FutureOr<QueryExecutor> Function() createExecutor,
expect(book.name, deathlyHallows.name);
var author = book.author;
print(author.toJson());
print(AuthorSerializer.toMap(author));
expect(author.id, jkRowling.id);
expect(author.name, jkRowling.name);
});
@ -62,7 +61,7 @@ belongsToTests(FutureOr<QueryExecutor> Function() createExecutor,
expect(book.name, deathlyHallows.name);
var author = book.author;
print(author.toJson());
print(AuthorSerializer.toMap(author));
expect(author.id, jkRowling.id);
expect(author.name, jkRowling.name);
});
@ -82,7 +81,7 @@ belongsToTests(FutureOr<QueryExecutor> Function() createExecutor,
expect(book.name, deathlyHallows.name);
var author = book.author;
print(author.toJson());
print(AuthorSerializer.toMap(author));
expect(author.id, jkRowling.id);
expect(author.name, jkRowling.name);
});
@ -106,7 +105,7 @@ belongsToTests(FutureOr<QueryExecutor> Function() createExecutor,
expect(book.name, deathlyHallows.name);
var author = book.author;
print(author.toJson());
print(AuthorSerializer.toMap(author));
expect(author.id, jkRowling.id);
expect(author.name, jkRowling.name);
});

View file

@ -1,7 +1,6 @@
import 'dart:async';
import 'package:angel_orm/angel_orm.dart';
import 'package:test/test.dart';
import 'models/fruit.dart';
import 'models/tree.dart';
hasManyTests(FutureOr<QueryExecutor> Function() createExecutor,
@ -30,7 +29,7 @@ hasManyTests(FutureOr<QueryExecutor> Function() createExecutor,
Fruit apple, banana;
void verify(Tree tree) {
print(tree.fruits.map((f) => f.toJson()).toList());
print(tree.fruits.map(FruitSerializer.toMap).toList());
expect(tree.fruits, hasLength(2));
expect(tree.fruits[0].commonName, apple.commonName);
expect(tree.fruits[1].commonName, banana.commonName);

View file

@ -1,7 +1,6 @@
import 'dart:async';
import 'package:angel_orm/angel_orm.dart';
import 'package:test/test.dart';
import 'models/foot.dart';
import 'models/leg.dart';
hasOneTests(FutureOr<QueryExecutor> Function() createExecutor,

View file

@ -1,15 +0,0 @@
library angel_orm.generator.models.author;
import 'package:angel_model/angel_model.dart';
import 'package:angel_migration/angel_migration.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
part 'author.g.dart';
@serializable
@orm
abstract class _Author extends Model {
@Column(length: 255, indexType: IndexType.unique)
@SerializableField(defaultValue: 'Tobe Osakwe')
String get name;
}

View file

@ -1,262 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of angel_orm.generator.models.author;
// **************************************************************************
// MigrationGenerator
// **************************************************************************
class AuthorMigration extends Migration {
@override
up(Schema schema) {
schema.create('authors', (table) {
table.serial('id')..primaryKey();
table.varChar('name', length: 255)
..defaultsTo('Tobe Osakwe')
..unique();
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('authors');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
class AuthorQuery extends Query<Author, AuthorQueryWhere> {
AuthorQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = AuthorQueryWhere(this);
}
@override
final AuthorQueryValues values = AuthorQueryValues();
AuthorQueryWhere _where;
@override
get casts {
return {};
}
@override
get tableName {
return 'authors';
}
@override
get fields {
return const ['id', 'name', 'created_at', 'updated_at'];
}
@override
AuthorQueryWhere get where {
return _where;
}
@override
AuthorQueryWhere newWhereClause() {
return AuthorQueryWhere(this);
}
static Author parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Author(
id: row[0].toString(),
name: (row[1] as String),
createdAt: (row[2] as DateTime),
updatedAt: (row[3] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class AuthorQueryWhere extends QueryWhere {
AuthorQueryWhere(AuthorQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
name = StringSqlExpressionBuilder(query, 'name'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final StringSqlExpressionBuilder name;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, name, createdAt, updatedAt];
}
}
class AuthorQueryValues extends MapQueryValues {
@override
get casts {
return {};
}
String get id {
return (values['id'] as String);
}
set id(String value) => values['id'] = value;
String get name {
return (values['name'] as String);
}
set name(String value) => values['name'] = value;
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Author model) {
name = model.name;
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@generatedSerializable
class Author extends _Author {
Author({this.id, this.name = 'Tobe Osakwe', this.createdAt, this.updatedAt});
@override
final String id;
@override
final String name;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Author copyWith(
{String id, String name, DateTime createdAt, DateTime updatedAt}) {
return new Author(
id: id ?? this.id,
name: name ?? this.name,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Author &&
other.id == id &&
other.name == name &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, name, createdAt, updatedAt]);
}
@override
String toString() {
return "Author(id=$id, name=$name, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return AuthorSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
const AuthorSerializer authorSerializer = const AuthorSerializer();
class AuthorEncoder extends Converter<Author, Map> {
const AuthorEncoder();
@override
Map convert(Author model) => AuthorSerializer.toMap(model);
}
class AuthorDecoder extends Converter<Map, Author> {
const AuthorDecoder();
@override
Author convert(Map map) => AuthorSerializer.fromMap(map);
}
class AuthorSerializer extends Codec<Author, Map> {
const AuthorSerializer();
@override
get encoder => const AuthorEncoder();
@override
get decoder => const AuthorDecoder();
static Author fromMap(Map map) {
return new Author(
id: map['id'] as String,
name: map['name'] as String ?? 'Tobe Osakwe',
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Author model) {
if (model == null) {
return null;
}
return {
'id': model.id,
'name': model.name,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class AuthorFields {
static const List<String> allFields = <String>[
id,
name,
createdAt,
updatedAt
];
static const String id = 'id';
static const String name = 'name';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -4,17 +4,24 @@ import 'package:angel_migration/angel_migration.dart';
import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
import 'author.dart';
part 'book.g.dart';
@serializable
@orm
class _Book extends Model {
@belongsTo
Author author;
_Author author;
@BelongsTo(localKey: "partner_author_id")
Author partnerAuthor;
_Author partnerAuthor;
String name;
}
@serializable
@orm
abstract class _Author extends Model {
@Column(length: 255, indexType: IndexType.unique)
@SerializableField(defaultValue: 'Tobe Osakwe')
String get name;
}

View file

@ -25,6 +25,25 @@ class BookMigration extends Migration {
}
}
class AuthorMigration extends Migration {
@override
up(Schema schema) {
schema.create('authors', (table) {
table.serial('id')..primaryKey();
table.varChar('name', length: 255)
..defaultsTo('Tobe Osakwe')
..unique();
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('authors');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
@ -87,12 +106,12 @@ class BookQuery extends Query<Book, BookQueryWhere> {
createdAt: (row[4] as DateTime),
updatedAt: (row[5] as DateTime));
if (row.length > 6) {
model =
model.copyWith(author: AuthorQuery.parseRow(row.skip(6).toList()));
model = model.copyWith(
author: AuthorQuery.parseRow(row.skip(6).take(4).toList()));
}
if (row.length > 10) {
model = model.copyWith(
partnerAuthor: AuthorQuery.parseRow(row.skip(10).toList()));
partnerAuthor: AuthorQuery.parseRow(row.skip(10).take(4).toList()));
}
return model;
}
@ -180,6 +199,113 @@ class BookQueryValues extends MapQueryValues {
}
}
class AuthorQuery extends Query<Author, AuthorQueryWhere> {
AuthorQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = AuthorQueryWhere(this);
}
@override
final AuthorQueryValues values = AuthorQueryValues();
AuthorQueryWhere _where;
@override
get casts {
return {};
}
@override
get tableName {
return 'authors';
}
@override
get fields {
return const ['id', 'name', 'created_at', 'updated_at'];
}
@override
AuthorQueryWhere get where {
return _where;
}
@override
AuthorQueryWhere newWhereClause() {
return AuthorQueryWhere(this);
}
static Author parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Author(
id: row[0].toString(),
name: (row[1] as String),
createdAt: (row[2] as DateTime),
updatedAt: (row[3] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class AuthorQueryWhere extends QueryWhere {
AuthorQueryWhere(AuthorQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
name = StringSqlExpressionBuilder(query, 'name'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final StringSqlExpressionBuilder name;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, name, createdAt, updatedAt];
}
}
class AuthorQueryValues extends MapQueryValues {
@override
get casts {
return {};
}
String get id {
return (values['id'] as String);
}
set id(String value) => values['id'] = value;
String get name {
return (values['name'] as String);
}
set name(String value) => values['name'] = value;
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Author model) {
name = model.name;
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@ -198,10 +324,10 @@ class Book extends _Book {
final String id;
@override
final Author author;
final _Author author;
@override
final Author partnerAuthor;
final _Author partnerAuthor;
@override
final String name;
@ -214,8 +340,8 @@ class Book extends _Book {
Book copyWith(
{String id,
Author author,
Author partnerAuthor,
_Author author,
_Author partnerAuthor,
String name,
DateTime createdAt,
DateTime updatedAt}) {
@ -253,6 +379,54 @@ class Book extends _Book {
}
}
@generatedSerializable
class Author extends _Author {
Author({this.id, this.name = 'Tobe Osakwe', this.createdAt, this.updatedAt});
@override
final String id;
@override
final String name;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Author copyWith(
{String id, String name, DateTime createdAt, DateTime updatedAt}) {
return new Author(
id: id ?? this.id,
name: name ?? this.name,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Author &&
other.id == id &&
other.name == name &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, name, createdAt, updatedAt]);
}
@override
String toString() {
return "Author(id=$id, name=$name, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return AuthorSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
@ -339,3 +513,72 @@ abstract class BookFields {
static const String updatedAt = 'updated_at';
}
const AuthorSerializer authorSerializer = const AuthorSerializer();
class AuthorEncoder extends Converter<Author, Map> {
const AuthorEncoder();
@override
Map convert(Author model) => AuthorSerializer.toMap(model);
}
class AuthorDecoder extends Converter<Map, Author> {
const AuthorDecoder();
@override
Author convert(Map map) => AuthorSerializer.fromMap(map);
}
class AuthorSerializer extends Codec<Author, Map> {
const AuthorSerializer();
@override
get encoder => const AuthorEncoder();
@override
get decoder => const AuthorDecoder();
static Author fromMap(Map map) {
return new Author(
id: map['id'] as String,
name: map['name'] as String ?? 'Tobe Osakwe',
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Author model) {
if (model == null) {
return null;
}
return {
'id': model.id,
'name': model.name,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class AuthorFields {
static const List<String> allFields = <String>[
id,
name,
createdAt,
updatedAt
];
static const String id = 'id';
static const String name = 'name';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -1,234 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of angel_orm_generator.test.models.customer;
// **************************************************************************
// MigrationGenerator
// **************************************************************************
class CustomerMigration extends Migration {
@override
up(Schema schema) {
schema.create('customers', (table) {
table.serial('id')..primaryKey();
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('customers');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
class CustomerQuery extends Query<Customer, CustomerQueryWhere> {
CustomerQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = CustomerQueryWhere(this);
}
@override
final CustomerQueryValues values = CustomerQueryValues();
CustomerQueryWhere _where;
@override
get casts {
return {};
}
@override
get tableName {
return 'customers';
}
@override
get fields {
return const ['id', 'created_at', 'updated_at'];
}
@override
CustomerQueryWhere get where {
return _where;
}
@override
CustomerQueryWhere newWhereClause() {
return CustomerQueryWhere(this);
}
static Customer parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Customer(
id: row[0].toString(),
createdAt: (row[1] as DateTime),
updatedAt: (row[2] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class CustomerQueryWhere extends QueryWhere {
CustomerQueryWhere(CustomerQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, createdAt, updatedAt];
}
}
class CustomerQueryValues extends MapQueryValues {
@override
get casts {
return {};
}
String get id {
return (values['id'] as String);
}
set id(String value) => values['id'] = value;
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Customer model) {
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@generatedSerializable
class Customer extends _Customer {
Customer({this.id, this.createdAt, this.updatedAt});
@override
final String id;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Customer copyWith({String id, DateTime createdAt, DateTime updatedAt}) {
return new Customer(
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Customer &&
other.id == id &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, createdAt, updatedAt]);
}
@override
String toString() {
return "Customer(id=$id, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return CustomerSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
const CustomerSerializer customerSerializer = const CustomerSerializer();
class CustomerEncoder extends Converter<Customer, Map> {
const CustomerEncoder();
@override
Map convert(Customer model) => CustomerSerializer.toMap(model);
}
class CustomerDecoder extends Converter<Map, Customer> {
const CustomerDecoder();
@override
Customer convert(Map map) => CustomerSerializer.fromMap(map);
}
class CustomerSerializer extends Codec<Customer, Map> {
const CustomerSerializer();
@override
get encoder => const CustomerEncoder();
@override
get decoder => const CustomerDecoder();
static Customer fromMap(Map map) {
return new Customer(
id: map['id'] as String,
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Customer model) {
if (model == null) {
return null;
}
return {
'id': model.id,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class CustomerFields {
static const List<String> allFields = <String>[id, createdAt, updatedAt];
static const String id = 'id';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -1,15 +0,0 @@
library angel_orm_generator.test.models.foot;
import 'package:angel_migration/angel_migration.dart';
import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
part 'foot.g.dart';
@serializable
@Orm(tableName: 'feet')
class _Foot extends Model {
int legId;
double nToes;
}

View file

@ -1,285 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of angel_orm_generator.test.models.foot;
// **************************************************************************
// MigrationGenerator
// **************************************************************************
class FootMigration extends Migration {
@override
up(Schema schema) {
schema.create('feet', (table) {
table.serial('id')..primaryKey();
table.integer('leg_id');
table.declare('n_toes', ColumnType('decimal'));
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('feet');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
class FootQuery extends Query<Foot, FootQueryWhere> {
FootQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = FootQueryWhere(this);
}
@override
final FootQueryValues values = FootQueryValues();
FootQueryWhere _where;
@override
get casts {
return {'n_toes': 'text'};
}
@override
get tableName {
return 'feet';
}
@override
get fields {
return const ['id', 'leg_id', 'n_toes', 'created_at', 'updated_at'];
}
@override
FootQueryWhere get where {
return _where;
}
@override
FootQueryWhere newWhereClause() {
return FootQueryWhere(this);
}
static Foot parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Foot(
id: row[0].toString(),
legId: (row[1] as int),
nToes: double.tryParse(row[2].toString()),
createdAt: (row[3] as DateTime),
updatedAt: (row[4] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class FootQueryWhere extends QueryWhere {
FootQueryWhere(FootQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
legId = NumericSqlExpressionBuilder<int>(query, 'leg_id'),
nToes = NumericSqlExpressionBuilder<double>(query, 'n_toes'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final NumericSqlExpressionBuilder<int> legId;
final NumericSqlExpressionBuilder<double> nToes;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, legId, nToes, createdAt, updatedAt];
}
}
class FootQueryValues extends MapQueryValues {
@override
get casts {
return {'n_toes': 'decimal'};
}
String get id {
return (values['id'] as String);
}
set id(String value) => values['id'] = value;
int get legId {
return (values['leg_id'] as int);
}
set legId(int value) => values['leg_id'] = value;
double get nToes {
return double.tryParse((values['n_toes'] as String));
}
set nToes(double value) => values['n_toes'] = value.toString();
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Foot model) {
legId = model.legId;
nToes = model.nToes;
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@generatedSerializable
class Foot extends _Foot {
Foot({this.id, this.legId, this.nToes, this.createdAt, this.updatedAt});
@override
final String id;
@override
final int legId;
@override
final double nToes;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Foot copyWith(
{String id,
int legId,
double nToes,
DateTime createdAt,
DateTime updatedAt}) {
return new Foot(
id: id ?? this.id,
legId: legId ?? this.legId,
nToes: nToes ?? this.nToes,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Foot &&
other.id == id &&
other.legId == legId &&
other.nToes == nToes &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, legId, nToes, createdAt, updatedAt]);
}
@override
String toString() {
return "Foot(id=$id, legId=$legId, nToes=$nToes, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return FootSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
const FootSerializer footSerializer = const FootSerializer();
class FootEncoder extends Converter<Foot, Map> {
const FootEncoder();
@override
Map convert(Foot model) => FootSerializer.toMap(model);
}
class FootDecoder extends Converter<Map, Foot> {
const FootDecoder();
@override
Foot convert(Map map) => FootSerializer.fromMap(map);
}
class FootSerializer extends Codec<Foot, Map> {
const FootSerializer();
@override
get encoder => const FootEncoder();
@override
get decoder => const FootDecoder();
static Foot fromMap(Map map) {
return new Foot(
id: map['id'] as String,
legId: map['leg_id'] as int,
nToes: map['n_toes'] as double,
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Foot model) {
if (model == null) {
return null;
}
return {
'id': model.id,
'leg_id': model.legId,
'n_toes': model.nToes,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class FootFields {
static const List<String> allFields = <String>[
id,
legId,
nToes,
createdAt,
updatedAt
];
static const String id = 'id';
static const String legId = 'leg_id';
static const String nToes = 'n_toes';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -1,14 +0,0 @@
library angel_orm_generator.test.models.fruit;
import 'package:angel_migration/angel_migration.dart';
import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
part 'fruit.g.dart';
@serializable
@orm
class _Fruit extends Model {
int treeId;
String commonName;
}

View file

@ -4,14 +4,21 @@ import 'package:angel_migration/angel_migration.dart';
import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
import 'foot.dart';
part 'leg.g.dart';
@serializable
@orm
class _Leg extends Model {
@hasOne
Foot foot;
_Foot foot;
String name;
}
@serializable
@Orm(tableName: 'feet')
class _Foot extends Model {
int legId;
double nToes;
}

View file

@ -23,6 +23,24 @@ class LegMigration extends Migration {
}
}
class FootMigration extends Migration {
@override
up(Schema schema) {
schema.create('foots', (table) {
table.serial('id')..primaryKey();
table.integer('leg_id');
table.declare('n_toes', ColumnType('decimal'));
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('foots');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
@ -32,7 +50,7 @@ class LegQuery extends Query<Leg, LegQueryWhere> {
trampoline ??= Set();
trampoline.add(tableName);
_where = LegQueryWhere(this);
leftJoin('feet', 'id', 'leg_id',
leftJoin('foots', 'id', 'leg_id',
additionalFields: const [
'id',
'leg_id',
@ -81,7 +99,8 @@ class LegQuery extends Query<Leg, LegQueryWhere> {
createdAt: (row[2] as DateTime),
updatedAt: (row[3] as DateTime));
if (row.length > 4) {
model = model.copyWith(foot: FootQuery.parseRow(row.skip(4).toList()));
model = model.copyWith(
foot: FootQuery.parseRow(row.skip(4).take(5).toList()));
}
return model;
}
@ -146,6 +165,123 @@ class LegQueryValues extends MapQueryValues {
}
}
class FootQuery extends Query<Foot, FootQueryWhere> {
FootQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = FootQueryWhere(this);
}
@override
final FootQueryValues values = FootQueryValues();
FootQueryWhere _where;
@override
get casts {
return {'n_toes': 'text'};
}
@override
get tableName {
return 'foots';
}
@override
get fields {
return const ['id', 'leg_id', 'n_toes', 'created_at', 'updated_at'];
}
@override
FootQueryWhere get where {
return _where;
}
@override
FootQueryWhere newWhereClause() {
return FootQueryWhere(this);
}
static Foot parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Foot(
id: row[0].toString(),
legId: (row[1] as int),
nToes: double.tryParse(row[2].toString()),
createdAt: (row[3] as DateTime),
updatedAt: (row[4] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class FootQueryWhere extends QueryWhere {
FootQueryWhere(FootQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
legId = NumericSqlExpressionBuilder<int>(query, 'leg_id'),
nToes = NumericSqlExpressionBuilder<double>(query, 'n_toes'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final NumericSqlExpressionBuilder<int> legId;
final NumericSqlExpressionBuilder<double> nToes;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, legId, nToes, createdAt, updatedAt];
}
}
class FootQueryValues extends MapQueryValues {
@override
get casts {
return {'n_toes': 'decimal'};
}
String get id {
return (values['id'] as String);
}
set id(String value) => values['id'] = value;
int get legId {
return (values['leg_id'] as int);
}
set legId(int value) => values['leg_id'] = value;
double get nToes {
return double.tryParse((values['n_toes'] as String));
}
set nToes(double value) => values['n_toes'] = value.toString();
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Foot model) {
legId = model.legId;
nToes = model.nToes;
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@ -158,7 +294,7 @@ class Leg extends _Leg {
final String id;
@override
final Foot foot;
final _Foot foot;
@override
final String name;
@ -171,7 +307,7 @@ class Leg extends _Leg {
Leg copyWith(
{String id,
Foot foot,
_Foot foot,
String name,
DateTime createdAt,
DateTime updatedAt}) {
@ -207,6 +343,63 @@ class Leg extends _Leg {
}
}
@generatedSerializable
class Foot extends _Foot {
Foot({this.id, this.legId, this.nToes, this.createdAt, this.updatedAt});
@override
final String id;
@override
final int legId;
@override
final double nToes;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Foot copyWith(
{String id,
int legId,
double nToes,
DateTime createdAt,
DateTime updatedAt}) {
return new Foot(
id: id ?? this.id,
legId: legId ?? this.legId,
nToes: nToes ?? this.nToes,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Foot &&
other.id == id &&
other.legId == legId &&
other.nToes == nToes &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, legId, nToes, createdAt, updatedAt]);
}
@override
String toString() {
return "Foot(id=$id, legId=$legId, nToes=$nToes, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return FootSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
@ -286,3 +479,77 @@ abstract class LegFields {
static const String updatedAt = 'updated_at';
}
const FootSerializer footSerializer = const FootSerializer();
class FootEncoder extends Converter<Foot, Map> {
const FootEncoder();
@override
Map convert(Foot model) => FootSerializer.toMap(model);
}
class FootDecoder extends Converter<Map, Foot> {
const FootDecoder();
@override
Foot convert(Map map) => FootSerializer.fromMap(map);
}
class FootSerializer extends Codec<Foot, Map> {
const FootSerializer();
@override
get encoder => const FootEncoder();
@override
get decoder => const FootDecoder();
static Foot fromMap(Map map) {
return new Foot(
id: map['id'] as String,
legId: map['leg_id'] as int,
nToes: map['n_toes'] as double,
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Foot model) {
if (model == null) {
return null;
}
return {
'id': model.id,
'leg_id': model.legId,
'n_toes': model.nToes,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class FootFields {
static const List<String> allFields = <String>[
id,
legId,
nToes,
createdAt,
updatedAt
];
static const String id = 'id';
static const String legId = 'leg_id';
static const String nToes = 'n_toes';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -4,14 +4,13 @@ import 'package:angel_migration/angel_migration.dart';
import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
import 'customer.dart';
part 'order.g.dart';
@orm
@serializable
abstract class _Order extends Model {
@belongsTo
Customer get customer;
_Customer get customer;
int get employeeId;
@ -19,3 +18,7 @@ abstract class _Order extends Model {
int get shipperId;
}
@orm
@serializable
class _Customer extends Model {}

View file

@ -26,6 +26,22 @@ class OrderMigration extends Migration {
}
}
class CustomerMigration extends Migration {
@override
up(Schema schema) {
schema.create('customers', (table) {
table.serial('id')..primaryKey();
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('customers');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
@ -89,7 +105,7 @@ class OrderQuery extends Query<Order, OrderQueryWhere> {
updatedAt: (row[6] as DateTime));
if (row.length > 7) {
model = model.copyWith(
customer: CustomerQuery.parseRow(row.skip(7).toList()));
customer: CustomerQuery.parseRow(row.skip(7).take(3).toList()));
}
return model;
}
@ -191,6 +207,103 @@ class OrderQueryValues extends MapQueryValues {
}
}
class CustomerQuery extends Query<Customer, CustomerQueryWhere> {
CustomerQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = CustomerQueryWhere(this);
}
@override
final CustomerQueryValues values = CustomerQueryValues();
CustomerQueryWhere _where;
@override
get casts {
return {};
}
@override
get tableName {
return 'customers';
}
@override
get fields {
return const ['id', 'created_at', 'updated_at'];
}
@override
CustomerQueryWhere get where {
return _where;
}
@override
CustomerQueryWhere newWhereClause() {
return CustomerQueryWhere(this);
}
static Customer parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Customer(
id: row[0].toString(),
createdAt: (row[1] as DateTime),
updatedAt: (row[2] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class CustomerQueryWhere extends QueryWhere {
CustomerQueryWhere(CustomerQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, createdAt, updatedAt];
}
}
class CustomerQueryValues extends MapQueryValues {
@override
get casts {
return {};
}
String get id {
return (values['id'] as String);
}
set id(String value) => values['id'] = value;
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Customer model) {
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@ -210,7 +323,7 @@ class Order extends _Order {
final String id;
@override
final Customer customer;
final _Customer customer;
@override
final int employeeId;
@ -229,7 +342,7 @@ class Order extends _Order {
Order copyWith(
{String id,
Customer customer,
_Customer customer,
int employeeId,
DateTime orderDate,
int shipperId,
@ -272,6 +385,48 @@ class Order extends _Order {
}
}
@generatedSerializable
class Customer extends _Customer {
Customer({this.id, this.createdAt, this.updatedAt});
@override
final String id;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Customer copyWith({String id, DateTime createdAt, DateTime updatedAt}) {
return new Customer(
id: id ?? this.id,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Customer &&
other.id == id &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, createdAt, updatedAt]);
}
@override
String toString() {
return "Customer(id=$id, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return CustomerSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
@ -365,3 +520,63 @@ abstract class OrderFields {
static const String updatedAt = 'updated_at';
}
const CustomerSerializer customerSerializer = const CustomerSerializer();
class CustomerEncoder extends Converter<Customer, Map> {
const CustomerEncoder();
@override
Map convert(Customer model) => CustomerSerializer.toMap(model);
}
class CustomerDecoder extends Converter<Map, Customer> {
const CustomerDecoder();
@override
Customer convert(Map map) => CustomerSerializer.fromMap(map);
}
class CustomerSerializer extends Codec<Customer, Map> {
const CustomerSerializer();
@override
get encoder => const CustomerEncoder();
@override
get decoder => const CustomerDecoder();
static Customer fromMap(Map map) {
return new Customer(
id: map['id'] as String,
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Customer model) {
if (model == null) {
return null;
}
return {
'id': model.id,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class CustomerFields {
static const List<String> allFields = <String>[id, createdAt, updatedAt];
static const String id = 'id';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -5,7 +5,6 @@ import 'package:angel_model/angel_model.dart';
import 'package:angel_orm/angel_orm.dart';
import 'package:angel_serialize/angel_serialize.dart';
import 'package:collection/collection.dart';
import 'fruit.dart';
part 'tree.g.dart';
@serializable
@ -15,5 +14,12 @@ class _Tree extends Model {
int rings;
@hasMany
List<Fruit> fruits;
List<_Fruit> fruits;
}
@serializable
@orm
class _Fruit extends Model {
int treeId;
String commonName;
}

View file

@ -23,6 +23,24 @@ class TreeMigration extends Migration {
}
}
class FruitMigration extends Migration {
@override
up(Schema schema) {
schema.create('fruits', (table) {
table.serial('id')..primaryKey();
table.integer('tree_id');
table.varChar('common_name');
table.timeStamp('created_at');
table.timeStamp('updated_at');
});
}
@override
down(Schema schema) {
schema.drop('fruits');
}
}
// **************************************************************************
// OrmGenerator
// **************************************************************************
@ -82,7 +100,7 @@ class TreeQuery extends Query<Tree, TreeQueryWhere> {
updatedAt: (row[3] as DateTime));
if (row.length > 4) {
model = model.copyWith(
fruits: [FruitQuery.parseRow(row.skip(4).toList())]
fruits: [FruitQuery.parseRow(row.skip(4).take(5).toList())]
.where((x) => x != null)
.toList());
}
@ -106,7 +124,7 @@ class TreeQuery extends Query<Tree, TreeQueryWhere> {
var l = out[idx];
return out
..[idx] = l.copyWith(
fruits: List<Fruit>.from(l.fruits ?? [])
fruits: List<_Fruit>.from(l.fruits ?? [])
..addAll(model.fruits ?? []));
}
});
@ -125,7 +143,7 @@ class TreeQuery extends Query<Tree, TreeQueryWhere> {
var l = out[idx];
return out
..[idx] = l.copyWith(
fruits: List<Fruit>.from(l.fruits ?? [])
fruits: List<_Fruit>.from(l.fruits ?? [])
..addAll(model.fruits ?? []));
}
});
@ -144,7 +162,7 @@ class TreeQuery extends Query<Tree, TreeQueryWhere> {
var l = out[idx];
return out
..[idx] = l.copyWith(
fruits: List<Fruit>.from(l.fruits ?? [])
fruits: List<_Fruit>.from(l.fruits ?? [])
..addAll(model.fruits ?? []));
}
});
@ -206,6 +224,123 @@ class TreeQueryValues extends MapQueryValues {
}
}
class FruitQuery extends Query<Fruit, FruitQueryWhere> {
FruitQuery({Set<String> trampoline}) {
trampoline ??= Set();
trampoline.add(tableName);
_where = FruitQueryWhere(this);
}
@override
final FruitQueryValues values = FruitQueryValues();
FruitQueryWhere _where;
@override
get casts {
return {};
}
@override
get tableName {
return 'fruits';
}
@override
get fields {
return const ['id', 'tree_id', 'common_name', 'created_at', 'updated_at'];
}
@override
FruitQueryWhere get where {
return _where;
}
@override
FruitQueryWhere newWhereClause() {
return FruitQueryWhere(this);
}
static Fruit parseRow(List row) {
if (row.every((x) => x == null)) return null;
var model = Fruit(
id: row[0].toString(),
treeId: (row[1] as int),
commonName: (row[2] as String),
createdAt: (row[3] as DateTime),
updatedAt: (row[4] as DateTime));
return model;
}
@override
deserialize(List row) {
return parseRow(row);
}
}
class FruitQueryWhere extends QueryWhere {
FruitQueryWhere(FruitQuery query)
: id = NumericSqlExpressionBuilder<int>(query, 'id'),
treeId = NumericSqlExpressionBuilder<int>(query, 'tree_id'),
commonName = StringSqlExpressionBuilder(query, 'common_name'),
createdAt = DateTimeSqlExpressionBuilder(query, 'created_at'),
updatedAt = DateTimeSqlExpressionBuilder(query, 'updated_at');
final NumericSqlExpressionBuilder<int> id;
final NumericSqlExpressionBuilder<int> treeId;
final StringSqlExpressionBuilder commonName;
final DateTimeSqlExpressionBuilder createdAt;
final DateTimeSqlExpressionBuilder updatedAt;
@override
get expressionBuilders {
return [id, treeId, commonName, createdAt, updatedAt];
}
}
class FruitQueryValues extends MapQueryValues {
@override
get casts {
return {};
}
String get id {
return (values['id'] as String);
}
set id(String value) => values['id'] = value;
int get treeId {
return (values['tree_id'] as int);
}
set treeId(int value) => values['tree_id'] = value;
String get commonName {
return (values['common_name'] as String);
}
set commonName(String value) => values['common_name'] = value;
DateTime get createdAt {
return (values['created_at'] as DateTime);
}
set createdAt(DateTime value) => values['created_at'] = value;
DateTime get updatedAt {
return (values['updated_at'] as DateTime);
}
set updatedAt(DateTime value) => values['updated_at'] = value;
void copyFrom(Fruit model) {
treeId = model.treeId;
commonName = model.commonName;
createdAt = model.createdAt;
updatedAt = model.updatedAt;
}
}
// **************************************************************************
// JsonModelGenerator
// **************************************************************************
@ -213,7 +348,11 @@ class TreeQueryValues extends MapQueryValues {
@generatedSerializable
class Tree extends _Tree {
Tree(
{this.id, this.rings, List<Fruit> fruits, this.createdAt, this.updatedAt})
{this.id,
this.rings,
List<_Fruit> fruits,
this.createdAt,
this.updatedAt})
: this.fruits = new List.unmodifiable(fruits ?? []);
@override
@ -223,7 +362,7 @@ class Tree extends _Tree {
final int rings;
@override
final List<Fruit> fruits;
final List<_Fruit> fruits;
@override
final DateTime createdAt;
@ -234,7 +373,7 @@ class Tree extends _Tree {
Tree copyWith(
{String id,
int rings,
List<Fruit> fruits,
List<_Fruit> fruits,
DateTime createdAt,
DateTime updatedAt}) {
return new Tree(
@ -249,7 +388,7 @@ class Tree extends _Tree {
return other is _Tree &&
other.id == id &&
other.rings == rings &&
const ListEquality<Fruit>(const DefaultEquality<Fruit>())
const ListEquality<_Fruit>(const DefaultEquality<_Fruit>())
.equals(other.fruits, fruits) &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
@ -270,6 +409,64 @@ class Tree extends _Tree {
}
}
@generatedSerializable
class Fruit extends _Fruit {
Fruit(
{this.id, this.treeId, this.commonName, this.createdAt, this.updatedAt});
@override
final String id;
@override
final int treeId;
@override
final String commonName;
@override
final DateTime createdAt;
@override
final DateTime updatedAt;
Fruit copyWith(
{String id,
int treeId,
String commonName,
DateTime createdAt,
DateTime updatedAt}) {
return new Fruit(
id: id ?? this.id,
treeId: treeId ?? this.treeId,
commonName: commonName ?? this.commonName,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt);
}
bool operator ==(other) {
return other is _Fruit &&
other.id == id &&
other.treeId == treeId &&
other.commonName == commonName &&
other.createdAt == createdAt &&
other.updatedAt == updatedAt;
}
@override
int get hashCode {
return hashObjects([id, treeId, commonName, createdAt, updatedAt]);
}
@override
String toString() {
return "Fruit(id=$id, treeId=$treeId, commonName=$commonName, createdAt=$createdAt, updatedAt=$updatedAt)";
}
Map<String, dynamic> toJson() {
return FruitSerializer.toMap(this);
}
}
// **************************************************************************
// SerializerGenerator
// **************************************************************************
@ -352,3 +549,77 @@ abstract class TreeFields {
static const String updatedAt = 'updated_at';
}
const FruitSerializer fruitSerializer = const FruitSerializer();
class FruitEncoder extends Converter<Fruit, Map> {
const FruitEncoder();
@override
Map convert(Fruit model) => FruitSerializer.toMap(model);
}
class FruitDecoder extends Converter<Map, Fruit> {
const FruitDecoder();
@override
Fruit convert(Map map) => FruitSerializer.fromMap(map);
}
class FruitSerializer extends Codec<Fruit, Map> {
const FruitSerializer();
@override
get encoder => const FruitEncoder();
@override
get decoder => const FruitDecoder();
static Fruit fromMap(Map map) {
return new Fruit(
id: map['id'] as String,
treeId: map['tree_id'] as int,
commonName: map['common_name'] as String,
createdAt: map['created_at'] != null
? (map['created_at'] is DateTime
? (map['created_at'] as DateTime)
: DateTime.parse(map['created_at'].toString()))
: null,
updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime)
: DateTime.parse(map['updated_at'].toString()))
: null);
}
static Map<String, dynamic> toMap(_Fruit model) {
if (model == null) {
return null;
}
return {
'id': model.id,
'tree_id': model.treeId,
'common_name': model.commonName,
'created_at': model.createdAt?.toIso8601String(),
'updated_at': model.updatedAt?.toIso8601String()
};
}
}
abstract class FruitFields {
static const List<String> allFields = <String>[
id,
treeId,
commonName,
createdAt,
updatedAt
];
static const String id = 'id';
static const String treeId = 'tree_id';
static const String commonName = 'common_name';
static const String createdAt = 'created_at';
static const String updatedAt = 'updated_at';
}

View file

@ -232,20 +232,21 @@ class WeirdJoinQuery extends Query<WeirdJoin, WeirdJoinQueryWhere> {
var model = WeirdJoin(id: (row[0] as int));
if (row.length > 2) {
model = model.copyWith(
unorthodox: UnorthodoxQuery.parseRow(row.skip(2).toList()));
unorthodox: UnorthodoxQuery.parseRow(row.skip(2).take(1).toList()));
}
if (row.length > 3) {
model = model.copyWith(song: SongQuery.parseRow(row.skip(3).toList()));
model = model.copyWith(
song: SongQuery.parseRow(row.skip(3).take(5).toList()));
}
if (row.length > 8) {
model = model.copyWith(
numbas: [NumbaQuery.parseRow(row.skip(8).toList())]
numbas: [NumbaQuery.parseRow(row.skip(8).take(2).toList())]
.where((x) => x != null)
.toList());
}
if (row.length > 10) {
model = model.copyWith(
foos: [FooQuery.parseRow(row.skip(10).toList())]
foos: [FooQuery.parseRow(row.skip(10).take(1).toList())]
.where((x) => x != null)
.toList());
}
@ -610,7 +611,7 @@ class FooQuery extends Query<Foo, FooQueryWhere> {
var model = Foo(bar: (row[0] as String));
if (row.length > 1) {
model = model.copyWith(
weirdJoins: [WeirdJoinQuery.parseRow(row.skip(1).toList())]
weirdJoins: [WeirdJoinQuery.parseRow(row.skip(1).take(2).toList())]
.where((x) => x != null)
.toList());
}
@ -760,10 +761,11 @@ class FooPivotQuery extends Query<FooPivot, FooPivotQueryWhere> {
var model = FooPivot();
if (row.length > 2) {
model = model.copyWith(
weirdJoin: WeirdJoinQuery.parseRow(row.skip(2).toList()));
weirdJoin: WeirdJoinQuery.parseRow(row.skip(2).take(2).toList()));
}
if (row.length > 4) {
model = model.copyWith(foo: FooQuery.parseRow(row.skip(4).toList()));
model =
model.copyWith(foo: FooQuery.parseRow(row.skip(4).take(1).toList()));
}
return model;
}

View file

@ -119,7 +119,7 @@ class UserQuery extends Query<User, UserQueryWhere> {
updatedAt: (row[5] as DateTime));
if (row.length > 6) {
model = model.copyWith(
roles: [RoleQuery.parseRow(row.skip(6).toList())]
roles: [RoleQuery.parseRow(row.skip(6).take(4).toList())]
.where((x) => x != null)
.toList());
}
@ -321,10 +321,12 @@ class RoleUserQuery extends Query<RoleUser, RoleUserQueryWhere> {
if (row.every((x) => x == null)) return null;
var model = RoleUser();
if (row.length > 2) {
model = model.copyWith(role: RoleQuery.parseRow(row.skip(2).toList()));
model = model.copyWith(
role: RoleQuery.parseRow(row.skip(2).take(4).toList()));
}
if (row.length > 6) {
model = model.copyWith(user: UserQuery.parseRow(row.skip(6).toList()));
model = model.copyWith(
user: UserQuery.parseRow(row.skip(6).take(6).toList()));
}
return model;
}
@ -432,7 +434,7 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
updatedAt: (row[3] as DateTime));
if (row.length > 4) {
model = model.copyWith(
users: [UserQuery.parseRow(row.skip(4).toList())]
users: [UserQuery.parseRow(row.skip(4).take(6).toList())]
.where((x) => x != null)
.toList());
}