* fix(mysql): health-check pooled connection before DDL query
`mysql_ddl` fetched a connection with a raw `pool.get_conn()` and issued
`SHOW CREATE TABLE` directly, unlike other read paths (`get_columns`,
`list_indexes`, ...) which go through `get_conn_with_health_check`. A
pooled connection that went stale while idle (server closed it after its
idle timeout, NAT/firewall dropped the TCP state, ...) would then fail on
the first DDL request after a period of inactivity, surfacing a low-level
connection error that a manual refresh would mask.
Route `mysql_ddl` through `get_conn_with_health_check` so stale
connections are pinged and replaced before the query runs, matching the
rest of the MySQL metadata path.
* fix(test): add redis_scan_page_size to ConnectionConfig test helpers
`d815a16b` (feat(redis): move scan page size to connections) added
`redis_scan_page_size` to `ConnectionConfig` but did not update several
struct-literal test helpers, so `cargo clippy --workspace --all-targets`
fails with `missing field redis_scan_page_size`. This is a pre-existing
breakage on `main` (CI has been red since that commit) and is unrelated to
this PR's actual change; included here only to unblock CI.
Helpers fixed here:
- src-tauri/src/commands/connection.rs (`mongodb_config`)
- crates/dbx-web/src/routes/connection.rs (`sqlite_config`)
- Use synchronous pool removal in desktop disconnect_db to prevent
race condition when user quickly disconnects and reconnects
- Rename recordMetadataLoadError to recordConnectionLostError and
export it for cross-store reuse
- Sync query execution errors back to connection state via
recordConnectionLostError in queryStore catch blocks
- Add backend check_connection_health method (dbx-core) with Tauri
command and web route for proactive pool verification
- Add frontend checkConnectionHealth API (tauri.ts/http.ts/api.ts)
- Enhance ensureConnected to verify backend pool health before
assuming connection is valid, auto-reconnect if stale
* feat(mq): implement Apache Pulsar message queue admin
- Add complete MQ admin adapter layer with version detection
* Pulsar adapter with multi-version API support
* OAuth2 token caching and authentication
* JWT token signing for Pulsar clients
* Transport layer (SSH/Proxy) integration
- Implement comprehensive admin operations
* Tenant, namespace, topic management
* Subscription and consumer/producer monitoring
* Rate limits, backlog quotas, retention policies
* Permissions and role-based access control
* Raw admin API for advanced operations
- Add desktop UI components
* MQ admin console with tabbed interface
* Tenant, namespace, topic panels
* Subscription management and cursor operations
* Monitoring panel with stats visualization
* Policy configuration UI
- Add web routes for MQ admin operations
- Add secret store support for MQ auth credentials
- Add comprehensive test coverage
* fix: del local test files
* fix(mq): mark message queue as unsupported mcpMode in driver manifest
MQ admin connections do not use the MCP query bridge - they use a
separate REST admin API. Mark mcpMode as 'unsupported' to align with
the test expectations and reflect the actual architecture.
Fixes CI test: driver-manifest.test.ts
* fix(mq): fix TypeScript errors in MQ components
- Fix typo in SubscriptionsPanel.vue: messagformatError(e)Id -> message.messageId
- Use formatError() helper in RawApiPanel.vue instead of accessing e?.message
- Fix undefined 'tab' reference in ConnectionTree.vue: use config.db_type instead
Fixes frontend CI TypeScript check errors.
* fix(mcp): add 'mq' to MCP server connection type description
The MCP server's connection type description must include all database
types from the driver manifest. Add 'mq' to the list to fix the test:
'add connection database type description includes every manifest database type'
Fixes: packages/mcp-server/tests/driver-manifest.test.ts
* fix(mq): add missing ConnectionConfig fields for Rust compilation
- Add gbase_server and keepalive_interval_secs fields to all ConnectionConfig
test constructors in mq/config.rs, mq/service.rs, and storage.rs
- Import uses_bare_mysql_pool in connection.rs tests module
Fixes compilation errors from upstream ConnectionConfig changes.
* chore(ui): simplify Pulsar icon to logo-only version
Remove text from Pulsar icon (127x30 -> 35x30), keeping only
the wave logo symbol for a cleaner, more consistent appearance
with other database icons.
* fix(mq): return removed pools from drain_connection_pools
---------
Co-authored-by: t8y2 <1156263951@qq.com>
Turso is a distributed SQLite database built on libSQL, offering HTTP-based
connectivity with auth token authentication. This change adds full support:
- New DatabaseType::Turso and PoolKind::Turso variants
- TursoClient driver using libSQL HTTP pipeline API (/v2/pipeline)
- Bearer token auth via password or url_params (auth_token=)
- Multi-statement batch pipeline for transactional integrity
- Standalone BEGIN/COMMIT/ROLLBACK treated as no-ops (pipeline is auto-commit)
- Full metadata support: tables, columns, indexes, foreign keys, triggers, DDL
- Frontend: connection form, SQL completion (SQLite syntax), capability sets
- Built-in databases (SQLite/Turso/DuckDB/RQLite/Access) placed first in selector
- Unit tests (15) + integration tests against live libsql-server (12)
- Single connection pool, skips TCP probe
Closes#948
start_tunnel() and start_chain() had a check-then-act race condition:
multiple concurrent callers could all see an empty cache and each
spawn a new SSH tunnel. The tunnel that lost the insert race was
orphaned, causing queries routed through it to fail.
Use double-check locking with stale entry eviction: hold the lock for
the cache lookup, release it during the slow SSH handshake, then
re-check under the lock before inserting. If another caller already
created the tunnel, abort the duplicate and return the existing port.
Also check handle liveness on cache hits so that callers don't get a
dead port back when the background tunnel task has exited.
Add a matching re-check in the MongoDB connection pool creation path.
Add idle_timeout_secs connection option (default 60s) to preempt
server-side connection idle timeouts that cause "unexpected end of
file" errors on pooled MongoDB connections.
Reject MongoDB queries in the generic SQL execution path before any
pool or session-key creation. Previously, a typo in a MongoDB shell
command would fall through to executeMulti / execute_sql_statement,
which called get_or_create_pool_for_session and leaked a session-scoped
MongoDB Client (and SSH tunnel resources) before eventually returning
"Use MongoDB-specific commands".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Database connection context menus now show a copy action when the connection has enabled transport layers. The action starts or reuses the ordered transport chain, copies the final local forwarding port, and keeps runtime config cached so later disconnect cleanup can stop the created tunnel.
Constraint: Local testing sometimes needs external tools to connect through DBX's generated proxy/tunnel endpoint
Rejected: Copy full host:port endpoint | user specifically asked for the port and existing tunnel host is always localhost
Rejected: Require an active pool before copying | local test workflows may need the tunnel before opening the DBX connection
Confidence: high
Scope-risk: moderate
Tested: pnpm test -- packages/app-tests/connectionTransport.test.ts (ran full app-tests: 862 passed)
Tested: pnpm typecheck
Tested: pnpm exec oxlint --vue-plugin apps/desktop/src/components/sidebar/TreeItem.vue apps/desktop/src/lib/connectionTransport.ts apps/desktop/src/lib/api.ts apps/desktop/src/lib/tauri.ts apps/desktop/src/lib/http.ts
Tested: cargo check -p dbx-core -p dbx-web
Tested: cargo check -p dbx
Tested: cargo fmt --check --all
Co-authored-by: caisin <caisin@caisins-Mac-mini.local>
* 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>