Updated DateTime to non UTC
This commit is contained in:
parent
f0a5e7c6fc
commit
793a8ac115
13 changed files with 141 additions and 40 deletions
20
docker/docker-compose-mariadb.yml
Normal file
20
docker/docker-compose-mariadb.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:latest
|
||||||
|
restart: "no"
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
environment:
|
||||||
|
- MARIADB_ROOT_PASSWORD=Qwerty
|
||||||
|
volumes:
|
||||||
|
- "mariadb:/var/lib/mysql"
|
||||||
|
networks:
|
||||||
|
- webnet
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mariadb:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
webnet:
|
20
docker/docker-compose-mysql.yml
Normal file
20
docker/docker-compose-mysql.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:latest
|
||||||
|
restart: "no"
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=Qwerty
|
||||||
|
volumes:
|
||||||
|
- "mysql:/var/lib/mysql"
|
||||||
|
networks:
|
||||||
|
- webnet
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
webnet:
|
|
@ -2,7 +2,7 @@ version: "3.8"
|
||||||
services:
|
services:
|
||||||
pgdb:
|
pgdb:
|
||||||
image: postgres:latest
|
image: postgres:latest
|
||||||
restart: always
|
restart: "no"
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "5432:5432"
|
||||||
environment:
|
environment:
|
||||||
|
@ -12,7 +12,6 @@ services:
|
||||||
- "db:/var/lib/postgresql/data"
|
- "db:/var/lib/postgresql/data"
|
||||||
networks:
|
networks:
|
||||||
- webnet
|
- webnet
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
db:
|
db:
|
||||||
driver: local
|
driver: local
|
||||||
|
|
21
docker/docker-compose-redis.yml
Normal file
21
docker/docker-compose-redis.yml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
redis:
|
||||||
|
image: redis:latest
|
||||||
|
restart: "no"
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=postgres
|
||||||
|
- POSTGRES_PASSWORD=postgres
|
||||||
|
volumes:
|
||||||
|
- "redis:/data"
|
||||||
|
networks:
|
||||||
|
- webnet
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
redis:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
webnet:
|
|
@ -23,7 +23,7 @@ class MariaDbSchema extends Schema {
|
||||||
_log.severe('Failed to run query: [ $sql ]', e);
|
_log.severe('Failed to run query: [ $sql ]', e);
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
affectedRows = result?.affectedRows ?? 0;
|
affectedRows = result.affectedRows ?? 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
return affectedRows;
|
return affectedRows;
|
||||||
|
|
|
@ -371,7 +371,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
|
||||||
var insertion = values?.compileInsert(this, tableName);
|
var insertion = values?.compileInsert(this, tableName);
|
||||||
|
|
||||||
if (insertion == '') {
|
if (insertion == '') {
|
||||||
throw StateError('No values have been specified for update.');
|
throw StateError('No values have been specified for insertion.');
|
||||||
} else {
|
} else {
|
||||||
var sql = compile({});
|
var sql = compile({});
|
||||||
var returningSql = '';
|
var returningSql = '';
|
||||||
|
|
|
@ -16,7 +16,7 @@ abstract class QueryValues {
|
||||||
|
|
||||||
String compileInsert(Query query, String tableName) {
|
String compileInsert(Query query, String tableName) {
|
||||||
var data = Map<String, dynamic>.from(toMap());
|
var data = Map<String, dynamic>.from(toMap());
|
||||||
var now = DateTime.now().toUtc();
|
var now = DateTime.now();
|
||||||
if (data.containsKey('created_at') && data['created_at'] == null) {
|
if (data.containsKey('created_at') && data['created_at'] == null) {
|
||||||
data['created_at'] = now;
|
data['created_at'] = now;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ abstract class QueryValues {
|
||||||
if (data.isEmpty) {
|
if (data.isEmpty) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
var now = DateTime.now().toUtc();
|
var now = DateTime.now();
|
||||||
if (data.containsKey('created_at') && data['created_at'] == null) {
|
if (data.containsKey('created_at') && data['created_at'] == null) {
|
||||||
data.remove('created_at');
|
data.remove('created_at');
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
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 (beta)
|
* MariaDbExecutor
|
||||||
* MySqlExecutor (beta)
|
* MySqlExecutor
|
||||||
|
|
||||||
## Supported database version
|
## Supported database version
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ This package contains the SQL Executor required by Angel3 ORM to work with MySQL
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 3306,
|
port: 3306,
|
||||||
db: 'orm_test',
|
db: 'orm_test',
|
||||||
user: 'Test',
|
user: 'test',
|
||||||
password: 'Test123*');
|
password: 'test123');
|
||||||
var connection = await MySqlConnection.connect(settings);
|
var connection = await MySqlConnection.connect(settings);
|
||||||
|
|
||||||
var logger = Logger('orm_mariadb');
|
var logger = Logger('orm_mariadb');
|
||||||
|
@ -44,7 +44,7 @@ This package contains the SQL Executor required by Angel3 ORM to work with MySQL
|
||||||
port: 3306,
|
port: 3306,
|
||||||
databaseName: "orm_test",
|
databaseName: "orm_test",
|
||||||
userName: "test",
|
userName: "test",
|
||||||
password: "Test123*",
|
password: "test123",
|
||||||
secure: false);
|
secure: false);
|
||||||
|
|
||||||
var logger = Logger('orm_mysql');
|
var logger = Logger('orm_mysql');
|
||||||
|
@ -52,8 +52,48 @@ This package contains the SQL Executor required by Angel3 ORM to work with MySQL
|
||||||
var executor = MySqlExecutor(connection, logger: logger);
|
var executor = MySqlExecutor(connection, logger: logger);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* Blob
|
||||||
|
* DateTime value not in UTC
|
||||||
|
* Transaction is broken
|
||||||
|
|
||||||
|
## Creating a new database in MariaDB/MySQL
|
||||||
|
|
||||||
|
1. Login to MariaDB/MySQL database console with the following command.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mysql -u root -p
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run the following commands to create a new database, `orm_test` and grant both local and remote access to user, `test`. Replace `orm_test`, `test` and `test123` with your own database name, username and password respectively.
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
create database orm_test;
|
||||||
|
|
||||||
|
create user 'test'@'localhost' identified by 'test123';
|
||||||
|
grant all privileges on orm_test.* to 'test'@'localhost';
|
||||||
|
|
||||||
|
create user 'test'@'%' identified by 'test123';
|
||||||
|
grant all privileges on orm_test.* to 'test'@'%';
|
||||||
|
```
|
||||||
|
|
||||||
## Known limitation
|
## Known limitation
|
||||||
|
|
||||||
* UTC time is not supported
|
### Using `mysql1` driver on MariabDb
|
||||||
|
|
||||||
|
* Blob
|
||||||
|
* DateTime value not in UTC
|
||||||
|
* Transaction is broken
|
||||||
|
|
||||||
|
### Using `mysql1` driver on MySQL
|
||||||
|
|
||||||
* Blob is not supported
|
* Blob is not supported
|
||||||
|
|
||||||
|
### Using `mysql_client` driver on MariabDb
|
||||||
|
|
||||||
|
* Blob is not supported
|
||||||
|
|
||||||
|
### Using `mysql_client` driver on MySQL
|
||||||
|
|
||||||
|
* Blob is not supported
|
||||||
|
|
|
@ -13,8 +13,8 @@ part 'main.g.dart';
|
||||||
void main() async {
|
void main() async {
|
||||||
//hierarchicalLoggingEnabled = true;
|
//hierarchicalLoggingEnabled = true;
|
||||||
|
|
||||||
//await mariaDBExample();
|
await mariaDBExample();
|
||||||
await mysqlExample();
|
//await mysqlExample();
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ Future<void> mariaDBExample() async {
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 3306,
|
port: 3306,
|
||||||
db: 'orm_test',
|
db: 'orm_test',
|
||||||
user: 'Test',
|
user: 'test',
|
||||||
password: 'Test123*');
|
password: 'test123');
|
||||||
var connection = await MySqlConnection.connect(settings);
|
var connection = await MySqlConnection.connect(settings);
|
||||||
|
|
||||||
print("Connected to MariaDb");
|
print("Connected to MariaDb");
|
||||||
|
@ -61,7 +61,7 @@ Future<void> mysqlExample() async {
|
||||||
port: 3306,
|
port: 3306,
|
||||||
databaseName: "orm_test",
|
databaseName: "orm_test",
|
||||||
userName: "test",
|
userName: "test",
|
||||||
password: "Test123*",
|
password: "test123",
|
||||||
secure: false);
|
secure: false);
|
||||||
|
|
||||||
print("Connected to MySQL");
|
print("Connected to MySQL");
|
||||||
|
|
|
@ -34,9 +34,9 @@ class MariaDbExecutor extends QueryExecutor {
|
||||||
|
|
||||||
var params = substitutionValues.values.toList();
|
var params = substitutionValues.values.toList();
|
||||||
|
|
||||||
//logger?.warning('Query: $query');
|
logger.warning('Query: $query');
|
||||||
//logger?.warning('Values: $params');
|
logger.warning('Values: $params');
|
||||||
//logger?.warning('Returning Query: $returningQuery');
|
logger.warning('Returning Query: $returningQuery');
|
||||||
|
|
||||||
if (returningQuery.isNotEmpty) {
|
if (returningQuery.isNotEmpty) {
|
||||||
// Handle insert, update and delete
|
// Handle insert, update and delete
|
||||||
|
@ -66,6 +66,7 @@ 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 {
|
||||||
T? returnValue = await _connection.transaction((ctx) async {
|
T? returnValue = await _connection.transaction((ctx) async {
|
||||||
|
// TODO: This is broken
|
||||||
var conn = ctx as MySqlConnection;
|
var conn = ctx as MySqlConnection;
|
||||||
try {
|
try {
|
||||||
logger.fine('Entering transaction');
|
logger.fine('Entering transaction');
|
||||||
|
|
|
@ -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:
|
# angel3_orm_generator:
|
||||||
# path: ../angel_orm_generator
|
# path: ../angel_orm_generator
|
||||||
# angel3_migration:
|
angel3_migration:
|
||||||
# path: ../angel_migration
|
path: ../angel_migration
|
||||||
|
|
|
@ -10,14 +10,14 @@ List tmpTables = [];
|
||||||
|
|
||||||
FutureOr<QueryExecutor> Function() createTables(List<String> schemas) {
|
FutureOr<QueryExecutor> Function() createTables(List<String> schemas) {
|
||||||
// For MySQL
|
// For MySQL
|
||||||
return () => _connectToMySql(schemas);
|
//return () => _connectToMySql(schemas);
|
||||||
|
|
||||||
// For MariaDB
|
// For MariaDB
|
||||||
// return () => _connectToMariaDb(tables);
|
return () => _connectToMariaDb(schemas);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For MySQL
|
// For MySQL
|
||||||
Future<void> dropTables(QueryExecutor executor) async {
|
Future<void> dropTables2(QueryExecutor executor) async {
|
||||||
var sqlExecutor = (executor as MySqlExecutor);
|
var sqlExecutor = (executor as MySqlExecutor);
|
||||||
for (var tableName in tmpTables.reversed) {
|
for (var tableName in tmpTables.reversed) {
|
||||||
await sqlExecutor.rawConnection.execute('drop table $tableName;');
|
await sqlExecutor.rawConnection.execute('drop table $tableName;');
|
||||||
|
@ -26,13 +26,13 @@ Future<void> dropTables(QueryExecutor executor) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For MariaDB
|
// For MariaDB
|
||||||
/* Future<void> dropTables(QueryExecutor executor) {
|
Future<void> dropTables(QueryExecutor executor) {
|
||||||
var sqlExecutor = (executor as MariaDbExecutor);
|
var sqlExecutor = (executor as MariaDbExecutor);
|
||||||
for (var tableName in tmpTables.reversed) {
|
for (var tableName in tmpTables.reversed) {
|
||||||
sqlExecutor.query(tableName, 'DROP TABLE $tableName', {});
|
sqlExecutor.query(tableName, 'DROP TABLE $tableName', {});
|
||||||
}
|
}
|
||||||
return sqlExecutor.close();
|
return sqlExecutor.close();
|
||||||
} */
|
}
|
||||||
|
|
||||||
String extractTableName(String createQuery) {
|
String extractTableName(String createQuery) {
|
||||||
var start = createQuery.indexOf('EXISTS');
|
var start = createQuery.indexOf('EXISTS');
|
||||||
|
@ -51,8 +51,8 @@ Future<MariaDbExecutor> _connectToMariaDb(List<String> schemas) async {
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 3306,
|
port: 3306,
|
||||||
db: 'orm_test',
|
db: 'orm_test',
|
||||||
user: 'Test',
|
user: 'test',
|
||||||
password: 'Test123*');
|
password: 'test123');
|
||||||
var connection = await MySqlConnection.connect(settings);
|
var connection = await MySqlConnection.connect(settings);
|
||||||
|
|
||||||
var logger = Logger('orm_mariadb');
|
var logger = Logger('orm_mariadb');
|
||||||
|
@ -87,7 +87,7 @@ Future<MySqlExecutor> _connectToMySql(List<String> schemas) async {
|
||||||
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);
|
secure: false);
|
||||||
|
|
||||||
await connection.connect(timeoutMs: 10000);
|
await connection.connect(timeoutMs: 10000);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:angel3_orm/angel3_orm.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'models/car.dart';
|
import 'models/car.dart';
|
||||||
|
|
||||||
final DateTime y2k = DateTime.utc(2000, 1, 1);
|
final DateTime y2k = DateTime(2000, 1, 1);
|
||||||
|
|
||||||
void standaloneTests(FutureOr<QueryExecutor> Function() createExecutor,
|
void standaloneTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
{FutureOr<void> Function(QueryExecutor)? close}) {
|
{FutureOr<void> Function(QueryExecutor)? close}) {
|
||||||
|
@ -173,9 +173,9 @@ void standaloneTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
});
|
});
|
||||||
|
|
||||||
test('insert', () async {
|
test('insert', () async {
|
||||||
var recalledAt = DateTime.now().toUtc();
|
var recalledAt = DateTime.now();
|
||||||
var query = CarQuery();
|
var query = CarQuery();
|
||||||
var now = DateTime.now().toUtc();
|
var now = DateTime.now();
|
||||||
query.values
|
query.values
|
||||||
..make = 'Honda'
|
..make = 'Honda'
|
||||||
..description = 'Hello'
|
..description = 'Hello'
|
||||||
|
@ -198,7 +198,7 @@ void standaloneTests(FutureOr<QueryExecutor> Function() createExecutor,
|
||||||
});
|
});
|
||||||
|
|
||||||
test('insert car', () async {
|
test('insert car', () async {
|
||||||
var recalledAt = DateTime.now().toUtc();
|
var recalledAt = DateTime.now();
|
||||||
var beetle = Car(
|
var beetle = Car(
|
||||||
make: 'Beetle',
|
make: 'Beetle',
|
||||||
description: 'Herbie',
|
description: 'Herbie',
|
||||||
|
|
Loading…
Reference in a new issue