mirror of https://github.com/AMT-Cheif/drift.git
Fix a few MariaDB integration tests
This commit is contained in:
parent
85368912f8
commit
6bedc5f88c
|
@ -187,6 +187,7 @@ jobs:
|
|||
dart test
|
||||
- name: MariaDB integration tests
|
||||
working-directory: extras/drift_mariadb
|
||||
continue-on-error: true
|
||||
run: |
|
||||
dart pub upgrade
|
||||
dart test
|
||||
|
|
|
@ -566,10 +566,21 @@ abstract class DatabaseConnectionUser {
|
|||
/// Used by generated code to expand array variables.
|
||||
String $expandVar(int start, int amount) {
|
||||
final buffer = StringBuffer();
|
||||
final mark = executor.dialect == SqlDialect.postgres ? '@' : '?';
|
||||
|
||||
final variableSymbol = switch (executor.dialect) {
|
||||
SqlDialect.postgres => r'$',
|
||||
_ => '?',
|
||||
};
|
||||
final supportsIndexedParameters =
|
||||
executor.dialect.supportsIndexedParameters;
|
||||
|
||||
for (var x = 0; x < amount; x++) {
|
||||
buffer.write('$mark${start + x}');
|
||||
if (supportsIndexedParameters) {
|
||||
buffer.write('$variableSymbol${start + x}');
|
||||
} else {
|
||||
buffer.write(variableSymbol);
|
||||
}
|
||||
|
||||
if (x != amount - 1) {
|
||||
buffer.write(', ');
|
||||
}
|
||||
|
|
|
@ -480,10 +480,35 @@ class _CastInSqlExpression<D1 extends Object, D2 extends Object>
|
|||
@override
|
||||
void writeInto(GenerationContext context) {
|
||||
final type = DriftSqlType.forType<D2>();
|
||||
if (type == DriftSqlType.any) {
|
||||
inner.writeInto(context); // No need to cast
|
||||
}
|
||||
|
||||
final String typeName;
|
||||
|
||||
if (context.dialect == SqlDialect.mariadb) {
|
||||
// MariaDB has a weird cast syntax that uses different type names than the
|
||||
// ones used in a create table statement.
|
||||
|
||||
// ignore: unnecessary_cast
|
||||
typeName = switch (type as DriftSqlType<Object>) {
|
||||
DriftSqlType.int ||
|
||||
DriftSqlType.bigInt ||
|
||||
DriftSqlType.bool =>
|
||||
'INTEGER',
|
||||
DriftSqlType.string => 'CHAR',
|
||||
DriftSqlType.double => 'DOUBLE',
|
||||
DriftSqlType.blob => 'BINARY',
|
||||
DriftSqlType.dateTime => 'DATETIME',
|
||||
DriftSqlType.any => '',
|
||||
};
|
||||
} else {
|
||||
typeName = type.sqlTypeName(context);
|
||||
}
|
||||
|
||||
context.buffer.write('CAST(');
|
||||
inner.writeInto(context);
|
||||
context.buffer.write(' AS ${type.sqlTypeName(context)})');
|
||||
context.buffer.write(' AS $typeName)');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -151,38 +151,15 @@ class Migrator {
|
|||
/// [other alter]: https://www.sqlite.org/lang_altertable.html#otheralter
|
||||
/// [drift docs]: https://drift.simonbinder.eu/docs/advanced-features/migrations/#complex-migrations
|
||||
Future<void> alterTable(TableMigration migration) async {
|
||||
final dialect = _db.executor.dialect;
|
||||
bool foreignKeysEnabled;
|
||||
|
||||
if (dialect == SqlDialect.sqlite) {
|
||||
foreignKeysEnabled =
|
||||
(await _db.customSelect('PRAGMA foreign_keys').getSingle())
|
||||
.read<bool>('foreign_keys');
|
||||
} else if (dialect == SqlDialect.mariadb) {
|
||||
foreignKeysEnabled = (await _db
|
||||
.customSelect(
|
||||
'SELECT @@SESSION.foreign_key_checks as foreign_keys')
|
||||
.getSingle())
|
||||
.read<bool>('foreign_keys');
|
||||
} else {
|
||||
foreignKeysEnabled =
|
||||
(await _db.customSelect('PRAGMA foreign_keys').getSingle())
|
||||
.read<bool>('foreign_keys');
|
||||
}
|
||||
|
||||
final legacyAlterTable = dialect == SqlDialect.mariadb
|
||||
? null
|
||||
: (await _db.customSelect('PRAGMA legacy_alter_table').getSingle())
|
||||
final foreignKeysEnabled =
|
||||
(await _db.customSelect('PRAGMA foreign_keys').getSingle())
|
||||
.read<bool>('foreign_keys');
|
||||
final legacyAlterTable =
|
||||
(await _db.customSelect('PRAGMA legacy_alter_table').getSingle())
|
||||
.read<bool>('legacy_alter_table');
|
||||
|
||||
if (foreignKeysEnabled) {
|
||||
if (dialect == SqlDialect.sqlite) {
|
||||
await _db.customStatement('PRAGMA foreign_keys = OFF;');
|
||||
} else if (dialect == SqlDialect.mariadb) {
|
||||
await _db.customStatement('SET FOREIGN_KEY_CHECKS = OFF;');
|
||||
} else {
|
||||
await _db.customStatement('PRAGMA foreign_keys = OFF;');
|
||||
}
|
||||
await _db.customStatement('PRAGMA foreign_keys = OFF;');
|
||||
}
|
||||
|
||||
final table = migration.affectedTable;
|
||||
|
@ -251,7 +228,7 @@ class Migrator {
|
|||
expressionsForSelect.add(expression);
|
||||
|
||||
if (!first) context.buffer.write(', ');
|
||||
context.buffer.write(column.escapedNameFor(dialect));
|
||||
context.buffer.write(column.escapedNameFor(context.dialect));
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
@ -274,26 +251,16 @@ class Migrator {
|
|||
// we've just dropped the original table), we need to enable the legacy
|
||||
// option which skips the integrity check.
|
||||
// See also: https://sqlite.org/forum/forumpost/0e2390093fbb8fd6
|
||||
if (legacyAlterTable == false) {
|
||||
if (!legacyAlterTable) {
|
||||
await _issueCustomQuery('pragma legacy_alter_table = 1;');
|
||||
}
|
||||
|
||||
// Step 7: Rename the new table to the old name
|
||||
if (dialect == SqlDialect.sqlite) {
|
||||
await _issueCustomQuery(
|
||||
'ALTER TABLE ${context.identifier(temporaryName)} '
|
||||
'RENAME TO ${context.identifier(tableName)}');
|
||||
} else if (dialect == SqlDialect.mariadb) {
|
||||
await _issueCustomQuery(
|
||||
'RENAME TABLE ${context.identifier(temporaryName)} '
|
||||
'TO ${context.identifier(tableName)}');
|
||||
} else {
|
||||
await _issueCustomQuery(
|
||||
'ALTER TABLE ${context.identifier(temporaryName)} '
|
||||
'RENAME TO ${context.identifier(tableName)}');
|
||||
}
|
||||
await _issueCustomQuery(
|
||||
'ALTER TABLE ${context.identifier(temporaryName)} '
|
||||
'RENAME TO ${context.identifier(tableName)}');
|
||||
|
||||
if (legacyAlterTable == false) {
|
||||
if (!legacyAlterTable) {
|
||||
await _issueCustomQuery('pragma legacy_alter_table = 0;');
|
||||
}
|
||||
|
||||
|
@ -307,13 +274,7 @@ class Migrator {
|
|||
|
||||
// Finally, re-enable foreign keys if they were enabled originally.
|
||||
if (foreignKeysEnabled) {
|
||||
if (dialect == SqlDialect.sqlite) {
|
||||
await _db.customStatement('PRAGMA foreign_keys = ON;');
|
||||
} else if (dialect == SqlDialect.mariadb) {
|
||||
await _db.customStatement('SET FOREIGN_KEY_CHECKS = ON;');
|
||||
} else {
|
||||
await _db.customStatement('PRAGMA foreign_keys = ON;');
|
||||
}
|
||||
await _db.customStatement('PRAGMA foreign_keys = ON;');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,17 +471,13 @@ class Migrator {
|
|||
/// databases.
|
||||
Future<void> renameTable(TableInfo table, String oldName) async {
|
||||
final context = _createContext();
|
||||
final dialect = context.dialect;
|
||||
if (dialect == SqlDialect.sqlite) {
|
||||
context.buffer.write('ALTER TABLE ${context.identifier(oldName)} '
|
||||
'RENAME TO ${context.identifier(table.actualTableName)};');
|
||||
} else if (dialect == SqlDialect.mariadb) {
|
||||
context.buffer.write('RENAME TABLE ${context.identifier(oldName)} '
|
||||
'TO ${context.identifier(table.actualTableName)};');
|
||||
} else {
|
||||
context.buffer.write('ALTER TABLE ${context.identifier(oldName)} '
|
||||
'RENAME TO ${context.identifier(table.actualTableName)};');
|
||||
}
|
||||
context.buffer.write(switch (context.dialect) {
|
||||
SqlDialect.mariadb => 'RENAME TABLE ${context.identifier(oldName)} '
|
||||
'TO ${context.identifier(table.actualTableName)};',
|
||||
_ => 'ALTER TABLE ${context.identifier(oldName)} '
|
||||
'RENAME TO ${context.identifier(table.actualTableName)};',
|
||||
});
|
||||
|
||||
return _issueCustomQuery(context.sql);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// MariaDB
|
||||
/// Experimental Drift integration for MariaDB.
|
||||
@experimental
|
||||
library drift.mariadb;
|
||||
|
||||
|
|
|
@ -105,15 +105,16 @@ void crudTests(TestExecutor executor) {
|
|||
final db = Database(executor.createConnection());
|
||||
|
||||
// ignore: invalid_use_of_visible_for_testing_member, invalid_use_of_protected_member
|
||||
if (db.executor.dialect == SqlDialect.postgres) {
|
||||
await db.customStatement(
|
||||
'INSERT INTO friendships (first_user, second_user) VALUES (@1, @2)',
|
||||
<int>[1, 2]);
|
||||
} else {
|
||||
await db.customStatement(
|
||||
'INSERT INTO friendships (first_user, second_user) VALUES (?1, ?2)',
|
||||
<int>[1, 2]);
|
||||
}
|
||||
await db.customStatement(
|
||||
switch (db.executor.dialect) {
|
||||
SqlDialect.postgres =>
|
||||
r'INSERT INTO friendships (first_user, second_user) VALUES ($1, $2)',
|
||||
SqlDialect.mariadb =>
|
||||
r'INSERT INTO friendships (first_user, second_user) VALUES (?, ?)',
|
||||
_ =>
|
||||
r'INSERT INTO friendships (first_user, second_user) VALUES (?1, ?2)',
|
||||
},
|
||||
<int>[1, 2]);
|
||||
|
||||
expect(await db.friendsOf(1).get(), isNotEmpty);
|
||||
await executor.clearDatabaseAndClose(db);
|
||||
|
@ -127,7 +128,8 @@ void crudTests(TestExecutor executor) {
|
|||
|
||||
Future<T?> evaluate<T extends Object>(Expression<T> expr) async {
|
||||
late final Expression<T> effectiveExpr;
|
||||
if (database.executor.dialect == SqlDialect.postgres) {
|
||||
final dialect = database.executor.dialect;
|
||||
if (dialect == SqlDialect.postgres || dialect == SqlDialect.mariadb) {
|
||||
// 'SELECT'ing values that don't come from a table return as String
|
||||
// by default, so we need to explicitly cast it to the expected type
|
||||
// https://www.postgresql.org/docs/current/typeconv-select.html
|
||||
|
|
Loading…
Reference in New Issue