mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-04-09 20:42:28 +08:00
* fix(schema): add missing base columns migration for proxy_config Add compatibility migration for older databases that may be missing the basic proxy_config columns (proxy_enabled, listen_address, listen_port, enable_logging) before adding newer timeout fields. * fix: add proxy_config base column patches for v3.9.0-2 upgrade Add base config column patches in create_tables_on_conn(): - proxy_enabled - listen_address - listen_port - enable_logging Ensures v3.9.0-2 users (user_version=2 but missing columns) can properly upgrade with all required fields added. * fix: migrate proxy_config singleton to per-app on startup for v2 databases Add startup migration for legacy proxy_config tables that still have singleton structure (no app_type column) even with user_version=2. This fixes the issue where v3.9.0-2 databases with v2 schema but legacy proxy_config structure would fail with "no such column: app_type" error. - Call migrate_proxy_config_to_per_app in create_tables_on_conn - Add regression test to verify the fix * style: cargo fmt --------- Co-authored-by: Jason <farion1231@gmail.com>
75 lines
2.5 KiB
Rust
75 lines
2.5 KiB
Rust
//! 统一供应商 (Universal Provider) DAO
|
|
//!
|
|
//! 提供统一供应商的 CRUD 操作。
|
|
|
|
use crate::database::{lock_conn, to_json_string, Database};
|
|
use crate::error::AppError;
|
|
use crate::provider::UniversalProvider;
|
|
use std::collections::HashMap;
|
|
|
|
/// 统一供应商的 Settings Key
|
|
const UNIVERSAL_PROVIDERS_KEY: &str = "universal_providers";
|
|
|
|
impl Database {
|
|
/// 获取所有统一供应商
|
|
pub fn get_all_universal_providers(
|
|
&self,
|
|
) -> Result<HashMap<String, UniversalProvider>, AppError> {
|
|
let conn = lock_conn!(self.conn);
|
|
|
|
let mut stmt = conn
|
|
.prepare("SELECT value FROM settings WHERE key = ?")
|
|
.map_err(|e| AppError::Database(e.to_string()))?;
|
|
|
|
let result: Option<String> = stmt
|
|
.query_row([UNIVERSAL_PROVIDERS_KEY], |row| row.get(0))
|
|
.ok();
|
|
|
|
match result {
|
|
Some(json) => serde_json::from_str(&json)
|
|
.map_err(|e| AppError::Database(format!("解析统一供应商数据失败: {e}"))),
|
|
None => Ok(HashMap::new()),
|
|
}
|
|
}
|
|
|
|
/// 获取单个统一供应商
|
|
pub fn get_universal_provider(&self, id: &str) -> Result<Option<UniversalProvider>, AppError> {
|
|
let providers = self.get_all_universal_providers()?;
|
|
Ok(providers.get(id).cloned())
|
|
}
|
|
|
|
/// 保存统一供应商(添加或更新)
|
|
pub fn save_universal_provider(&self, provider: &UniversalProvider) -> Result<(), AppError> {
|
|
let mut providers = self.get_all_universal_providers()?;
|
|
providers.insert(provider.id.clone(), provider.clone());
|
|
self.save_all_universal_providers(&providers)
|
|
}
|
|
|
|
/// 删除统一供应商
|
|
pub fn delete_universal_provider(&self, id: &str) -> Result<bool, AppError> {
|
|
let mut providers = self.get_all_universal_providers()?;
|
|
let existed = providers.remove(id).is_some();
|
|
if existed {
|
|
self.save_all_universal_providers(&providers)?;
|
|
}
|
|
Ok(existed)
|
|
}
|
|
|
|
/// 保存所有统一供应商(内部方法)
|
|
fn save_all_universal_providers(
|
|
&self,
|
|
providers: &HashMap<String, UniversalProvider>,
|
|
) -> Result<(), AppError> {
|
|
let conn = lock_conn!(self.conn);
|
|
let json = to_json_string(providers)?;
|
|
|
|
conn.execute(
|
|
"INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)",
|
|
[UNIVERSAL_PROVIDERS_KEY, &json],
|
|
)
|
|
.map_err(|e| AppError::Database(e.to_string()))?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|