优化 conversation_repository.rs 使用连接池
修复内容: - initialize_tables 方法强制使用连接池 - 避免 get_connection().lock() 死锁风险 - 添加连接池状态检查和错误处理 - 添加调试日志便于问题排查 这是数据库连接池优化计划的第1步,逐步替换所有旧的单连接模式。
This commit is contained in:
parent
f31783f682
commit
b6999c379b
|
|
@ -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(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Vec<ProductImage>> {
|
||||
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<Vec<OutfitImage>> {
|
||||
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<OutfitImageStats> {
|
||||
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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue