mirror of https://github.com/AMT-Cheif/drift.git
Block database after error in migration
This commit is contained in:
parent
af55bd0f92
commit
0ec19f4705
|
@ -1,3 +1,9 @@
|
|||
## 2.16.0-dev
|
||||
|
||||
- When a migration throws, the database will now block subsequent operations
|
||||
instead of potentially allowing them to operate on a database in an
|
||||
inconsistent state.
|
||||
|
||||
## 2.15.0
|
||||
|
||||
- Methods in the query builder API now respect custom types.
|
||||
|
|
|
@ -386,6 +386,7 @@ class _WrappingTransactionExecutor extends _TransactionExecutor {
|
|||
class DelegatedDatabase extends _BaseExecutor {
|
||||
/// The [DatabaseDelegate] to send queries to.
|
||||
final DatabaseDelegate delegate;
|
||||
(Object, StackTrace)? _migrationError;
|
||||
|
||||
@override
|
||||
bool logStatements;
|
||||
|
@ -415,6 +416,12 @@ class DelegatedDatabase extends _BaseExecutor {
|
|||
'database connection and open that instead.'));
|
||||
}
|
||||
|
||||
// If we have been unable to run migrations, the database is likely in an
|
||||
// inconsistent state and we should prevent subsequent operations on it.
|
||||
if (_migrationError case (var err, var trace)?) {
|
||||
Error.throwWithStackTrace(err, trace);
|
||||
}
|
||||
|
||||
final alreadyOpen = await delegate.isOpen;
|
||||
if (alreadyOpen) {
|
||||
_ensureOpenCalled = true;
|
||||
|
@ -423,8 +430,14 @@ class DelegatedDatabase extends _BaseExecutor {
|
|||
|
||||
await delegate.open(user);
|
||||
_ensureOpenCalled = true;
|
||||
await _runMigrations(user);
|
||||
return true;
|
||||
|
||||
try {
|
||||
await _runMigrations(user);
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
_migrationError = (e, s);
|
||||
rethrow;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -231,6 +231,20 @@ void main() {
|
|||
)),
|
||||
);
|
||||
});
|
||||
|
||||
test('prevents database access after failed migrations', () async {
|
||||
final db = TodoDb(NativeDatabase.memory());
|
||||
final exception = 'exception';
|
||||
db.migration = MigrationStrategy(onCreate: (_) async => throw exception);
|
||||
|
||||
await expectLater(db.customSelect('SELECT 1').get(), throwsA(exception));
|
||||
|
||||
// The database should now be unusable.
|
||||
db.migration = MigrationStrategy();
|
||||
await expectLater(db.customSelect('SELECT 1').get(), throwsA(exception));
|
||||
|
||||
await db.close();
|
||||
});
|
||||
}
|
||||
|
||||
class _FakeExecutorUser extends QueryExecutorUser {
|
||||
|
|
Loading…
Reference in New Issue