//! 工程依赖关系 — module_dependencies 表 CRUD(V35,工程间依赖边) //! //! 简化版:insert / delete / list_by_field(查 project_id)。 use std::sync::Arc; use rusqlite::{params, Row}; use tokio::sync::Mutex; use crate::db::Database; use crate::models::ModuleDependencyRecord; use super::{storage_err}; fn dep_from_row(row: &Row<'_>) -> std::result::Result { Ok(ModuleDependencyRecord { id: row.get("id")?, project_id: row.get("project_id")?, from_module_id: row.get("from_module_id")?, to_module_id: row.get("to_module_id")?, dep_type: row.get("dep_type")?, label: row.get("label")?, created_at: row.get("created_at")?, }) } pub struct ModuleDependencyRepo { conn: Arc>, } impl ModuleDependencyRepo { pub fn new(db: &Database) -> Self { Self { conn: db.conn() } } pub async fn insert(&self, record: ModuleDependencyRecord) -> Result { let conn = self.conn.clone(); tokio::task::spawn_blocking(move || { let guard = conn.blocking_lock(); let r = &record; let affected = guard .execute( "INSERT INTO module_dependencies \ (id, project_id, from_module_id, to_module_id, dep_type, label, created_at) \ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)", params![ r.id, r.project_id, r.from_module_id, r.to_module_id, r.dep_type, r.label, r.created_at, ], ) .map_err(storage_err)?; Ok(affected > 0) }) .await .map_err(storage_err)? } pub async fn delete(&self, id: &str) -> Result { let conn = self.conn.clone(); let id = id.to_owned(); tokio::task::spawn_blocking(move || { let guard = conn.blocking_lock(); let affected = guard .execute("DELETE FROM module_dependencies WHERE id = ?1", params![id]) .map_err(storage_err)?; Ok(affected > 0) }) .await .map_err(storage_err)? } pub async fn list_by_field(&self, field: &str, value: &str) -> Result, df_types::error::Error> { let conn = self.conn.clone(); let field = field.to_owned(); let value = value.to_owned(); tokio::task::spawn_blocking(move || { let guard = conn.blocking_lock(); let sql = format!( "SELECT id, project_id, from_module_id, to_module_id, dep_type, label, created_at \ FROM module_dependencies WHERE {field} = ?1 ORDER BY created_at ASC" ); let mut stmt = guard.prepare(&sql).map_err(storage_err)?; let rows = stmt .query_map(params![value], dep_from_row) .map_err(storage_err)?; let mut results = Vec::new(); for r in rows { results.push(r.map_err(storage_err)?); } Ok(results) }) .await .map_err(storage_err)? } }