//! 语音识别历史:SQLite 访问与 Tauri 状态 use std::path::PathBuf; use std::sync::Arc; use tokio::sync::RwLock; use crate::asr_db::{AsrDb, AsrHistoryRecord}; #[derive(Debug, Default)] pub struct AsrStore { inner: Arc>>>, } impl AsrStore { pub fn new() -> Self { Self::default() } pub async fn init(&self, db_path: PathBuf) -> Result<(), String> { let db = tokio::task::spawn_blocking(move || { AsrDb::open(db_path).map_err(|e| e.to_string()) }) .await .map_err(|e| e.to_string())??; let count = tokio::task::spawn_blocking({ let db = Arc::new(db); let db2 = db.clone(); move || db2.list().map(|l| (db, l.len())).map_err(|e| e.to_string()) }) .await .map_err(|e| e.to_string())??; let (db, n) = count; *self.inner.write().await = Some(db); log::info!(target: "asr", "ASR 历史数据库已初始化,共 {n} 条记录"); Ok(()) } async fn with_db(&self, f: F) -> Result where F: FnOnce(Arc) -> Result + Send + 'static, T: Send + 'static, { let db = self .inner .read() .await .clone() .ok_or_else(|| "ASR 数据库未初始化".to_string())?; tokio::task::spawn_blocking(move || f(db)) .await .map_err(|e| e.to_string())? } pub async fn list(&self) -> Result, String> { self.with_db(|db| db.list().map_err(|e| e.to_string())).await } pub async fn insert( &self, name: String, source_path: String, result_text: String, ) -> Result { self.with_db(move |db| { db.insert(&name, &source_path, &result_text) .map_err(|e| e.to_string()) }) .await } pub async fn update_name(&self, id: i64, name: String) -> Result<(), String> { self.with_db(move |db| db.update_name(id, &name).map_err(|e| e.to_string())) .await } pub async fn delete(&self, id: i64) -> Result { self.with_db(move |db| db.delete(id).map_err(|e| e.to_string())) .await } }