Merge pull request #65 from dukefirehawk/fix-bug/mysql-query

Fix bug/mysql query
This commit is contained in:
Thomas Hii 2022-05-16 13:09:36 +08:00 committed by GitHub
commit f4ba4fb25c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 322 additions and 276 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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);
} }

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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,66 +20,8 @@ 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(
String tableName, String query, Map<String, dynamic> substitutionValues, String tableName, String query, Map<String, dynamic> substitutionValues,
@ -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) { try {
return await f(this); logger.fine('Entering transaction');
} var tx = MariaDbExecutor(conn, logger: logger);
return await f(tx);
await _connection.transaction((context) async { } catch (e) {
var executor = MySqlExecutor(context, logger: logger); logger.severe('Failed to run transaction', e);
rethrow;
} finally {
logger.fine('Exiting transaction');
}
}); });
*/
}
/*
@override
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) async {
if (_connection is Transaction) {
return await f(this);
}
Transaction? tx; return returnValue!;
try {
tx = await _startTransaction();
var executor = MySqlExecutor(tx, logger: logger);
var result = await f(executor);
await tx.commit();
return result;
} catch (_) {
await tx?.rollback();
rethrow;
}
} }
*/
} }

View file

@ -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

View file

@ -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_migration: angel3_orm_generator:
# path: ../angel_migration path: ../angel_orm_generator
# angel3_orm_generator: # angel3_migration:
# path: ../angel_orm_generator # path: ../angel_migration

View file

@ -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));
}); });
} }

View file

@ -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);
}
} }
} }
} }

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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),

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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),

View file

@ -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,

View file

@ -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)
); );

View file

@ -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),

View file

@ -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,

View file

@ -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)
); );

View file

@ -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);

View file

@ -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}) {

View file

@ -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

View file

@ -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

View file

@ -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...

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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());

View file

@ -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

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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());

View file

@ -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