Fixed migration runner for MySQL

This commit is contained in:
thomashii@dukefirehawk.com 2022-07-27 22:21:36 +08:00
parent aff68b2f07
commit 98dfef8e33
5 changed files with 79 additions and 42 deletions

View file

@ -5,6 +5,8 @@
* Upgraded to `lints` 2.x.x
* Fixed issue #70. Incorrectly generated SQL for `defaultsTo('Default Value')`
* Mapped timestamp to datetime for MySQL and MariaDB
* Fixed `MariaDbMigrationRunner` to work with MariaDB
* Fixed `MySqlMigrationRunner` to work with MySQL and MariaDB
## 6.0.1

View file

@ -9,14 +9,20 @@ Database migration runner for Angel3 ORM.
Supported database:
* PostgreSQL version 10 or later
* MariaDB 10.2.x or later
* MySQL 8.x or later
* PostgreSQL 10.x or greater
* MariaDB 10.2.x or greater
* MySQL 8.x or greater
## Usage
* Use `PostgresMigrationRunner` to perform the database migration for PostgreSQL.
* Use `PostgresMigrationRunner` to perform database migration for PostgreSQL.
* Use `MySqlMigrationRunner` to perform the database migration for MySQL and MariaDB. This is implemented with [`mysql_client`](https://pub.dev/packages?q=mysql_client) driver.
* Use `MySqlMigrationRunner` to perform database migration for MySQL and MariaDB. This runner is using [`mysql_client`](https://pub.dev/packages?q=mysql_client) driver.
* Use `MariaDbMigrationRunner` to perform the database migration for MariaDB. [`mysql1`](https://pub.dev/packages?q=mysql1).
* Use `MariaDbMigrationRunner` to perform database migration for MariaDB. This runner is using[`mysql1`](https://pub.dev/packages?q=mysql1) driver.
## Supported Operations
* reset - Clear out all records in the `migrations` table and drop all the managed ORM tables.
* up - Generate all the managed ORM tables based on the ORM models.
* refresh - Run `reset` follow by `up`

View file

@ -45,7 +45,7 @@ class MariaDbMigrationRunner implements MigrationRunner {
PRIMARY KEY(id)
);
''').then((result) {
_log.info('Check and create "migrations" table');
_log.fine('Check and create "migrations" table');
}).catchError((e) {
_log.severe('Failed to create "migrations" table.', e);
});
@ -54,18 +54,25 @@ class MariaDbMigrationRunner implements MigrationRunner {
@override
Future up() async {
await _init();
var r = await connection.query('SELECT path from migrations;');
var existing = r.expand((x) => x).cast<String>();
var toRun = <String>[];
var result = await connection.query('SELECT path from migrations;');
var existing = <String>[];
if (result.isNotEmpty) {
existing = result.expand((x) => x).cast<String>().toList();
}
var toRun = <String>[];
migrations.forEach((k, v) {
if (!existing.contains(k)) toRun.add(k);
});
if (toRun.isNotEmpty) {
var r = await connection.query('SELECT MAX(batch) from migrations;');
var rTmp = r.toList();
var curBatch = int.tryParse(rTmp[0][0] ?? '0') as int;
var result = await connection.query('SELECT MAX(batch) from migrations;');
var curBatch = 0;
if (result.isNotEmpty) {
var firstRow = result.toList();
curBatch = int.tryParse(firstRow[0][0] ?? '0') as int;
}
var batch = curBatch + 1;
for (var k in toRun) {
@ -73,11 +80,10 @@ class MariaDbMigrationRunner implements MigrationRunner {
var schema = MariaDbSchema();
migration.up(schema);
_log.info('Added "$k" into "migrations" table.');
try {
await schema.run(connection).then((_) async {
var result = await connection.query(
"INSERT INTO MIGRATIONS (batch, path) VALUES ($batch, '$k')");
"INSERT INTO migrations (batch, path) VALUES ($batch, '$k')");
return result.affectedRows;
});
@ -94,13 +100,21 @@ class MariaDbMigrationRunner implements MigrationRunner {
Future rollback() async {
await _init();
var r = await connection.query('SELECT MAX(batch) from migrations;');
var rTmp = r.toList();
var curBatch = int.tryParse(rTmp[0][0] ?? 0) as int;
var result = await connection.query('SELECT MAX(batch) from migrations;');
r = await connection
var curBatch = 0;
if (result.isNotEmpty) {
var firstRow = result.toList();
curBatch = int.tryParse(firstRow[0][0]) as int;
}
result = await connection
.query('SELECT path from migrations WHERE batch = $curBatch;');
var existing = r.expand((x) => x).cast<String>();
var existing = <String>[];
if (result.isNotEmpty) {
existing = result.expand((x) => x).cast<String>().toList();
}
var toRun = <String>[];
migrations.forEach((k, v) {
@ -128,7 +142,11 @@ class MariaDbMigrationRunner implements MigrationRunner {
await _init();
var r = await connection
.query('SELECT path from migrations ORDER BY batch DESC;');
var existing = r.expand((x) => x).cast<String>();
var existing = <String>[];
if (r.isNotEmpty) {
existing = r.expand((x) => x).cast<String>().toList();
}
var toRun = existing.where(migrations.containsKey).toList();
if (toRun.isNotEmpty) {

View file

@ -42,7 +42,7 @@ class MariaDbSchema extends Schema {
@override
void drop(String tableName, {bool cascade = false}) {
var c = cascade == true ? ' CASCADE' : '';
_writeln('DROP TABLE "$tableName"$c;');
_writeln('DROP TABLE $tableName$c;');
}
@override

View file

@ -54,8 +54,11 @@ class MySqlMigrationRunner implements MigrationRunner {
@override
Future up() async {
await _init();
var r = await connection.execute('SELECT path from migrations;');
var existing = r.rows.cast<String>(); //.expand((x) => x).cast<String>();
var result = await connection.execute('SELECT path from migrations;');
var existing = <String>[];
if (result.rows.isNotEmpty) {
existing = result.rows.first.assoc().values.cast<String>().toList();
}
var toRun = <String>[];
migrations.forEach((k, v) {
@ -63,11 +66,14 @@ class MySqlMigrationRunner implements MigrationRunner {
});
if (toRun.isNotEmpty) {
var r = await connection.execute('SELECT MAX(batch) from migrations;');
var rTmp = r.rows.first; //r.toList();
var curBatch =
int.tryParse(rTmp.colAt(0) ?? "0") ?? 0; //(rTmp[0][0] ?? 0) as int;
var batch = curBatch + 1;
var result =
await connection.execute('SELECT MAX(batch) from migrations;');
var curBatch = 0;
if (result.rows.isNotEmpty) {
var firstRow = result.rows.first;
curBatch = int.tryParse(firstRow.colAt(0) ?? "0") ?? 0;
}
curBatch++;
for (var k in toRun) {
var migration = migrations[k]!;
@ -77,16 +83,13 @@ class MySqlMigrationRunner implements MigrationRunner {
await schema.run(connection).then((_) async {
var result = await connection
.execute(
"INSERT INTO MIGRATIONS (batch, path) VALUES ($batch, '$k')")
"INSERT INTO migrations (batch, path) VALUES ($curBatch, '$k')")
.catchError((e) {
_log.severe('Failed to insert into "migrations" table.', e);
});
return result.affectedRows.toInt();
});
//return connection.execute(
// 'INSERT INTO MIGRATIONS (batch, path) VALUES ($batch, \'$k\');');
}
} else {
_log.warning('Nothing to add into "migrations" table.');
@ -97,14 +100,18 @@ class MySqlMigrationRunner implements MigrationRunner {
Future rollback() async {
await _init();
var r = await connection.execute('SELECT MAX(batch) from migrations;');
var rTmp = r.rows.first; //r.toList();
var curBatch =
int.tryParse(rTmp.colAt(0) ?? "0") ?? 0; //(rTmp[0][0] ?? 0) as int;
r = await connection
var result = await connection.execute('SELECT MAX(batch) from migrations;');
var curBatch = 0;
if (result.rows.isNotEmpty) {
var firstRow = result.rows.first;
curBatch = int.tryParse(firstRow.colAt(0) ?? "0") ?? 0;
}
result = await connection
.execute('SELECT path from migrations WHERE batch = $curBatch;');
var existing = r.rows.cast<String>(); //r.expand((x) => x).cast<String>();
var existing = <String>[];
if (result.rows.isNotEmpty) {
existing = result.rows.first.assoc().values.cast<String>().toList();
}
var toRun = <String>[];
migrations.forEach((k, v) {
@ -130,9 +137,13 @@ class MySqlMigrationRunner implements MigrationRunner {
@override
Future reset() async {
await _init();
var r = await connection
var result = await connection
.execute('SELECT path from migrations ORDER BY batch DESC;');
var existing = r.rows.cast<String>(); //r.expand((x) => x).cast<String>();
var existing = <String>[];
if (result.rows.isNotEmpty) {
var firstRow = result.rows.first;
existing = firstRow.assoc().values.cast<String>().toList();
}
var toRun = existing.where(migrations.containsKey).toList();
if (toRun.isNotEmpty) {