Skip to content

Commit

Permalink
Block database after error in migration
Browse files Browse the repository at this point in the history
  • Loading branch information
simolus3 committed Jan 31, 2024
1 parent af55bd0 commit 0ec19f4
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
6 changes: 6 additions & 0 deletions drift/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
17 changes: 15 additions & 2 deletions drift/lib/src/runtime/executor/helpers/engines.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
});
}

Expand Down
14 changes: 14 additions & 0 deletions drift/test/platforms/ffi/native_database_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 0ec19f4

Please sign in to comment.