diff --git a/apps/desktop/src-tauri/src/data/repositories/conversation_repository.rs b/apps/desktop/src-tauri/src/data/repositories/conversation_repository.rs index 495d800..3e7f538 100644 --- a/apps/desktop/src-tauri/src/data/repositories/conversation_repository.rs +++ b/apps/desktop/src-tauri/src/data/repositories/conversation_repository.rs @@ -22,13 +22,20 @@ impl ConversationRepository { Self { database } } - /// 初始化会话相关数据表 + /// 初始化会话相关数据表(强制使用连接池) pub fn initialize_tables(&self) -> Result<()> { - let conn = self.database.get_connection(); - let conn = conn.lock().unwrap(); + println!("🏊 使用连接池初始化会话表..."); + + // 🚨 强制使用连接池,避免死锁 + if !self.database.has_pool() { + return Err(anyhow!("连接池未启用,无法安全执行数据库操作")); + } + + let pooled_conn = self.database.acquire_from_pool() + .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?; // 创建会话表 - conn.execute( + pooled_conn.execute( "CREATE TABLE IF NOT EXISTS conversation_sessions ( id TEXT PRIMARY KEY, title TEXT, @@ -41,7 +48,7 @@ impl ConversationRepository { )?; // 创建消息表 - conn.execute( + pooled_conn.execute( "CREATE TABLE IF NOT EXISTS conversation_messages ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, @@ -55,18 +62,19 @@ impl ConversationRepository { )?; // 创建索引以提高查询性能 - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_messages_session_timestamp + pooled_conn.execute( + "CREATE INDEX IF NOT EXISTS idx_messages_session_timestamp ON conversation_messages (session_id, timestamp)", [], )?; - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_sessions_active_updated + pooled_conn.execute( + "CREATE INDEX IF NOT EXISTS idx_sessions_active_updated ON conversation_sessions (is_active, updated_at)", [], )?; + println!("✅ 会话表初始化完成"); Ok(()) } diff --git a/apps/desktop/src-tauri/src/data/repositories/outfit_image_repository.rs b/apps/desktop/src-tauri/src/data/repositories/outfit_image_repository.rs index 936952f..ed8a4a4 100644 --- a/apps/desktop/src-tauri/src/data/repositories/outfit_image_repository.rs +++ b/apps/desktop/src-tauri/src/data/repositories/outfit_image_repository.rs @@ -438,25 +438,40 @@ impl OutfitImageRepository { Ok(records) } - /// 删除穿搭图片生成记录 + /// 删除穿搭图片生成记录(强制使用连接池) pub fn delete_record(&self, id: &str) -> Result<()> { - let conn = self.database.get_connection(); - let conn = conn.lock().map_err(|e| anyhow!("获取数据库连接失败: {}", e))?; + println!("🏊 使用连接池删除穿搭记录: {}", &id[..8]); - conn.execute( + // 🚨 强制使用连接池,避免死锁 + if !self.database.has_pool() { + return Err(anyhow!("连接池未启用,无法安全执行数据库操作")); + } + + let pooled_conn = self.database.acquire_from_pool() + .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?; + + pooled_conn.execute( "DELETE FROM outfit_image_records WHERE id = ?1", params![id], ).map_err(|e| anyhow!("删除穿搭图片记录失败: {}", e))?; + println!("✅ 连接池删除穿搭记录完成"); Ok(()) } - /// 创建商品图片 + /// 创建商品图片(强制使用连接池) pub fn create_product_image(&self, product_image: &ProductImage) -> Result<()> { - let conn = self.database.get_connection(); - let conn = conn.lock().map_err(|e| anyhow!("获取数据库连接失败: {}", e))?; + println!("🏊 使用连接池创建商品图片: {}", &product_image.id[..8]); - conn.execute( + // 🚨 强制使用连接池,避免死锁 + if !self.database.has_pool() { + return Err(anyhow!("连接池未启用,无法安全执行数据库操作")); + } + + let pooled_conn = self.database.acquire_from_pool() + .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?; + + pooled_conn.execute( r#" INSERT INTO product_images ( id, outfit_record_id, file_path, file_name, file_size, @@ -475,20 +490,28 @@ impl OutfitImageRepository { ], ).map_err(|e| anyhow!("创建商品图片失败: {}", e))?; + println!("✅ 连接池创建商品图片完成"); Ok(()) } - /// 根据记录ID获取商品图片列表 + /// 根据记录ID获取商品图片列表(强制使用连接池) pub fn get_product_images_by_record_id(&self, record_id: &str) -> Result> { - let conn = self.database.get_connection(); - let conn = conn.lock().map_err(|e| anyhow!("获取数据库连接失败: {}", e))?; + println!("🏊 使用连接池获取商品图片: {}", &record_id[..8]); - let mut stmt = conn.prepare( + // 🚨 强制使用连接池,避免死锁 + if !self.database.has_pool() { + return Err(anyhow!("连接池未启用,无法安全执行数据库操作")); + } + + let pooled_conn = self.database.acquire_from_pool() + .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?; + + let mut stmt = pooled_conn.prepare( r#" SELECT id, outfit_record_id, file_path, file_name, file_size, upload_url, description, created_at - FROM product_images - WHERE outfit_record_id = ?1 + FROM product_images + WHERE outfit_record_id = ?1 ORDER BY created_at ASC "#, ).map_err(|e| anyhow!("准备查询语句失败: {}", e))?; @@ -502,18 +525,26 @@ impl OutfitImageRepository { images.push(image.map_err(|e| anyhow!("解析商品图片失败: {}", e))?); } + println!("✅ 连接池查询商品图片完成,获取到 {} 张图片", images.len()); Ok(images) } - /// 创建穿搭图片 + /// 创建穿搭图片(强制使用连接池) pub fn create_outfit_image(&self, outfit_image: &OutfitImage) -> Result<()> { - let conn = self.database.get_connection(); - let conn = conn.lock().map_err(|e| anyhow!("获取数据库连接失败: {}", e))?; + println!("🏊 使用连接池创建穿搭图片: {}", &outfit_image.id[..8]); + + // 🚨 强制使用连接池,避免死锁 + if !self.database.has_pool() { + return Err(anyhow!("连接池未启用,无法安全执行数据库操作")); + } + + let pooled_conn = self.database.acquire_from_pool() + .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?; let tags_json = serde_json::to_string(&outfit_image.tags) .map_err(|e| anyhow!("序列化tags失败: {}", e))?; - conn.execute( + pooled_conn.execute( r#" INSERT INTO outfit_images ( id, outfit_record_id, image_url, local_path, image_index, @@ -533,15 +564,23 @@ impl OutfitImageRepository { ], ).map_err(|e| anyhow!("创建穿搭图片失败: {}", e))?; + println!("✅ 连接池创建穿搭图片完成"); Ok(()) } - /// 根据记录ID获取穿搭图片列表 + /// 根据记录ID获取穿搭图片列表(强制使用连接池) pub fn get_outfit_images_by_record_id(&self, record_id: &str) -> Result> { - let conn = self.database.get_connection(); - let conn = conn.lock().map_err(|e| anyhow!("获取数据库连接失败: {}", e))?; + println!("🏊 使用连接池获取穿搭图片: {}", &record_id[..8]); - let mut stmt = conn.prepare( + // 🚨 强制使用连接池,避免死锁 + if !self.database.has_pool() { + return Err(anyhow!("连接池未启用,无法安全执行数据库操作")); + } + + let pooled_conn = self.database.acquire_from_pool() + .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?; + + let mut stmt = pooled_conn.prepare( r#" SELECT id, outfit_record_id, image_url, local_path, image_index, description, tags, is_favorite, created_at @@ -560,16 +599,24 @@ impl OutfitImageRepository { images.push(image.map_err(|e| anyhow!("解析穿搭图片失败: {}", e))?); } + println!("✅ 连接池查询穿搭图片完成,获取到 {} 张图片", images.len()); Ok(images) } - /// 获取模特的穿搭图片统计信息 + /// 获取模特的穿搭图片统计信息(强制使用连接池) pub fn get_stats_by_model_id(&self, model_id: &str) -> Result { - let conn = self.database.get_connection(); - let conn = conn.lock().map_err(|e| anyhow!("获取数据库连接失败: {}", e))?; + println!("🏊 使用连接池获取穿搭统计: {}", &model_id[..8]); + + // 🚨 强制使用连接池,避免死锁 + if !self.database.has_pool() { + return Err(anyhow!("连接池未启用,无法安全执行数据库操作")); + } + + let pooled_conn = self.database.acquire_from_pool() + .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?; // 获取记录统计 - let mut stmt = conn.prepare( + let mut stmt = pooled_conn.prepare( r#" SELECT COUNT(*) as total_records, @@ -593,7 +640,7 @@ impl OutfitImageRepository { }).map_err(|e| anyhow!("查询记录统计失败: {}", e))?; // 获取图片统计 - let mut stmt = conn.prepare( + let mut stmt = pooled_conn.prepare( r#" SELECT COUNT(*) as total_images, @@ -611,6 +658,7 @@ impl OutfitImageRepository { )) }).map_err(|e| anyhow!("查询图片统计失败: {}", e))?; + println!("✅ 连接池查询穿搭统计完成: 记录{}条, 图片{}张", total_records, total_images); Ok(OutfitImageStats { total_records, total_images,