chore: add rustfmt.toml and apply unified code formatting

This commit is contained in:
t8y2
2026-05-05 14:16:18 +08:00
parent edcdd652ae
commit 41445ff474
53 changed files with 1177 additions and 2592 deletions
+15 -60
View File
@@ -6,9 +6,7 @@ use axum::Json;
use futures::stream::Stream;
use serde::Deserialize;
use dbx_core::ai::{
AiCompletionRequest, AiConfig, AiConversation, AiStreamChunk,
};
use dbx_core::ai::{AiCompletionRequest, AiConfig, AiConversation, AiStreamChunk};
use crate::error::AppError;
use crate::state::WebState;
@@ -62,24 +60,12 @@ pub async fn save_ai_config(
State(state): State<Arc<WebState>>,
Json(body): Json<SaveAiConfigRequest>,
) -> Result<Json<()>, AppError> {
state
.app
.storage
.save_ai_config(&body.config)
.await
.map_err(AppError)?;
state.app.storage.save_ai_config(&body.config).await.map_err(AppError)?;
Ok(Json(()))
}
pub async fn load_ai_config(
State(state): State<Arc<WebState>>,
) -> Result<Json<Option<AiConfig>>, AppError> {
let config = state
.app
.storage
.load_ai_config()
.await
.map_err(AppError)?;
pub async fn load_ai_config(State(state): State<Arc<WebState>>) -> Result<Json<Option<AiConfig>>, AppError> {
let config = state.app.storage.load_ai_config().await.map_err(AppError)?;
Ok(Json(config))
}
@@ -91,24 +77,12 @@ pub async fn save_ai_conversation(
State(state): State<Arc<WebState>>,
Json(body): Json<SaveAiConversationRequest>,
) -> Result<Json<()>, AppError> {
state
.app
.storage
.save_ai_conversation(&body.conversation)
.await
.map_err(AppError)?;
state.app.storage.save_ai_conversation(&body.conversation).await.map_err(AppError)?;
Ok(Json(()))
}
pub async fn load_ai_conversations(
State(state): State<Arc<WebState>>,
) -> Result<Json<Vec<AiConversation>>, AppError> {
let conversations = state
.app
.storage
.load_ai_conversations()
.await
.map_err(AppError)?;
pub async fn load_ai_conversations(State(state): State<Arc<WebState>>) -> Result<Json<Vec<AiConversation>>, AppError> {
let conversations = state.app.storage.load_ai_conversations().await.map_err(AppError)?;
Ok(Json(conversations))
}
@@ -116,12 +90,7 @@ pub async fn delete_ai_conversation(
State(state): State<Arc<WebState>>,
Path(id): Path<String>,
) -> Result<Json<()>, AppError> {
state
.app
.storage
.delete_ai_conversation(&id)
.await
.map_err(AppError)?;
state.app.storage.delete_ai_conversation(&id).await.map_err(AppError)?;
Ok(Json(()))
}
@@ -129,12 +98,8 @@ pub async fn delete_ai_conversation(
// AI complete (non-streaming)
// ---------------------------------------------------------------------------
pub async fn ai_complete(
Json(body): Json<AiCompleteRequest>,
) -> Result<Json<String>, AppError> {
let result = dbx_core::ai::complete(&body.request)
.await
.map_err(AppError)?;
pub async fn ai_complete(Json(body): Json<AiCompleteRequest>) -> Result<Json<String>, AppError> {
let result = dbx_core::ai::complete(&body.request).await.map_err(AppError)?;
Ok(Json(result))
}
@@ -142,12 +107,8 @@ pub async fn ai_complete(
// AI test connection
// ---------------------------------------------------------------------------
pub async fn ai_test_connection(
Json(body): Json<AiTestConnectionRequest>,
) -> Result<Json<String>, AppError> {
let result = dbx_core::ai::test_connection_core(&body.config)
.await
.map_err(AppError)?;
pub async fn ai_test_connection(Json(body): Json<AiTestConnectionRequest>) -> Result<Json<String>, AppError> {
let result = dbx_core::ai::test_connection_core(&body.config).await.map_err(AppError)?;
Ok(Json(result))
}
@@ -155,9 +116,7 @@ pub async fn ai_test_connection(
// AI cancel stream
// ---------------------------------------------------------------------------
pub async fn ai_cancel_stream(
Json(body): Json<AiCancelStreamRequest>,
) -> Result<Json<bool>, AppError> {
pub async fn ai_cancel_stream(Json(body): Json<AiCancelStreamRequest>) -> Result<Json<bool>, AppError> {
let result = dbx_core::ai::cancel_stream(&body.session_id).await;
Ok(Json(result))
}
@@ -184,12 +143,8 @@ pub async fn ai_stream(
.await;
if let Err(_e) = result {
let error_chunk = AiStreamChunk {
session_id: sid.clone(),
delta: String::new(),
reasoning_delta: None,
done: true,
};
let error_chunk =
AiStreamChunk { session_id: sid.clone(), delta: String::new(), reasoning_delta: None, done: true };
let _ = tx.send(serde_json::to_string(&error_chunk).unwrap_or_default());
}
+10 -40
View File
@@ -35,24 +35,15 @@ pub async fn test_connection(
// Store config temporarily
let temp_id = format!("__test_{}", uuid::Uuid::new_v4());
app.configs
.lock()
.await
.insert(temp_id.clone(), config.clone());
app.configs.lock().await.insert(temp_id.clone(), config.clone());
// Try to connect
let result = app
.get_or_create_pool(&temp_id, config.database.as_deref())
.await;
let result = app.get_or_create_pool(&temp_id, config.database.as_deref()).await;
// Clean up any pool keys created for the temporary connection, including
// database-scoped keys like "__test_uuid:database".
let mut connections = app.connections.lock().await;
let temp_keys: Vec<String> = connections
.keys()
.filter(|key| key.starts_with(&temp_id))
.cloned()
.collect();
let temp_keys: Vec<String> = connections.keys().filter(|key| key.starts_with(&temp_id)).cloned().collect();
for key in temp_keys {
connections.remove(&key);
}
@@ -73,15 +64,9 @@ pub async fn connect_db(
let app = &state.app;
let connection_id = config.id.clone();
app.configs
.lock()
.await
.insert(connection_id.clone(), config.clone());
app.configs.lock().await.insert(connection_id.clone(), config.clone());
let pool_key = app
.get_or_create_pool(&connection_id, config.database.as_deref())
.await
.map_err(AppError)?;
let pool_key = app.get_or_create_pool(&connection_id, config.database.as_deref()).await.map_err(AppError)?;
Ok(Json(pool_key))
}
@@ -94,11 +79,8 @@ pub async fn disconnect_db(
let mut connections = app.connections.lock().await;
// Remove all pool keys that start with this connection_id
let keys_to_remove: Vec<String> = connections
.keys()
.filter(|k| k.starts_with(&body.connection_id))
.cloned()
.collect();
let keys_to_remove: Vec<String> =
connections.keys().filter(|k| k.starts_with(&body.connection_id)).cloned().collect();
for key in keys_to_remove {
connections.remove(&key);
}
@@ -114,23 +96,11 @@ pub async fn save_connections(
State(state): State<Arc<WebState>>,
Json(body): Json<SaveConnectionsRequest>,
) -> Result<Json<()>, AppError> {
state
.app
.storage
.save_connections(&body.configs)
.await
.map_err(AppError)?;
state.app.storage.save_connections(&body.configs).await.map_err(AppError)?;
Ok(Json(()))
}
pub async fn load_connections(
State(state): State<Arc<WebState>>,
) -> Result<Json<Vec<ConnectionConfig>>, AppError> {
let configs = state
.app
.storage
.load_connections()
.await
.map_err(AppError)?;
pub async fn load_connections(State(state): State<Arc<WebState>>) -> Result<Json<Vec<ConnectionConfig>>, AppError> {
let configs = state.app.storage.load_connections().await.map_err(AppError)?;
Ok(Json(configs))
}
+3 -18
View File
@@ -24,12 +24,7 @@ pub async fn save_history(
State(state): State<Arc<WebState>>,
Json(body): Json<SaveHistoryRequest>,
) -> Result<Json<()>, AppError> {
state
.app
.storage
.save_history_entry(&body.entry)
.await
.map_err(AppError)?;
state.app.storage.save_history_entry(&body.entry).await.map_err(AppError)?;
Ok(Json(()))
}
@@ -39,12 +34,7 @@ pub async fn load_history(
) -> Result<Json<Vec<HistoryEntry>>, AppError> {
let limit = q.limit.unwrap_or(100);
let offset = q.offset.unwrap_or(0);
let entries = state
.app
.storage
.load_history_entries(limit, offset)
.await
.map_err(AppError)?;
let entries = state.app.storage.load_history_entries(limit, offset).await.map_err(AppError)?;
Ok(Json(entries))
}
@@ -57,11 +47,6 @@ pub async fn delete_history_entry(
State(state): State<Arc<WebState>>,
Path(id): Path<String>,
) -> Result<Json<()>, AppError> {
state
.app
.storage
.delete_history_entry(&id)
.await
.map_err(AppError)?;
state.app.storage.delete_history_entry(&id).await.map_err(AppError)?;
Ok(Json(()))
}
+3 -15
View File
@@ -17,23 +17,11 @@ pub async fn save_sidebar_layout(
State(state): State<Arc<WebState>>,
Json(body): Json<SaveLayoutRequest>,
) -> Result<Json<()>, AppError> {
state
.app
.storage
.save_sidebar_layout(&body.layout)
.await
.map_err(AppError)?;
state.app.storage.save_sidebar_layout(&body.layout).await.map_err(AppError)?;
Ok(Json(()))
}
pub async fn load_sidebar_layout(
State(state): State<Arc<WebState>>,
) -> Result<Json<serde_json::Value>, AppError> {
let layout = state
.app
.storage
.load_sidebar_layout()
.await
.map_err(AppError)?;
pub async fn load_sidebar_layout(State(state): State<Arc<WebState>>) -> Result<Json<serde_json::Value>, AppError> {
let layout = state.app.storage.load_sidebar_layout().await.map_err(AppError)?;
Ok(Json(layout.unwrap_or(serde_json::json!(null))))
}
+5 -10
View File
@@ -62,9 +62,8 @@ pub async fn list_databases(
State(state): State<Arc<WebState>>,
Json(req): Json<MongoConnectionRequest>,
) -> Result<Json<Vec<String>>, AppError> {
let result = dbx_core::mongo_ops::mongo_list_databases_core(&state.app, &req.connection_id)
.await
.map_err(AppError)?;
let result =
dbx_core::mongo_ops::mongo_list_databases_core(&state.app, &req.connection_id).await.map_err(AppError)?;
Ok(Json(result))
}
@@ -72,13 +71,9 @@ pub async fn list_collections(
State(state): State<Arc<WebState>>,
Json(req): Json<MongoCollectionRequest>,
) -> Result<Json<Vec<String>>, AppError> {
let result = dbx_core::mongo_ops::mongo_list_collections_core(
&state.app,
&req.connection_id,
&req.database,
)
.await
.map_err(AppError)?;
let result = dbx_core::mongo_ops::mongo_list_collections_core(&state.app, &req.connection_id, &req.database)
.await
.map_err(AppError)?;
Ok(Json(result))
}
+8 -22
View File
@@ -34,9 +34,7 @@ pub async fn execute_query(
State(state): State<Arc<WebState>>,
Json(req): Json<ExecuteQueryRequest>,
) -> Result<Json<serde_json::Value>, AppError> {
let execution_id = req
.execution_id
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
let execution_id = req.execution_id.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
let registered = state.app.running_queries.register(execution_id);
let cancel_token = registered.token();
@@ -59,9 +57,7 @@ pub async fn execute_multi(
State(state): State<Arc<WebState>>,
Json(req): Json<ExecuteQueryRequest>,
) -> Result<Json<serde_json::Value>, AppError> {
let execution_id = req
.execution_id
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
let execution_id = req.execution_id.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
let registered = state.app.running_queries.register(execution_id);
let cancel_token = registered.token();
@@ -84,14 +80,9 @@ pub async fn execute_batch(
State(state): State<Arc<WebState>>,
Json(req): Json<ExecuteBatchRequest>,
) -> Result<Json<serde_json::Value>, AppError> {
let result = dbx_core::query::execute_statements(
&state.app,
&req.connection_id,
&req.database,
&req.statements,
)
.await
.map_err(AppError)?;
let result = dbx_core::query::execute_statements(&state.app, &req.connection_id, &req.database, &req.statements)
.await
.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -109,14 +100,9 @@ pub async fn execute_script(
Json(req): Json<ExecuteQueryRequest>,
) -> Result<Json<serde_json::Value>, AppError> {
let statements = dbx_core::sql::split_sql_statements(&req.sql);
let result = dbx_core::query::execute_statements(
&state.app,
&req.connection_id,
&req.database,
&statements,
)
.await
.map_err(AppError)?;
let result = dbx_core::query::execute_statements(&state.app, &req.connection_id, &req.database, &statements)
.await
.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
+17 -43
View File
@@ -69,9 +69,8 @@ pub async fn list_databases(
State(state): State<Arc<WebState>>,
Json(req): Json<RedisConnectionRequest>,
) -> Result<Json<serde_json::Value>, AppError> {
let result = dbx_core::redis_ops::redis_list_databases_core(&state.app, &req.connection_id)
.await
.map_err(AppError)?;
let result =
dbx_core::redis_ops::redis_list_databases_core(&state.app, &req.connection_id).await.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -96,9 +95,8 @@ pub async fn get_value(
State(state): State<Arc<WebState>>,
Json(req): Json<RedisKeyRequest>,
) -> Result<Json<serde_json::Value>, AppError> {
let result = dbx_core::redis_ops::redis_get_value_core(&state.app, &req.connection_id, &req.key)
.await
.map_err(AppError)?;
let result =
dbx_core::redis_ops::redis_get_value_core(&state.app, &req.connection_id, &req.key).await.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -106,15 +104,9 @@ pub async fn set_string(
State(state): State<Arc<WebState>>,
Json(req): Json<RedisSetStringRequest>,
) -> Result<Json<()>, AppError> {
dbx_core::redis_ops::redis_set_string_core(
&state.app,
&req.connection_id,
&req.key,
&req.value,
req.ttl,
)
.await
.map_err(AppError)?;
dbx_core::redis_ops::redis_set_string_core(&state.app, &req.connection_id, &req.key, &req.value, req.ttl)
.await
.map_err(AppError)?;
Ok(Json(()))
}
@@ -122,9 +114,7 @@ pub async fn delete_key(
State(state): State<Arc<WebState>>,
Json(req): Json<RedisKeyRequest>,
) -> Result<Json<()>, AppError> {
dbx_core::redis_ops::redis_delete_key_core(&state.app, &req.connection_id, &req.key)
.await
.map_err(AppError)?;
dbx_core::redis_ops::redis_delete_key_core(&state.app, &req.connection_id, &req.key).await.map_err(AppError)?;
Ok(Json(()))
}
@@ -133,15 +123,9 @@ pub async fn hash_set(
Json(req): Json<RedisHashRequest>,
) -> Result<Json<()>, AppError> {
let value = req.value.as_deref().unwrap_or("");
dbx_core::redis_ops::redis_hash_set_core(
&state.app,
&req.connection_id,
&req.key,
&req.field,
value,
)
.await
.map_err(AppError)?;
dbx_core::redis_ops::redis_hash_set_core(&state.app, &req.connection_id, &req.key, &req.field, value)
.await
.map_err(AppError)?;
Ok(Json(()))
}
@@ -149,14 +133,9 @@ pub async fn hash_del(
State(state): State<Arc<WebState>>,
Json(req): Json<RedisHashRequest>,
) -> Result<Json<()>, AppError> {
dbx_core::redis_ops::redis_hash_del_core(
&state.app,
&req.connection_id,
&req.key,
&req.field,
)
.await
.map_err(AppError)?;
dbx_core::redis_ops::redis_hash_del_core(&state.app, &req.connection_id, &req.key, &req.field)
.await
.map_err(AppError)?;
Ok(Json(()))
}
@@ -196,13 +175,8 @@ pub async fn set_remove(
State(state): State<Arc<WebState>>,
Json(req): Json<RedisSetRequest>,
) -> Result<Json<()>, AppError> {
dbx_core::redis_ops::redis_set_remove_core(
&state.app,
&req.connection_id,
&req.key,
&req.member,
)
.await
.map_err(AppError)?;
dbx_core::redis_ops::redis_set_remove_core(&state.app, &req.connection_id, &req.key, &req.member)
.await
.map_err(AppError)?;
Ok(Json(()))
}
+18 -54
View File
@@ -19,9 +19,7 @@ pub async fn list_databases(
State(state): State<Arc<WebState>>,
Query(q): Query<SchemaQuery>,
) -> Result<Json<serde_json::Value>, AppError> {
let result = dbx_core::schema::list_databases_core(&state.app, &q.connection_id)
.await
.map_err(AppError)?;
let result = dbx_core::schema::list_databases_core(&state.app, &q.connection_id).await.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -30,9 +28,7 @@ pub async fn list_schemas(
Query(q): Query<SchemaQuery>,
) -> Result<Json<Vec<String>>, AppError> {
let database = q.database.as_deref().unwrap_or("");
let result = dbx_core::schema::list_schemas_core(&state.app, &q.connection_id, database)
.await
.map_err(AppError)?;
let result = dbx_core::schema::list_schemas_core(&state.app, &q.connection_id, database).await.map_err(AppError)?;
Ok(Json(result))
}
@@ -43,9 +39,7 @@ pub async fn list_tables(
let database = q.database.as_deref().unwrap_or("");
let schema = q.schema.as_deref().unwrap_or("");
let result =
dbx_core::schema::list_tables_core(&state.app, &q.connection_id, database, schema)
.await
.map_err(AppError)?;
dbx_core::schema::list_tables_core(&state.app, &q.connection_id, database, schema).await.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -56,15 +50,9 @@ pub async fn list_columns(
let database = q.database.as_deref().unwrap_or("");
let schema = q.schema.as_deref().unwrap_or("");
let table = q.table.as_deref().unwrap_or("");
let result = dbx_core::schema::get_columns_core(
&state.app,
&q.connection_id,
database,
schema,
table,
)
.await
.map_err(AppError)?;
let result = dbx_core::schema::get_columns_core(&state.app, &q.connection_id, database, schema, table)
.await
.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -75,15 +63,9 @@ pub async fn list_indexes(
let database = q.database.as_deref().unwrap_or("");
let schema = q.schema.as_deref().unwrap_or("");
let table = q.table.as_deref().unwrap_or("");
let result = dbx_core::schema::list_indexes_core(
&state.app,
&q.connection_id,
database,
schema,
table,
)
.await
.map_err(AppError)?;
let result = dbx_core::schema::list_indexes_core(&state.app, &q.connection_id, database, schema, table)
.await
.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -94,15 +76,9 @@ pub async fn list_foreign_keys(
let database = q.database.as_deref().unwrap_or("");
let schema = q.schema.as_deref().unwrap_or("");
let table = q.table.as_deref().unwrap_or("");
let result = dbx_core::schema::list_foreign_keys_core(
&state.app,
&q.connection_id,
database,
schema,
table,
)
.await
.map_err(AppError)?;
let result = dbx_core::schema::list_foreign_keys_core(&state.app, &q.connection_id, database, schema, table)
.await
.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -113,15 +89,9 @@ pub async fn list_triggers(
let database = q.database.as_deref().unwrap_or("");
let schema = q.schema.as_deref().unwrap_or("");
let table = q.table.as_deref().unwrap_or("");
let result = dbx_core::schema::list_triggers_core(
&state.app,
&q.connection_id,
database,
schema,
table,
)
.await
.map_err(AppError)?;
let result = dbx_core::schema::list_triggers_core(&state.app, &q.connection_id, database, schema, table)
.await
.map_err(AppError)?;
Ok(Json(serde_json::to_value(result).map_err(|e| AppError(e.to_string()))?))
}
@@ -132,14 +102,8 @@ pub async fn get_ddl(
let database = q.database.as_deref().unwrap_or("");
let schema = q.schema.as_deref().unwrap_or("");
let table = q.table.as_deref().unwrap_or("");
let result = dbx_core::schema::get_table_ddl_core(
&state.app,
&q.connection_id,
database,
schema,
table,
)
.await
.map_err(AppError)?;
let result = dbx_core::schema::get_table_ddl_core(&state.app, &q.connection_id, database, schema, table)
.await
.map_err(AppError)?;
Ok(Json(result))
}
+6 -21
View File
@@ -3,8 +3,8 @@ use std::sync::Arc;
use axum::extract::{Multipart, Path, State};
use axum::response::sse::{Event, Sse};
use axum::Json;
use dbx_core::sql;
use dbx_core::query;
use dbx_core::sql;
use futures::stream::Stream;
use serde::Deserialize;
@@ -40,15 +40,8 @@ pub async fn preview_sql_file(
let tmp_dir = state.data_dir.join("tmp");
std::fs::create_dir_all(&tmp_dir).map_err(|e| AppError(e.to_string()))?;
while let Some(field) = multipart
.next_field()
.await
.map_err(|e| AppError(e.to_string()))?
{
let file_name = field
.file_name()
.unwrap_or("upload.sql")
.to_string();
while let Some(field) = multipart.next_field().await.map_err(|e| AppError(e.to_string()))? {
let file_name = field.file_name().unwrap_or("upload.sql").to_string();
let data = field.bytes().await.map_err(|e| AppError(e.to_string()))?;
let file_path = tmp_dir.join(&file_name);
@@ -77,11 +70,7 @@ pub async fn execute_sql_file(
let execution_id = req.execution_id.clone();
let (tx, _) = tokio::sync::broadcast::channel::<String>(256);
state
.sse_channels
.write()
.await
.insert(execution_id.clone(), tx.clone());
state.sse_channels.write().await.insert(execution_id.clone(), tx.clone());
let app = state.app.clone();
let state_clone = state.clone();
@@ -149,9 +138,7 @@ pub async fn execute_sql_file(
let _ = tx.send(json);
}
match query::execute_sql_statement(&app, &req.connection_id, &req.database, stmt, None)
.await
{
match query::execute_sql_statement(&app, &req.connection_id, &req.database, stmt, None).await {
Ok(result) => {
success_count += 1;
total_affected += result.affected_rows;
@@ -220,9 +207,7 @@ pub async fn sql_file_progress(
Path(execution_id): Path<String>,
) -> Result<Sse<impl Stream<Item = Result<Event, std::convert::Infallible>>>, AppError> {
let channels = state.sse_channels.read().await;
let tx = channels
.get(&execution_id)
.ok_or_else(|| AppError("Execution not found".to_string()))?;
let tx = channels.get(&execution_id).ok_or_else(|| AppError("Execution not found".to_string()))?;
let rx = tx.subscribe();
drop(channels);
Ok(crate::sse::sse_from_channel(rx))
+9 -32
View File
@@ -3,9 +3,7 @@ use std::sync::Arc;
use axum::extract::{Multipart, Path, State};
use axum::response::sse::{Event, Sse};
use axum::Json;
use dbx_core::table_import::{
self, TableImportRequest,
};
use dbx_core::table_import::{self, TableImportRequest};
use dbx_core::transfer;
use futures::stream::Stream;
use serde::Deserialize;
@@ -32,27 +30,17 @@ pub async fn preview_import(
let tmp_dir = state.data_dir.join("tmp");
std::fs::create_dir_all(&tmp_dir).map_err(|e| AppError(e.to_string()))?;
while let Some(field) = multipart
.next_field()
.await
.map_err(|e| AppError(e.to_string()))?
{
let file_name = field
.file_name()
.unwrap_or("upload.csv")
.to_string();
while let Some(field) = multipart.next_field().await.map_err(|e| AppError(e.to_string()))? {
let file_name = field.file_name().unwrap_or("upload.csv").to_string();
let data = field.bytes().await.map_err(|e| AppError(e.to_string()))?;
let file_path = tmp_dir.join(&file_name);
std::fs::write(&file_path, &data).map_err(|e| AppError(e.to_string()))?;
let file_path_str = file_path.to_string_lossy().to_string();
let preview = table_import::preview_table_import_file_core(&file_path_str)
.map_err(AppError)?;
let preview = table_import::preview_table_import_file_core(&file_path_str).map_err(AppError)?;
return Ok(Json(
serde_json::to_value(preview).map_err(|e| AppError(e.to_string()))?,
));
return Ok(Json(serde_json::to_value(preview).map_err(|e| AppError(e.to_string()))?));
}
Err(AppError("No file uploaded".to_string()))
@@ -66,11 +54,7 @@ pub async fn execute_import(
let import_id = req.import_id.clone();
let (tx, _) = tokio::sync::broadcast::channel::<String>(256);
state
.sse_channels
.write()
.await
.insert(import_id.clone(), tx.clone());
state.sse_channels.write().await.insert(import_id.clone(), tx.clone());
let app = state.app.clone();
let state_clone = state.clone();
@@ -91,10 +75,7 @@ pub async fn execute_import(
}
};
let pool_key = match app
.get_or_create_pool(&req.connection_id, Some(&req.database))
.await
{
let pool_key = match app.get_or_create_pool(&req.connection_id, Some(&req.database)).await {
Ok(k) => k,
Err(e) => {
let _ = tx.send(
@@ -118,9 +99,7 @@ pub async fn execute_import(
&pool_key,
|id: &str| {
let id = id.to_string();
Box::pin(async move {
transfer::is_cancelled(&id).await
})
Box::pin(async move { transfer::is_cancelled(&id).await })
},
|progress| {
if let Ok(json) = serde_json::to_string(&progress) {
@@ -159,9 +138,7 @@ pub async fn import_progress(
Path(import_id): Path<String>,
) -> Result<Sse<impl Stream<Item = Result<Event, std::convert::Infallible>>>, AppError> {
let channels = state.sse_channels.read().await;
let tx = channels
.get(&import_id)
.ok_or_else(|| AppError("Import not found".to_string()))?;
let tx = channels.get(&import_id).ok_or_else(|| AppError("Import not found".to_string()))?;
let rx = tx.subscribe();
drop(channels);
Ok(crate::sse::sse_from_channel(rx))
+5 -17
View File
@@ -31,11 +31,7 @@ pub async fn start_transfer(
// Create a broadcast channel for progress
let (tx, _) = tokio::sync::broadcast::channel::<String>(256);
state
.sse_channels
.write()
.await
.insert(transfer_id.clone(), tx.clone());
state.sse_channels.write().await.insert(transfer_id.clone(), tx.clone());
let app = state.app.clone();
let state_clone = state.clone();
@@ -56,9 +52,7 @@ pub async fn start_transfer(
}
};
let source_pool_key = match app
.get_or_create_pool(&req.source_connection_id, Some(&req.source_database))
.await
let source_pool_key = match app.get_or_create_pool(&req.source_connection_id, Some(&req.source_database)).await
{
Ok(k) => k,
Err(e) => {
@@ -66,9 +60,7 @@ pub async fn start_transfer(
return;
}
};
let target_pool_key = match app
.get_or_create_pool(&req.target_connection_id, Some(&req.target_database))
.await
let target_pool_key = match app.get_or_create_pool(&req.target_connection_id, Some(&req.target_database)).await
{
Ok(k) => k,
Err(e) => {
@@ -151,9 +143,7 @@ pub async fn start_transfer(
state_clone.sse_channels.write().await.remove(&req.transfer_id);
});
Ok(Json(
serde_json::json!({ "transferId": transfer_id }),
))
Ok(Json(serde_json::json!({ "transferId": transfer_id })))
}
pub async fn transfer_progress(
@@ -161,9 +151,7 @@ pub async fn transfer_progress(
Path(transfer_id): Path<String>,
) -> Result<Sse<impl Stream<Item = Result<Event, std::convert::Infallible>>>, AppError> {
let channels = state.sse_channels.read().await;
let tx = channels
.get(&transfer_id)
.ok_or_else(|| AppError("Transfer not found".to_string()))?;
let tx = channels.get(&transfer_id).ok_or_else(|| AppError("Transfer not found".to_string()))?;
let rx = tx.subscribe();
drop(channels);
Ok(crate::sse::sse_from_channel(rx))