100 lines
2.7 KiB
Rust
100 lines
2.7 KiB
Rust
//! 画中画/字幕素材:SQLite 访问与 Tauri 状态
|
||
|
||
use std::path::PathBuf;
|
||
use std::sync::Arc;
|
||
|
||
use tokio::sync::RwLock;
|
||
|
||
use crate::material_db::{MaterialDb, MaterialRecord};
|
||
|
||
#[derive(Debug, Default)]
|
||
pub struct MaterialStore {
|
||
inner: Arc<RwLock<Option<Arc<MaterialDb>>>>,
|
||
}
|
||
|
||
impl MaterialStore {
|
||
pub fn new() -> Self {
|
||
Self::default()
|
||
}
|
||
|
||
pub async fn init(&self, db_path: PathBuf) -> Result<(), String> {
|
||
let db = tokio::task::spawn_blocking(move || {
|
||
MaterialDb::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: "material", "素材数据库已初始化,共 {n} 条记录");
|
||
Ok(())
|
||
}
|
||
|
||
async fn with_db<F, T>(&self, f: F) -> Result<T, String>
|
||
where
|
||
F: FnOnce(Arc<MaterialDb>) -> Result<T, String> + Send + 'static,
|
||
T: Send + 'static,
|
||
{
|
||
let db = self
|
||
.inner
|
||
.read()
|
||
.await
|
||
.clone()
|
||
.ok_or_else(|| "素材数据库未初始化".to_string())?;
|
||
tokio::task::spawn_blocking(move || f(db))
|
||
.await
|
||
.map_err(|e| e.to_string())?
|
||
}
|
||
|
||
pub async fn list(&self) -> Result<Vec<MaterialRecord>, String> {
|
||
self.with_db(|db| db.list().map_err(|e| e.to_string()))
|
||
.await
|
||
}
|
||
|
||
pub async fn insert(
|
||
&self,
|
||
name: String,
|
||
path: String,
|
||
material_type: String,
|
||
info: serde_json::Value,
|
||
created_at: i64,
|
||
updated_at: i64,
|
||
) -> Result<MaterialRecord, String> {
|
||
self.with_db(move |db| {
|
||
db.insert(
|
||
&name,
|
||
&path,
|
||
&material_type,
|
||
info,
|
||
created_at,
|
||
updated_at,
|
||
)
|
||
.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 get(&self, id: i64) -> Result<Option<MaterialRecord>, String> {
|
||
self.with_db(move |db| db.get(id).map_err(|e| e.to_string()))
|
||
.await
|
||
}
|
||
|
||
pub async fn delete(&self, id: i64) -> Result<bool, String> {
|
||
self.with_db(move |db| db.delete(id).map_err(|e| e.to_string()))
|
||
.await
|
||
}
|
||
}
|