diff --git a/lib/features/mysql/mysql_table_view.dart b/lib/features/mysql/mysql_table_view.dart index 16a7b203..740a2662 100644 --- a/lib/features/mysql/mysql_table_view.dart +++ b/lib/features/mysql/mysql_table_view.dart @@ -233,21 +233,11 @@ class MysqlTableDataDelegate extends TableDataMutationDelegate { }); } + /// Pooled sessions are shared with every other view of this database, so + /// cancelling never closes them: a statement that is still running finishes + /// or times out on its own, and the lease is released by [dispose]. @override - void cancel({bool interruptIfBusy = false}) { - if (interruptIfBusy) { - MysqlService.instance.interrupt( - connectionRow, - database: database, - mode: MysqlSessionMode.readOnly, - ); - MysqlService.instance.interrupt( - connectionRow, - database: database, - mode: MysqlSessionMode.tableWrite, - ); - } - } + void cancel({bool interruptIfBusy = false}) {} @override void dispose() { diff --git a/lib/features/postgresql/postgres_table_view.dart b/lib/features/postgresql/postgres_table_view.dart index 5158aa13..c69db4a6 100644 --- a/lib/features/postgresql/postgres_table_view.dart +++ b/lib/features/postgresql/postgres_table_view.dart @@ -234,21 +234,11 @@ class PostgresTableDataDelegate extends TableDataMutationDelegate { }); } + /// Pooled sessions are shared with every other view of this database, so + /// cancelling never closes them: a statement that is still running finishes + /// or times out on its own, and the lease is released by [dispose]. @override - void cancel({bool interruptIfBusy = false}) { - if (interruptIfBusy) { - PostgresService.instance.interrupt( - connectionRow, - database: database, - mode: PgSessionMode.readOnly, - ); - PostgresService.instance.interrupt( - connectionRow, - database: database, - mode: PgSessionMode.tableWrite, - ); - } - } + void cancel({bool interruptIfBusy = false}) {} @override void dispose() { diff --git a/lib/features/sqlite/sqlite_table_view.dart b/lib/features/sqlite/sqlite_table_view.dart index 00f0b75f..1f1061b7 100644 --- a/lib/features/sqlite/sqlite_table_view.dart +++ b/lib/features/sqlite/sqlite_table_view.dart @@ -221,19 +221,11 @@ class SqliteTableDataDelegate extends TableDataMutationDelegate { }); } + /// Pooled sessions are shared with every other view of this database, so + /// cancelling never closes them: a statement that is still running finishes + /// or times out on its own, and the lease is released by [dispose]. @override - void cancel({bool interruptIfBusy = false}) { - if (interruptIfBusy) { - SqliteService.instance.interrupt( - connectionRow, - mode: SqliteSessionMode.readOnly, - ); - SqliteService.instance.interrupt( - connectionRow, - mode: SqliteSessionMode.tableWrite, - ); - } - } + void cancel({bool interruptIfBusy = false}) {} @override void dispose() { diff --git a/lib/features/workspace/generic_table_view.dart b/lib/features/workspace/generic_table_view.dart index dedd67a3..d93460b4 100644 --- a/lib/features/workspace/generic_table_view.dart +++ b/lib/features/workspace/generic_table_view.dart @@ -286,7 +286,8 @@ class GenericTableViewState extends material.State { void dispose() { TableViewCommandBridge.instance.unregister(owner: this); _resetStaging(); - widget.delegate.cancel(interruptIfBusy: true); + // Closing the tab releases its lease. It must not interrupt the shared + // session: other views of the database may be using it. widget.delegate.dispose(); super.dispose(); } diff --git a/test/features/workspace/generic_table_view_relations_test.dart b/test/features/workspace/generic_table_view_relations_test.dart index 2fca6023..bf65dbba 100644 --- a/test/features/workspace/generic_table_view_relations_test.dart +++ b/test/features/workspace/generic_table_view_relations_test.dart @@ -86,4 +86,15 @@ void main() { await t.pump(); expect(find.byType(ErdView), findsNothing); }); + + testWidgets('closing a table tab releases its delegate without cancelling it', + (t) async { + final delegate = FakeTableDataDelegate(); + await pumpGenericTableView(t, delegate); + await t.pumpWidget(const material.SizedBox()); + await t.pump(); + // The session is shared with other views: closing must not interrupt it. + expect(delegate.cancelCount, 0); + expect(delegate.disposeCount, 1); + }); }