Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/core/database/sqlite_connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ class SqliteConnection {
path,
options: OpenDatabaseOptions(
readOnly: readOnly,
// Every SqliteConnection needs its own handle. With the sqflite
// default (singleInstance: true) a second open of the same path
// returns the first Database: a Save session would reuse a
// read-only browse handle, and closing any pooled session would
// close the file for every other session too.
singleInstance: false,
onOpen: (db) async {
await db.execute('PRAGMA busy_timeout = 5000');
await db.rawQuery('SELECT 1');
Expand Down
33 changes: 4 additions & 29 deletions lib/features/mysql/mysql_sql_workspace.dart
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ class _MysqlSqlWorkspaceState extends material.State<MysqlSqlWorkspace> {
final hasDirtyStaging =
session.stagingBuffer != null && session.stagingBuffer!.isDirty;
final hasUnsavedText = session.isModified ||
(session.filePath == null && session.controller.text.trim().isNotEmpty);
(session.filePath == null &&
session.controller.text.trim().isNotEmpty);
final String message;
if (hasDirtyStaging && hasUnsavedText) {
message =
Expand Down Expand Up @@ -551,8 +552,7 @@ class _MysqlSqlWorkspaceState extends material.State<MysqlSqlWorkspace> {
session.stagingBuffer?.dispose();
setState(() {
session.rows = newRows;
session.stagingBuffer =
DataGridStagingBuffer(
session.stagingBuffer = DataGridStagingBuffer(
columns: session.columns,
rows: session.rows,
primaryKeys: session.resultGridPrimaryKeys,
Expand All @@ -562,32 +562,7 @@ class _MysqlSqlWorkspaceState extends material.State<MysqlSqlWorkspace> {
} catch (e) {
if (mounted) {
setState(() => session.savingChanges = false);
await showAppDialog<void>(
context: context,
builder: (ctx) => QueryaDialogCard(
constraints: const material.BoxConstraints(maxWidth: 420),
child: material.Padding(
padding: const material.EdgeInsets.all(20),
child: material.Column(
mainAxisSize: material.MainAxisSize.min,
crossAxisAlignment: material.CrossAxisAlignment.start,
children: [
const Text('Save Changes Failed').semiBold().large(),
const Gap(8),
Text(e.toString()).muted().small(),
const Gap(20),
material.Align(
alignment: material.Alignment.centerRight,
child: PrimaryButton(
onPressed: () => material.Navigator.of(ctx).pop(),
child: const Text('OK'),
),
),
],
),
),
),
);
await showTableViewSaveFailedDialog(context: context, error: e);
}
}
}
Expand Down
10 changes: 2 additions & 8 deletions lib/features/mysql/mysql_table_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ class _MysqlTableViewState extends material.State<MysqlTableView> {
});
showAppToast(
context: context,
message: '${outcome.statementCount} change(s) saved',
message: tableViewSavedMessage(outcome.statementCount),
variant: AppToastVariant.success,
);
await _fetch(refreshCount: true);
Expand All @@ -609,7 +609,7 @@ class _MysqlTableViewState extends material.State<MysqlTableView> {
});
showAppToast(
context: context,
message: '${outcome.statementCount} change(s) saved',
message: tableViewSavedMessage(outcome.statementCount),
variant: AppToastVariant.success,
);
return;
Expand Down Expand Up @@ -705,12 +705,6 @@ class _MysqlTableViewState extends material.State<MysqlTableView> {
),
),
const Gap(6),
if (_stagingBuffer != null)
TableBrowserPendingActions(
buffer: _stagingBuffer!,
onSave: () => unawaited(_applyStagedChanges()),
isSaving: _isSaving,
),
OutlineButton(
size: ButtonSize.small,
onPressed: _openSqlEditor,
Expand Down
27 changes: 1 addition & 26 deletions lib/features/postgresql/postgres_sql_workspace.dart
Original file line number Diff line number Diff line change
Expand Up @@ -689,32 +689,7 @@ class _PostgresSqlWorkspaceState extends material.State<PostgresSqlWorkspace> {
} catch (e) {
if (mounted) {
setState(() => session.savingChanges = false);
await showAppDialog<void>(
context: context,
builder: (ctx) => QueryaDialogCard(
constraints: const material.BoxConstraints(maxWidth: 420),
child: material.Padding(
padding: const material.EdgeInsets.all(20),
child: material.Column(
mainAxisSize: material.MainAxisSize.min,
crossAxisAlignment: material.CrossAxisAlignment.start,
children: [
const Text('Save Changes Failed').semiBold().large(),
const Gap(8),
Text(e.toString()).muted().small(),
const Gap(20),
material.Align(
alignment: material.Alignment.centerRight,
child: PrimaryButton(
onPressed: () => material.Navigator.of(ctx).pop(),
child: const Text('OK'),
),
),
],
),
),
),
);
await showTableViewSaveFailedDialog(context: context, error: e);
}
}
}
Expand Down
11 changes: 2 additions & 9 deletions lib/features/postgresql/postgres_table_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ class _PostgresTableViewState extends material.State<PostgresTableView> {
});
showAppToast(
context: context,
message: '${outcome.statementCount} change(s) saved',
message: tableViewSavedMessage(outcome.statementCount),
variant: AppToastVariant.success,
);
await _fetch(refreshCount: true);
Expand All @@ -627,7 +627,7 @@ class _PostgresTableViewState extends material.State<PostgresTableView> {
});
showAppToast(
context: context,
message: '${outcome.statementCount} change(s) saved',
message: tableViewSavedMessage(outcome.statementCount),
variant: AppToastVariant.success,
);
return;
Expand Down Expand Up @@ -667,13 +667,6 @@ class _PostgresTableViewState extends material.State<PostgresTableView> {
onGoPrevious: _goToPreviousPage,
onGoNext: _goToNextPage,
onRefresh: () => unawaited(_onRefresh()),
pendingActions: _stagingBuffer == null
? null
: TableBrowserPendingActions(
buffer: _stagingBuffer!,
onSave: () => unawaited(_applyStagedChanges()),
isSaving: _isSaving,
),
);
final buffer = _stagingBuffer;
if (buffer == null) return toolbar();
Expand Down
33 changes: 4 additions & 29 deletions lib/features/sqlite/sqlite_sql_workspace.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ class _SqliteSqlWorkspaceState extends material.State<SqliteSqlWorkspace> {
final hasDirtyStaging =
session.stagingBuffer != null && session.stagingBuffer!.isDirty;
final hasUnsavedText = session.isModified ||
(session.filePath == null && session.controller.text.trim().isNotEmpty);
(session.filePath == null &&
session.controller.text.trim().isNotEmpty);
final String message;
if (hasDirtyStaging && hasUnsavedText) {
message =
Expand Down Expand Up @@ -530,8 +531,7 @@ class _SqliteSqlWorkspaceState extends material.State<SqliteSqlWorkspace> {
session.stagingBuffer?.dispose();
setState(() {
session.rows = newRows;
session.stagingBuffer =
DataGridStagingBuffer(
session.stagingBuffer = DataGridStagingBuffer(
columns: session.columns,
rows: session.rows,
primaryKeys: session.resultGridPrimaryKeys,
Expand All @@ -541,32 +541,7 @@ class _SqliteSqlWorkspaceState extends material.State<SqliteSqlWorkspace> {
} catch (e) {
if (mounted) {
setState(() => session.savingChanges = false);
await showAppDialog<void>(
context: context,
builder: (ctx) => QueryaDialogCard(
constraints: const material.BoxConstraints(maxWidth: 420),
child: material.Padding(
padding: const material.EdgeInsets.all(20),
child: material.Column(
mainAxisSize: material.MainAxisSize.min,
crossAxisAlignment: material.CrossAxisAlignment.start,
children: [
const Text('Save Changes Failed').semiBold().large(),
const Gap(8),
Text(e.toString()).muted().small(),
const Gap(20),
material.Align(
alignment: material.Alignment.centerRight,
child: PrimaryButton(
onPressed: () => material.Navigator.of(ctx).pop(),
child: const Text('OK'),
),
),
],
),
),
),
);
await showTableViewSaveFailedDialog(context: context, error: e);
}
}
}
Expand Down
40 changes: 29 additions & 11 deletions lib/features/sqlite/sqlite_table_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,32 @@ class _SqliteTableViewState extends material.State<SqliteTableView> {
);
}

/// Browse connection, re-acquired when the pooled session was closed under
/// us (tree Disconnect, another view interrupting the shared slot).
Future<SqliteConnection?> _ensureBrowseConnection() async {
final current = _connection;
if (current != null && current.isConnected) return current;
_lease?.release();
_lease = null;
try {
final lease = await SqliteService.instance.acquire(
widget.connectionRow,
mode: SqliteSessionMode.readOnly,
);
if (!mounted) {
lease.release();
return null;
}
_lease = lease;
return lease.connection;
} catch (_) {
return null;
}
}

Future<void> _fetch() async {
final conn = _connection;
final conn = await _ensureBrowseConnection();
if (!mounted) return;
if (conn == null || !conn.isConnected) {
if (mounted && _loading) {
setState(() {
Expand Down Expand Up @@ -410,7 +434,7 @@ class _SqliteTableViewState extends material.State<SqliteTableView> {
});
showAppToast(
context: context,
message: '${outcome.statementCount} change(s) saved',
message: tableViewSavedMessage(outcome.statementCount),
variant: AppToastVariant.success,
);
await _fetch();
Expand All @@ -432,7 +456,7 @@ class _SqliteTableViewState extends material.State<SqliteTableView> {
});
showAppToast(
context: context,
message: '${outcome.statementCount} change(s) saved',
message: tableViewSavedMessage(outcome.statementCount),
variant: AppToastVariant.success,
);
return;
Expand All @@ -447,8 +471,8 @@ class _SqliteTableViewState extends material.State<SqliteTableView> {
}

Future<void> _showDdlDialog() async {
final conn = _connection;
if (conn == null || !conn.isConnected) return;
final conn = await _ensureBrowseConnection();
if (!mounted || conn == null || !conn.isConnected) return;
final navigator = material.Navigator.of(context, rootNavigator: true);
unawaited(showAppDialog<void>(
context: context,
Expand Down Expand Up @@ -622,12 +646,6 @@ class _SqliteTableViewState extends material.State<SqliteTableView> {
),
),
const Gap(6),
if (_stagingBuffer != null)
TableBrowserPendingActions(
buffer: _stagingBuffer!,
onSave: () => unawaited(_applyStagedChanges()),
isSaving: _isSaving,
),
OutlineButton(
size: ButtonSize.small,
onPressed: _loading
Expand Down
Loading
Loading