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-660map_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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions