* Preserve ordered SSH and proxy connection layers
Replace separate SSH/proxy connection fields with ordered transport_layers while keeping legacy migration and secret fallback paths intact. The UI now edits SSH tunnel/proxy layers in configured order without a global SSH enable gate.
Constraint: Existing saved SSH tunnels, proxy settings, and secret-store keys must continue to load through migration.
Rejected: Folding proxy fields into SshTunnelConfig | mixes proxy semantics into an SSH-specific structure.
Confidence: high
Scope-risk: moderate
Directive: Keep SSH/proxy structs provider-specific; put cross-layer chaining in transport_layer_tunnel orchestration.
Tested: git diff --check; cargo fmt --check; cargo check --workspace; cargo test -p dbx-core --lib; vue-tsc --noEmit --project apps/desktop/tsconfig.json; tsc -p packages/node-core/tsconfig.json --noEmit; oxlint --vue-plugin apps/desktop/src; tsx --tsconfig apps/desktop/tsconfig.json --test packages/app-tests/*.test.ts; tsx --test packages/node-core/tests/*.test.ts
Not-tested: Live external SSH/proxy/database endpoint integration.
* Keep ordered transport changes CI-format clean
Constraint: CI pnpm check failed only on oxfmt formatting for two desktop TypeScript files
Confidence: high
Scope-risk: narrow
Directive: Keep generated/editor config changes out of this PR fix commit
Tested: PATH="/Volumes/data/code/rust/dbx/node_modules/.bin:/Users/hekx/.codex/tmp/arg0/codex-arg0nuL34n:/Users/hekx/.cargo/bin:/Users/hekx/.local/bin:/opt/homebrew/opt/llvm/bin:/opt/homebrew/opt/libpq/bin:/Volumes/data/Users/hekx/.opencode/bin:/Users/hekx/.bun/bin:/Volumes/data/sdks/flutter/bin:/Volumes/data/Users/hekx/.cargo/bin:/Users/hekx/.local/bin:/opt/homebrew/opt/llvm/bin:/opt/homebrew/opt/libpq/bin:/Volumes/data/Users/hekx/.opencode/bin:/Users/hekx/.bun/bin:/Volumes/data/Users/hekx/Library/pnpm:/Volumes/data/sdks/flutter/bin:/Volumes/data/Users/hekx/.cargo/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/pkg/env/global/bin:/opt/X11/bin:/Library/Apple/usr/bin:/Applications/Wireshark.app/Contents/MacOS:/usr/local/go/bin:/opt/homebrew/bin:/opt/podman/bin:/Applications/Ghostty.app/Contents/MacOS" rtk node scripts/run-check.mjs
Not-tested: GitHub Actions rerun not observed locally
* Keep Rust checks warning-clean
Constraint: cargo clippy --workspace --all-targets --all-features -- -D warnings failed across core, web, and tauri crates
Rejected: Broad workspace-level clippy suppression | kept allows local to long-argument command/API boundaries
Confidence: high
Scope-risk: moderate
Directive: Preserve src-tauri/tauri.conf.json as an unrelated local change outside this commit
Tested: rtk cargo clippy --workspace --all-targets --all-features -- -D warnings
Not-tested: Full GitHub Actions rerun not observed locally
* Reuse existing proxy tunnels on retry
Proxy tunnel startup now mirrors SSH tunnel behavior by returning the existing local port for an active connection id instead of replacing the managed handle. A second map check aborts a just-spawned duplicate handle if a concurrent retry won the race before insertion, preventing orphaned listeners while keeping the change narrow.
Constraint: Reviewer requested proxy tunnel behavior align with SSH local-port reuse
Rejected: Always overwrite and abort the previous handle | less consistent with SSH behavior and churns listeners during retries
Confidence: high
Scope-risk: narrow
Tested: cargo fmt --check --all
Tested: cargo test -p dbx-core db::proxy_tunnel::tests::start_tunnel_reuses_existing_local_port
Tested: cargo clippy -p dbx-core --all-targets -- -D warnings
---------
Co-authored-by: hekx <hekx@momandeMac-mini.local>
Co-authored-by: caisin <caisin@caisins-Mac-mini.local>
Previously, cancelling a DuckDB query only dropped the tokio CancellationToken,
but the actual DuckDB C call continued running in spawn_blocking. This caused
the UI to show "正在停止..." until timeout silently expired.
Now, RunningQueries stores per-execution interrupt callbacks. For DuckDB and
ExternalTabular branches, an InterruptHandle is registered on query start so
cancel() calls duckdb_interrupt() at the C level, truly stopping the query.
Previously execute_batch always used the hardcoded 30s default timeout,
ignoring the user's query_timeout_secs connection setting. This caused
long-running ALTER TABLE statements on large tables to time out even
when the user configured a longer timeout or disabled it entirely.
Right-click a column header in the data grid to copy the ALTER TABLE
statement for that column, making it easy to replicate column definitions
across databases. Supports all major dialects (MySQL, Postgres, SQL Server,
Oracle, ClickHouse, SQLite, DuckDB, H2).
Closes#516
Add queryTimeoutSecs to editor settings with UI control in the settings
dialog. 0 means no timeout. Applied to all query execution paths including
sidebar table data loading and EXPLAIN queries.
Closes#441.
DuckDB was not recognized as a schema-aware database, so only the
default "main" schema was shown in the object tree and schema selector.
Added DuckDB to schema-aware type lists, implemented schema listing via
information_schema.schemata, and replaced hardcoded table_schema = 'main'
with parameterized queries.
Add schema selector to the editor toolbar for schema-aware databases
(PostgreSQL, SQL Server, Oracle). When a schema is selected, the backend
sets the appropriate search_path before executing queries so users no
longer need to write schema-qualified table names.
Refactor all database drivers, query execution, schema operations, and
business logic into a shared `dbx-core` crate. The Tauri desktop app
becomes a thin shell delegating to dbx-core, enabling future web and
CLI frontends to reuse the same core.
- New elasticsearch_driver using reqwest HTTP client
- Reuse MongoDB document browser (MongoDocBrowser) for ES indices
- ES indices shown as collections under "default" database
- Document CRUD via ES REST API (_search, _doc)
- No extra dependencies (uses existing reqwest)