feat: export entire database as SQL file

Add a new "Export Database" feature accessible from the sidebar
right-click menu on database/schema nodes. Generates a .sql file
containing CREATE TABLE DDL, batched INSERT statements, and
view/procedure/function source code.

Backend (database_export.rs):
- Stream-writes SQL to file with configurable batch size
- Supports all SQL database types via existing DDL/INSERT generators
- Progress events with cancellation support
- Graceful error handling (continues on per-table failures)

Frontend (DatabaseExportDialog.vue):
- Connection/database/schema selector
- Checkboxes: structure, data, objects
- Real-time progress with current table and row count
- Cancel button

Wired up through Tauri commands, Web SSE routes, and API layer.
This commit is contained in:
t8y2
2026-05-13 01:08:16 +08:00
parent 83216b2765
commit 9ba2976d11
14 changed files with 1134 additions and 139 deletions
+53
View File
@@ -0,0 +1,53 @@
use std::sync::Arc;
use tauri::{AppHandle, Emitter, State};
use crate::commands::connection::AppState;
pub use dbx_core::database_export::{DatabaseExportRequest, ExportProgress, ExportStatus};
fn emit_progress(app: &AppHandle, progress: ExportProgress) {
let _ = app.emit("database-export-progress", progress);
}
#[tauri::command]
pub async fn export_database_sql(
app: AppHandle,
state: State<'_, Arc<AppState>>,
request: DatabaseExportRequest,
) -> Result<(), String> {
let state = state.inner().clone();
let export_id = request.export_id.clone();
tokio::spawn(async move {
let result = dbx_core::database_export::export_database_sql_core(&state, &request, |progress| {
emit_progress(&app, progress)
})
.await;
if let Err(e) = result {
emit_progress(
&app,
ExportProgress {
export_id: export_id.clone(),
current_object: String::new(),
object_index: 0,
total_objects: 0,
rows_exported: 0,
total_rows: None,
status: ExportStatus::Error,
error: Some(e),
},
);
}
dbx_core::database_export::clear_export_cancelled(&export_id).await;
});
Ok(())
}
#[tauri::command]
pub async fn cancel_database_export(export_id: String) -> Result<(), String> {
dbx_core::database_export::set_export_cancelled(&export_id).await;
Ok(())
}