use chrono::{DateTime, Utc};
#[cfg(debug_assertions)]
use rat_logger::debug;
use rat_quickdb::types::*;
use rat_quickdb::*;
use rat_quickdb::{ModelManager, ModelOperations, add_database, set_default_alias};
define_model! {
struct MainUser {
id: String,
name: String,
email: String,
age: Option<i32>, }
collection = "users",
database = "main_db", fields = {
id: string_field(None, None, None).required().unique(),
name: string_field(Some(100), Some(1), None).required(),
email: string_field(Some(255), Some(1), None).required(),
age: integer_field(None, None), }
}
define_model! {
struct ArchiveUser {
id: String,
name: String,
email: String,
archived_at: DateTime<Utc>,
}
collection = "users",
database = "archive_db", fields = {
id: string_field(None, None, None).required().unique(),
name: string_field(Some(100), Some(1), None).required(),
email: string_field(Some(255), Some(1), None).required(),
archived_at: datetime_field().required(), }
}
define_model! {
struct LogEntry {
id: String,
message: String,
level: String,
timestamp: DateTime<Utc>,
}
collection = "logs",
fields = {
id: string_field(None, None, None).required().unique(),
message: string_field(None, None, None).required(),
level: string_field(Some(20), Some(1), None).required(),
timestamp: datetime_field().required(), }
}
#[tokio::main]
async fn main() -> QuickDbResult<()> {
println!("🚀 测试模型数据库别名功能");
println!("===========================");
setup_test_databases().await?;
test_model_database_alias();
test_cross_database_operations().await?;
test_default_alias_fallback().await?;
cleanup_test_databases().await?;
println!("\n✅ 所有测试完成!");
Ok(())
}
async fn setup_test_databases() -> QuickDbResult<()> {
println!("\n📋 设置测试数据库...");
let old_files = ["test_main.db", "test_archive.db", "test_default.db"];
for file in &old_files {
if std::path::Path::new(file).exists() {
if let Err(e) = std::fs::remove_file(file) {
println!("⚠️ 删除旧文件 {} 失败: {}", file, e);
} else {
println!("🗑️ 删除旧文件: {}", file);
}
}
}
let main_config = DatabaseConfig {
db_type: DatabaseType::SQLite,
connection: ConnectionConfig::SQLite {
path: "test_main.db".to_string(),
create_if_missing: true,
},
pool: PoolConfig::default(),
alias: "main_db".to_string(),
cache: None,
id_strategy: IdStrategy::Uuid,
};
let archive_config = DatabaseConfig {
db_type: DatabaseType::SQLite,
connection: ConnectionConfig::SQLite {
path: "test_archive.db".to_string(),
create_if_missing: true,
},
pool: PoolConfig::default(),
alias: "archive_db".to_string(),
cache: None,
id_strategy: IdStrategy::Uuid,
};
let default_config = DatabaseConfig {
db_type: DatabaseType::SQLite,
connection: ConnectionConfig::SQLite {
path: "test_default.db".to_string(),
create_if_missing: true,
},
pool: PoolConfig::default(),
alias: "default".to_string(),
cache: None,
id_strategy: IdStrategy::Uuid,
};
add_database(main_config).await?;
add_database(archive_config).await?;
add_database(default_config).await?;
println!("✅ 测试数据库设置完成");
println!("📁 数据库文件路径:test_main.db, test_archive.db, test_default.db");
Ok(())
}
fn test_model_database_alias() {
println!("\n🔍 测试1:验证模型的数据库别名获取");
println!("=========================================");
let main_alias = MainUser::database_alias();
println!("MainUser 数据库别名: {:?}", main_alias);
assert_eq!(main_alias, Some("main_db".to_string()));
let archive_alias = ArchiveUser::database_alias();
println!("ArchiveUser 数据库别名: {:?}", archive_alias);
assert_eq!(archive_alias, Some("archive_db".to_string()));
let log_alias = LogEntry::database_alias();
println!("LogEntry 数据库别名: {:?}", log_alias);
assert_eq!(log_alias, None);
println!("✅ 模型数据库别名获取测试通过");
}
async fn test_cross_database_operations() -> QuickDbResult<()> {
println!("\n🔄 测试2:验证跨库操作");
println!("========================");
let main_user = MainUser {
id: "main_user_1".to_string(),
name: "主库用户".to_string(),
email: "main@example.com".to_string(),
age: Some(25), };
match main_user.save().await {
Ok(id) => println!("✅ 主数据库用户创建成功: {}", id),
Err(e) => println!("❌ 主数据库用户创建失败: {}", e),
}
let archive_user = ArchiveUser {
id: "archive_user_1".to_string(),
name: "归档用户".to_string(),
email: "archive@example.com".to_string(),
archived_at: DateTime::parse_from_rfc3339("2023-01-01T00:00:00Z")
.unwrap()
.with_timezone(&Utc),
};
match archive_user.save().await {
Ok(id) => println!("✅ 归档数据库用户创建成功: {}", id),
Err(e) => println!("❌ 归档数据库用户创建失败: {}", e),
}
match ModelManager::<MainUser>::find_by_id("main_user_1").await {
Ok(Some(user)) => println!("✅ 从主数据库查询到用户: {}", user.name),
Ok(None) => println!("⚠️ 主数据库中未找到用户"),
Err(e) => println!("❌ 主数据库查询失败: {}", e),
}
match ModelManager::<ArchiveUser>::find_by_id("archive_user_1").await {
Ok(Some(user)) => println!("✅ 从归档数据库查询到用户: {}", user.name),
Ok(None) => println!("⚠️ 归档数据库中未找到用户"),
Err(e) => println!("❌ 归档数据库查询失败: {}", e),
}
println!("✅ 跨库操作测试完成");
Ok(())
}
async fn test_default_alias_fallback() -> QuickDbResult<()> {
println!("\n🔄 测试3:验证默认别名回退");
println!("==========================");
set_default_alias("default").await?;
let log_entry = LogEntry {
id: "log_1".to_string(),
message: "测试日志消息".to_string(),
level: "INFO".to_string(),
timestamp: DateTime::parse_from_rfc3339("2023-01-01T12:00:00Z")
.unwrap()
.with_timezone(&Utc),
};
match log_entry.save().await {
Ok(id) => println!("✅ 默认数据库日志创建成功: {}", id),
Err(e) => println!("❌ 默认数据库日志创建失败: {}", e),
}
match ModelManager::<LogEntry>::find_by_id("log_1").await {
Ok(Some(log)) => println!("✅ 从默认数据库查询到日志: {}", log.message),
Ok(None) => println!("⚠️ 默认数据库中未找到日志"),
Err(e) => println!("❌ 默认数据库查询失败: {}", e),
}
println!("✅ 默认别名回退测试完成");
Ok(())
}
async fn cleanup_test_databases() -> QuickDbResult<()> {
println!("\n🧹 清理测试数据库...");
println!("📁 保留测试文件以便检查:test_main.db, test_archive.db, test_default.db");
for file in ["test_main.db", "test_archive.db", "test_default.db"] {
if std::path::Path::new(file).exists() {
println!("✅ 数据库文件存在: {}", file);
} else {
println!("❌ 数据库文件不存在: {}", file);
}
}
Ok(())
}