fix: sort tables by FK dependency in transfer and export
This commit is contained in:
1 parent
71db24813e
commit
c4c427fb67
11 files changed
+292
-6
No files matched your search
@@ -454,9 +454,37 @@ pub fn build_export_sql_insert(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn build_database_sql_export(
|
||||
options: dbx_core::database_export::BuildDatabaseSqlExportOptions,
|
||||
pub async fn build_database_sql_export(
|
||||
state: tauri::State<'_, std::sync::Arc<dbx_core::connection::AppState>>,
|
||||
mut options: dbx_core::database_export::BuildDatabaseSqlExportOptions,
|
||||
) -> Result<String, String> {
|
||||
// Sort tables by FK dependency when connection info is available.
|
||||
if let (Some(ref conn_id), Some(ref database), Some(ref schema)) =
|
||||
(&options.connection_id, &options.database, &options.schema)
|
||||
{
|
||||
if options.tables.len() > 1 {
|
||||
let table_names: Vec<String> = options.tables.iter().filter_map(|t| t.table_name.clone()).collect();
|
||||
if table_names.len() > 1 {
|
||||
if let Ok(sorted_names) = dbx_core::transfer::sort_tables_by_fk_dependency(
|
||||
&state,
|
||||
conn_id,
|
||||
database,
|
||||
schema,
|
||||
&table_names,
|
||||
true,
|
||||
)
|
||||
.await
|
||||
{
|
||||
options.tables.sort_by_key(|t| {
|
||||
sorted_names
|
||||
.iter()
|
||||
.position(|n| Some(n.as_str()) == t.table_name.as_deref())
|
||||
.unwrap_or(usize::MAX)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dbx_core::database_export::build_database_sql_export(options)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,22 @@ pub async fn start_transfer(
|
||||
state.get_or_create_pool(&request.target_connection_id, Some(&request.target_database)).await?;
|
||||
|
||||
tokio::spawn(async move {
|
||||
let total_tables = request.tables.len();
|
||||
// Sort tables by FK dependency so referenced tables are transferred first.
|
||||
let sorted_tables = dbx_core::transfer::sort_tables_by_fk_dependency(
|
||||
&state,
|
||||
&request.source_connection_id,
|
||||
&request.source_database,
|
||||
&request.source_schema,
|
||||
&request.tables,
|
||||
true,
|
||||
)
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
log::warn!("[transfer] failed to sort tables by FK dependency, using original order: {e}");
|
||||
request.tables.clone()
|
||||
});
|
||||
|
||||
let total_tables = sorted_tables.len();
|
||||
log::info!("[transfer] starting transfer_id={} tables={}", transfer_id, total_tables);
|
||||
|
||||
if matches!(source_db_type, dbx_core::models::connection::DatabaseType::Postgres)
|
||||
@@ -86,7 +101,7 @@ pub async fn start_transfer(
|
||||
}
|
||||
}
|
||||
|
||||
for (i, table) in request.tables.iter().enumerate() {
|
||||
for (i, table) in sorted_tables.iter().enumerate() {
|
||||
if dbx_core::transfer::is_cancelled(&transfer_id).await {
|
||||
emit_progress(
|
||||
&app,
|
||||
@@ -249,3 +264,19 @@ pub async fn cancel_transfer(transfer_id: String) -> Result<(), String> {
|
||||
dbx_core::transfer::set_cancelled(&transfer_id).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sort table names by foreign key dependency.
|
||||
/// `parents_first: true` → parent tables first (insert/export order).
|
||||
/// `parents_first: false` → child tables first (drop order).
|
||||
#[tauri::command]
|
||||
pub async fn sort_tables_by_fk_dependency(
|
||||
state: tauri::State<'_, std::sync::Arc<AppState>>,
|
||||
connection_id: String,
|
||||
database: String,
|
||||
schema: String,
|
||||
tables: Vec<String>,
|
||||
parents_first: bool,
|
||||
) -> Result<Vec<String>, String> {
|
||||
dbx_core::transfer::sort_tables_by_fk_dependency(&state, &connection_id, &database, &schema, &tables, parents_first)
|
||||
.await
|
||||
}
|
||||
Reference in new issue
Block a user