feat: Oracle Cloud Wallet + connection resilience overhaul#107
Merged
Conversation
…bust JRE download - Add Oracle connection method selector (Basic/TNS/Cloud Wallet) with SID/Service Name toggle - Add TNS names directory browser with auto-populated alias dropdown - Add Cloud Wallet (ATP/ADW) support with wallet directory, password, and service level - Add Role selector (NORMAL/SYSDBA/SYSOPER) with pill-toggle UI - Redesign SSL/TLS mode as segmented radio group with hover descriptions - Place Host/Port on same row, dynamic label for Service Name/SID field - Add red asterisk indicators on required fields - Increase dialog max-width from lg to xl Backend: - Add OracleConnectionOptions struct flowing through ServerConfig→ConnectionConfig→ConnectParams - Implement build_oracle_url() with 4 URL formats (SID, Service Name, TNS, Cloud Wallet) - Add tnsnames.ora parser for TNS alias auto-population - Add direct JDBC driver download from Maven Central (no Java needed) - Fix Adoptium JRE download URL (separate os/arch path segments) - Add JRE download validation (size check, gzip magic bytes, atomic swap with rollback) - Fix Java binary executable permission check (is_valid_java now checks +x) - Handle macOS .jdk bundle format (Contents/Home/bin/java) - Skip bridge JAR validation when Java is macOS stub - Add process health check before bridge requests - Skip non-JSON lines in bridge response parsing - Retry empty bridge response after 1s delay Java: - Pass TNS_ADMIN and wallet_password as HikariCP data source properties - Parse oracle_options from ConnectParams JSON UI/UX: - Add sequential step progress with per-item status and retry buttons - Show download progress bar during JRE/bridge/driver downloads - Add retry-on-error for individual setup steps - Show loading indicator during connection test - Add Connection successful/failed summary with error details - Disable Test Connection and Save buttons during testing - Prevent form submission on Browse buttons (type=button) - Bundle carbon icons locally instead of CDN fetch
- Add error display for TNS/Wallet fields (tnsAdminDir, tnsAlias) with
proper i18n keys instead of reusing hostRequired
- Add await to retryStep('driver') + concurrent-invocation guard in
handleTestConnection to prevent race conditions
- Add onUnmounted cleanup for progress event listener to prevent leaks
- Preserve host/port when switching Oracle connection methods
- Use Content-Length header for download progress instead of hardcoded
totals for accurate progress bars
Frontend (ServerFormDialog.vue): - Validate SID/Service Name for Basic Oracle connections - Password show/hide toggle on all 4 password fields - Auto-clear corrupted TNS alias on edit when it doesn't match loaded aliases - Remove misleading service level dropdown (alias suffix encodes it) - Load TNS aliases when editing existing TNS/Wallet connections - Preserve host/port across Oracle method switches - New i18n keys: databaseRequired, tnsAdminDirRequired, tnsAliasRequired Java bridge (ProtocolHandler.java, ConnectionManager.java): - Full exception cause chain in error responses - Bypass DriverManager for isolated-classloader drivers - JVM SSL keyStore config (-Djavax.net.ssl.keyStore) for mTLS client cert Rust (fallback.rs, launcher.rs, tns_parser.rs): - Full TNS descriptor lookup from tnsnames.ora (inline URL format) - JVM args plumbing for SSL keystore configuration - Stderr capture in connection errors for diagnostics
G1 (P0): Add TDengine to drivers.toml and registry key mapping
G2 (P1): Add vendor-specific error patterns for MySQL, PostgreSQL,
SQL Server, Snowflake, DuckDB, H2 in ErrorClassifier
G3 (P2): Refactor classify(String) -> classify(Throwable) with
full exception cause-chain traversal
G4 (P3): Guard oracle_options to Oracle db_type only in
to_connection_config() (defense-in-depth)
… trait, LRU cache Commit 1: Foundation - state.rs: Mutex<HashMap> -> RwLock<HashMap> for parallel reads - config.rs: Add connect_timeout_secs (default 10s) + query_timeout_secs (default 30s) with builder methods and serde defaults - state.rs: Propagate timeout fields in ServerConfig + to_connection_config() - connection.rs: Enforce connect_timeout via tokio::time::timeout in connect_server - query.rs: Enforce query_timeout via tokio::time::timeout in execute_query - Lock migration: 38 .lock().await -> .read().await/.write().await across browse, connection, query, transfer, sql, commands (6 files) Commit 2: Connection Guardian - src/connection/guardian.rs: Single background tokio task monitoring all connections. Health state machine (Healthy->Degraded->Dead->Reconnecting). Auto-reconnect with exponential backoff (1s..30s). Idle eviction at 30min. Emits 'connection-state-changed' Tauri events for reactive frontend. Commit 3: ConnectionHandle Trait - src/connection/handle.rs: Object-safe trait unifying all 9 adapter types - src/connection/handle_impl.rs: Implements trait on ActiveConnection via delegate! macro, eliminating 337+ match-arm dispatches across commands Commit 4: LRU Connection Cache - src/connection/cache.rs: Bounded LRU cache (max 20 entries) with pool-key based indexing. Reconnect gate (Notify) prevents thundering herd on simultaneous reconnects. Frontend: - connectionStore.ts: Add connectTimeoutSecs/queryTimeoutSecs to ServerConnection type. Serialize timeouts in test/connect server config. Add startStateListener() action listening for 'connection-state-changed' Tauri events for reactive connection status updates. 255/255 tests pass. Zero warnings.
tokio::spawn panics before the runtime is fully initialized in Tauri's setup closure. Use tauri::async_runtime::spawn which is guaranteed to have a reactor running.
Match dbx's pattern: flex-1 spacer with data-tauri-drag-region between the title and action buttons provides a guaranteed clear drag target for moving the window on macOS with titleBarStyle: Overlay.
data-tauri-drag-region requires decorations:false to work. dbx uses the same approach on Windows/Linux. Without this, the native titlebar blocks the drag-region attribute on macOS. This removes native traffic light buttons — the existing pl-[90px] header padding reserves space to add custom window controls later.
Revert set_decorations(false) on macOS — dbx keeps decorations:true and relies on the native transparent titlebar for window dragging. Remove data-tauri-drag-region from AppHeader to prevent -webkit-app-region:drag from potentially conflicting with the native titlebar drag behavior on macOS.
Bypass Tauri's data-tauri-drag-region handling with direct CSS to ensure the header is recognized as a drag region. Tauri's attribute translation may not be working reliably on all macOS versions.
…ve elements This is the standard Electron/frameless pattern: make the entire page draggable by default and explicitly exclude buttons, inputs, links and other interactive elements via -webkit-app-region:no-drag. Eliminates dependency on per-element data-tauri-drag-region and works reliably regardless of component nesting depth.
…, LRU cache
- Fix GUARDIAN.set() — the global was never initialized, making all
health checks, quality scoring, and AI agent warnings silently skip.
Now the guardian background task is properly stored and accessible.
- Wire ConnectionHandle trait into 3 commands:
- connect_server: test_connection() replaces 9-variant match
- disconnect_server: disconnect() replaces 9-variant match
- execute_query: execute_query() + query_timeout_secs() replace
147 lines of per-adapter variant matching
Added query_timeout_secs() to the trait for timeout access.
- Wire LRU cache into AppState (cache field initialized, eviction
on disconnect_server). Ready for cross-database query optimization.
The ConnectionHandle trait and LRU cache now deliver real value:
fewer match arms, cleaner commands, and infrastructure for future
adapter additions without touching every command file.
P0: Wrap create_and_connect_adapter() in connect_timeout. Previously only test_connection() was guarded — a hung TCP/TLS handshake in adapter.connect() would freeze the UI indefinitely. P1: Fix inverted boolean in evict_idle. 'exists' was assigned !contains_key(), then negated again in 'if !exists' — causing: - Active connections to have their health records removed without actual disconnection (connection leak) - Already-removed connections to trigger disconnect on nothing Oracle audit: 7/7 goals verified, 2 active bugs fixed.
- Fix cache::get_or_create to accept &AppState instead of &Arc<AppState> so it's callable from Tauri commands via State<'_, AppState> - Populate cache on every execute_query for cross-database reuse - Add guardian health check to explain_query (was missing, only execute_query had it) - Cache eviction already works on disconnect_server
After browsing command trait migration, MySQL list_schemas was delegating to the adapter which returned ALL databases instead of just the selected one. The old code had a MySQL special case: 'return Ok(vec![database]);' Fix the MySQL adapter to use the database parameter: when a specific database is given, return just that one. Otherwise fall through to listing all databases. Found by reviewer during browse command migration audit.
…e + explain_query Deep agent finished migrating the remaining browse command handlers and explain_query to use ConnectionHandle trait dispatch. Net reduction of 49 lines across browse.rs, query.rs, and connectionStore.ts.
Previously only oracle, db2, h2 were supported — all other JDBC databases returned 'No direct JDBC driver download'. Now uses DriverRegistry::get_config_by_name() to look up any registered JDBC driver configuration by its registry key. Added get_config_by_name() to DriverRegistry for string-based lookup, enabling the download command to accept any db_type from the frontend without hardcoding a DatabaseType match.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Oracle ATP/ADW Cloud Wallet support, JDBC bridge hardening across all databases, and comprehensive connection resilience improvements.
Changes
Oracle Cloud Wallet (ATP/ADW)
JDBC Bridge Hardening
Connection Resilience
Verification