dbx/crates/dbx-core/src
runstone a440415e86 feat(readonly): add read-only mode for all database connections
## Background
Add a read-only toggle for database connections that blocks all write
operations (INSERT, UPDATE, DELETE, DROP, etc.) when enabled, allowing
only read queries (SELECT, SHOW, EXPLAIN, etc.). Closes #889.

## Changes

### Data Model
- Added `read_only: bool` field to ConnectionConfig (Rust struct, TS
  interfaces, and ConnectionConfigData deserialization layer)
- Used `#[serde(default, skip_serializing_if = "is_false")]` for
  backward/forward compatibility with existing configs

### Frontend UI
- Added "Read Only" checkbox in connection dialog
- 7-language i18n support (en/es/it/pt-BR/zh-CN/zh-TW)

### SQL Classification (query_execution_sql.rs)
- Added `is_write_sql()` with two-layer defense:
  - Layer 1: First-keyword check (must start with known read keyword)
  - Layer 2: Embedded dangerous keyword detection (catches CTE-wrapped
    writes like `WITH ... AS (DELETE FROM ...)`)
  - `FROM` keyword supported as DuckDB SELECT-less syntax indicator
- Added `check_read_only()` returning descriptive error with connection name
- Added 16 unit tests covering: pure reads/writes, CTE, case insensitivity,
  string literal masking, comment stripping, stored procedure calls, edge cases

### SQL Execution Guards (query.rs / transfer.rs)
- Added `check_read_only_for_connection()` and `_multi()` helper functions
  with lazy name clone (only allocates when read_only is true)
- 6 interception points: `do_execute`, MySQL batch, SQL Server batch,
  DuckDB batch, transaction execution, transfer execution

### Non-SQL Write Guards — Tauri Commands
- Added `ensure_connection_writable()` helper (connection.rs)
- Mongo: 6 write entry points (insert/update/delete, single + batch)
- Redis: 15 write entry points (SET, DEL, HSET, HDEL, LPUSH, LSET, LREM,
  SADD, SREM, ZADD, ZREM, EXPIRE, FLUSHDB, delete_keys, execute_command)
  - execute_command uses RedisCommandSafety classification to allow
    safe read commands through raw command interface
- etcd: 2 write entry points (put, delete)
- sql_file: SQL file execution guarded
- MCP Bridge: 4 write entry points (Insert/Update/Delete/SQL query)

### Non-SQL Write Guards — Web API
- Local `ensure_writable()` helper in each route module
- Redis: 12 write endpoints including classified execute_command
- Mongo: 6 write endpoints
- etcd: 2 write endpoints
- sql_file, table_import, transfer: early rejection

### Test Updates
- Updated ConnectionConfig construction in 7 test files with
  `read_only: false` initialization

## Defense-in-Depth
- Layer 1: Command/Route-level early rejection (saves resources)
- Layer 2: Core SQL classifier (`is_write_sql` — first keyword + embedded scan)
- Layer 3: Core execution-time interception (do_execute/transfer/transaction)
2026-06-10 10:58:52 +08:00
..
db fix(redis): enhance hash value text extraction for search 2026-06-09 13:15:20 +08:00
external Preserve ordered SSH and proxy connection layers (#802) 2026-06-06 23:22:29 +08:00
models feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
agent_catalog.rs fix: exclude etcd from driver store and fix CI test overlap 2026-06-08 02:08:08 +08:00
agent_connection.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
agent_kv.rs feat(etcd): add agent-backed etcd support 2026-06-08 00:58:42 +08:00
agent_manager.rs feat: add driver runtime manager 2026-06-04 23:20:15 +08:00
agent_runtime.rs feat: add driver runtime manager 2026-06-04 23:20:15 +08:00
agent_service.rs feat(etcd): add agent-backed etcd support 2026-06-08 00:58:42 +08:00
ai.rs fix(ai): support proxied API channels 2026-06-08 20:32:54 +08:00
cloud_sync.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
connection.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
connection_secrets.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
csv_export.rs Preserve ordered SSH and proxy connection layers (#802) 2026-06-06 23:22:29 +08:00
data_compare.rs Preserve ordered SSH and proxy connection layers (#802) 2026-06-06 23:22:29 +08:00
data_grid_neo4j_sql.rs refactor: extract Neo4j and TDengine SQL logic from data_grid_sql.rs 2026-05-25 23:21:47 +08:00
data_grid_sql.rs fix(core): use ClickHouse array syntax `[...]` instead of PostgreSQL `{...}` for array literals 2026-06-07 22:45:11 +08:00
data_grid_tdengine_sql.rs refactor: extract Neo4j and TDengine SQL logic from data_grid_sql.rs 2026-05-25 23:21:47 +08:00
database_capabilities.rs feat: add rqlite database support 2026-06-05 01:02:07 +08:00
database_export.rs feat(sidebar): lazily load database object groups 2026-06-07 23:44:40 +08:00
database_search_sql.rs
db_admin_sql.rs feat(dameng): full DM8 database support 2026-06-08 02:07:00 +08:00
driver_runtime.rs feat: add driver runtime manager 2026-06-04 23:20:15 +08:00
history.rs
jdbc.rs feat: enable driver management on web version 2026-05-26 01:23:26 +08:00
lib.rs feat: support H2 file connections 2026-06-08 20:09:27 +08:00
mongo_ops.rs fix: sort sidebar metadata nodes consistently 2026-06-05 16:44:41 +08:00
object_source_sql.rs feat(postgres): support sequence objects 2026-06-08 22:54:14 +08:00
path_utils.rs feat: support H2 file connections 2026-06-08 20:09:27 +08:00
plugins.rs feat: add driver runtime manager 2026-06-04 23:20:15 +08:00
query.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
query_cancel.rs fix: cancel DuckDB queries via duckdb_interrupt instead of only cancelling async future 2026-06-04 17:20:13 +08:00
query_execution_sql.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
query_result_sql.rs fix(oracle): skip SQL pagination clauses for Oracle 11g compatibility 2026-06-09 00:44:20 +08:00
redis_ops.rs Add Redis cluster support and improve key loading 2026-05-28 00:08:59 +08:00
saved_sql.rs
schema.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
schema_diff.rs Preserve ordered SSH and proxy connection layers (#802) 2026-06-06 23:22:29 +08:00
sql.rs fix(sqlserver): preserve procedure DDL batches 2026-06-03 18:14:33 +08:00
sql_analysis.rs fix(duckdb): return rows for shorthand result queries 2026-06-03 11:13:14 +08:00
sql_dialect.rs fix(oracle): skip SQL pagination clauses for Oracle 11g compatibility 2026-06-09 00:44:20 +08:00
sql_editability.rs Preserve ordered SSH and proxy connection layers (#802) 2026-06-06 23:22:29 +08:00
sql_file_import.rs Preserve ordered SSH and proxy connection layers (#802) 2026-06-06 23:22:29 +08:00
storage.rs feat: add user-facing debug logs 2026-06-08 12:16:49 +08:00
table_export.rs Preserve ordered SSH and proxy connection layers (#802) 2026-06-06 23:22:29 +08:00
table_import.rs fix(import): accept JSON files with UTF-8 BOM 2026-06-08 17:07:17 +08:00
table_structure_sql.rs fix: quote temporal type default values in SQL generation 2026-06-06 02:12:53 +08:00
text_export.rs
transfer.rs feat(readonly): add read-only mode for all database connections 2026-06-10 10:58:52 +08:00
types.rs feat(postgres): support sequence objects 2026-06-08 22:54:14 +08:00
update.rs fix(updates): guard portable builds from installer updates (#550) 2026-05-30 19:15:37 +08:00
xlsx_export.rs feat: support double-clicking .db/.sqlite/.duckdb files to open in IDE 2026-05-29 17:25:52 +08:00