From a5149147cd5646c52bad70a6887f4c265c3571fb Mon Sep 17 00:00:00 2001 From: JSR Date: Thu, 19 Mar 2026 17:39:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BF=9D=E5=AD=98PostgreSQL?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E5=B9=B6=E5=9C=A8=E5=90=AF=E5=8A=A8=E6=97=B6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/database.rs | 10 ++- src-tauri/src/lib.rs | 116 +++++++++++++++++++++++------ 2 files changed, 101 insertions(+), 25 deletions(-) diff --git a/src-tauri/src/commands/database.rs b/src-tauri/src/commands/database.rs index 4c38f1b..b38bb3f 100644 --- a/src-tauri/src/commands/database.rs +++ b/src-tauri/src/commands/database.rs @@ -706,6 +706,14 @@ pub async fn db_switch_connection( }; { + let settings_db_path = sqlite_db_path(&app_handle)?; + let settings_conn = create_sqlite_connection(&settings_db_path) + .await + .map_err(|e| e.to_string())?; + run_migration(&settings_conn, DatabaseType::SQLite) + .await + .map_err(|e| e.to_string())?; + let state_guard = state.read(); { let mut db_guard = state_guard.db.write(); @@ -713,7 +721,7 @@ pub async fn db_switch_connection( } let mut settings = state_guard.settings.write(); - settings.attach_db(Some(conn)); + settings.attach_db(Some(settings_conn)); settings.initialize().await.map_err(|e| e.to_string())?; settings .set_value( diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index a777d87..bb0c130 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -7,9 +7,10 @@ pub mod utils; use parking_lot::RwLock; use std::sync::Arc; -use crate::db::connection::create_sqlite_connection; +use crate::db::connection::{create_postgres_connection, create_sqlite_connection}; use crate::db::connection::DatabaseType; use crate::db::migration::run_migration; +use crate::services::settings::{SettingsKey, SettingsValue}; use crate::{commands::*, state::AppState}; use tauri::{App, Manager}; #[cfg(desktop)] @@ -142,31 +143,98 @@ fn setup_database(app: &mut App) -> Result<(), Box> { .to_string(); let db_result = tauri::async_runtime::block_on(async { - let conn = create_sqlite_connection(&db_path_str).await?; - run_migration(&conn, DatabaseType::SQLite).await?; - Ok::<_, Box>(conn) + let sqlite_conn = create_sqlite_connection(&db_path_str).await?; + run_migration(&sqlite_conn, DatabaseType::SQLite).await?; + + let state = handle.state::(); + let state_guard = state.write(); + let mut active_conn = sqlite_conn.clone(); + + { + let mut settings = state_guard.settings.write(); + settings.attach_db(Some(sqlite_conn.clone())); + settings + .initialize() + .await + .map_err(|e| format!("Failed to initialize settings from sqlite: {}", e))?; + + let pg_connection_string = match settings.get_value(SettingsKey::PgConnectionString) { + SettingsValue::String(s) => s, + _ => String::new(), + }; + + if !pg_connection_string.trim().is_empty() { + match create_postgres_connection(&pg_connection_string).await { + Ok(pg_conn) => { + if let Err(e) = run_migration(&pg_conn, DatabaseType::PostgreSQL).await { + eprintln!("PostgreSQL migration failed on startup, fallback to sqlite: {}", e); + settings + .set_value( + SettingsKey::PgConnectionStatus, + SettingsValue::Json(serde_json::json!({ + "connected": false, + "type": "sqlite", + "error": e.to_string() + })), + ) + .await + .map_err(|err| format!("Failed to save pg status: {}", err))?; + } else { + active_conn = pg_conn; + settings + .set_value( + SettingsKey::PgConnectionStatus, + SettingsValue::Json(serde_json::json!({ + "connected": true, + "type": "postgresql" + })), + ) + .await + .map_err(|err| format!("Failed to save pg status: {}", err))?; + eprintln!("Auto connected to PostgreSQL from saved connection string"); + } + } + Err(e) => { + eprintln!("PostgreSQL auto-connect failed, fallback to sqlite: {}", e); + settings + .set_value( + SettingsKey::PgConnectionStatus, + SettingsValue::Json(serde_json::json!({ + "connected": false, + "type": "sqlite", + "error": e.to_string() + })), + ) + .await + .map_err(|err| format!("Failed to save pg status: {}", err))?; + } + } + } else { + settings + .set_value( + SettingsKey::PgConnectionStatus, + SettingsValue::Json(serde_json::json!({ + "connected": true, + "type": "sqlite" + })), + ) + .await + .map_err(|err| format!("Failed to save sqlite status: {}", err))?; + } + } + + { + let mut db_guard = state_guard.db.write(); + *db_guard = Some(active_conn); + } + + Ok::<_, Box>(()) }); - match db_result { - Ok(conn) => { - let state = handle.state::(); - let state_guard = state.write(); - { - let mut db_guard = state_guard.db.write(); - *db_guard = Some(conn.clone()); - } - { - let mut settings = state_guard.settings.write(); - settings.attach_db(Some(conn)); - if let Err(e) = tauri::async_runtime::block_on(settings.initialize()) { - eprintln!("Failed to initialize settings from database: {}", e); - } - } - eprintln!("Database connected to: {}", db_path_str); - } - Err(e) => { - eprintln!("Failed to connect to database: {}", e); - } + if let Err(e) = db_result { + eprintln!("Failed to connect to database: {}", e); + } else { + eprintln!("Database bootstrap completed, sqlite settings db: {}", db_path_str); } Ok(())