Skip to content

[Audit] Transfer module review: adapter coverage, missing features, and bugs before releaseΒ #112

Description

@Blankll

Transfer Module Audit β€” Pre-Release Issues

All issues found during a comprehensive review of the transfer module (src-tauri/src/commands/transfer.rs, src-tauri/src/transfer/, and related frontend code).


πŸ”΄ Critical (must fix before release)

S1. execute_migration_data has todo!() β€” will panic at runtime

File: src-tauri/src/commands/transfer.rs:257

The migration match only covers 4Γ—4 = 16 combinations (Postgres/MySQL/SQLServer/SQLite). Any other source/target combination hits todo!() and panics. Compare with browse.rs / query.rs which already handle all 9 ActiveConnection variants correctly.

_ => todo!(),

S2. All 8 transfer commands only handle 4/9 ActiveConnection variants

File: src-tauri/src/commands/transfer.rs (lines 40, 72, 118, 150, 257, 301, 320, 553)

ActiveConnection has 9 variants but all transfer commands only dispatch 4:

Variant Databases Status
Postgres PostgreSQL, CockroachDB, Redshift, TimescaleDB, etc. (20 PG-compat databases) βœ…
MySQL MySQL, MariaDB, TiDB, OceanBase, etc. (14 MySQL-compat databases) βœ…
SQLServer SQL Server βœ…
SQLite SQLite βœ…
ClickHouse ClickHouse ❌ _ => Err("...not supported")
JdbcBridge Oracle, DuckDB, Firebird, DB2, H2, Snowflake, TDengine, Hive, Databricks, Hana, Teradata, Vertica, Exasol, BigQuery, Dameng, etc. (~23 databases) ❌ _ => Err("...not supported")
HttpSql Trino, Presto ❌ _ => Err("...not supported")
Rqlite RQLite ❌ _ => Err("...not supported")
Turso Turso/libSQL ❌ _ => Err("...not supported")

Impact: ~47 database types are blocked from export/import/migration/DDL generation even though their adapters fully implement the DatabaseAdapter trait. The transfer core functions (execute_export<A>, etc.) are generic over A: DatabaseAdapter β€” the bug is only in the dispatch layer.

Affected commands:

  • preview_export_data (line 40)
  • execute_export_data (line 72)
  • execute_import_data (line 118)
  • preview_migration_data (line 150)
  • execute_migration_data (line 257 β€” todo!())
  • auto_map_migration_columns (line 301)
  • generate_ddl_for_objects (line 320)
  • execute_sql_content (line 553)

S3. HttpSqlAdapter missing metadata methods

File: src-tauri/src/database/http_sql.rs

HttpSqlAdapter only implements the 6 required DatabaseAdapter methods. It does not override:

  • list_databases β†’ returns Err(DbError::unsupported("list_databases"))
  • list_tables β†’ same
  • list_columns β†’ same
  • get_table_info β†’ same

Even if S2 is fixed, Trino/Presto users would fail on Database or Server scope export/migration because execute_export calls these methods internally.

Note: All other adapters (ClickHouse, Rqlite, Turso, JdbcBridge) implement these methods correctly β€” only HttpSqlAdapter is missing them.


🟠 High Priority (functional gaps)

H1. Migration has no frontend at all

  • Backend registers 3 migration commands: preview_migration_data, execute_migration_data, auto_map_migration_columns
  • Frontend TransferPage.vue only has Export / Import tabs β€” no Migration tab
  • transferApi.ts exposes 0 migration functions
  • src/types/transfer.ts has no MigrationRequest / MigrationPreview / MigrationMapping types
  • transferStore.ts TaskKind only includes export | import, no migration

Impact: Cross-database migration is a README-promoted feature ("Move data between any supported engines" and "Cross-engine transfer β€” migrate data between different database types") but is completely unreachable from the UI.

H2. 5 of 10 backend commands have no frontend invoke wrappers

Command In transferApi.ts? UI Component?
preview_export_data βœ… βœ… ExportWizard
execute_export_data βœ… βœ… ExportExecuteStep
detect_file_format βœ… βœ… ImportWizard
preview_import_data βœ… βœ… ImportFileStep
execute_import_data βœ… βœ… ImportExecuteStep
preview_migration_data ❌ ❌
execute_migration_data ❌ ❌
auto_map_migration_columns ❌ ❌
generate_ddl_for_objects ❌ (i18n key exists) ❌
execute_sql_content ❌ ❌

H3. transferApi.ts not exported from barrel

File: src/datasources/index.ts

transferApi is missing from the barrel exports β€” cannot be imported via @/datasources/transferApi, only deep imports work.

H4. generate_create_table_sql is a stub β€” produces invalid SQL

File: src-tauri/src/transfer/export.rs:983-998

fn generate_create_table_sql(table: &str, _table_info: &TableInfo, ...) -> String {
    sql.push_str(&format!("CREATE TABLE \"{}\" (\n", table));
    sql.push_str(");");  // ← No column definitions!
}

When SQL export has include_create_table: true, the generated CREATE TABLE contains zero column definitions β€” producing invalid SQL. The _table_info parameter is completely ignored.


🟑 Medium Priority (consistency & quality)

M1. Type mapping only handles 4 target engines

File: src-tauri/src/transfer/migration.rs:601-660 β€” map_type_to_engine()

Only PostgreSQL, MySQL, SQLite, SqlServer have type conversion mappings. All other ~67 databases as migration targets get passthrough (no conversion). This means:

  • DuckDB β†’ incompatible types passed through
  • ClickHouse β†’ incompatible types passed through
  • Oracle/JDBC β†’ incompatible types passed through

The auto_map_migration_columns command (line 277-283) also only recognizes 4 target engine strings.

M2. DDL generation only has 4 dialect implementations

File: src-tauri/src/transfer/ddl.rs:14-21

generate_ddl_for_engine dispatches to 4 specific dialect functions. Everything else (~67 databases) falls through to generate_generic_ddl, which is an alias for generate_postgres_ddl. ClickHouse (CODEC, TTL, ENGINE=MergeTree) and DuckDB would get completely invalid DDL.

M3. SQL generation hardcodes ANSI double-quote identifiers

Multiple places use " for identifier quoting:

  • build_export_query / build_count_query (export.rs:880-899)
  • generate_insert_sql (export.rs:1000-1031)
  • execute_batch_insert_for_target (import.rs:675-738)

MySQL requires `, SQL Server requires []. A working quote_identifier() function already exists in browse.rs:38-50 but is not reused here.

M4. SQL script splitting by ; is fragile

File: commands/transfer.rs:399-422 (split_sql_statements) and import.rs:126-162

Splitting SQL by ; breaks on semicolons inside string literals, stored procedure bodies, or triggers.


🟒 Low Priority

L1. ConflictStrategy defined but never used

ConflictStrategy::Skip/Replace/Upsert/Abort is defined in types.rs but execute_batch_insert_for_target always executes a plain INSERT with no conflict handling.

L2. Insufficient test coverage

File Has Tests?
transfer/types.rs βœ…
transfer/export.rs βœ… (format/filename utilities only)
transfer/import.rs ❌
transfer/migration.rs ❌
transfer/ddl.rs ❌
commands/transfer.rs ❌

Summary

Severity Count Key Items
πŸ”΄ Critical 3 todo!() panic; 47 databases blocked from transfer; HttpSql missing metadata
🟠 High 4 No migration UI; 5 commands unreachable; barrel missing; CREATE TABLE stub
🟑 Medium 4 Type mapping/DDL/SQL only cover 4 engines; SQL splitting fragile
🟒 Low 2 ConflictStrategy unused; test coverage gaps

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions