Skip to content

Release/260408#73

Merged
codeErrorSleep merged 15 commits into
mainfrom
release/260408
Apr 11, 2026
Merged

Release/260408#73
codeErrorSleep merged 15 commits into
mainfrom
release/260408

Conversation

@codeErrorSleep

@codeErrorSleep codeErrorSleep commented Apr 10, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

Release Notes v0.3.3

  • New Features

    • Added StarRocks database driver support
    • Dynamic MySQL charset and collation selection in connection dialogs
    • Column comments visibility toggle in data grids
    • Enhanced SQL export with separate DML, DDL, and combined format options
    • Table header interactions: click to copy column names, double-click to sort
    • macOS Developer menu with window reload and DevTools toggle
  • Improvements

    • Better SQL import parsing for PostgreSQL dollar-quoted strings, MySQL DELIMITER syntax, Oracle PL/SQL blocks, and SQLite triggers
    • Enhanced error handling and display with error boundaries
  • Chores

    • Fixed Bun runtime to version 1.3.10
    • Refactored UpgradeLink upload workflow

codeErrorSleep and others added 15 commits April 8, 2026 15:29
…sive guards

- Add ErrorBoundary component to catch render errors at root and tab level,
  replacing white screen with a visible error message
- Fix useEffect dep loop in TableView: remove columnWidths from calculateAutoColumnWidths
  effect deps and read via ref instead, eliminating extra re-renders on data load
- Add null/non-object row guard in TableView render loop to prevent TypeError
  crashing the render when data contains unexpected values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the single "Export as SQL" right-click menu item with three
separate options — Export DML (INSERT), Export DDL (CREATE), and
Export DML & DDL — so users can choose exactly what to export.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MSSQL DDL is rebuilt from column metadata and lacks foreign keys,
unique constraints, check constraints, and indexes. Add a SQL comment
block at the top of the output to warn users of this limitation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract do_table_export() to replace ~110 lines duplicated between
export_table_data and export_table_data_direct. Remove columns param
from ExportWriter::new (CSV header now written via write_csv_header),
so get_table_metadata is only called when actually fetching rows —
SqlDdl-only mode no longer makes an unnecessary metadata round-trip.
Replace dead SqlDdl arm in write_row with unreachable!().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Freeze bun version to match local development environment,
preventing --frozen-lockfile errors due to version differences.
Add a settings switch (default off) to show field comments in small text
below the column name in table headers. Comments are truncated to avoid
affecting column width. Supports en/zh/ja i18n.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move the upgradelink-upload job out of release.yml into a dedicated
workflow (.github/workflows/upgradelink-upload.yml) triggered manually
via workflow_dispatch with a required tag input.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 10, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR adds comprehensive StarRocks database driver support, enhances SQL export with DML/DDL/Full variants, implements MySQL charset/collation APIs, adds PostgreSQL dollar-quote parsing, introduces UI features like column comments and error boundaries, reorganizes the release workflow, pins Bun version, and includes associated test coverage and localizations.

Changes

Cohort / File(s) Summary
CI Workflow Configuration
.github/workflows/build-multiplatform.yml, .github/workflows/ci.yml, .github/workflows/release.yml, .github/workflows/upgradelink-upload.yml
Pinned Bun runtime from latest to 1.3.10 across build/CI jobs; removed UpgradeLink upload from release workflow and created dedicated uploadelink-upload.yml triggered via manual dispatch with required tag input.
Version Management
package.json, src-tauri/tauri.conf.json
Incremented application version from 0.3.2 to 0.3.3.
StarRocks Database Driver Support
src-tauri/src/db/drivers/mod.rs, src-tauri/src/db/drivers/mysql.rs, src-tauri/tests/common/starrocks_context.rs, src-tauri/tests/starrocks_integration.rs, src-tauri/tests/starrocks_command_integration.rs, src/lib/driver-registry.tsx, src/lib/driver-registry.unit.test.ts
Added StarRocks as MySQL-family driver with is_mysql_family_driver() predicate, driver-aware default port 9030, StarRocks-specific connection option handling, Docker-based test context, and comprehensive integration/command tests.
SQL Export Enhancement
src-tauri/src/commands/transfer.rs, src-tauri/src/commands/query.rs, src/components/business/Sidebar/ConnectionList.tsx, src/components/business/DataGrid/TableView.tsx, src/components/business/Editor/SqlEditor.tsx, src/components/business/Sidebar/connection-list/helpers.tsx, src/components/business/Sidebar/connection-list/helpers.unit.test.ts, src/services/api.ts
Replaced Sql export format with SqlDml, SqlDdl, and SqlFull; refactored table export with do_table_export() helper; added DDL fetching for DDL/Full exports; updated UI export menus with granular SQL format options.
MySQL Charset/Collation Commands
src-tauri/src/commands/connection.rs, src-tauri/src/lib.rs, src-tauri/tests/mysql_stateful_command_integration.rs, src-tauri/tests/mariadb_command_integration.rs, src/components/business/Sidebar/ConnectionList.tsx, src/services/api.ts, src/services/mocks.ts, src/services/mocks.service.test.ts
Added Tauri commands get_mysql_charsets_by_id and get_mysql_collations_by_id with validation and filtering; integrated dynamic charset/collation loading in connection dialog with error handling; added mock implementations and test coverage.
PostgreSQL Dollar-Quote Parsing
src-tauri/src/commands/query.rs, src-tauri/src/db/drivers/postgres.rs, src-tauri/tests/postgres_stateful_command_integration.rs
Implemented parse_dollar_quote_tag() and skip_dollar_quote() helpers to handle PostgreSQL $$...$$ and $tag$...$tag$ quoted strings; updated statement splitting and keyword collection to respect dollar-quoted boundaries; added integration test for PL/pgSQL functions/triggers.
Connection & Driver Utilities
src-tauri/src/connection_input/mod.rs, src-tauri/src/ssh.rs, scripts/test-integration.sh, src-tauri/src/db/drivers/mssql.rs, src-tauri/src/db/drivers/oracle.rs, src/lib/connection-form/rules.ts, src/lib/connection-form/rules.unit.test.ts
Generalized MySQL-family detection using is_mysql_family_driver() predicate; centralized target port resolution with default_target_port(); added StarRocks integration test selection; updated DDL comments for MSSQL; reformatted Oracle driver code; updated connection normalization tests.
UI Components & Error Handling
src/components/ErrorBoundary.tsx, src/App.tsx, src/components/business/DataGrid/ComplexValueViewer.tsx, src/components/business/DataGrid/TableView.tsx, src/components/business/DataGrid/tableView/utils.ts, src/components/business/DataGrid/tableView/utils.unit.test.ts, src/components/settings/SettingsDialog.tsx, src/main.tsx
Added ErrorBoundary component for per-tab error containment; added column comments visibility toggle with persistent settings; implemented header click handler for single-click copy / double-click sort via createSingleAndDoubleClickHandler(); updated table scope resolution to use isMysqlFamilyDriver() predicate; extended UI state and props for new features.
Tauri Configuration & Sidebar
src-tauri/Cargo.toml, src-tauri/src/lib.rs, src/components/business/Sidebar/Sidebar.tsx
Enabled Tauri devtools feature in Cargo manifest; added macOS "Developer" submenu with Reload and Toggle DevTools commands; registered new MySQL command handlers in invoke system; updated sidebar export format type signature.
Integration & Unit Tests
src-tauri/tests/common/shared.rs, src-tauri/tests/oracle_command_integration.rs, src-tauri/tests/oracle_integration.rs, src-tauri/tests/postgres_integration.rs, src-tauri/tests/sqlite_command_integration.rs, src-tauri/tests/api.unit.test.ts
Added test utility constants and helpers (CONNECT_RETRY_ATTEMPTS, init_state_with_local_db); expanded Oracle/PostgreSQL/SQLite command tests for import and DDL handling; added unit test for new MySQL charset/collation APIs; updated assertion formatting and test structure.
Localization
src/lib/i18n/locales/en.ts, src/lib/i18n/locales/ja.ts, src/lib/i18n/locales/zh.ts
Added English/Japanese/Chinese translations for new UI features: column comment visibility toggle, granular SQL export options (exportSqlDml, exportSqlDdl, exportSqlFull), and table header interaction hints/toasts.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as Connection Dialog
    participant API as Frontend API
    participant Tauri as Tauri Command
    participant DB as MySQL/StarRocks
    
    User->>UI: Select MySQL-family driver
    User->>UI: Open "Create Database" dialog
    Note over UI: Load charset/collation options
    UI->>API: getMysqlCharsets(connectionId)
    API->>Tauri: invoke("get_mysql_charsets_by_id", {id})
    Tauri->>DB: SHOW CHARACTER SET
    DB-->>Tauri: charset list
    Tauri-->>API: [charset1, charset2, ...]
    API-->>UI: charsets populated
    
    User->>UI: Select charset from dropdown
    UI->>API: getMysqlCollations(connectionId, charset)
    API->>Tauri: invoke("get_mysql_collations_by_id", {id, charset})
    Tauri->>DB: SHOW COLLATION WHERE Charset = ?
    DB-->>Tauri: collation list
    Tauri-->>API: [collation1, collation2, ...]
    API-->>UI: collations populated & filtered
    
    User->>UI: Create database
    UI-->>User: Database created with selected charset/collation
Loading
sequenceDiagram
    actor User
    participant TableView
    participant ExportAPI
    participant Tauri
    participant FileSystem
    
    User->>TableView: Right-click table → Export
    Note over TableView: New export format options
    alt Export SQL DML
        User->>TableView: Click "exportSqlDml"
        TableView->>ExportAPI: export_table_data(format: "sql_dml")
        ExportAPI->>Tauri: Fetch table rows only
    else Export SQL DDL
        User->>TableView: Click "exportSqlDdl"
        TableView->>ExportAPI: export_table_data(format: "sql_ddl")
        ExportAPI->>Tauri: Fetch table DDL via get_table_ddl()
        Tauri-->>ExportAPI: CREATE TABLE statement
    else Export SQL Full
        User->>TableView: Click "exportSqlFull"
        TableView->>ExportAPI: export_table_data(format: "sql_full")
        ExportAPI->>Tauri: Fetch DDL + rows (do_table_export helper)
    end
    ExportAPI->>FileSystem: Write .sql file
    FileSystem-->>User: Export complete
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly Related PRs

  • Release/260402 #63: Modifies driver-registration, driver-selection, and MySQL-family detection code paths that are extended here for StarRocks; overlapping refactoring of connection drivers and registry utilities.
  • Release/260325 #49: Shares changes to SQL parsing (dollar-quote handling), driver/SSH port logic, and CI workflow setup; likely precursor or parallel work on query parsing enhancements.

Poem

🐰 A rabbit hops through databases with glee,
StarRocks joined the family tree!
Charsets and collations now flow free,
With SQL export in DML, DDL, or decree—
Error boundaries catch the fallibility. 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Release/260408' uses a generic release branch naming convention and does not clearly convey the specific changes in this changeset to a reviewer. Consider using a descriptive title that summarizes the main feature or change, such as 'Add StarRocks database support and refactor SQL export formats' or 'Add StarRocks support with MySQL charset/collation queries'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/260408

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review

Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: CI Success

Failed stage: Check all jobs succeeded [❌]

Failed test name: ""

Failure summary:

The action failed because a bash step explicitly exited with a non-zero code when it detected
failing smoke tests.
- The condition if [ "failure" != "success" ]; then ... exit 1 evaluated true,
printed Smoke tests failed, and terminated the job (exit code 1).

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

28:  Metadata: read
29:  Models: read
30:  Packages: write
31:  Pages: write
32:  PullRequests: write
33:  RepositoryProjects: write
34:  SecurityEvents: write
35:  Statuses: write
36:  ##[endgroup]
37:  Secret source: Actions
38:  Prepare workflow directory
39:  Prepare all required actions
40:  Complete job name: CI Success
41:  ##[group]Run if [ "failure" != "success" ]; then
42:  �[36;1mif [ "failure" != "success" ]; then�[0m
43:  �[36;1m  echo "Smoke tests failed"�[0m
44:  �[36;1m  exit 1�[0m
45:  �[36;1mfi�[0m
46:  �[36;1mif [ "skipped" != "success" ]; then�[0m
47:  �[36;1m  echo "Integration tests failed"�[0m
48:  �[36;1m  exit 1�[0m
49:  �[36;1mfi�[0m
50:  �[36;1mecho "All CI checks passed!"�[0m
51:  shell: /usr/bin/bash -e {0}
52:  ##[endgroup]
53:  Smoke tests failed
54:  ##[error]Process completed with exit code 1.
55:  Cleaning up orphan processes

@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Release 0.3.3 - StarRocks support, SQL export refactoring, and advanced parsing enhancements

✨ Enhancement 🧪 Tests 📝 Documentation

Grey Divider

Walkthroughs

Description
• **StarRocks driver support**: Added comprehensive StarRocks database driver integration with
  MySQL-compatible connection options, custom port defaults (9030), and SSH tunnel configuration
• **SQL export enhancements**: Refactored export logic into reusable do_table_export function and
  split ExportFormat::Sql into three variants (SqlDml, SqlDdl, SqlFull) for granular control
• **Advanced SQL parsing**: Enhanced statement parsing to support MySQL DELIMITER commands, SQLite
  trigger blocks, Oracle PL/SQL blocks with / terminators, and PostgreSQL dollar-quoted strings
• **MySQL charset/collation API**: Added new Tauri commands get_mysql_charsets_by_id and
  get_mysql_collations_by_id with dynamic loading in UI
• **Column comments feature**: Implemented header interaction system with single/double-click
  distinction for copying column names and sorting, plus persistent column comments display setting
• **Developer tools**: Added Developer menu with Reload and Toggle DevTools options for enhanced
  debugging
• **Comprehensive test coverage**: Added integration tests for StarRocks, MySQL delimiter scripts,
  Oracle PL/SQL procedures, SQLite triggers, PostgreSQL functions, and MariaDB charset operations
• **Error handling**: Introduced ErrorBoundary component for graceful error display and added
  StarRocks error handling in transaction SQL import flow
• **UI/UX improvements**: Dynamic MySQL options loading, expanded collation lists for MSSQL and
  PostgreSQL, improved code formatting and accessibility
• **Version bump**: Updated to version 0.3.3 with Bun version pinning to 1.3.10 across CI/CD
  workflows
Diagram
flowchart LR
  A["StarRocks Driver"] -->|"MySQL-compatible"| B["Connection Pool"]
  C["SQL Export"] -->|"Refactored"| D["DML/DDL/Full Variants"]
  E["SQL Parsing"] -->|"Enhanced"| F["MySQL DELIMITER<br/>Oracle PL/SQL<br/>PostgreSQL $quotes<br/>SQLite Triggers"]
  G["MySQL API"] -->|"New Commands"| H["Charsets & Collations"]
  I["UI Features"] -->|"Column Comments<br/>Click Handler"| J["TableView Component"]
  K["Error Handling"] -->|"ErrorBoundary"| L["Graceful Errors"]
  M["Tests"] -->|"Integration Coverage"| N["StarRocks/MySQL/Oracle<br/>PostgreSQL/SQLite/MariaDB"]
Loading

Grey Divider

File Changes

1. src-tauri/src/commands/transfer.rs ✨ Enhancement +876/-219

Refactor export logic and enhance SQL parsing for multiple databases

• Refactored SQL export logic into a new do_table_export function to eliminate code duplication
 between export_table_data and export_table_data_direct
• Split ExportFormat::Sql into three variants: SqlDml, SqlDdl, and SqlFull to support
 separate DDL and DML export modes
• Enhanced SQL statement parsing to support MySQL DELIMITER commands, SQLite trigger blocks, and
 Oracle PL/SQL blocks with proper terminator detection
• Added write_csv_header and write_ddl methods to ExportWriter for better separation of
 concerns
• Added error handling for StarRocks driver in transaction SQL import flow

src-tauri/src/commands/transfer.rs


2. src-tauri/tests/mysql_stateful_command_integration.rs 🧪 Tests +244/-0

Add MySQL delimiter and charset integration tests

• Added integration test for MySQL DELIMITER script import with procedures and triggers
• Added tests for MySQL charset and collation retrieval commands
• Tests verify proper handling of semicolons inside string literals within delimiter blocks

src-tauri/tests/mysql_stateful_command_integration.rs


3. src-tauri/src/commands/connection.rs ✨ Enhancement +168/-4

Add MySQL charset and collation query commands

• Added get_mysql_charsets_by_id and get_mysql_collations_by_id Tauri commands with optional
 charset filtering
• Added corresponding _direct variants for internal use
• Implemented is_safe_option_token validation to prevent SQL injection in charset parameter
• Updated database creation logic to use is_mysql_family_driver helper for consistency

src-tauri/src/commands/connection.rs


View more (51)
4. src-tauri/tests/oracle_command_integration.rs 🧪 Tests +116/-12

Add Oracle PL/SQL import integration test

• Added helper functions for Oracle test state initialization and connection creation
• Added integration test for Oracle PL/SQL procedure import with CREATE OR REPLACE and /
 terminator
• Test verifies proper parsing and execution of Oracle block structures

src-tauri/tests/oracle_command_integration.rs


5. src-tauri/src/db/drivers/mysql.rs ✨ Enhancement +72/-5

Add StarRocks driver support with custom connection options

• Added mysql_family_default_port function to return driver-specific default ports (9030 for
 StarRocks, 3306 for others)
• Updated normalize_mysql_host_and_port to accept driver parameter for correct port defaults
• Added build_connect_options function to configure StarRocks-specific connection options (disable
 SQL mode mutations)
• Updated connection pool creation to use connect_with for custom options

src-tauri/src/db/drivers/mysql.rs


6. src-tauri/tests/sqlite_command_integration.rs 🧪 Tests +116/-1

Add SQLite trigger import integration test

• Added helper functions for SQLite test state initialization and connection creation
• Added integration test for SQLite trigger import with proper semicolon handling inside trigger
 bodies
• Test verifies trigger execution and audit log functionality

src-tauri/tests/sqlite_command_integration.rs


7. src-tauri/src/commands/query.rs ✨ Enhancement +72/-0

Add PostgreSQL dollar-quoted string support

• Added parse_dollar_quote_tag and skip_dollar_quote functions to handle PostgreSQL
 dollar-quoted strings
• Updated is_single_statement, collect_top_level_keywords, and has_top_level_limit to skip
 dollar-quoted blocks
• Added tests for PostgreSQL function definitions with dollar quotes

src-tauri/src/commands/query.rs


8. src-tauri/tests/postgres_stateful_command_integration.rs 🧪 Tests +104/-0

Add PostgreSQL function and trigger import test

• Added integration test for PostgreSQL function and trigger import with dollar-quoted PL/pgSQL code
• Test verifies proper parsing of CREATE OR REPLACE FUNCTION and trigger execution

src-tauri/tests/postgres_stateful_command_integration.rs


9. src-tauri/src/lib.rs ✨ Enhancement +34/-1

Add developer menu and register new commands

• Added Developer menu with Reload and Toggle DevTools options
• Implemented menu event handlers for debug_reload and debug_toggle_devtools
• Registered new Tauri commands for MySQL charset and collation retrieval

src-tauri/src/lib.rs


10. src-tauri/src/db/drivers/postgres.rs ✨ Enhancement +73/-0

Add PostgreSQL dollar-quoted string parsing

• Added parse_dollar_quote_tag and skip_dollar_quote functions to handle PostgreSQL
 dollar-quoted strings
• Updated split_sql_statements to skip dollar-quoted blocks when splitting statements
• Added tests for dollar-quoted function definitions with and without tags

src-tauri/src/db/drivers/postgres.rs


11. src-tauri/tests/starrocks_command_integration.rs 🧪 Tests +103/-0

Add StarRocks command integration tests

• New test file for StarRocks command integration
• Added test for database creation via create_database_by_id_direct
• Includes helper functions for StarRocks connection setup and cleanup

src-tauri/tests/starrocks_command_integration.rs


12. src-tauri/tests/postgres_integration.rs Formatting +33/-7

Reformat assertion formatting for consistency

• Reformatted multi-line assertions for improved readability
• No functional changes to test logic

src-tauri/tests/postgres_integration.rs


13. src-tauri/tests/starrocks_integration.rs 🧪 Tests +120/-0

Add StarRocks database integration tests

• New test file for StarRocks database integration
• Added comprehensive integration test covering database creation, table operations, and data
 retrieval
• Tests verify StarRocks compatibility with MySQL driver interface

src-tauri/tests/starrocks_integration.rs


14. src-tauri/src/db/drivers/oracle.rs Formatting +12/-11

Reformat code for consistency

• Reformatted multi-line code for improved readability
• No functional changes to Oracle driver logic

src-tauri/src/db/drivers/oracle.rs


15. src-tauri/src/ssh.rs ✨ Enhancement +43/-8

Add driver-specific SSH tunnel port defaults

• Added default_target_port function to return driver-specific SSH tunnel target ports
• Updated SSH tunnel configuration to use the new helper function
• Added test for StarRocks default port (9030) validation

src-tauri/src/ssh.rs


16. src-tauri/tests/mariadb_command_integration.rs 🧪 Tests +90/-0

Add MariaDB charset and collation tests

• Added integration tests for MariaDB SHOW CHARACTER SET command
• Added integration test for MariaDB SHOW COLLATION with charset filtering
• Tests verify charset and collation retrieval functionality

src-tauri/tests/mariadb_command_integration.rs


17. src-tauri/tests/common/starrocks_context.rs 🧪 Tests +77/-0

Add StarRocks test context helper module

• New test context module for StarRocks integration tests
• Provides connection form creation from Docker containers or local environment
• Supports environment variable overrides for host, port, user, password, and database

src-tauri/tests/common/starrocks_context.rs


18. src-tauri/src/db/drivers/mod.rs ✨ Enhancement +16/-3

Add MySQL family driver helper function

• Added is_mysql_family_driver helper function to identify MySQL-compatible drivers (mysql,
 mariadb, tidb, starrocks)
• Updated driver connection routing to use the new helper function
• Added test for StarRocks inclusion in MySQL family drivers

src-tauri/src/db/drivers/mod.rs


19. src-tauri/tests/oracle_integration.rs Formatting +10/-15

Reformat code for consistency

• Reformatted multi-line assertions and function calls for improved readability
• No functional changes to Oracle integration tests

src-tauri/tests/oracle_integration.rs


20. src-tauri/src/connection_input/mod.rs ✨ Enhancement +17/-2

Update connection normalization for MySQL family drivers

• Updated connection form normalization to use is_mysql_family_driver helper
• Added test for StarRocks embedded port parsing
• Ensures consistent handling of MySQL-family drivers including StarRocks

src-tauri/src/connection_input/mod.rs


21. src-tauri/tests/common/shared.rs Miscellaneous +3/-0

Add dead code annotations to test utilities

• Added #[allow(dead_code)] attributes to unused constants and functions
• No functional changes to shared test utilities

src-tauri/tests/common/shared.rs


22. src-tauri/src/db/drivers/mssql.rs 📝 Documentation +4/-1

Add DDL reconstruction limitation comment

• Enhanced DDL reconstruction to include informational comment about limitations
• Comment notes that foreign keys, unique constraints, check constraints, and indexes are not
 included

src-tauri/src/db/drivers/mssql.rs


23. src/lib/connection-form/rules.ts Formatting +1/-4

Clean up import statement formatting

• Removed unnecessary line breaks in import statement
• Improved code formatting consistency

src/lib/connection-form/rules.ts


24. src/components/business/DataGrid/tableView/utils.unit.test.ts 🧪 Tests +105/-12

StarRocks support and click handler tests

• Added import for createSingleAndDoubleClickHandler function
• Added test cases for StarRocks database support in formatSQLValue, getQualifiedTableName, and
 quoteIdent functions
• Added comprehensive test suite for createSingleAndDoubleClickHandler covering single-click,
 double-click, and cancellation scenarios
• Reformatted existing test code for improved readability with better line breaks

src/components/business/DataGrid/tableView/utils.unit.test.ts


25. src/services/mocks.ts ✨ Enhancement +125/-11

MySQL charset and collation mock functions

• Added mockGetMysqlCharsets function returning list of MySQL character sets
• Added mockGetMysqlCollations function returning MySQL collations filtered by charset
• Registered new mock commands in invokeMock for charset and collation retrieval
• Reformatted mock data objects for improved code readability

src/services/mocks.ts


26. src/lib/driver-registry.unit.test.ts 🧪 Tests +14/-2

StarRocks driver registry tests

• Updated driver count from 9 to 10 to include StarRocks
• Added StarRocks assertions to multiple test cases including getDriverConfig, getDefaultPort,
 isMysqlFamilyDriver, supportsSSLCA, supportsCreateDatabase, and supportsSchemaBrowsing
• Added test for StarRocks import capability being unsupported

src/lib/driver-registry.unit.test.ts


27. src/services/mocks.service.test.ts 🧪 Tests +100/-1

MySQL charset and collation service tests

• Added imports for mockGetMysqlCharsets and mockGetMysqlCollations functions
• Added test suite for mockGetMysqlCharsets validating charset list content and format
• Added test suite for mockGetMysqlCollations validating collation filtering by charset
• Added tests for invokeMock command mapping for charset and collation retrieval

src/services/mocks.service.test.ts


28. src/components/business/Sidebar/connection-list/helpers.unit.test.ts 🧪 Tests +45/-2

Export helper function tests

• Added import and test suite for getExportDefaultName function with multiple format types
• Updated export filter tests to use specific SQL format types (sql_dml, sql_ddl, sql_full)
 instead of generic sql

src/components/business/Sidebar/connection-list/helpers.unit.test.ts


29. src/services/api.unit.test.ts 🧪 Tests +27/-3

API tests for StarRocks and MySQL options

• Added StarRocks to normalizeImportDriver test cases
• Added test for StarRocks import capability being unsupported
• Added new API command mappings for get_mysql_charsets_by_id and get_mysql_collations_by_id
• Reformatted test code for improved readability

src/services/api.unit.test.ts


30. src/lib/i18n/locales/ja.ts 📝 Documentation +17/-1

Japanese i18n translations for data grid features

• Added new dataGrid settings section with column comments display option
• Split exportSql into three separate options: exportSqlDml, exportSqlDdl, and exportSqlFull
• Added new tableView section with header action hints and column copy toast messages

src/lib/i18n/locales/ja.ts


31. src/lib/connection-form/rules.unit.test.ts 🧪 Tests +7/-4

Connection form rules tests for StarRocks

• Added StarRocks test cases to isMysqlFamilyDriver, allowsHostWithPort, and
 requiresPasswordOnCreate tests
• Updated normalizeConnectionFormInput test to use StarRocks with port 9031 instead of MySQL

src/lib/connection-form/rules.unit.test.ts


32. src/components/business/DataGrid/tableView/utils.ts ✨ Enhancement +40/-4

Click handler utility and MySQL family refactoring

• Added import for isMysqlFamilyDriver utility function
• Added HeaderInteractionState interface for managing header click state
• Added createSingleAndDoubleClickHandler function to handle single and double click events with
 configurable delay
• Refactored quoteIdent and getQualifiedTableName to use isMysqlFamilyDriver for cleaner MySQL
 family detection

src/components/business/DataGrid/tableView/utils.ts


33. src/lib/i18n/locales/zh.ts 📝 Documentation +17/-1

Chinese i18n translations for data grid features

• Added new dataGrid settings section with column comments display option in Chinese
• Split exportSql into three separate options: exportSqlDml, exportSqlDdl, and exportSqlFull
• Added new tableView section with header action hints and column copy toast messages in Chinese

src/lib/i18n/locales/zh.ts


34. src/lib/i18n/locales/en.ts 📝 Documentation +17/-1

English i18n translations for data grid features

• Added new dataGrid settings section with column comments display option
• Split exportSql into three separate options: exportSqlDml, exportSqlDdl, and exportSqlFull
• Added new tableView section with header action hints and column copy toast messages

src/lib/i18n/locales/en.ts


35. src/services/api.ts ✨ Enhancement +10/-1

API type and method updates

• Updated TransferFormat type to include sql_dml, sql_ddl, and sql_full instead of generic
 sql
• Added getMysqlCharsets and getMysqlCollations methods to connections API

src/services/api.ts


36. scripts/test-integration.sh 🧪 Tests +5/-1

StarRocks integration test support

• Added StarRocks integration test cases to the test runner
• Updated error message to include StarRocks in the list of valid database options

scripts/test-integration.sh


37. src/components/business/DataGrid/TableView.tsx ✨ Enhancement +146/-58

Header interaction and column comments feature

• Added import for createSingleAndDoubleClickHandler utility
• Added showColumnComments prop to display column comments in table headers
• Implemented header click handler for copying column names and sorting with single/double-click
 distinction
• Added refs for managing column widths and header click states
• Enhanced header rendering with column comments display and improved accessibility
• Added DDL button to toolbar and reorganized export menu options to use new SQL format types
• Added null check for row data in table body rendering
• Reformatted code for improved readability

src/components/business/DataGrid/TableView.tsx


38. src/components/business/Sidebar/ConnectionList.tsx ✨ Enhancement +207/-23

Dynamic MySQL options and expanded collation support

• Replaced hardcoded MySQL charset/collation options with dynamic loading from API
• Added state management for mysqlCharsets, mysqlCollations, and loadingMysqlOptions
• Added effects to fetch charset and collation options when create database dialog opens
• Expanded MSSQL collation options list significantly
• Expanded PostgreSQL encoding options list
• Updated export format handling to use new SQL format types (sql_dml, sql_ddl, sql_full)
• Refactored MySQL family detection to use isMysqlFamilyDriver utility

src/components/business/Sidebar/ConnectionList.tsx


39. src/App.tsx ✨ Enhancement +128/-119

Error boundary and column comments integration

• Added ErrorBoundary component import and wrapping around tab content
• Added isMysqlFamilyDriver import for cleaner driver detection
• Added showColumnComments state management
• Refactored MySQL family driver detection to use utility function
• Updated export format handling to use new SQL format types
• Passed showColumnComments prop to TableView component
• Added settings dialog props for column comments toggle

src/App.tsx


40. src/components/business/DataGrid/ComplexValueViewer.tsx Formatting +45/-14

Code formatting improvements

• Reformatted code for improved readability with better line breaks and indentation
• No functional changes to the component logic

src/components/business/DataGrid/ComplexValueViewer.tsx


41. src/components/settings/SettingsDialog.tsx ✨ Enhancement +28/-1

Column comments setting in preferences

• Added showColumnComments and onShowColumnCommentsChange props to settings dialog
• Added state management for column comments toggle
• Added UI section for column comments setting with toggle switch
• Integrated column comments setting with persistent storage via saveSetting

src/components/settings/SettingsDialog.tsx


42. .github/workflows/release.yml ⚙️ Configuration changes +1/-30

Bun version pinning

• Pinned Bun version to 1.3.10 instead of using latest

.github/workflows/release.yml


43. src/lib/driver-registry.tsx ✨ Enhancement +16/-1

StarRocks driver registration

• Added starrocks to DRIVER_IDS array
• Added StarRocks driver configuration with port 9030, MySQL family support, and unsupported import
 capability
• Reformatted getConnectionIcon function for improved readability

src/lib/driver-registry.tsx


44. src/components/ErrorBoundary.tsx Error handling +47/-0

Error boundary component creation

• Created new error boundary component to catch and display render errors
• Implements React error boundary pattern with custom error UI
• Logs errors to console for debugging

src/components/ErrorBoundary.tsx


45. src/components/business/Editor/SqlEditor.tsx ✨ Enhancement +3/-1

StarRocks SQL editor support

• Added StarRocks to SQL syntax highlighting language mapping (maps to MySQL)
• Added StarRocks case to SQL language selection logic
• Updated export format handling to use sql_dml instead of generic sql

src/components/business/Editor/SqlEditor.tsx


46. src/components/business/Sidebar/Sidebar.tsx ✨ Enhancement +5/-2

Export format type updates

• Updated export format type signature to include new SQL format types (sql_dml, sql_ddl,
 sql_full)
• Reformatted TabsTrigger component for improved readability

src/components/business/Sidebar/Sidebar.tsx


47. src/components/business/Sidebar/connection-list/helpers.tsx ✨ Enhancement +6/-3

Export helper functions update

• Updated getExportDefaultName to map new SQL format types to .sql extension
• Updated getExportFilter function signature to accept new SQL format types

src/components/business/Sidebar/connection-list/helpers.tsx


48. src/main.tsx ✨ Enhancement +10/-7

Error boundary and context menu enhancement

• Added ErrorBoundary component wrapping the entire app
• Enhanced context menu prevention to also check for altKey modifier
• Reformatted code for improved readability

src/main.tsx


49. .github/workflows/upgradelink-upload.yml ⚙️ Configuration changes +29/-0

UpgradeLink release upload workflow

• Created new workflow for uploading releases to UpgradeLink service
• Accepts release tag as input parameter
• Uses UpgradeLink action to upload latest.json for Tauri app updates

.github/workflows/upgradelink-upload.yml


50. .github/workflows/ci.yml ⚙️ Configuration changes +2/-2

Bun version pinning in CI

• Pinned Bun version to 1.3.10 in multiple workflow steps instead of using latest

.github/workflows/ci.yml


51. src-tauri/Cargo.toml Dependencies +1/-1

Tauri devtools feature

• Added devtools feature to Tauri dependency for development debugging

src-tauri/Cargo.toml


52. package.json ⚙️ Configuration changes +1/-1

Version bump

• Bumped version from 0.3.2 to 0.3.3

package.json


53. src-tauri/tauri.conf.json ⚙️ Configuration changes +1/-1

Version bump

• Updated version from 0.3.2 to 0.3.3

src-tauri/tauri.conf.json


54. .github/workflows/build-multiplatform.yml ⚙️ Configuration changes +1/-1

Bun version pinning in build

• Pinned Bun version to 1.3.10 instead of using latest

.github/workflows/build-multiplatform.yml


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Apr 10, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3)   📘 Rule violations (1)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (2) ➹ Performance (1)
📘\ ☼ Reliability (1)

Grey Divider


Action required

1. build_connect_options() bypasses conn_failed_error() 📘
Description
build_connect_options() maps DSN parse failures to a raw [CONN_FAILED] {e} string instead of
using conn_failed_error(), producing inconsistent and less helpful connection-failure messaging.
This breaks the required standardized, hint-augmented error format for connection failures.
Code

src-tauri/src/db/drivers/mysql.rs[R174-176]

+fn build_connect_options(dsn: &str, driver: &str) -> Result<MySqlConnectOptions, String> {
+    let mut options =
+        MySqlConnectOptions::from_str(dsn).map_err(|e| format!("[CONN_FAILED] {e}"))?;
Evidence
PR Compliance ID 4 requires connection failure paths to use conn_failed_error() for consistent,
user-friendly messages. The changed code in mysql.rs returns [CONN_FAILED] {e} directly for
connect-options parsing errors rather than calling conn_failed_error().

CLAUDE.md
src-tauri/src/db/drivers/mysql.rs[174-176]
src-tauri/src/db/drivers/mod.rs[26-75]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src-tauri/src/db/drivers/mysql.rs` returns a generic `[CONN_FAILED] {e}` string when parsing MySQL connection options fails, instead of using the standardized `conn_failed_error()` helper.

## Issue Context
Compliance requires consistent, hint-augmented connection failure messages generated via `conn_failed_error()`.

## Fix Focus Areas
- src-tauri/src/db/drivers/mysql.rs[174-176]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Delimiter alloc per character 🐞
Description
parse_sql_statements() allocates a new Vec<char> for the current delimiter on every loop iteration,
causing excessive allocations and potentially making large SQL imports extremely slow or appear
hung. This is on the hot path for SQL import and is amplified by the 20MB file-size allowance.
Code

src-tauri/src/commands/transfer.rs[R1373-1376]

                let ch = chars[i];
                let next = chars.get(i + 1).copied();
+                let delimiter_chars: Vec<char> = delimiter.chars().collect();
+
Evidence
The import splitter runs a while-loop over every character in the SQL file, but reconstructs
delimiter_chars via allocation each iteration; with MAX_IMPORT_FILE_SIZE_BYTES set to 20MB this
can lead to millions of allocations in a single import.

src-tauri/src/commands/transfer.rs[11-13]
src-tauri/src/commands/transfer.rs[1334-1400]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`parse_sql_statements()` allocates `delimiter_chars: Vec<char>` inside the per-character scan loop, causing massive allocation overhead for large SQL files.

### Issue Context
This function is used by SQL import planning; imports allow up to 20MB, so the current implementation can trigger millions of allocations.

### Fix Focus Areas
- src-tauri/src/commands/transfer.rs[1334-1400]

### Implementation notes
- Move `delimiter_chars` out of the loop (e.g., `let mut delimiter_chars = vec![';'];`).
- When a MySQL `DELIMITER` command is parsed and `delimiter` changes, also refresh `delimiter_chars = delimiter.chars().collect()`.
- Inside the loop, use the cached `delimiter_chars` without reallocating.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. DELIMITER keyword case-sensitive 🐞
Description
parse_mysql_delimiter_command() only recognizes uppercase "DELIMITER", so scripts using
lowercase/mixed-case (e.g., "delimiter $$") won’t update the delimiter and statement splitting can
break. This can cause otherwise valid MySQL import scripts to be parsed into incorrect statements.
Code

src-tauri/src/commands/transfer.rs[R964-967]

+    let keyword: Vec<char> = "DELIMITER".chars().collect();
+    if !starts_with_chars(chars, cursor, &keyword) {
+        return None;
+    }
Evidence
The delimiter parser compares the input against an uppercase literal using a case-sensitive
character match. Elsewhere in the same module, keyword parsing is explicitly case-insensitive (e.g.,
MSSQL GO detection), indicating this should likely be case-insensitive too.

src-tauri/src/commands/transfer.rs[954-967]
src-tauri/src/commands/transfer.rs[725-731]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`parse_mysql_delimiter_command()` only matches the exact uppercase token `DELIMITER`, so `delimiter` / `Delimiter` lines are ignored and parsing can produce wrong statement boundaries.

### Issue Context
MySQL import splitting relies on `DELIMITER` lines to handle procedures/triggers; failing to detect them breaks statement parsing.

### Fix Focus Areas
- src-tauri/src/commands/transfer.rs[954-1003]

### Implementation notes
- Replace the case-sensitive `starts_with_chars(..., "DELIMITER")` check with an ASCII case-insensitive comparison.
- Prefer a non-allocating helper (e.g., `starts_with_chars_ignore_ascii_case(chars, idx, "DELIMITER")`).
- Keep existing behavior that requires the token to appear at the (whitespace-trimmed) start of the line.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. StarRocks SQL export quoting 🐞
Description
StarRocks is now classified as a MySQL-family driver, but Rust SQL export still quotes identifiers
as MySQL-family only for mysql/mariadb/tidb (not starrocks). This makes SQL export formatting
inconsistent across the app’s MySQL-family codepaths and can produce unexpected identifier quoting
for StarRocks exports.
Code

src-tauri/src/db/drivers/mod.rs[R22-24]

+pub fn is_mysql_family_driver(driver: &str) -> bool {
+    matches!(driver, "mysql" | "mariadb" | "tidb" | "starrocks")
+}
Evidence
The PR explicitly adds StarRocks to the MySQL-family set, and the frontend quotes MySQL-family
identifiers using backticks. However, the backend SQL export quote_ident() does not include
starrocks in its MySQL-family/backtick branch, so StarRocks exports will be quoted differently than
other MySQL-family flows in the repo.

src-tauri/src/db/drivers/mod.rs[22-24]
src/components/business/DataGrid/tableView/utils.ts[177-187]
src-tauri/src/commands/transfer.rs[1806-1817]
src/lib/driver-registry.tsx[106-117]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Backend SQL export identifier quoting (`quote_ident`) does not treat `starrocks` as MySQL-family even though the PR classifies StarRocks as MySQL-family elsewhere.

### Issue Context
- Rust driver layer: `is_mysql_family_driver()` includes `starrocks`.
- Frontend SQL building/quoting for MySQL-family uses backticks.
- Backend SQL export currently backticks only mysql/mariadb/tidb/clickhouse.

### Fix Focus Areas
- src-tauri/src/commands/transfer.rs[1806-1817]
- src-tauri/src/db/drivers/mod.rs[22-24]

### Implementation notes
- Update `quote_ident()` to also treat `starrocks` as backtick-quoted (e.g., add `|| driver.eq_ignore_ascii_case("starrocks")`).
- Optionally, centralize the logic by reusing `is_mysql_family_driver` (ensure case-insensitive handling by normalizing before calling).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +174 to +176
fn build_connect_options(dsn: &str, driver: &str) -> Result<MySqlConnectOptions, String> {
let mut options =
MySqlConnectOptions::from_str(dsn).map_err(|e| format!("[CONN_FAILED] {e}"))?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. build_connect_options() bypasses conn_failed_error() 📘 Rule violation ☼ Reliability

build_connect_options() maps DSN parse failures to a raw [CONN_FAILED] {e} string instead of
using conn_failed_error(), producing inconsistent and less helpful connection-failure messaging.
This breaks the required standardized, hint-augmented error format for connection failures.
Agent Prompt
## Issue description
`src-tauri/src/db/drivers/mysql.rs` returns a generic `[CONN_FAILED] {e}` string when parsing MySQL connection options fails, instead of using the standardized `conn_failed_error()` helper.

## Issue Context
Compliance requires consistent, hint-augmented connection failure messages generated via `conn_failed_error()`.

## Fix Focus Areas
- src-tauri/src/db/drivers/mysql.rs[174-176]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 1373 to +1376
let ch = chars[i];
let next = chars.get(i + 1).copied();
let delimiter_chars: Vec<char> = delimiter.chars().collect();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Delimiter alloc per character 🐞 Bug ➹ Performance

parse_sql_statements() allocates a new Vec<char> for the current delimiter on every loop iteration,
causing excessive allocations and potentially making large SQL imports extremely slow or appear
hung. This is on the hot path for SQL import and is amplified by the 20MB file-size allowance.
Agent Prompt
### Issue description
`parse_sql_statements()` allocates `delimiter_chars: Vec<char>` inside the per-character scan loop, causing massive allocation overhead for large SQL files.

### Issue Context
This function is used by SQL import planning; imports allow up to 20MB, so the current implementation can trigger millions of allocations.

### Fix Focus Areas
- src-tauri/src/commands/transfer.rs[1334-1400]

### Implementation notes
- Move `delimiter_chars` out of the loop (e.g., `let mut delimiter_chars = vec![';'];`).
- When a MySQL `DELIMITER` command is parsed and `delimiter` changes, also refresh `delimiter_chars = delimiter.chars().collect()`.
- Inside the loop, use the cached `delimiter_chars` without reallocating.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src-tauri/src/connection_input/mod.rs (1)

57-62: ⚠️ Potential issue | 🟡 Minor

Re-validate port after parsing embedded host:port.

Line 53 validates form.port before parsing, but Line 59 can overwrite it with an embedded value. db:70000 currently bypasses range checks.

🛠️ Proposed fix
     if crate::db::drivers::is_mysql_family_driver(&driver) {
         if let Some(host) = form.host.clone() {
             let (normalized_host, normalized_port) = parse_host_embedded_port(&host, form.port);
             form.host = Some(normalized_host);
             form.port = normalized_port.or(form.port);
+            validate_port_range("port", form.port)?;
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/connection_input/mod.rs` around lines 57 - 62, After parsing an
embedded host:port via parse_host_embedded_port in the is_mysql_family_driver
branch, re-run the port range validation on the potentially updated form.port
(the value assigned to form.port after parse_host_embedded_port) and reject or
clear values that fall outside the valid TCP port range (1–65535); update the
code that originally validated form.port before parsing to also validate the
post-parse value so inputs like "db:70000" do not bypass checks. Ensure you
reference the same validation logic (or helper) when validating form.port after
parse_host_embedded_port to keep behavior consistent with the initial check on
form.port.
🧹 Nitpick comments (11)
src-tauri/src/commands/query.rs (1)

79-110: Extract dollar-quote parser helpers into shared SQL utility.

parse_dollar_quote_tag/skip_dollar_quote are now duplicated with src-tauri/src/db/drivers/postgres.rs; centralizing avoids parser drift between command guards and driver splitting logic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/commands/query.rs` around lines 79 - 110,
parse_dollar_quote_tag and skip_dollar_quote are duplicated; extract their logic
into a shared SQL utility module (e.g., create a new module like
sql::dollar_quote) and move the implementations there, then replace the local
functions in src-tauri/src/commands/query.rs (parse_dollar_quote_tag,
skip_dollar_quote) and the duplicate in src-tauri/src/db/drivers/postgres.rs to
call the shared helpers instead; ensure the shared functions keep the same
signatures (accepting &[u8] and usize) and update imports/usages accordingly so
both command guards and driver parsing use the single centralized
implementation.
src-tauri/tests/common/shared.rs (1)

8-11: Remove redundant #[allow(dead_code)] on active retry helpers.

These items are already used; keeping suppression here weakens dead-code signal for future changes.

🧹 Proposed patch
-#[allow(dead_code)]
 const CONNECT_RETRY_ATTEMPTS: usize = 20;
-#[allow(dead_code)]
 const CONNECT_RETRY_DELAY_MS: u64 = 500;
@@
-#[allow(dead_code)]
 pub async fn connect_with_retry<T, F, Fut>(mut connect: F) -> T

Also applies to: 93-94

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/tests/common/shared.rs` around lines 8 - 11, Remove the redundant
#[allow(dead_code)] attributes from the active retry helper constants
CONNECT_RETRY_ATTEMPTS and CONNECT_RETRY_DELAY_MS by deleting the attribute
lines immediately above those const declarations; also remove the same
#[allow(dead_code)] suppression from any other retry-related constants in this
module (the other retry helper constants) so that dead-code warnings remain
meaningful for future changes.
src/components/business/Sidebar/Sidebar.tsx (1)

42-43: Use shared export format type instead of inline union.

Defining the format union inline here can drift from src/services/api.ts. Prefer reusing the shared TransferFormat type.

♻️ Proposed refactor
-import { ConnectionForm, SavedQuery } from "@/services/api";
+import { ConnectionForm, SavedQuery, type TransferFormat } from "@/services/api";
...
-    format: "csv" | "json" | "sql_dml" | "sql_ddl" | "sql_full",
+    format: TransferFormat,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/business/Sidebar/Sidebar.tsx` around lines 42 - 43, Replace
the inline union type for the "format" prop with the shared TransferFormat type
from src/services/api.ts: import TransferFormat into Sidebar (or the module
where the prop/type is declared) and change the property signature from format:
"csv" | "json" | "sql_dml" | "sql_ddl" | "sql_full" to format: TransferFormat;
ensure any usages of format (e.g., in Sidebar component, prop interfaces or
function signatures) compile after updating the import.
src/App.tsx (2)

1709-1730: Duplicate schema derivation logic.

The schema derivation logic at lines 1717-1725 duplicates the resolveTableScope function defined at lines 185-204. Consider reusing resolveTableScope to maintain consistency and reduce duplication.

♻️ Suggested refactor to reuse resolveTableScope
                             tableContext={
                               tab.connectionId &&
                               tab.database &&
                               tab.tableName &&
                               tab.driver
                                 ? {
                                     connectionId: tab.connectionId,
                                     database: tab.database,
-                                    schema:
-                                      isMysqlFamilyDriver(tab.driver as any) ||
-                                      tab.driver === "clickhouse"
-                                        ? tab.database
-                                        : tab.driver === "mssql"
-                                          ? "dbo"
-                                          : tab.driver === "duckdb"
-                                            ? "main"
-                                            : "public",
+                                    schema: resolveTableScope(
+                                      tab.driver,
+                                      tab.database,
+                                      tab.schema,
+                                    ).schema,
                                     table: tab.tableName,
                                     driver: tab.driver,
                                   }
                                 : undefined
                             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/App.tsx` around lines 1709 - 1730, The inline schema derivation
duplicates resolveTableScope; update the tableContext construction for the tab
(where tableContext is set) to call the existing resolveTableScope function
instead of reimplementing the conditional chain: pass the tab.driver and
tab.database (and any other expected params) into resolveTableScope to obtain
the schema/scope, then use that returned value for the schema field while
keeping the other fields (connectionId, database, table, driver) as before; this
will eliminate the duplicated logic and keep behavior consistent with
resolveTableScope.

190-191: Type cast as any bypasses type safety.

The cast isMysqlFamilyDriver(driver as any) bypasses TypeScript's type checking. Since driver is a string but isMysqlFamilyDriver expects Driver, consider adding a type guard to maintain type safety.

♻️ Optional: Add a safe wrapper in driver-registry
// In src/lib/driver-registry.tsx
export const isMysqlFamilyDriverSafe = (driver: string | undefined): boolean => {
  const config = DRIVER_REGISTRY.find((d) => d.id === driver);
  return config?.isMysqlFamily ?? false;
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/App.tsx` around lines 190 - 191, The current expression using a type cast
bypasses type safety: replace the as any cast by adding a safe string-based
guard and using it in the isDatabaseScoped calculation; implement a helper like
isMysqlFamilyDriverSafe(driver: string | undefined) in driver-registry that
looks up DRIVER_REGISTRY by id and returns config?.isMysqlFamily ?? false,
export it, then update the isDatabaseScoped computation to use
isMysqlFamilyDriverSafe(driver) || driver === "clickhouse" (referencing the
isDatabaseScoped variable and isMysqlFamilyDriver/isMysqlFamilyDriverSafe
helpers to locate the code).
src/components/ErrorBoundary.tsx (1)

14-46: Consider adding a reset mechanism for error recovery.

The ErrorBoundary implementation is correct, but once an error is caught, there's no way to reset the error state. This means if a tab errors, the user must close and reopen it. Consider adding a key-based reset or a "Try Again" button.

♻️ Optional: Add reset capability
 interface Props {
   children: ReactNode;
   /** Custom fallback rendered instead of the default error UI. */
   fallback?: ReactNode;
+  /** Key to reset error state when changed. */
+  resetKey?: string | number;
 }

 interface State {
   error: Error | null;
 }

 export class ErrorBoundary extends Component<Props, State> {
   state: State = { error: null };

   static getDerivedStateFromError(error: Error): State {
     return { error };
   }

+  componentDidUpdate(prevProps: Props) {
+    if (this.state.error && prevProps.resetKey !== this.props.resetKey) {
+      this.setState({ error: null });
+    }
+  }
+
   componentDidCatch(error: Error, info: ErrorInfo) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/ErrorBoundary.tsx` around lines 14 - 46, ErrorBoundary
currently sets error in getDerivedStateFromError and never clears it, preventing
recovery; add a reset mechanism by introducing a resetErrorBoundary method that
sets state.error back to null and call it from either (a) a "Try Again" button
rendered when this.props.fallback is absent or (b) when a new resetKey prop
changes (watch resetKey in componentDidUpdate to clear error). Update render to
show a small "Try Again" button alongside the error UI that invokes
resetErrorBoundary, and expose resetErrorBoundary as a public method if parent
components should trigger resets programmatically; modify Prop types to include
optional fallback and optional resetKey as needed.
src-tauri/tests/common/starrocks_context.rs (2)

22-30: Consider increasing the WaitFor timeout for StarRocks.

StarRocks can take longer than 20 seconds to fully initialize. While wait_for_port has a 120-second timeout, the container's WaitFor::seconds(20) might cause premature port exposure before the service is ready. Consider increasing this or using a more robust readiness check if tests become flaky.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/tests/common/starrocks_context.rs` around lines 22 - 30, The
current GenericImage construction uses WaitFor::seconds(20) which may be too
short for StarRocks; update the readiness handling by increasing the wait
timeout (e.g., to 120s or higher) on the with_wait_for call (replace
WaitFor::seconds(20) with a larger value) or replace the simple seconds-based
wait with a more robust readiness check (e.g., waiting for a specific log line
or a successful TCP response) so that GenericImage::with_wait_for/WaitFor usage
aligns with the longer shared::wait_for_port(Duration::from_secs(120)) check.

44-56: Redundant environment override call.

starrocks_form_from_local_env already reads from environment variables (lines 47-51), then apply_starrocks_env_overrides is called again on line 54. Since apply_starrocks_env_overrides checks the same environment variables, this second call is redundant.

♻️ Suggested fix
 fn starrocks_form_from_local_env() -> ConnectionForm {
     let mut form = ConnectionForm {
         driver: "starrocks".to_string(),
         host: Some(shared::env_or("STARROCKS_HOST", "localhost")),
         port: Some(shared::env_i64("STARROCKS_PORT", 9030)),
         username: Some(shared::env_or("STARROCKS_USER", "root")),
         password: Some(shared::env_or("STARROCKS_PASSWORD", "")),
         database: env::var("STARROCKS_DB").ok(),
         ..Default::default()
     };
-    apply_starrocks_env_overrides(&mut form);
     form
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/tests/common/starrocks_context.rs` around lines 44 - 56, The
function starrocks_form_from_local_env currently constructs ConnectionForm by
reading environment variables directly and then redundantly calls
apply_starrocks_env_overrides(&mut form); remove that redundant call (or
alternatively initialize form with Default::default() and let
apply_starrocks_env_overrides populate fields) so that only one path reads and
applies the STARROCKS_* environment variables; update
starrocks_form_from_local_env to either rely solely on the inline
env_or/env_i64/env::var assignments or solely on apply_starrocks_env_overrides,
and delete the extra apply_starrocks_env_overrides invocation accordingly.
src/components/business/DataGrid/tableView/utils.ts (2)

177-188: Consider typing the driver parameter to avoid as any cast.

The as any cast suggests a type mismatch between the function parameter and what isMysqlFamilyDriver expects. Consider updating the parameter type or the isMysqlFamilyDriver function signature to accept the same type.

♻️ Suggested improvement
-export function quoteIdent(driver: string | undefined, name: string): string {
+export function quoteIdent(driver: string | undefined | null, name: string): string {
   if (
-    (driver && isMysqlFamilyDriver(driver as any)) ||
+    (driver && isMysqlFamilyDriver(driver)) ||
     driver === "clickhouse"
   ) {

This would require updating isMysqlFamilyDriver to accept string instead of a more restricted type.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/business/DataGrid/tableView/utils.ts` around lines 177 - 188,
The quoteIdent function uses an unsafe cast `as any` because the driver
parameter's type doesn't match isMysqlFamilyDriver's expected type; update the
signature of quoteIdent(driver: string | undefined, name: string) to use the
exact type isMysqlFamilyDriver accepts (or change isMysqlFamilyDriver to accept
string | undefined) so you can call isMysqlFamilyDriver(driver) without casting,
then remove the `as any` cast in quoteIdent and adjust any callers if needed;
reference the quoteIdent function and isMysqlFamilyDriver to locate and align
their types.

280-287: Same type cast issue as in quoteIdent.

This is the same as any pattern. Consider addressing both locations together.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/business/DataGrid/tableView/utils.ts` around lines 280 - 287,
The getQualifiedTableName function uses an unsafe "as any" cast when calling
isMysqlFamilyDriver (same issue exists in quoteIdent); fix by aligning types
instead of casting—either change the driver parameter type on
getQualifiedTableName and quoteIdent to the proper DriverType/enum used across
the module or update isMysqlFamilyDriver's signature to accept a string (or the
actual driver type) so you can call isMysqlFamilyDriver(driver) without casting;
remove the "as any" casts and adjust imports/types accordingly so the call sites
and helper signatures share a consistent driver type.
src-tauri/tests/postgres_stateful_command_integration.rs (1)

819-823: Make touch_count assertion type-robust

At Line 819, the test assumes c is always a string. If query decoding returns a numeric JSON value, this panics even when behavior is correct.

Suggested patch
-    let count = verify.data[0]["c"]
-        .as_str()
-        .and_then(|v| v.parse::<i64>().ok())
-        .expect("touch_count should parse");
+    let count = verify.data[0]["c"]
+        .as_i64()
+        .or_else(|| verify.data[0]["c"].as_str().and_then(|v| v.parse::<i64>().ok()))
+        .expect("touch_count should parse");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/tests/postgres_stateful_command_integration.rs` around lines 819 -
823, The test assumes verify.data[0]["c"] is a string; make the extraction
robust to both string and numeric JSON by matching the serde_json::Value: if
it's a string, parse to i64, if it's a number use as_i64() (or as_u64() then
cast) and then assert_eq!(count, 2). Update the code around verify.data[0]["c"]
in the test (the touch_count assertion) to handle Value::String and
Value::Number branches and produce a single i64 `count` for the assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/upgradelink-upload.yml:
- Line 18: The workflow currently references the third-party action by a mutable
tag "uses: toolsetlink/upgradelink-action@3.0.2"; replace that tag with the
action's immutable full commit SHA (e.g., "uses:
toolsetlink/upgradelink-action@<full-commit-sha>") to prevent retargeting—locate
the action repo, copy the commit SHA for the desired release, and update the
workflow entry that mentions toolsetlink/upgradelink-action accordingly.

In `@scripts/test-integration.sh`:
- Around line 42-45: The integration matrix omits StarRocks when IT_DB=all;
update the script so the "all" case triggers the StarRocks tests by adding the
same run_integration_test calls used in the starrocks) case. Locate the case or
switch that handles IT_DB="all" in scripts/test-integration.sh and add
run_integration_test "starrocks_integration" and run_integration_test
"starrocks_command_integration" alongside the other DB entries so full CI runs
include the new driver path; use the existing run_integration_test invocation
pattern to ensure consistent behavior.

In `@src-tauri/Cargo.toml`:
- Line 21: Remove the unconditional "devtools" dependency feature from the tauri
dependency entry in Cargo.toml and instead declare a Cargo feature named
"devtools" that enables the tauri/devtools dependency feature; specifically,
stop listing features = ["devtools"] on the tauri dependency and add a
[features] section where devtools = ["tauri/devtools"], so devtools is only
activated when building with --features devtools (and update your dev/local
build commands to pass --features devtools as needed).

In `@src-tauri/src/commands/connection.rs`:
- Around line 422-479: Both get_mysql_charsets_by_id and
get_mysql_collations_by_id must reject non-MySQL drivers up-front like the
create_database_by_id* handlers do: inside the execute_with_retry closure (or
before calling it) check the driver's family and return Err("[UNSUPPORTED] This
operation is only supported for MySQL connections") when it is not
DriverFamily::Mysql. Reference the functions get_mysql_charsets_by_id and
get_mysql_collations_by_id, the existing execute_with_retry helper, and mirror
the driver-family guard pattern used in create_database_by_id* so non-MySQL
connection ids produce the predictable [UNSUPPORTED] error instead of raw SQL
errors.

In `@src-tauri/src/commands/transfer.rs`:
- Around line 297-298: Reject ExportFormat::SqlDdl early in the query-export
entry points so we return a proper error instead of letting ExportWriter later
hit the unreachable! panic: add a guard that checks for ExportFormat::SqlDdl and
returns an Err (or Tauri command error) before constructing ExportWriter or
calling write_csv_header; apply the same check in the other query-export sites
that create ExportWriter (the callsite that uses write_csv_header and the other
locations around the code that pass ExportFormat::SqlDdl at the spots
corresponding to lines 335-336 and 1745 in this diff) so no path ever forwards a
SqlDdl format into ExportWriter for query exports.
- Around line 1203-1221: The Oracle block detector only treats "CREATE OR
REPLACE ..." as a block and only looks for a final token exactly equal to "END",
so update the logic around is_oracle_block and the termination checks to also
treat plain "CREATE" followed directly by a PL/SQL object keyword (e.g., when
tokens.first()==Some("create") and the object keyword appears at index 1 or 3
depending on presence of "or") as a block (cover both "create or replace <obj>"
and "create <obj>" forms referenced in the tokens checks), and change the
end-detection (the code paths around the later checks you flagged) to consider
"END <object_name>;" patterns by inspecting the last two tokens (normalize/trim
punctuation) so that if the penultimate token is "end" and the final token is
the object name (possibly with trailing semicolon or "/") the parser treats the
block as terminated; apply the same adjusted logic in the other occurrences you
noted (the similar checks at the other line ranges).

In `@src-tauri/src/db/drivers/mysql.rs`:
- Around line 63-69: The mysql_family_default_port function incorrectly treats
"tidb" like generic MySQL and returns 3306; update mysql_family_default_port to
check driver.eq_ignore_ascii_case("tidb") and return 4000 for that case
(preserving the existing starrocks => 9030 branch and the fallback => 3306) so
omitted-port connections to tidb use the registry-expected default.
- Around line 174-177: The parse error returned from
MySqlConnectOptions::from_str in build_connect_options currently formats a raw
"[CONN_FAILED]" string; replace that map_err call to invoke the standardized
conn_failed_error helper so the error is enriched with context (dsn and driver)
and TLS/auth/network hints—i.e., call conn_failed_error(...) (passing the
original parse error, dsn, and driver as required by conn_failed_error's
signature) instead of format!("[CONN_FAILED] {e}").
- Around line 233-240: build_dsn_with_ca_path may create a temporary CA file
(ca_cert_path) which is currently leaked if MySqlPoolOptions::connect_with
fails; modify the flow in the function using build_dsn_with_ca_path,
build_connect_options and connect_with so that ca_cert_path is either stored
into the MysqlDriver before awaiting connect_with or is cleaned up on any early
return: e.g., capture the ca_cert_path, attempt connect_with, and on Err call
the existing cleanup routine (or drop/unlink the temp file) before returning the
error; ensure MysqlDriver contains the saved ca_cert_path when connection
succeeds so normal shutdown can clean it up.

In `@src/components/business/DataGrid/TableView.tsx`:
- Around line 1717-1748: The DDL button is incorrectly hidden by the combined
condition checking onCreateQuery; instead render each action independently: keep
the New Query Button rendered when tableContext && onCreateQuery (using
onCreateQuery with tableContext.connectionId/database/driver), and render the
DDL Button only when tableContext && onOpenDDL (leave its onClick as
handleShowDDL or call onOpenDDL if handleShowDDL simply proxies it). Update the
JSX conditions so the two Buttons are in separate conditional blocks keyed to
their respective callbacks (onCreateQuery for the query button, onOpenDDL for
the DDL button).
- Around line 1983-1993: The current header interaction uses
createSingleAndDoubleClickHandler (via headerClickStateRef and
headerInteraction) to make copy the single-click action and sort the
double-click action; change this so sorting (handleSortClick) is the
primary/keyboard-accessible action and copying (handleHeaderCopy) is a secondary
affordance—remove or stop relying on double-click for sort, wire handleSortClick
to the primary click/keyboard handler (and ensure headerActionLabel reflects
that), and move handleHeaderCopy to a separate visible/accessible control or
context menu/button so copy is not the primary click behavior; update uses of
createSingleAndDoubleClickHandler/headerInteraction accordingly.
- Around line 1847-1853: handleExport is being called with format tokens like
"sql_dml" which are concatenated into defaultPath (.${format}) producing
filenames like *.sql_dml; change the export calls or handleExport logic so the
saved filename uses the actual .sql extension. Either map internal format names
to extensions inside handleExport (e.g., formatToExt("sql_dml") -> "sql") when
building defaultPath, or update the DropdownMenuItem calls that pass "sql_dml"
(the onClick arrows that call handleExport("current_page", "sql_dml") and the
similar calls at the other DropdownMenuItem locations) to pass "sql" as the
extension argument while preserving any internal type identifier separately;
reference handleExport and the DropdownMenuItem calls around the
"current_page","sql_dml" usages for locating the fix.

In `@src/components/business/Editor/SqlEditor.tsx`:
- Line 877: The export now generates filenames ending with ".sql_dml" for the
"sql_dml" format; update the export behavior so "sql_dml" uses the standard
".sql" extension by normalizing the format before building the filename. Locate
the handler handleExportResult (and any place it derives filename from the
format string) and map "sql_dml" → "sql" (either by normalizing the format
argument passed from the onClick or inside handleExportResult) so generated
filenames use ".sql" while preserving the original format identifier for export
logic.

In `@src/components/business/Sidebar/ConnectionList.tsx`:
- Around line 459-493: The two useEffect blocks that call
api.connections.getMysqlCharsets and getMysqlCollations must ignore stale
responses: add a cancellation guard inside each effect (e.g., let cancelled =
false; cleanup sets cancelled = true) and only call setMysqlCharsets /
setMysqlCollations / setLoadingMysqlOptions when cancelled is false (and
optionally verify createDbConnectionId and isCreateDbDialogOpen still match),
then return the cleanup function; apply this same cancellation-guard pattern to
both the charset-loading effect and the collation-loading effect so late network
responses cannot overwrite cleared or newer state for createDbConnectionId,
isCreateDbDialogOpen, isMySqlFamilyCreateDb, or createDbForm.charset.

In `@src/main.tsx`:
- Line 8: The import of ErrorBoundary in main.tsx uses a relative path; update
the import to use the project alias by replacing the relative import with the
alias form (importing ErrorBoundary from "@/components/ErrorBoundary") so it
follows the repo convention for TypeScript files; ensure any related
tsconfig/paths are already configured and update only the import statement
referencing ErrorBoundary in main.tsx.

---

Outside diff comments:
In `@src-tauri/src/connection_input/mod.rs`:
- Around line 57-62: After parsing an embedded host:port via
parse_host_embedded_port in the is_mysql_family_driver branch, re-run the port
range validation on the potentially updated form.port (the value assigned to
form.port after parse_host_embedded_port) and reject or clear values that fall
outside the valid TCP port range (1–65535); update the code that originally
validated form.port before parsing to also validate the post-parse value so
inputs like "db:70000" do not bypass checks. Ensure you reference the same
validation logic (or helper) when validating form.port after
parse_host_embedded_port to keep behavior consistent with the initial check on
form.port.

---

Nitpick comments:
In `@src-tauri/src/commands/query.rs`:
- Around line 79-110: parse_dollar_quote_tag and skip_dollar_quote are
duplicated; extract their logic into a shared SQL utility module (e.g., create a
new module like sql::dollar_quote) and move the implementations there, then
replace the local functions in src-tauri/src/commands/query.rs
(parse_dollar_quote_tag, skip_dollar_quote) and the duplicate in
src-tauri/src/db/drivers/postgres.rs to call the shared helpers instead; ensure
the shared functions keep the same signatures (accepting &[u8] and usize) and
update imports/usages accordingly so both command guards and driver parsing use
the single centralized implementation.

In `@src-tauri/tests/common/shared.rs`:
- Around line 8-11: Remove the redundant #[allow(dead_code)] attributes from the
active retry helper constants CONNECT_RETRY_ATTEMPTS and CONNECT_RETRY_DELAY_MS
by deleting the attribute lines immediately above those const declarations; also
remove the same #[allow(dead_code)] suppression from any other retry-related
constants in this module (the other retry helper constants) so that dead-code
warnings remain meaningful for future changes.

In `@src-tauri/tests/common/starrocks_context.rs`:
- Around line 22-30: The current GenericImage construction uses
WaitFor::seconds(20) which may be too short for StarRocks; update the readiness
handling by increasing the wait timeout (e.g., to 120s or higher) on the
with_wait_for call (replace WaitFor::seconds(20) with a larger value) or replace
the simple seconds-based wait with a more robust readiness check (e.g., waiting
for a specific log line or a successful TCP response) so that
GenericImage::with_wait_for/WaitFor usage aligns with the longer
shared::wait_for_port(Duration::from_secs(120)) check.
- Around line 44-56: The function starrocks_form_from_local_env currently
constructs ConnectionForm by reading environment variables directly and then
redundantly calls apply_starrocks_env_overrides(&mut form); remove that
redundant call (or alternatively initialize form with Default::default() and let
apply_starrocks_env_overrides populate fields) so that only one path reads and
applies the STARROCKS_* environment variables; update
starrocks_form_from_local_env to either rely solely on the inline
env_or/env_i64/env::var assignments or solely on apply_starrocks_env_overrides,
and delete the extra apply_starrocks_env_overrides invocation accordingly.

In `@src-tauri/tests/postgres_stateful_command_integration.rs`:
- Around line 819-823: The test assumes verify.data[0]["c"] is a string; make
the extraction robust to both string and numeric JSON by matching the
serde_json::Value: if it's a string, parse to i64, if it's a number use as_i64()
(or as_u64() then cast) and then assert_eq!(count, 2). Update the code around
verify.data[0]["c"] in the test (the touch_count assertion) to handle
Value::String and Value::Number branches and produce a single i64 `count` for
the assertion.

In `@src/App.tsx`:
- Around line 1709-1730: The inline schema derivation duplicates
resolveTableScope; update the tableContext construction for the tab (where
tableContext is set) to call the existing resolveTableScope function instead of
reimplementing the conditional chain: pass the tab.driver and tab.database (and
any other expected params) into resolveTableScope to obtain the schema/scope,
then use that returned value for the schema field while keeping the other fields
(connectionId, database, table, driver) as before; this will eliminate the
duplicated logic and keep behavior consistent with resolveTableScope.
- Around line 190-191: The current expression using a type cast bypasses type
safety: replace the as any cast by adding a safe string-based guard and using it
in the isDatabaseScoped calculation; implement a helper like
isMysqlFamilyDriverSafe(driver: string | undefined) in driver-registry that
looks up DRIVER_REGISTRY by id and returns config?.isMysqlFamily ?? false,
export it, then update the isDatabaseScoped computation to use
isMysqlFamilyDriverSafe(driver) || driver === "clickhouse" (referencing the
isDatabaseScoped variable and isMysqlFamilyDriver/isMysqlFamilyDriverSafe
helpers to locate the code).

In `@src/components/business/DataGrid/tableView/utils.ts`:
- Around line 177-188: The quoteIdent function uses an unsafe cast `as any`
because the driver parameter's type doesn't match isMysqlFamilyDriver's expected
type; update the signature of quoteIdent(driver: string | undefined, name:
string) to use the exact type isMysqlFamilyDriver accepts (or change
isMysqlFamilyDriver to accept string | undefined) so you can call
isMysqlFamilyDriver(driver) without casting, then remove the `as any` cast in
quoteIdent and adjust any callers if needed; reference the quoteIdent function
and isMysqlFamilyDriver to locate and align their types.
- Around line 280-287: The getQualifiedTableName function uses an unsafe "as
any" cast when calling isMysqlFamilyDriver (same issue exists in quoteIdent);
fix by aligning types instead of casting—either change the driver parameter type
on getQualifiedTableName and quoteIdent to the proper DriverType/enum used
across the module or update isMysqlFamilyDriver's signature to accept a string
(or the actual driver type) so you can call isMysqlFamilyDriver(driver) without
casting; remove the "as any" casts and adjust imports/types accordingly so the
call sites and helper signatures share a consistent driver type.

In `@src/components/business/Sidebar/Sidebar.tsx`:
- Around line 42-43: Replace the inline union type for the "format" prop with
the shared TransferFormat type from src/services/api.ts: import TransferFormat
into Sidebar (or the module where the prop/type is declared) and change the
property signature from format: "csv" | "json" | "sql_dml" | "sql_ddl" |
"sql_full" to format: TransferFormat; ensure any usages of format (e.g., in
Sidebar component, prop interfaces or function signatures) compile after
updating the import.

In `@src/components/ErrorBoundary.tsx`:
- Around line 14-46: ErrorBoundary currently sets error in
getDerivedStateFromError and never clears it, preventing recovery; add a reset
mechanism by introducing a resetErrorBoundary method that sets state.error back
to null and call it from either (a) a "Try Again" button rendered when
this.props.fallback is absent or (b) when a new resetKey prop changes (watch
resetKey in componentDidUpdate to clear error). Update render to show a small
"Try Again" button alongside the error UI that invokes resetErrorBoundary, and
expose resetErrorBoundary as a public method if parent components should trigger
resets programmatically; modify Prop types to include optional fallback and
optional resetKey as needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 18bc9511-2075-40af-abd9-e01396eaa899

📥 Commits

Reviewing files that changed from the base of the PR and between 23c87ad and d64114a.

📒 Files selected for processing (54)
  • .github/workflows/build-multiplatform.yml
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • .github/workflows/upgradelink-upload.yml
  • package.json
  • scripts/test-integration.sh
  • src-tauri/Cargo.toml
  • src-tauri/src/commands/connection.rs
  • src-tauri/src/commands/query.rs
  • src-tauri/src/commands/transfer.rs
  • src-tauri/src/connection_input/mod.rs
  • src-tauri/src/db/drivers/mod.rs
  • src-tauri/src/db/drivers/mssql.rs
  • src-tauri/src/db/drivers/mysql.rs
  • src-tauri/src/db/drivers/oracle.rs
  • src-tauri/src/db/drivers/postgres.rs
  • src-tauri/src/lib.rs
  • src-tauri/src/ssh.rs
  • src-tauri/tauri.conf.json
  • src-tauri/tests/common/shared.rs
  • src-tauri/tests/common/starrocks_context.rs
  • src-tauri/tests/mariadb_command_integration.rs
  • src-tauri/tests/mysql_stateful_command_integration.rs
  • src-tauri/tests/oracle_command_integration.rs
  • src-tauri/tests/oracle_integration.rs
  • src-tauri/tests/postgres_integration.rs
  • src-tauri/tests/postgres_stateful_command_integration.rs
  • src-tauri/tests/sqlite_command_integration.rs
  • src-tauri/tests/starrocks_command_integration.rs
  • src-tauri/tests/starrocks_integration.rs
  • src/App.tsx
  • src/components/ErrorBoundary.tsx
  • src/components/business/DataGrid/ComplexValueViewer.tsx
  • src/components/business/DataGrid/TableView.tsx
  • src/components/business/DataGrid/tableView/utils.ts
  • src/components/business/DataGrid/tableView/utils.unit.test.ts
  • src/components/business/Editor/SqlEditor.tsx
  • src/components/business/Sidebar/ConnectionList.tsx
  • src/components/business/Sidebar/Sidebar.tsx
  • src/components/business/Sidebar/connection-list/helpers.tsx
  • src/components/business/Sidebar/connection-list/helpers.unit.test.ts
  • src/components/settings/SettingsDialog.tsx
  • src/lib/connection-form/rules.ts
  • src/lib/connection-form/rules.unit.test.ts
  • src/lib/driver-registry.tsx
  • src/lib/driver-registry.unit.test.ts
  • src/lib/i18n/locales/en.ts
  • src/lib/i18n/locales/ja.ts
  • src/lib/i18n/locales/zh.ts
  • src/main.tsx
  • src/services/api.ts
  • src/services/api.unit.test.ts
  • src/services/mocks.service.test.ts
  • src/services/mocks.ts

runs-on: ubuntu-22.04
steps:
- name: Upload latest.json to UpgradeLink
uses: toolsetlink/upgradelink-action@3.0.2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Resolve the peeled commit behind tag 3.0.2
git ls-remote https://github.com/toolsetlink/upgradelink-action refs/tags/3.0.2^{} | awk '{print $1}'

Repository: codeErrorSleep/dbpaw

Length of output: 104


Pin third-party GitHub Action to an immutable commit SHA.

Using @3.0.2 is mutable and can be retargeted. For release workflows, pin to a full commit SHA instead.

🔒 Suggested change
-        uses: toolsetlink/upgradelink-action@3.0.2
+        uses: toolsetlink/upgradelink-action@5d1d2fdafb4372bd0b527909639f3ea786e8856d
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/upgradelink-upload.yml at line 18, The workflow currently
references the third-party action by a mutable tag "uses:
toolsetlink/upgradelink-action@3.0.2"; replace that tag with the action's
immutable full commit SHA (e.g., "uses:
toolsetlink/upgradelink-action@<full-commit-sha>") to prevent retargeting—locate
the action repo, copy the commit SHA for the desired release, and update the
workflow entry that mentions toolsetlink/upgradelink-action accordingly.

Comment on lines +42 to +45
starrocks)
run_integration_test "starrocks_integration"
run_integration_test "starrocks_command_integration"
;;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add StarRocks to the all integration matrix.

Line 42 adds targeted StarRocks execution, but IT_DB=all still omits StarRocks, so CI full runs won’t cover the new driver path.

✅ Proposed patch
   all)
+    run_integration_test "starrocks_integration"
+    run_integration_test "starrocks_command_integration"
     run_integration_test "mysql_integration"
     run_integration_test "mysql_command_integration"
     run_integration_test "mysql_stateful_command_integration"

Based on learnings: For new database driver additions, follow the step-by-step checklist in ADD_NEW_DB.md for exact file paths, line numbers, and implementation details; update scripts/test-integration.sh to include the new driver.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/test-integration.sh` around lines 42 - 45, The integration matrix
omits StarRocks when IT_DB=all; update the script so the "all" case triggers the
StarRocks tests by adding the same run_integration_test calls used in the
starrocks) case. Locate the case or switch that handles IT_DB="all" in
scripts/test-integration.sh and add run_integration_test "starrocks_integration"
and run_integration_test "starrocks_command_integration" alongside the other DB
entries so full CI runs include the new driver path; use the existing
run_integration_test invocation pattern to ensure consistent behavior.

Comment thread src-tauri/Cargo.toml

[dependencies]
tauri = { version = "2", features = [] }
tauri = { version = "2", features = ["devtools"] }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Check Rust/Tauri code paths for devtools usage and debug gating ==="
rg -n -C2 --type=rust --type=toml 'devtools|open_devtools|close_devtools|debug_toggle_devtools|cfg\(debug_assertions\)'

echo
echo "=== Check workflows/scripts for release builds enabling custom features ==="
rg -n -C2 'tauri build|cargo tauri build|--features'

Repository: codeErrorSleep/dbpaw

Length of output: 3369


🏁 Script executed:

#!/bin/bash
# Check Cargo.toml for build profile overrides
echo "=== Check Cargo.toml for build profile configuration ==="
cat -n src-tauri/Cargo.toml | tail -30

echo
echo "=== Check if menu creation has any conditional guards ==="
rg -n -B5 -A5 'developer_menu' src-tauri/src/lib.rs

Repository: codeErrorSleep/dbpaw

Length of output: 2958


🏁 Script executed:

#!/bin/bash
# Check for any release profile configuration in full Cargo.toml
echo "=== Full Cargo.toml to check for [profile.release] section ==="
wc -l src-tauri/Cargo.toml
cat -n src-tauri/Cargo.toml | grep -A10 '\[profile'

Repository: codeErrorSleep/dbpaw

Length of output: 150


🏁 Script executed:

#!/bin/bash
# Show entire Cargo.toml
echo "=== Full Cargo.toml content ==="
cat -n src-tauri/Cargo.toml

Repository: codeErrorSleep/dbpaw

Length of output: 2254


Disable Tauri devtools in production by using a feature flag.

The devtools feature is globally enabled and unconditionally added to the Developer menu—enabling end-users to access devtools in production. This weakens security posture.

🔧 Suggested approach
 [dependencies]
-tauri = { version = "2", features = ["devtools"] }
+tauri = { version = "2" }
+
+[features]
+default = []
+devtools = ["tauri/devtools"]

Enable --features devtools only in local/dev builds.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/Cargo.toml` at line 21, Remove the unconditional "devtools"
dependency feature from the tauri dependency entry in Cargo.toml and instead
declare a Cargo feature named "devtools" that enables the tauri/devtools
dependency feature; specifically, stop listing features = ["devtools"] on the
tauri dependency and add a [features] section where devtools =
["tauri/devtools"], so devtools is only activated when building with --features
devtools (and update your dev/local build commands to pass --features devtools
as needed).

Comment on lines +422 to +479
#[tauri::command]
pub async fn get_mysql_charsets_by_id(
state: State<'_, AppState>,
id: i64,
) -> Result<Vec<String>, String> {
super::execute_with_retry(&state, id, None, |driver| async move {
let result = driver
.execute_query("SHOW CHARACTER SET".to_string())
.await?;
let mut charsets: Vec<String> = result
.data
.iter()
.filter_map(|row| {
row.get("Charset")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
})
.collect();
charsets.sort();
Ok(charsets)
})
.await
}

#[tauri::command]
pub async fn get_mysql_collations_by_id(
state: State<'_, AppState>,
id: i64,
charset: Option<String>,
) -> Result<Vec<String>, String> {
let sql = match &charset {
Some(cs) if is_safe_option_token(cs) => {
format!("SHOW COLLATION WHERE Charset = '{}'", cs)
}
Some(cs) => {
return Err(format!("[VALIDATION_ERROR] Invalid charset: {}", cs));
}
None => "SHOW COLLATION".to_string(),
};
super::execute_with_retry(&state, id, None, |driver| {
let sql = sql.clone();
async move {
let result = driver.execute_query(sql).await?;
let mut collations: Vec<String> = result
.data
.iter()
.filter_map(|row| {
row.get("Collation")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
})
.collect();
collations.sort();
Ok(collations)
}
})
.await
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Reject non-MySQL connections before running these queries.

These handlers currently execute SHOW CHARACTER SET / SHOW COLLATION for any saved connection id. If a non-MySQL connection reaches them, callers get a raw SQL error instead of a predictable [UNSUPPORTED] response. Mirroring the driver-family guard used in create_database_by_id* would make this API much safer to consume.

Also applies to: 481-536

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/commands/connection.rs` around lines 422 - 479, Both
get_mysql_charsets_by_id and get_mysql_collations_by_id must reject non-MySQL
drivers up-front like the create_database_by_id* handlers do: inside the
execute_with_retry closure (or before calling it) check the driver's family and
return Err("[UNSUPPORTED] This operation is only supported for MySQL
connections") when it is not DriverFamily::Mysql. Reference the functions
get_mysql_charsets_by_id and get_mysql_collations_by_id, the existing
execute_with_retry helper, and mirror the driver-family guard pattern used in
create_database_by_id* so non-MySQL connection ids produce the predictable
[UNSUPPORTED] error instead of raw SQL errors.

Comment on lines +297 to +298
let mut writer = ExportWriter::new(output_path.clone(), format)?;
writer.write_csv_header(&columns)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Reject sql_ddl for query exports before this hits unreachable!.

Both query-export entry points still pass ExportFormat::SqlDdl into the writer, and any non-empty result will panic on the unreachable! branch instead of returning a normal export error.

Suggested guard
+fn validate_query_export_format(format: &ExportFormat) -> Result<(), String> {
+    if matches!(format, ExportFormat::SqlDdl) {
+        return Err("[EXPORT_ERROR] sql_ddl is only supported for table exports".to_string());
+    }
+    Ok(())
+}
+
 #[tauri::command]
 pub async fn export_query_result(
     state: State<'_, AppState>,
@@
 ) -> Result<ExportResult, String> {
+    validate_query_export_format(&format)?;
     let output_path =
         resolve_output_path(file_path, "query_result", extension_for_format(&format))?;
@@
 pub async fn export_query_result_direct(
@@
 ) -> Result<ExportResult, String> {
+    validate_query_export_format(&format)?;
     let output_path =
         resolve_output_path(file_path, "query_result", extension_for_format(&format))?;
@@
-            ExportFormat::SqlDdl => unreachable!("SqlDdl rows are never written"),
+            ExportFormat::SqlDdl => {
+                return Err("[EXPORT_ERROR] sql_ddl is only supported for table exports".to_string());
+            }

Also applies to: 335-336, 1745-1745

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/commands/transfer.rs` around lines 297 - 298, Reject
ExportFormat::SqlDdl early in the query-export entry points so we return a
proper error instead of letting ExportWriter later hit the unreachable! panic:
add a guard that checks for ExportFormat::SqlDdl and returns an Err (or Tauri
command error) before constructing ExportWriter or calling write_csv_header;
apply the same check in the other query-export sites that create ExportWriter
(the callsite that uses write_csv_header and the other locations around the code
that pass ExportFormat::SqlDdl at the spots corresponding to lines 335-336 and
1745 in this diff) so no path ever forwards a SqlDdl format into ExportWriter
for query exports.

Comment on lines 1847 to 1853
<DropdownMenuItem
onClick={() => void handleExport("current_page", "sql")}
onClick={() =>
void handleExport("current_page", "sql_dml")
}
>
SQL
</DropdownMenuItem>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Keep the suggested file extension as .sql.

These new format values are passed into handleExport(), which still builds defaultPath with .${format}. That now pre-fills filenames like *.sql_dml even though the actual artifact is still SQL.

Minimal fix near handleExport()
-      const defaultPath = `${tableContext.table}_${timestamp}.${format}`;
+      const extension =
+        format === "csv" ? "csv" : format === "json" ? "json" : "sql";
+      const defaultPath = `${tableContext.table}_${timestamp}.${extension}`;

Also applies to: 1871-1875, 1893-1899

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/business/DataGrid/TableView.tsx` around lines 1847 - 1853,
handleExport is being called with format tokens like "sql_dml" which are
concatenated into defaultPath (.${format}) producing filenames like *.sql_dml;
change the export calls or handleExport logic so the saved filename uses the
actual .sql extension. Either map internal format names to extensions inside
handleExport (e.g., formatToExt("sql_dml") -> "sql") when building defaultPath,
or update the DropdownMenuItem calls that pass "sql_dml" (the onClick arrows
that call handleExport("current_page", "sql_dml") and the similar calls at the
other DropdownMenuItem locations) to pass "sql" as the extension argument while
preserving any internal type identifier separately; reference handleExport and
the DropdownMenuItem calls around the "current_page","sql_dml" usages for
locating the fix.

Comment on lines +1983 to +1993
const headerActionLabel = t("tableView.header.actionHint", {
column,
});
const headerClickState =
headerClickStateRef.current[column] ??
(headerClickStateRef.current[column] = { timerId: null });
const headerInteraction = createSingleAndDoubleClickHandler(
headerClickState,
() => handleHeaderCopy(column),
() => handleSortClick(column),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't make sorting depend solely on double-click.

With copy on click and sort on double-click, header sorting no longer has a clear primary path for keyboard and other non-pointer input. Keep sort reachable through a primary/keyboard action, and move copy to a separate affordance if needed.

Also applies to: 2009-2035

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/business/DataGrid/TableView.tsx` around lines 1983 - 1993, The
current header interaction uses createSingleAndDoubleClickHandler (via
headerClickStateRef and headerInteraction) to make copy the single-click action
and sort the double-click action; change this so sorting (handleSortClick) is
the primary/keyboard-accessible action and copying (handleHeaderCopy) is a
secondary affordance—remove or stop relying on double-click for sort, wire
handleSortClick to the primary click/keyboard handler (and ensure
headerActionLabel reflects that), and move handleHeaderCopy to a separate
visible/accessible control or context menu/button so copy is not the primary
click behavior; update uses of
createSingleAndDoubleClickHandler/headerInteraction accordingly.

</DropdownMenuItem>
<DropdownMenuItem
onClick={() => void handleExportResult("sql")}
onClick={() => void handleExportResult("sql_dml")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

sql_dml now produces a nonstandard default file extension.

After this change, default filename generation uses .sql_dml (from .${format}) instead of .sql, which is a user-facing export regression.

🔧 Proposed fix
-      const defaultPath = `query_result_${timestamp}.${format}`;
+      const extension =
+        format === "csv" ? "csv" : format === "json" ? "json" : "sql";
+      const defaultPath = `query_result_${timestamp}.${extension}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/business/Editor/SqlEditor.tsx` at line 877, The export now
generates filenames ending with ".sql_dml" for the "sql_dml" format; update the
export behavior so "sql_dml" uses the standard ".sql" extension by normalizing
the format before building the filename. Locate the handler handleExportResult
(and any place it derives filename from the format string) and map "sql_dml" →
"sql" (either by normalizing the format argument passed from the onClick or
inside handleExportResult) so generated filenames use ".sql" while preserving
the original format identifier for export logic.

Comment on lines +459 to +493
useEffect(() => {
if (
!isCreateDbDialogOpen ||
!isMySqlFamilyCreateDb ||
!createDbConnectionId
)
return;
setLoadingMysqlOptions(true);
api.connections
.getMysqlCharsets(Number(createDbConnectionId))
.then(setMysqlCharsets)
.catch(() => setMysqlCharsets(["utf8mb4", "utf8", "latin1"]))
.finally(() => setLoadingMysqlOptions(false));
}, [isCreateDbDialogOpen, isMySqlFamilyCreateDb, createDbConnectionId]);

useEffect(() => {
if (
!isCreateDbDialogOpen ||
!isMySqlFamilyCreateDb ||
!createDbConnectionId
)
return;
api.connections
.getMysqlCollations(
Number(createDbConnectionId),
createDbForm.charset || undefined,
)
.then(setMysqlCollations)
.catch(() => setMysqlCollations([]));
}, [
isCreateDbDialogOpen,
isMySqlFamilyCreateDb,
createDbConnectionId,
createDbForm.charset,
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Ignore stale MySQL option responses.

Both effects update state unconditionally after the request resolves. If the dialog closes, the connection changes, or the user switches charset quickly, an older response can repopulate cleared state or overwrite the newer collation list with stale data.

Use a cancellation guard for the refetch path
 useEffect(() => {
-  if (
-    !isCreateDbDialogOpen ||
-    !isMySqlFamilyCreateDb ||
-    !createDbConnectionId
-  )
-    return;
-  api.connections
-    .getMysqlCollations(
-      Number(createDbConnectionId),
-      createDbForm.charset || undefined,
-    )
-    .then(setMysqlCollations)
-    .catch(() => setMysqlCollations([]));
+  if (
+    !isCreateDbDialogOpen ||
+    !isMySqlFamilyCreateDb ||
+    !createDbConnectionId
+  ) {
+    setMysqlCollations([]);
+    return;
+  }
+  let cancelled = false;
+  setMysqlCollations([]);
+  api.connections
+    .getMysqlCollations(
+      Number(createDbConnectionId),
+      createDbForm.charset || undefined,
+    )
+    .then((opts) => {
+      if (!cancelled) setMysqlCollations(opts);
+    })
+    .catch(() => {
+      if (!cancelled) setMysqlCollations([]);
+    });
+  return () => {
+    cancelled = true;
+  };
 }, [
   isCreateDbDialogOpen,
   isMySqlFamilyCreateDb,
   createDbConnectionId,
   createDbForm.charset,
 ]);

Apply the same pattern to the charset-loading effect as well.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
if (
!isCreateDbDialogOpen ||
!isMySqlFamilyCreateDb ||
!createDbConnectionId
)
return;
setLoadingMysqlOptions(true);
api.connections
.getMysqlCharsets(Number(createDbConnectionId))
.then(setMysqlCharsets)
.catch(() => setMysqlCharsets(["utf8mb4", "utf8", "latin1"]))
.finally(() => setLoadingMysqlOptions(false));
}, [isCreateDbDialogOpen, isMySqlFamilyCreateDb, createDbConnectionId]);
useEffect(() => {
if (
!isCreateDbDialogOpen ||
!isMySqlFamilyCreateDb ||
!createDbConnectionId
)
return;
api.connections
.getMysqlCollations(
Number(createDbConnectionId),
createDbForm.charset || undefined,
)
.then(setMysqlCollations)
.catch(() => setMysqlCollations([]));
}, [
isCreateDbDialogOpen,
isMySqlFamilyCreateDb,
createDbConnectionId,
createDbForm.charset,
]);
useEffect(() => {
if (
!isCreateDbDialogOpen ||
!isMySqlFamilyCreateDb ||
!createDbConnectionId
)
return;
setLoadingMysqlOptions(true);
api.connections
.getMysqlCharsets(Number(createDbConnectionId))
.then(setMysqlCharsets)
.catch(() => setMysqlCharsets(["utf8mb4", "utf8", "latin1"]))
.finally(() => setLoadingMysqlOptions(false));
}, [isCreateDbDialogOpen, isMySqlFamilyCreateDb, createDbConnectionId]);
useEffect(() => {
if (
!isCreateDbDialogOpen ||
!isMySqlFamilyCreateDb ||
!createDbConnectionId
) {
setMysqlCollations([]);
return;
}
let cancelled = false;
setMysqlCollations([]);
api.connections
.getMysqlCollations(
Number(createDbConnectionId),
createDbForm.charset || undefined,
)
.then((opts) => {
if (!cancelled) setMysqlCollations(opts);
})
.catch(() => {
if (!cancelled) setMysqlCollations([]);
});
return () => {
cancelled = true;
};
}, [
isCreateDbDialogOpen,
isMySqlFamilyCreateDb,
createDbConnectionId,
createDbForm.charset,
]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/business/Sidebar/ConnectionList.tsx` around lines 459 - 493,
The two useEffect blocks that call api.connections.getMysqlCharsets and
getMysqlCollations must ignore stale responses: add a cancellation guard inside
each effect (e.g., let cancelled = false; cleanup sets cancelled = true) and
only call setMysqlCharsets / setMysqlCollations / setLoadingMysqlOptions when
cancelled is false (and optionally verify createDbConnectionId and
isCreateDbDialogOpen still match), then return the cleanup function; apply this
same cancellation-guard pattern to both the charset-loading effect and the
collation-loading effect so late network responses cannot overwrite cleared or
newer state for createDbConnectionId, isCreateDbDialogOpen,
isMySqlFamilyCreateDb, or createDbForm.charset.

Comment thread src/main.tsx
import { Toaster } from "./components/ui/sonner";
import "./lib/i18n";
import { initI18nFromStore } from "./lib/i18n";
import { ErrorBoundary } from "./components/ErrorBoundary";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use @/ alias for this import.

Please switch this new import to the project alias to match repo conventions.

♻️ Proposed fix
-import { ErrorBoundary } from "./components/ErrorBoundary";
+import { ErrorBoundary } from "@/components/ErrorBoundary";

As per coding guidelines, src/**/*.{ts,tsx}: Use path alias @/ mapping to ./src/ for imports in TypeScript files.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { ErrorBoundary } from "./components/ErrorBoundary";
import { ErrorBoundary } from "@/components/ErrorBoundary";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main.tsx` at line 8, The import of ErrorBoundary in main.tsx uses a
relative path; update the import to use the project alias by replacing the
relative import with the alias form (importing ErrorBoundary from
"@/components/ErrorBoundary") so it follows the repo convention for TypeScript
files; ensure any related tsconfig/paths are already configured and update only
the import statement referencing ErrorBoundary in main.tsx.

@codeErrorSleep codeErrorSleep merged commit 5a3ec9e into main Apr 11, 2026
13 of 18 checks passed
@codeErrorSleep codeErrorSleep deleted the release/260408 branch April 12, 2026 08:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant