6.6 KiB
6.6 KiB
SQLite 数据库存储功能验证计划
📋 当前状态分析
✅ 已实现的功能
根据代码分析,SQLite数据库存储已经基本实现:
- 数据库连接:
src/storage/database.rs
实现了完整的SQLite存储层 - 表结构: 自动创建users表,包含所有必要字段
- CRUD操作: 实现了所有用户管理操作
- 错误处理: 包含数据库特定的错误处理
- 配置支持:
src/main.rs
支持通过环境变量切换存储类型
🔍 需要验证的功能点
1. 数据库连接和初始化
- 验证SQLite数据库文件创建
- 验证表结构正确创建
- 验证连接池正常工作
2. CRUD操作完整性
- 创建用户功能
- 读取用户功能(按ID和用户名)
- 更新用户功能
- 删除用户功能
- 列出所有用户功能
3. 数据一致性和约束
- 用户名唯一性约束
- 数据类型转换正确性
- 时间戳处理正确性
- UUID处理正确性
4. 错误处理
- 重复用户名错误处理
- 数据库连接错误处理
- 数据格式错误处理
🧪 验证方法
方法1: 单元测试验证
创建专门的数据库测试文件 tests/database_tests.rs
:
//! SQLite 数据库存储测试
use rust_user_api::{
models::user::User,
storage::{database::DatabaseUserStore, UserStore},
utils::errors::ApiError,
};
use uuid::Uuid;
use chrono::Utc;
use tempfile::tempdir;
#[tokio::test]
async fn test_database_crud_operations() {
// 创建临时数据库
let temp_dir = tempdir().expect("Failed to create temp directory");
let db_path = temp_dir.path().join("test.db");
let database_url = format!("sqlite://{}", db_path.display());
let store = DatabaseUserStore::from_url(&database_url)
.await
.expect("Failed to create database store");
// 测试创建用户
let user = User {
id: Uuid::new_v4(),
username: "dbtest".to_string(),
email: "dbtest@example.com".to_string(),
password_hash: "hashed_password".to_string(),
created_at: Utc::now(),
updated_at: Utc::now(),
};
let created_user = store.create_user(user.clone()).await.unwrap();
assert_eq!(created_user.username, "dbtest");
// 测试读取用户
let retrieved_user = store.get_user(&user.id).await.unwrap();
assert!(retrieved_user.is_some());
// 测试按用户名读取
let user_by_name = store.get_user_by_username("dbtest").await.unwrap();
assert!(user_by_name.is_some());
// 测试更新用户
let mut updated_user = user.clone();
updated_user.username = "updated_dbtest".to_string();
let update_result = store.update_user(&user.id, updated_user).await.unwrap();
assert!(update_result.is_some());
// 测试删除用户
let delete_result = store.delete_user(&user.id).await.unwrap();
assert!(delete_result);
}
#[tokio::test]
async fn test_database_constraints() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let db_path = temp_dir.path().join("test_constraints.db");
let database_url = format!("sqlite://{}", db_path.display());
let store = DatabaseUserStore::from_url(&database_url)
.await
.expect("Failed to create database store");
// 创建第一个用户
let user1 = User {
id: Uuid::new_v4(),
username: "duplicate_test".to_string(),
email: "test1@example.com".to_string(),
password_hash: "hashed_password".to_string(),
created_at: Utc::now(),
updated_at: Utc::now(),
};
store.create_user(user1).await.unwrap();
// 尝试创建相同用户名的用户
let user2 = User {
id: Uuid::new_v4(),
username: "duplicate_test".to_string(), // 相同用户名
email: "test2@example.com".to_string(),
password_hash: "hashed_password".to_string(),
created_at: Utc::now(),
updated_at: Utc::now(),
};
let result = store.create_user(user2).await;
assert!(result.is_err());
if let Err(ApiError::Conflict(msg)) = result {
assert!(msg.contains("用户名已存在"));
} else {
panic!("Expected Conflict error for duplicate username");
}
}
方法2: 集成测试验证
修改现有的集成测试,添加数据库模式测试:
- 设置环境变量
DATABASE_URL=sqlite://test_integration.db
- 运行现有的集成测试
- 验证数据持久化到数据库文件
方法3: 手动验证
- 创建
.env
文件,启用数据库模式 - 启动服务器
- 使用API创建用户
- 重启服务器
- 验证用户数据仍然存在
🔧 需要添加的依赖
在 Cargo.toml
的 [dev-dependencies]
中添加:
tempfile = "3.0" # 用于创建临时测试数据库
📝 验证步骤
步骤1: 添加数据库测试
- 创建
tests/database_tests.rs
- 添加tempfile依赖
- 实现数据库CRUD测试
- 实现约束测试
步骤2: 运行测试验证
# 运行数据库测试
cargo test database_tests
# 运行所有测试
cargo test
步骤3: 集成测试验证
# 设置数据库环境变量
export DATABASE_URL=sqlite://test_integration.db
# 启动服务器
cargo run
# 在另一个终端运行集成测试
cargo test integration_tests
步骤4: 手动功能验证
- 创建
.env
文件:
DATABASE_URL=sqlite://users.db
- 启动服务器并测试API
- 检查数据库文件是否创建
- 重启服务器验证数据持久化
🚨 可能遇到的问题
问题1: 数据库文件权限
症状: 无法创建或写入数据库文件 解决方案: 确保应用有写入权限,使用绝对路径
问题2: SQLite版本兼容性
症状: SQL语法错误或功能不支持 解决方案: 检查SQLite版本,更新SQL语句
问题3: 连接池配置
症状: 并发访问时出现连接错误 解决方案: 配置适当的连接池大小
问题4: 数据类型转换
症状: UUID或时间戳存储/读取错误 解决方案: 检查数据类型转换逻辑
✅ 验证完成标准
数据库存储功能验证完成的标准:
- ✅ 所有数据库单元测试通过
- ✅ 集成测试在数据库模式下通过
- ✅ 手动验证数据持久化正常
- ✅ 错误处理机制正常工作
- ✅ 性能测试满足要求
📋 下一步行动
完成数据库验证后,继续TODO列表中的下一项:
- 添加数据库迁移系统
- 实现数据库连接池配置
- 添加API分页功能
注意: 这个验证计划需要切换到Code模式来实际实现测试代码和进行验证。