feat: add per-connection read-only mode
Connections default to read-only. SQL editor wraps queries in a read-only transaction so PostgreSQL rejects mutations. Data mutation commands (update_row, insert_row, delete_rows) are blocked at the Rust layer. Toolbar toggle with confirmation dialog lets users switch to read-write. Badges shown in workspace, table viewer, and status bar. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,16 +74,32 @@ pub async fn execute_query(
|
||||
connection_id: String,
|
||||
sql: String,
|
||||
) -> TuskResult<QueryResult> {
|
||||
let read_only = state.is_read_only(&connection_id).await;
|
||||
|
||||
let pools = state.pools.read().await;
|
||||
let pool = pools
|
||||
.get(&connection_id)
|
||||
.ok_or(TuskError::NotConnected(connection_id))?;
|
||||
|
||||
let start = Instant::now();
|
||||
let rows = sqlx::query(&sql)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.map_err(TuskError::Database)?;
|
||||
let rows = if read_only {
|
||||
let mut tx = pool.begin().await.map_err(TuskError::Database)?;
|
||||
sqlx::query("SET TRANSACTION READ ONLY")
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(TuskError::Database)?;
|
||||
let result = sqlx::query(&sql)
|
||||
.fetch_all(&mut *tx)
|
||||
.await
|
||||
.map_err(TuskError::Database);
|
||||
tx.rollback().await.map_err(TuskError::Database)?;
|
||||
result?
|
||||
} else {
|
||||
sqlx::query(&sql)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.map_err(TuskError::Database)?
|
||||
};
|
||||
let execution_time_ms = start.elapsed().as_millis();
|
||||
|
||||
let mut columns = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user