orm_service preview
This commit is contained in:
parent
0f9c4adfe0
commit
9f98a3350e
30 changed files with 1432 additions and 1001 deletions
|
@ -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(
|
||||
|
|
4
angel_orm_service/analysis_options.yaml
Normal file
4
angel_orm_service/analysis_options.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
include: package:pedantic/analysis_options.yaml
|
||||
analyzer:
|
||||
strong-mode:
|
||||
implicit-casts: false
|
14
angel_orm_service/example/connect.dart
Normal file
14
angel_orm_service/example/connect.dart
Normal 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;
|
||||
}
|
38
angel_orm_service/example/main.dart
Normal file
38
angel_orm_service/example/main.dart
Normal 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');
|
||||
}
|
11
angel_orm_service/example/migrate.dart
Normal file
11
angel_orm_service/example/migrate.dart
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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';
|
||||
|
176
angel_orm_service/lib/angel_orm_service.dart
Normal file
176
angel_orm_service/lib/angel_orm_service.dart
Normal 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;
|
||||
}
|
||||
}
|
0
angel_orm_service/mono_pkg.yaml
Normal file
0
angel_orm_service/mono_pkg.yaml
Normal file
18
angel_orm_service/pubspec.yaml
Normal file
18
angel_orm_service/pubspec.yaml
Normal 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
|
|
@ -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
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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';
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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';
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue