Merge pull request #65 from dukefirehawk/fix-bug/mysql-query
Fix bug/mysql query
This commit is contained in:
commit
f4ba4fb25c
48 changed files with 322 additions and 276 deletions
|
@ -1,5 +1,9 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 6.0.1
|
||||||
|
|
||||||
|
* Added `mapToDateTime`
|
||||||
|
|
||||||
## 6.0.0
|
## 6.0.0
|
||||||
|
|
||||||
* Updated to SDK 2.16.x
|
* Updated to SDK 2.16.x
|
||||||
|
|
|
@ -19,3 +19,27 @@ String mapToText(dynamic value) {
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DateTime? mapToDateTime(dynamic value) {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value is String) {
|
||||||
|
return DateTime.tryParse(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mapToDouble(dynamic value) {
|
||||||
|
if (value == null) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (value is String) {
|
||||||
|
return double.tryParse(value) ?? 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is! double) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel3_orm
|
name: angel3_orm
|
||||||
version: 6.0.0
|
version: 6.0.1
|
||||||
description: Runtime support for Angel3 ORM. Includes base classes for queries.
|
description: Runtime support for Angel3 ORM. Includes base classes for queries.
|
||||||
homepage: https://angel3-framework.web.app/
|
homepage: https://angel3-framework.web.app/
|
||||||
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm
|
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 6.0.1
|
||||||
|
|
||||||
|
* Fixed timestamp or date field to DateTime mapping
|
||||||
|
* Fixed double or float field to double mapping
|
||||||
|
|
||||||
## 6.0.0
|
## 6.0.0
|
||||||
|
|
||||||
* Updated to SDK 2.16.x
|
* Updated to SDK 2.16.x
|
||||||
|
|
|
@ -93,14 +93,12 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Employee(
|
var model = Employee(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
uniqueId: fields.contains('unique_id') ? (row[3] as String?) : null,
|
uniqueId: fields.contains('unique_id') ? (row[3] as String?) : null,
|
||||||
firstName: fields.contains('first_name') ? (row[4] as String?) : null,
|
firstName: fields.contains('first_name') ? (row[4] as String?) : null,
|
||||||
lastName: fields.contains('last_name') ? (row[5] as String?) : null,
|
lastName: fields.contains('last_name') ? (row[5] as String?) : null,
|
||||||
salary: fields.contains('salary')
|
salary: fields.contains('salary') ? mapToDouble(row[6]) : null);
|
||||||
? double.tryParse(row[6].toString())
|
|
||||||
: null);
|
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,9 +262,10 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
.property('decode')
|
.property('decode')
|
||||||
.call([expr.asA(refer('String'))]).asA(type);
|
.call([expr.asA(refer('String'))]).asA(type);
|
||||||
} else if (floatTypes.contains(ctx.columns[field.name]?.type)) {
|
} else if (floatTypes.contains(ctx.columns[field.name]?.type)) {
|
||||||
expr = refer('double')
|
//expr = refer('double')
|
||||||
.property('tryParse')
|
// .property('tryParse')
|
||||||
.call([expr.property('toString').call([])]);
|
// .call([expr.property('toString').call([])]);
|
||||||
|
expr = refer('mapToDouble').call([expr]);
|
||||||
} else if (fType is InterfaceType && fType.element.isEnum) {
|
} else if (fType is InterfaceType && fType.element.isEnum) {
|
||||||
var isNull = expr.equalTo(literalNull);
|
var isNull = expr.equalTo(literalNull);
|
||||||
expr = isNull.conditional(literalNull,
|
expr = isNull.conditional(literalNull,
|
||||||
|
@ -272,6 +273,10 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
} else if (fType.isDartCoreBool) {
|
} else if (fType.isDartCoreBool) {
|
||||||
// Generated Code: mapToBool(row[i])
|
// Generated Code: mapToBool(row[i])
|
||||||
expr = refer('mapToBool').call([expr]);
|
expr = refer('mapToBool').call([expr]);
|
||||||
|
} else if (fType.element?.displayName == 'DateTime') {
|
||||||
|
//print("fType: ${fType.element?.displayName}");
|
||||||
|
// Generated Code: mapToDateTime(row[i])
|
||||||
|
expr = refer('mapToDateTime').call([expr]);
|
||||||
} else {
|
} else {
|
||||||
// Generated Code: (row[i] as type?)
|
// Generated Code: (row[i] as type?)
|
||||||
expr = expr.asA(type);
|
expr = expr.asA(type);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel3_orm_generator
|
name: angel3_orm_generator
|
||||||
version: 6.0.0
|
version: 6.0.1
|
||||||
description: Code generators for Angel3 ORM. Generates query builder classes.
|
description: Code generators for Angel3 ORM. Generates query builder classes.
|
||||||
homepage: https://angel3-framework.web.app/
|
homepage: https://angel3-framework.web.app/
|
||||||
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_generator
|
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_generator
|
||||||
|
@ -30,7 +30,7 @@ dev_dependencies:
|
||||||
postgres: ^2.4.0
|
postgres: ^2.4.0
|
||||||
test: ^1.21.0
|
test: ^1.21.0
|
||||||
lints: ^1.0.0
|
lints: ^1.0.0
|
||||||
# dependency_overrides:
|
dependency_overrides:
|
||||||
# angel3_container:
|
# angel3_container:
|
||||||
# path: ../../container/angel_container
|
# path: ../../container/angel_container
|
||||||
# angel3_framework:
|
# angel3_framework:
|
||||||
|
@ -47,8 +47,8 @@ dev_dependencies:
|
||||||
# path: ../../serialize/angel_serialize
|
# path: ../../serialize/angel_serialize
|
||||||
# angel3_serialize_generator:
|
# angel3_serialize_generator:
|
||||||
# path: ../../serialize/angel_serialize_generator
|
# path: ../../serialize/angel_serialize_generator
|
||||||
# angel3_orm:
|
angel3_orm:
|
||||||
# path: ../angel_orm
|
path: ../angel_orm
|
||||||
# angel3_migration:
|
# angel3_migration:
|
||||||
# path: ../angel_migration
|
# path: ../angel_migration
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 6.0.0-beta.3
|
||||||
|
|
||||||
|
* Fixed transaction for `MariaDbExecutor`
|
||||||
|
* Fixed transaction for `MySqlExecutor`
|
||||||
|
* Fixed error for non `id` primary key
|
||||||
|
* Changed test cases to use tables instead of temporary tables to overcome limitations
|
||||||
|
|
||||||
## 6.0.0-beta.2
|
## 6.0.0-beta.2
|
||||||
|
|
||||||
* Updated README
|
* Updated README
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
This package contains the SQL Executor required by Angel3 ORM to work with MySQL and MariaDB respectively. In order to better support the differences in MySQL and MariaDb underlying protocols, two different drives have to be used. For MariaDb 10.2.x, `mysql1` driver provides the best results, while `mysql_client` driver handles MySQL 8.x.x without issues.
|
This package contains the SQL Executor required by Angel3 ORM to work with MySQL and MariaDB respectively. In order to better support the differences in MySQL and MariaDb underlying protocols, two different drives have to be used. For MariaDb 10.2.x, `mysql1` driver provides the best results, while `mysql_client` driver handles MySQL 8.x.x without issues.
|
||||||
|
|
||||||
* MariaDbExecutor (stable)
|
* MariaDbExecutor (beta)
|
||||||
* MySqlExecutor (beta)
|
* MySqlExecutor (beta)
|
||||||
|
|
||||||
## Supported database version
|
## Supported database version
|
||||||
|
@ -51,3 +51,9 @@ This package contains the SQL Executor required by Angel3 ORM to work with MySQL
|
||||||
await connection.connect(timeoutMs: 10000);
|
await connection.connect(timeoutMs: 10000);
|
||||||
var executor = MySqlExecutor(connection, logger: logger);
|
var executor = MySqlExecutor(connection, logger: logger);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Known limitation
|
||||||
|
|
||||||
|
* UTC time is not supported
|
||||||
|
* Blob is not supported
|
||||||
|
|
|
@ -81,8 +81,8 @@ class TodoQuery extends Query<Todo, TodoQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Todo(
|
var model = Todo(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
isComplete: fields.contains('is_complete') ? mapToBool(row[3]) : null,
|
isComplete: fields.contains('is_complete') ? mapToBool(row[3]) : null,
|
||||||
text: fields.contains('text') ? (row[4] as String?) : null);
|
text: fields.contains('text') ? (row[4] as String?) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
|
|
|
@ -4,12 +4,14 @@ import 'package:logging/logging.dart';
|
||||||
import 'package:mysql1/mysql1.dart';
|
import 'package:mysql1/mysql1.dart';
|
||||||
|
|
||||||
class MariaDbExecutor extends QueryExecutor {
|
class MariaDbExecutor extends QueryExecutor {
|
||||||
/// An optional [Logger] to write to.
|
/// An optional [Logger] print information to. A default logger will be used if not set
|
||||||
final Logger? logger;
|
late Logger logger;
|
||||||
|
|
||||||
final MySqlConnection _connection;
|
final MySqlConnection _connection;
|
||||||
|
|
||||||
MariaDbExecutor(this._connection, {this.logger});
|
MariaDbExecutor(this._connection, {Logger? logger}) {
|
||||||
|
this.logger = logger ?? Logger('MariaDbExecutor');
|
||||||
|
}
|
||||||
|
|
||||||
final Dialect _dialect = const MySQLDialect();
|
final Dialect _dialect = const MySQLDialect();
|
||||||
|
|
||||||
|
@ -18,65 +20,7 @@ class MariaDbExecutor extends QueryExecutor {
|
||||||
|
|
||||||
Future<void> close() {
|
Future<void> close() {
|
||||||
return _connection.close();
|
return _connection.close();
|
||||||
/*
|
|
||||||
if (_connection is MySqlConnection) {
|
|
||||||
return (_connection as MySqlConnection).close();
|
|
||||||
} else {
|
|
||||||
return Future.value();
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Future<Transaction> _startTransaction() {
|
|
||||||
if (_connection is Transaction) {
|
|
||||||
return Future.value(_connection as Transaction?);
|
|
||||||
} else if (_connection is MySqlConnection) {
|
|
||||||
return (_connection as MySqlConnection).begin();
|
|
||||||
} else {
|
|
||||||
throw StateError('Connection must be transaction or connection');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<List>> query(
|
|
||||||
String tableName, String query, Map<String, dynamic> substitutionValues,
|
|
||||||
[List<String> returningFields = const []]) {
|
|
||||||
// Change @id -> ?
|
|
||||||
for (var name in substitutionValues.keys) {
|
|
||||||
query = query.replaceAll('@$name', '?');
|
|
||||||
}
|
|
||||||
|
|
||||||
logger?.fine('Query: $query');
|
|
||||||
logger?.fine('Values: $substitutionValues');
|
|
||||||
|
|
||||||
if (returningFields.isNotEmpty != true) {
|
|
||||||
return _connection!
|
|
||||||
.prepared(query, substitutionValues.values)
|
|
||||||
.then((results) => results.map((r) => r.toList()).toList());
|
|
||||||
} else {
|
|
||||||
return Future(() async {
|
|
||||||
var tx = await _startTransaction();
|
|
||||||
|
|
||||||
try {
|
|
||||||
var writeResults =
|
|
||||||
await tx.prepared(query, substitutionValues.values);
|
|
||||||
var fieldSet = returningFields.map((s) => '`$s`').join(',');
|
|
||||||
var fetchSql = 'select $fieldSet from $tableName where id = ?;';
|
|
||||||
logger?.fine(fetchSql);
|
|
||||||
var readResults =
|
|
||||||
await tx.prepared(fetchSql, [writeResults.insertId]);
|
|
||||||
var mapped = readResults.map((r) => r.toList()).toList();
|
|
||||||
await tx.commit();
|
|
||||||
return mapped;
|
|
||||||
} catch (_) {
|
|
||||||
await tx.rollback();
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<List>> query(
|
Future<List<List>> query(
|
||||||
|
@ -101,9 +45,8 @@ class MariaDbExecutor extends QueryExecutor {
|
||||||
var result = await _connection.query(query, params);
|
var result = await _connection.query(query, params);
|
||||||
|
|
||||||
query = returningQuery;
|
query = returningQuery;
|
||||||
//logger?.warning('Result.insertId: ${result.insertId}');
|
// logger?.warning('Result.insertId: ${result.insertId}');
|
||||||
// Has primary key
|
// Has primary key
|
||||||
//if (result.insertId != 0) {
|
|
||||||
if (returningQuery.endsWith('.id=?')) {
|
if (returningQuery.endsWith('.id=?')) {
|
||||||
params = [result.insertId];
|
params = [result.insertId];
|
||||||
}
|
}
|
||||||
|
@ -122,35 +65,20 @@ class MariaDbExecutor extends QueryExecutor {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) async {
|
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) async {
|
||||||
return f(this);
|
T? returnValue = await _connection.transaction((ctx) async {
|
||||||
/*
|
var conn = ctx as MySqlConnection;
|
||||||
if (_connection is! MySqlConnection) {
|
|
||||||
return await f(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
await _connection.transaction((context) async {
|
|
||||||
var executor = MySqlExecutor(context, logger: logger);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@override
|
|
||||||
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) async {
|
|
||||||
if (_connection is Transaction) {
|
|
||||||
return await f(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Transaction? tx;
|
|
||||||
try {
|
try {
|
||||||
tx = await _startTransaction();
|
logger.fine('Entering transaction');
|
||||||
var executor = MySqlExecutor(tx, logger: logger);
|
var tx = MariaDbExecutor(conn, logger: logger);
|
||||||
var result = await f(executor);
|
return await f(tx);
|
||||||
await tx.commit();
|
} catch (e) {
|
||||||
return result;
|
logger.severe('Failed to run transaction', e);
|
||||||
} catch (_) {
|
|
||||||
await tx?.rollback();
|
|
||||||
rethrow;
|
rethrow;
|
||||||
|
} finally {
|
||||||
|
logger.fine('Exiting transaction');
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return returnValue!;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,14 @@ import 'package:logging/logging.dart';
|
||||||
import 'package:mysql_client/mysql_client.dart';
|
import 'package:mysql_client/mysql_client.dart';
|
||||||
|
|
||||||
class MySqlExecutor extends QueryExecutor {
|
class MySqlExecutor extends QueryExecutor {
|
||||||
/// An optional [Logger] to write to.
|
/// An optional [Logger] to write to. A default logger will be used if not set
|
||||||
final Logger? logger;
|
late Logger logger;
|
||||||
|
|
||||||
final MySQLConnection _connection;
|
final MySQLConnection _connection;
|
||||||
|
|
||||||
MySqlExecutor(this._connection, {this.logger});
|
MySqlExecutor(this._connection, {Logger? logger}) {
|
||||||
|
this.logger = logger ?? Logger('MySqlExecutor');
|
||||||
|
}
|
||||||
|
|
||||||
final Dialect _dialect = const MySQLDialect();
|
final Dialect _dialect = const MySQLDialect();
|
||||||
|
|
||||||
|
@ -18,15 +20,10 @@ class MySqlExecutor extends QueryExecutor {
|
||||||
|
|
||||||
Future<void> close() {
|
Future<void> close() {
|
||||||
return _connection.close();
|
return _connection.close();
|
||||||
/*
|
|
||||||
if (_connection is MySqlConnection) {
|
|
||||||
return (_connection as MySqlConnection).close();
|
|
||||||
} else {
|
|
||||||
return Future.value();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MySQLConnection get rawConnection => _connection;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Future<Transaction> _startTransaction() {
|
Future<Transaction> _startTransaction() {
|
||||||
if (_connection is Transaction) {
|
if (_connection is Transaction) {
|
||||||
|
@ -86,13 +83,23 @@ class MySqlExecutor extends QueryExecutor {
|
||||||
// Change @id -> ?
|
// Change @id -> ?
|
||||||
for (var name in substitutionValues.keys) {
|
for (var name in substitutionValues.keys) {
|
||||||
query = query.replaceAll('@$name', ':$name');
|
query = query.replaceAll('@$name', ':$name');
|
||||||
|
|
||||||
|
// Convert UTC time to local time
|
||||||
|
var value = substitutionValues[name];
|
||||||
|
if (value is DateTime && value.isUtc) {
|
||||||
|
var t = value.toLocal();
|
||||||
|
logger.warning('Datetime deteted: $name');
|
||||||
|
logger.warning('Datetime: UTC -> $value, Local -> $t');
|
||||||
|
|
||||||
|
substitutionValues[name] = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//var params = substitutionValues.values.toList();
|
//var params = substitutionValues.values.toList();
|
||||||
var params = [];
|
//var params = [];
|
||||||
|
|
||||||
logger?.warning('Query: $query');
|
logger.warning('Query: $query');
|
||||||
logger?.warning('Values: $substitutionValues');
|
logger.warning('Values: $substitutionValues');
|
||||||
//logger?.warning('Returning Query: $returningQuery');
|
//logger?.warning('Returning Query: $returningQuery');
|
||||||
|
|
||||||
if (returningQuery.isNotEmpty) {
|
if (returningQuery.isNotEmpty) {
|
||||||
|
@ -101,53 +108,64 @@ class MySqlExecutor extends QueryExecutor {
|
||||||
if (query.startsWith("INSERT")) {
|
if (query.startsWith("INSERT")) {
|
||||||
var result = await _connection.execute(query, substitutionValues);
|
var result = await _connection.execute(query, substitutionValues);
|
||||||
|
|
||||||
logger?.warning(result.lastInsertID);
|
logger.warning(result.lastInsertID);
|
||||||
|
|
||||||
query = returningQuery;
|
query = returningQuery;
|
||||||
//logger?.warning('Result.insertId: ${result.insertId}');
|
//logger?.warning('Result.insertId: ${result.insertId}');
|
||||||
// Has primary key
|
// Has primary key
|
||||||
//if (result.insertId != 0) {
|
|
||||||
if (returningQuery.endsWith('.id=?')) {
|
if (returningQuery.endsWith('.id=?')) {
|
||||||
query = query.replaceAll("?", ":id");
|
query = query.replaceAll("?", ":id");
|
||||||
//params = [result.lastInsertID];
|
|
||||||
substitutionValues.clear();
|
substitutionValues.clear();
|
||||||
substitutionValues['id'] = result.lastInsertID;
|
substitutionValues['id'] = result.lastInsertID;
|
||||||
|
} else {
|
||||||
|
query = _convertSQL(query, substitutionValues);
|
||||||
}
|
}
|
||||||
} else if (query.startsWith("UPDATE")) {
|
} else if (query.startsWith("UPDATE")) {
|
||||||
await _connection.execute(query, substitutionValues);
|
await _connection.execute(query, substitutionValues);
|
||||||
query = returningQuery;
|
query = returningQuery;
|
||||||
params = [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger?.warning('Query 2: $query');
|
logger.warning('Query 2: $query');
|
||||||
logger?.warning('Values 2: $substitutionValues');
|
logger.warning('Values 2: $substitutionValues');
|
||||||
|
|
||||||
// Handle select
|
// Handle select
|
||||||
return _connection.execute(query, substitutionValues).then((results) {
|
return _connection.execute(query, substitutionValues).then((results) {
|
||||||
logger?.warning("SELECT");
|
logger.warning("SELECT");
|
||||||
//for (var element in results.cols) {
|
|
||||||
// print(
|
|
||||||
// '${element.name} ${element.type.toString()} ${element.runtimeType.toString()}');
|
|
||||||
//}
|
|
||||||
|
|
||||||
return results.rows.map((r) => r.typedAssoc().values.toList()).toList();
|
return results.rows.map((r) => r.typedAssoc().values.toList()).toList();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
String _convertSQL(String query, Map<String, dynamic> substitutionValues) {
|
||||||
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) async {
|
var newQuery = query;
|
||||||
logger?.warning("Transaction");
|
for (var k in substitutionValues.keys) {
|
||||||
return f(this);
|
var fromPattern = '.$k = ?';
|
||||||
/*
|
var toPattern = '.$k = :$k';
|
||||||
if (_connection is! MySqlConnection) {
|
newQuery = newQuery.replaceFirst(fromPattern, toPattern);
|
||||||
return await f(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await _connection.transaction((context) async {
|
return newQuery;
|
||||||
var executor = MySqlExecutor(context, logger: logger);
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) async {
|
||||||
|
logger.warning("Transaction");
|
||||||
|
|
||||||
|
T? returnValue = await _connection.transactional((ctx) async {
|
||||||
|
try {
|
||||||
|
logger.fine('Entering transaction');
|
||||||
|
var tx = MySqlExecutor(ctx, logger: logger);
|
||||||
|
return await f(tx);
|
||||||
|
} catch (e) {
|
||||||
|
logger.severe('Failed to run transaction', e);
|
||||||
|
rethrow;
|
||||||
|
} finally {
|
||||||
|
logger.fine('Exiting transaction');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
|
return returnValue!;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel3_orm_mysql
|
name: angel3_orm_mysql
|
||||||
version: 6.0.0-beta.2
|
version: 6.0.0-beta.3
|
||||||
description: MySQL support for Angel3 ORM. Includes functionality for querying and transactions.
|
description: MySQL support for Angel3 ORM. Includes functionality for querying and transactions.
|
||||||
homepage: https://angel3-framework.web.app/
|
homepage: https://angel3-framework.web.app/
|
||||||
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_mysql
|
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_mysql
|
||||||
|
@ -9,7 +9,7 @@ dependencies:
|
||||||
angel3_orm: ^6.0.0
|
angel3_orm: ^6.0.0
|
||||||
logging: ^1.0.0
|
logging: ^1.0.0
|
||||||
mysql1: ^0.19.0
|
mysql1: ^0.19.0
|
||||||
mysql_client: ^0.0.11
|
mysql_client: ^0.0.15
|
||||||
optional: ^6.0.0
|
optional: ^6.0.0
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
angel3_orm_generator: ^6.0.0
|
angel3_orm_generator: ^6.0.0
|
||||||
|
@ -17,18 +17,18 @@ dev_dependencies:
|
||||||
build_runner: ^2.0.1
|
build_runner: ^2.0.1
|
||||||
test: ^1.21.0
|
test: ^1.21.0
|
||||||
lints: ^1.0.0
|
lints: ^1.0.0
|
||||||
# dependency_overrides:
|
dependency_overrides:
|
||||||
# angel3_serialize:
|
# angel3_serialize:
|
||||||
# path: ../../serialize/angel_serialize
|
# path: ../../serialize/angel_serialize
|
||||||
# angel3_serialize_generator:
|
# angel3_serialize_generator:
|
||||||
# path: ../../serialize/angel_serialize_generator
|
# path: ../../serialize/angel_serialize_generator
|
||||||
# angel3_model:
|
# angel3_model:
|
||||||
# path: ../../model
|
# path: ../../model
|
||||||
# angel3_orm_test:
|
angel3_orm_test:
|
||||||
# path: ../angel_orm_test
|
path: ../angel_orm_test
|
||||||
# angel3_orm:
|
angel3_orm:
|
||||||
# path: ../angel_orm
|
path: ../angel_orm
|
||||||
|
angel3_orm_generator:
|
||||||
|
path: ../angel_orm_generator
|
||||||
# angel3_migration:
|
# angel3_migration:
|
||||||
# path: ../angel_migration
|
# path: ../angel_migration
|
||||||
# angel3_orm_generator:
|
|
||||||
# path: ../angel_orm_generator
|
|
||||||
|
|
|
@ -11,23 +11,28 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
group('mysql', () {
|
group('mysql', () {
|
||||||
group('belongsTo',
|
group(
|
||||||
() => belongsToTests(my(['author', 'book']), close: closeMy));
|
'belongsTo',
|
||||||
|
() => belongsToTests(createTables(['author', 'book']),
|
||||||
|
close: dropTables));
|
||||||
group(
|
group(
|
||||||
'edgeCase',
|
'edgeCase',
|
||||||
() => edgeCaseTests(my(['unorthodox', 'weird_join', 'song', 'numba']),
|
() => edgeCaseTests(
|
||||||
close: closeMy));
|
createTables(['unorthodox', 'weird_join', 'song', 'numba']),
|
||||||
|
close: dropTables));
|
||||||
group('enumAndNested',
|
group('enumAndNested',
|
||||||
() => enumAndNestedTests(my(['has_car']), close: closeMy));
|
() => enumAndNestedTests(createTables(['has_car']), close: dropTables));
|
||||||
group('hasMany', () => hasManyTests(my(['tree', 'fruit']), close: closeMy));
|
group('hasMany',
|
||||||
|
() => hasManyTests(createTables(['tree', 'fruit']), close: dropTables));
|
||||||
// NOTE: MySQL/MariaDB do not support jsonb data type
|
// NOTE: MySQL/MariaDB do not support jsonb data type
|
||||||
//group('hasMap', () => hasMapTests(my(['has_map']), close: closeMy));
|
//group('hasMap', () => hasMapTests(createTables(['has_maps']), close: dropTables));
|
||||||
// NOTE: mysql1 driver do not support CAST();
|
// NOTE: mysql1 driver do not support CAST();
|
||||||
//group('hasOne', () => hasOneTests(my(['leg', 'foot']), close: closeMy));
|
//group('hasOne', () => hasOneTests(createTables(['legs', 'feet']), close: dropTables));
|
||||||
group(
|
group(
|
||||||
'manyToMany',
|
'manyToMany',
|
||||||
() =>
|
() => manyToManyTests(createTables(['user', 'role', 'user_role']),
|
||||||
manyToManyTests(my(['user', 'role', 'user_role']), close: closeMy));
|
close: dropTables));
|
||||||
group('standalone', () => standaloneTests(my(['car']), close: closeMy));
|
group('standalone',
|
||||||
|
() => standaloneTests(createTables(['car']), close: dropTables));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,47 @@ import 'package:logging/logging.dart';
|
||||||
import 'package:mysql1/mysql1.dart';
|
import 'package:mysql1/mysql1.dart';
|
||||||
import 'package:mysql_client/mysql_client.dart';
|
import 'package:mysql_client/mysql_client.dart';
|
||||||
|
|
||||||
FutureOr<QueryExecutor> Function() my(Iterable<String> schemas) {
|
List tmpTables = [];
|
||||||
return () => connectToMySql(schemas);
|
|
||||||
|
FutureOr<QueryExecutor> Function() createTables(List<String> schemas) {
|
||||||
|
// For MySQL
|
||||||
|
return () => _connectToMySql(schemas);
|
||||||
|
|
||||||
|
// For MariaDB
|
||||||
|
// return () => _connectToMariaDb(tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> closeMy(QueryExecutor executor) =>
|
// For MySQL
|
||||||
(executor as MySqlExecutor).close();
|
Future<void> dropTables(QueryExecutor executor) async {
|
||||||
|
var sqlExecutor = (executor as MySqlExecutor);
|
||||||
|
for (var tableName in tmpTables.reversed) {
|
||||||
|
await sqlExecutor.rawConnection.execute('drop table $tableName;');
|
||||||
|
}
|
||||||
|
return sqlExecutor.close();
|
||||||
|
}
|
||||||
|
|
||||||
// Executor for MariaDB 10.2.x
|
// For MariaDB
|
||||||
Future<MariaDbExecutor> connectToMariaDb(Iterable<String> schemas) async {
|
/* Future<void> dropTables(QueryExecutor executor) {
|
||||||
|
var sqlExecutor = (executor as MariaDbExecutor);
|
||||||
|
for (var tableName in tmpTables.reversed) {
|
||||||
|
sqlExecutor.query(tableName, 'DROP TABLE $tableName', {});
|
||||||
|
}
|
||||||
|
return sqlExecutor.close();
|
||||||
|
} */
|
||||||
|
|
||||||
|
String extractTableName(String createQuery) {
|
||||||
|
var start = createQuery.indexOf('EXISTS');
|
||||||
|
var end = createQuery.indexOf('(');
|
||||||
|
|
||||||
|
if (start == -1 || end == -1) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return createQuery.substring(start + 6, end).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executor for MariaDB
|
||||||
|
Future<MariaDbExecutor> _connectToMariaDb(List<String> schemas) async {
|
||||||
var settings = ConnectionSettings(
|
var settings = ConnectionSettings(
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 3306,
|
port: 3306,
|
||||||
|
@ -23,7 +55,9 @@ Future<MariaDbExecutor> connectToMariaDb(Iterable<String> schemas) async {
|
||||||
password: 'Test123*');
|
password: 'Test123*');
|
||||||
var connection = await MySqlConnection.connect(settings);
|
var connection = await MySqlConnection.connect(settings);
|
||||||
|
|
||||||
var logger = Logger('orm_mysql');
|
var logger = Logger('orm_mariadb');
|
||||||
|
|
||||||
|
tmpTables.clear();
|
||||||
|
|
||||||
for (var s in schemas) {
|
for (var s in schemas) {
|
||||||
// MySQL driver does not support multiple sql queries
|
// MySQL driver does not support multiple sql queries
|
||||||
|
@ -34,6 +68,11 @@ Future<MariaDbExecutor> connectToMariaDb(Iterable<String> schemas) async {
|
||||||
if (q.trim().isNotEmpty) {
|
if (q.trim().isNotEmpty) {
|
||||||
//await connection.execute(q);
|
//await connection.execute(q);
|
||||||
await connection.query(q);
|
await connection.query(q);
|
||||||
|
|
||||||
|
var tableName = extractTableName(q);
|
||||||
|
if (tableName != '') {
|
||||||
|
tmpTables.add(tableName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,20 +80,22 @@ Future<MariaDbExecutor> connectToMariaDb(Iterable<String> schemas) async {
|
||||||
return MariaDbExecutor(connection, logger: logger);
|
return MariaDbExecutor(connection, logger: logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executor for MySQL 8.x.x
|
// Executor for MySQL
|
||||||
Future<MySqlExecutor> connectToMySql(Iterable<String> schemas) async {
|
Future<MySqlExecutor> _connectToMySql(List<String> schemas) async {
|
||||||
var connection = await MySQLConnection.createConnection(
|
var connection = await MySQLConnection.createConnection(
|
||||||
databaseName: 'orm_test',
|
databaseName: 'orm_test',
|
||||||
port: 3306,
|
port: 3306,
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
userName: Platform.environment['MYSQL_USERNAME'] ?? 'test',
|
userName: Platform.environment['MYSQL_USERNAME'] ?? 'test',
|
||||||
password: Platform.environment['MYSQL_PASSWORD'] ?? 'Test123*',
|
password: Platform.environment['MYSQL_PASSWORD'] ?? 'Test123*',
|
||||||
);
|
secure: false);
|
||||||
|
|
||||||
await connection.connect();
|
await connection.connect(timeoutMs: 10000);
|
||||||
|
|
||||||
var logger = Logger('orm_mysql');
|
var logger = Logger('orm_mysql');
|
||||||
|
|
||||||
|
tmpTables.clear();
|
||||||
|
|
||||||
for (var s in schemas) {
|
for (var s in schemas) {
|
||||||
// MySQL driver does not support multiple sql queries
|
// MySQL driver does not support multiple sql queries
|
||||||
var data = await File('test/migrations/$s.sql').readAsString();
|
var data = await File('test/migrations/$s.sql').readAsString();
|
||||||
|
@ -63,6 +104,11 @@ Future<MySqlExecutor> connectToMySql(Iterable<String> schemas) async {
|
||||||
//print("Table: [$q]");
|
//print("Table: [$q]");
|
||||||
if (q.trim().isNotEmpty) {
|
if (q.trim().isNotEmpty) {
|
||||||
await connection.execute(q);
|
await connection.execute(q);
|
||||||
|
|
||||||
|
var tableName = extractTableName(q);
|
||||||
|
if (tableName != '') {
|
||||||
|
tmpTables.add(tableName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE authors (
|
CREATE TABLE IF NOT EXISTS authors (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
name varchar(255) UNIQUE NOT NULL,
|
name varchar(255) UNIQUE NOT NULL,
|
||||||
created_at timestamp,
|
created_at timestamp,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE books (
|
CREATE TABLE IF NOT EXISTS books (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
author_id int NOT NULL,
|
author_id int NOT NULL,
|
||||||
partner_author_id int,
|
partner_author_id int,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE cars (
|
CREATE TABLE IF NOT EXISTS cars (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
make varchar(255) NOT NULL,
|
make varchar(255) NOT NULL,
|
||||||
description TEXT NOT NULL,
|
description TEXT NOT NULL,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE feet (
|
CREATE TABLE IF NOT EXISTS feet (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
leg_id int NOT NULL,
|
leg_id int NOT NULL,
|
||||||
n_toes int NOT NULL,
|
n_toes int NOT NULL,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE fruits (
|
CREATE TABLE IF NOT EXISTS fruits (
|
||||||
id serial,
|
id serial,
|
||||||
tree_id int,
|
tree_id int,
|
||||||
common_name varchar(255),
|
common_name varchar(255),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE has_cars (
|
CREATE TABLE IF NOT EXISTS has_cars (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
type int not null,
|
type int not null,
|
||||||
created_at timestamp,
|
created_at timestamp,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE has_maps (
|
CREATE TABLE IF NOT EXISTS has_maps (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
value jsonb not null,
|
value jsonb not null,
|
||||||
list jsonb not null,
|
list jsonb not null,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE legs (
|
CREATE TABLE IF NOT EXISTS legs (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
name varchar(255) NOT NULL,
|
name varchar(255) NOT NULL,
|
||||||
created_at timestamp,
|
created_at timestamp,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE numbas (
|
CREATE TABLE IF NOT EXISTS numbas (
|
||||||
i int NOT NULL UNIQUE,
|
i int NOT NULL UNIQUE,
|
||||||
parent int,
|
parent int,
|
||||||
created_at TIMESTAMP,
|
created_at TIMESTAMP,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE roles (
|
CREATE TABLE IF NOT EXISTS roles (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
name varchar(255),
|
name varchar(255),
|
||||||
created_at timestamp,
|
created_at timestamp,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE songs (
|
CREATE TABLE IF NOT EXISTS songs (
|
||||||
id serial,
|
id serial,
|
||||||
weird_join_id int,
|
weird_join_id int,
|
||||||
title varchar(255),
|
title varchar(255),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE trees (
|
CREATE TABLE IF NOT EXISTS trees (
|
||||||
id serial,
|
id serial,
|
||||||
rings smallint UNIQUE,
|
rings smallint UNIQUE,
|
||||||
created_at timestamp,
|
created_at timestamp,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE unorthodoxes (
|
CREATE TABLE IF NOT EXISTS unorthodoxes (
|
||||||
name varchar(255) NOT NULL UNIQUE,
|
name varchar(255) NOT NULL UNIQUE,
|
||||||
PRIMARY KEY(name)
|
PRIMARY KEY(name)
|
||||||
);
|
);
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
username varchar(255),
|
username varchar(255),
|
||||||
password varchar(255),
|
password varchar(255),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CREATE TEMPORARY TABLE role_users (
|
CREATE TABLE IF NOT EXISTS role_users (
|
||||||
id serial PRIMARY KEY,
|
id serial PRIMARY KEY,
|
||||||
user_id int NOT NULL,
|
user_id int NOT NULL,
|
||||||
role_id int NOT NULL,
|
role_id int NOT NULL,
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
CREATE TEMPORARY TABLE weird_joins (
|
CREATE TABLE IF NOT EXISTS weird_joins (
|
||||||
id serial,
|
id serial,
|
||||||
join_name varchar(255),
|
join_name varchar(255),
|
||||||
PRIMARY KEY(id)
|
PRIMARY KEY(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TEMPORARY TABLE foos (
|
CREATE TABLE IF NOT EXISTS foos (
|
||||||
bar varchar(255) not null UNIQUE,
|
bar varchar(255) not null UNIQUE,
|
||||||
PRIMARY KEY(bar)
|
PRIMARY KEY(bar)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TEMPORARY TABLE foo_pivots (
|
CREATE TABLE IF NOT EXISTS foo_pivots (
|
||||||
weird_join_id int,
|
weird_join_id int,
|
||||||
foo_bar varchar(255)
|
foo_bar varchar(255)
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,7 +14,7 @@ void main() async {
|
||||||
// if (rec.stackTrace != null) print(rec.stackTrace);
|
// if (rec.stackTrace != null) print(rec.stackTrace);
|
||||||
//});
|
//});
|
||||||
|
|
||||||
belongsToTests(my(['author', 'book']), close: closeMy);
|
belongsToTests(createTables(['author', 'book']), close: dropTables);
|
||||||
|
|
||||||
//hasOneTests(my(['leg', 'foot']), close: closeMy);
|
//hasOneTests(my(['leg', 'foot']), close: closeMy);
|
||||||
//standaloneTests(my(['car']), close: closeMy);
|
//standaloneTests(my(['car']), close: closeMy);
|
||||||
|
|
|
@ -9,7 +9,8 @@ import 'package:postgres/postgres.dart';
|
||||||
class PostgreSqlExecutor extends QueryExecutor {
|
class PostgreSqlExecutor extends QueryExecutor {
|
||||||
final PostgreSQLExecutionContext _connection;
|
final PostgreSQLExecutionContext _connection;
|
||||||
|
|
||||||
/// An optional [Logger] to print information to.
|
/// An optional [Logger] to print information to. A default logger will be used
|
||||||
|
/// if not set
|
||||||
late Logger logger;
|
late Logger logger;
|
||||||
|
|
||||||
PostgreSqlExecutor(this._connection, {Logger? logger}) {
|
PostgreSqlExecutor(this._connection, {Logger? logger}) {
|
||||||
|
|
|
@ -16,14 +16,14 @@ dev_dependencies:
|
||||||
angel3_orm_test: ^6.0.0
|
angel3_orm_test: ^6.0.0
|
||||||
test: ^1.21.0
|
test: ^1.21.0
|
||||||
lints: ^1.0.0
|
lints: ^1.0.0
|
||||||
# dependency_overrides:
|
dependency_overrides:
|
||||||
# angel3_serialize:
|
# angel3_serialize:
|
||||||
# path: ../../serialize/angel_serialize
|
# path: ../../serialize/angel_serialize
|
||||||
# angel3_model:
|
# angel3_model:
|
||||||
# path: ../../model
|
# path: ../../model
|
||||||
# angel3_orm_test:
|
angel3_orm_test:
|
||||||
# path: ../angel_orm_test
|
path: ../angel_orm_test
|
||||||
# angel3_orm:
|
angel3_orm:
|
||||||
# path: ../angel_orm
|
path: ../angel_orm
|
||||||
# angel3_migration:
|
# angel3_migration:
|
||||||
# path: ../angel_migration
|
# path: ../angel_migration
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 6.0.1
|
||||||
|
|
||||||
|
* Updated generated test cases
|
||||||
|
|
||||||
## 6.0.0
|
## 6.0.0
|
||||||
|
|
||||||
* Updated to SDK 2.16.x
|
* Updated to SDK 2.16.x
|
||||||
|
|
|
@ -61,7 +61,8 @@ void manyToManyTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
..username = 'thosakwe'
|
..username = 'thosakwe'
|
||||||
..password = 'Hahahahayoureallythoughtiwasstupidenoughtotypethishere'
|
..password = 'Hahahahayoureallythoughtiwasstupidenoughtotypethishere'
|
||||||
..email = 'thosakwe AT gmail.com';
|
..email = 'thosakwe AT gmail.com';
|
||||||
thosakwe = (await thosakweQuery.insert(executor)).value;
|
var result = await thosakweQuery.insert(executor);
|
||||||
|
thosakwe = result.value;
|
||||||
print('=== THOSAKWE: ${thosakwe?.toJson()}');
|
print('=== THOSAKWE: ${thosakwe?.toJson()}');
|
||||||
|
|
||||||
// Allow thosakwe to publish...
|
// Allow thosakwe to publish...
|
||||||
|
|
|
@ -122,8 +122,8 @@ class BookQuery extends Query<Book, BookQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Book(
|
var model = Book(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
name: fields.contains('name') ? (row[5] as String?) : null);
|
name: fields.contains('name') ? (row[5] as String?) : null);
|
||||||
if (row.length > 6) {
|
if (row.length > 6) {
|
||||||
var modelOpt = AuthorQuery().parseRow(row.skip(6).take(4).toList());
|
var modelOpt = AuthorQuery().parseRow(row.skip(6).take(4).toList());
|
||||||
|
@ -285,8 +285,8 @@ class AuthorQuery extends Query<Author, AuthorQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Author(
|
var model = Author(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
name: fields.contains('name') ? (row[3] as String?) : null);
|
name: fields.contains('name') ? (row[3] as String?) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,15 +91,15 @@ class CarQuery extends Query<Car, CarQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Car(
|
var model = Car(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
make: fields.contains('make') ? (row[3] as String?) : null,
|
make: fields.contains('make') ? (row[3] as String?) : null,
|
||||||
description:
|
description:
|
||||||
fields.contains('description') ? (row[4] as String?) : null,
|
fields.contains('description') ? (row[4] as String?) : null,
|
||||||
familyFriendly:
|
familyFriendly:
|
||||||
fields.contains('family_friendly') ? mapToBool(row[5]) : null,
|
fields.contains('family_friendly') ? mapToBool(row[5]) : null,
|
||||||
recalledAt:
|
recalledAt:
|
||||||
fields.contains('recalled_at') ? (row[6] as DateTime?) : null);
|
fields.contains('recalled_at') ? mapToDateTime(row[6]) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,8 @@ class NumbersQuery extends Query<Numbers, NumbersQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Numbers(
|
var model = Numbers(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
two: fields.contains('two') ? (row[3] as int?) : null);
|
two: fields.contains('two') ? (row[3] as int?) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
}
|
}
|
||||||
|
@ -218,8 +218,8 @@ class AlphabetQuery extends Query<Alphabet, AlphabetQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Alphabet(
|
var model = Alphabet(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
value: fields.contains('value') ? (row[3] as String?) : null);
|
value: fields.contains('value') ? (row[3] as String?) : null);
|
||||||
if (row.length > 5) {
|
if (row.length > 5) {
|
||||||
var modelOpt = NumbersQuery().parseRow(row.skip(5).take(4).toList());
|
var modelOpt = NumbersQuery().parseRow(row.skip(5).take(4).toList());
|
||||||
|
|
|
@ -81,8 +81,8 @@ class HasCarQuery extends Query<HasCar, HasCarQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = HasCar(
|
var model = HasCar(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
type: fields.contains('type')
|
type: fields.contains('type')
|
||||||
? row[3] == null
|
? row[3] == null
|
||||||
? null
|
? null
|
||||||
|
|
|
@ -111,8 +111,8 @@ class LegQuery extends Query<Leg, LegQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Leg(
|
var model = Leg(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
name: fields.contains('name') ? (row[3] as String?) : null);
|
name: fields.contains('name') ? (row[3] as String?) : null);
|
||||||
if (row.length > 4) {
|
if (row.length > 4) {
|
||||||
var modelOpt = FootQuery().parseRow(row.skip(4).take(5).toList());
|
var modelOpt = FootQuery().parseRow(row.skip(4).take(5).toList());
|
||||||
|
@ -240,12 +240,10 @@ class FootQuery extends Query<Foot, FootQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Foot(
|
var model = Foot(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
legId: fields.contains('leg_id') ? (row[3] as int?) : null,
|
legId: fields.contains('leg_id') ? (row[3] as int?) : null,
|
||||||
nToes: fields.contains('n_toes')
|
nToes: fields.contains('n_toes') ? mapToDouble(row[4]) : null);
|
||||||
? double.tryParse(row[4].toString())
|
|
||||||
: null);
|
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,10 +115,10 @@ class OrderQuery extends Query<Order, OrderQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Order(
|
var model = Order(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
employeeId: fields.contains('employee_id') ? (row[4] as int?) : null,
|
employeeId: fields.contains('employee_id') ? (row[4] as int?) : null,
|
||||||
orderDate: fields.contains('order_date') ? (row[5] as DateTime?) : null,
|
orderDate: fields.contains('order_date') ? mapToDateTime(row[5]) : null,
|
||||||
shipperId: fields.contains('shipper_id') ? (row[6] as int?) : null);
|
shipperId: fields.contains('shipper_id') ? (row[6] as int?) : null);
|
||||||
if (row.length > 7) {
|
if (row.length > 7) {
|
||||||
var modelOpt = CustomerQuery().parseRow(row.skip(7).take(3).toList());
|
var modelOpt = CustomerQuery().parseRow(row.skip(7).take(3).toList());
|
||||||
|
@ -284,9 +284,9 @@ class CustomerQuery extends Query<Customer, CustomerQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Customer(
|
var model = Customer(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt:
|
updatedAt:
|
||||||
fields.contains('updated_at') ? (row[2] as DateTime?) : null);
|
fields.contains('updated_at') ? mapToDateTime(row[2]) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,8 +82,8 @@ class PersonQuery extends Query<Person, PersonQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Person(
|
var model = Person(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
name: fields.contains('name') ? (row[3] as String?) : null,
|
name: fields.contains('name') ? (row[3] as String?) : null,
|
||||||
age: fields.contains('age') ? (row[4] as int?) : null);
|
age: fields.contains('age') ? (row[4] as int?) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
|
|
|
@ -93,13 +93,11 @@ class PersonOrderQuery extends Query<PersonOrder, PersonOrderQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = PersonOrder(
|
var model = PersonOrder(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
personId: fields.contains('person_id') ? (row[3] as int?) : null,
|
personId: fields.contains('person_id') ? (row[3] as int?) : null,
|
||||||
name: fields.contains('name') ? (row[4] as String?) : null,
|
name: fields.contains('name') ? (row[4] as String?) : null,
|
||||||
price: fields.contains('price')
|
price: fields.contains('price') ? mapToDouble(row[5]) : null,
|
||||||
? double.tryParse(row[5].toString())
|
|
||||||
: null,
|
|
||||||
deleted: fields.contains('deleted') ? mapToBool(row[6]) : null);
|
deleted: fields.contains('deleted') ? mapToBool(row[6]) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
}
|
}
|
||||||
|
@ -258,12 +256,10 @@ class OrderWithPersonInfoQuery
|
||||||
}
|
}
|
||||||
var model = OrderWithPersonInfo(
|
var model = OrderWithPersonInfo(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
name: fields.contains('name') ? (row[3] as String?) : null,
|
name: fields.contains('name') ? (row[3] as String?) : null,
|
||||||
price: fields.contains('price')
|
price: fields.contains('price') ? mapToDouble(row[4]) : null,
|
||||||
? double.tryParse(row[4].toString())
|
|
||||||
: null,
|
|
||||||
deleted: fields.contains('deleted') ? mapToBool(row[5]) : null,
|
deleted: fields.contains('deleted') ? mapToBool(row[5]) : null,
|
||||||
personName: fields.contains('person_name') ? (row[6] as String?) : null,
|
personName: fields.contains('person_name') ? (row[6] as String?) : null,
|
||||||
personAge: fields.contains('person_age') ? (row[7] as int?) : null);
|
personAge: fields.contains('person_age') ? (row[7] as int?) : null);
|
||||||
|
|
|
@ -110,8 +110,8 @@ class TreeQuery extends Query<Tree, TreeQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Tree(
|
var model = Tree(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
rings: fields.contains('rings') ? (row[3] as int?) : null);
|
rings: fields.contains('rings') ? (row[3] as int?) : null);
|
||||||
if (row.length > 4) {
|
if (row.length > 4) {
|
||||||
var modelOpt = FruitQuery().parseRow(row.skip(4).take(5).toList());
|
var modelOpt = FruitQuery().parseRow(row.skip(4).take(5).toList());
|
||||||
|
@ -299,8 +299,8 @@ class FruitQuery extends Query<Fruit, FruitQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Fruit(
|
var model = Fruit(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
treeId: fields.contains('tree_id') ? (row[3] as int?) : null,
|
treeId: fields.contains('tree_id') ? (row[3] as int?) : null,
|
||||||
commonName:
|
commonName:
|
||||||
fields.contains('common_name') ? (row[4] as String?) : null);
|
fields.contains('common_name') ? (row[4] as String?) : null);
|
||||||
|
|
|
@ -486,8 +486,8 @@ class SongQuery extends Query<Song, SongQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Song(
|
var model = Song(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
weirdJoinId: fields.contains('weird_join_id') ? (row[3] as int?) : null,
|
weirdJoinId: fields.contains('weird_join_id') ? (row[3] as int?) : null,
|
||||||
title: fields.contains('title') ? (row[4] as String?) : null);
|
title: fields.contains('title') ? (row[4] as String?) : null);
|
||||||
return Optional.of(model);
|
return Optional.of(model);
|
||||||
|
|
|
@ -127,8 +127,8 @@ class UserQuery extends Query<User, UserQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = User(
|
var model = User(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
username: fields.contains('username') ? (row[3] as String?) : null,
|
username: fields.contains('username') ? (row[3] as String?) : null,
|
||||||
password: fields.contains('password') ? (row[4] as String?) : null,
|
password: fields.contains('password') ? (row[4] as String?) : null,
|
||||||
email: fields.contains('email') ? (row[5] as String?) : null);
|
email: fields.contains('email') ? (row[5] as String?) : null);
|
||||||
|
@ -487,8 +487,8 @@ class RoleQuery extends Query<Role, RoleQueryWhere> {
|
||||||
}
|
}
|
||||||
var model = Role(
|
var model = Role(
|
||||||
id: fields.contains('id') ? row[0].toString() : null,
|
id: fields.contains('id') ? row[0].toString() : null,
|
||||||
createdAt: fields.contains('created_at') ? (row[1] as DateTime?) : null,
|
createdAt: fields.contains('created_at') ? mapToDateTime(row[1]) : null,
|
||||||
updatedAt: fields.contains('updated_at') ? (row[2] as DateTime?) : null,
|
updatedAt: fields.contains('updated_at') ? mapToDateTime(row[2]) : null,
|
||||||
name: fields.contains('name') ? (row[3] as String?) : null);
|
name: fields.contains('name') ? (row[3] as String?) : null);
|
||||||
if (row.length > 4) {
|
if (row.length > 4) {
|
||||||
var modelOpt = UserQuery().parseRow(row.skip(4).take(6).toList());
|
var modelOpt = UserQuery().parseRow(row.skip(4).take(6).toList());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel3_orm_test
|
name: angel3_orm_test
|
||||||
version: 6.0.0
|
version: 6.0.1
|
||||||
description: Common tests for Angel3 ORM. Reference implmentation of the generated ORM files.
|
description: Common tests for Angel3 ORM. Reference implmentation of the generated ORM files.
|
||||||
homepage: https://angel3-framework.web.app/
|
homepage: https://angel3-framework.web.app/
|
||||||
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_test
|
repository: https://github.com/dukefirehawk/angel/tree/master/packages/orm/angel_orm_test
|
||||||
|
@ -19,26 +19,26 @@ dev_dependencies:
|
||||||
angel3_framework: ^6.0.0
|
angel3_framework: ^6.0.0
|
||||||
build_runner: ^2.0.1
|
build_runner: ^2.0.1
|
||||||
lints: ^1.0.0
|
lints: ^1.0.0
|
||||||
# dependency_overrides:
|
dependency_overrides:
|
||||||
# angel3_container:
|
# angel3_container:
|
||||||
# path: ../../container/angel_container
|
# path: ../../container/angel_container
|
||||||
# angel3_framework:
|
# angel3_framework:
|
||||||
# path: ../../framework
|
# path: ../../framework
|
||||||
# angel3_http_exception:
|
# angel3_http_exception:
|
||||||
# path: ../../http_exception
|
# path: ../../http_exception
|
||||||
# angel3_model:
|
# angel3_model:
|
||||||
# path: ../../model
|
# path: ../../model
|
||||||
# angel3_route:
|
# angel3_route:
|
||||||
# path: ../../route
|
# path: ../../route
|
||||||
# angel3_mock_request:
|
# angel3_mock_request:
|
||||||
# path: ../../mock_request
|
# path: ../../mock_request
|
||||||
# angel3_serialize:
|
# angel3_serialize:
|
||||||
# path: ../../serialize/angel_serialize
|
# path: ../../serialize/angel_serialize
|
||||||
# angel3_serialize_generator:
|
# angel3_serialize_generator:
|
||||||
# path: ../../serialize/angel_serialize_generator
|
# path: ../../serialize/angel_serialize_generator
|
||||||
# angel3_orm:
|
angel3_orm:
|
||||||
# path: ../angel_orm
|
path: ../angel_orm
|
||||||
# angel3_migration:
|
# angel3_migration:
|
||||||
# path: ../angel_migration
|
# path: ../angel_migration
|
||||||
# angel3_orm_generator:
|
angel3_orm_generator:
|
||||||
# path: ../angel_orm_generator
|
path: ../angel_orm_generator
|
||||||
|
|
Loading…
Reference in a new issue