rat_quickdb 0.5.2

强大的跨数据库ODM库,支持自动索引创建、统一接口和现代异步架构
Documentation
//! 手动缓存清理示例
//! 
//! 本示例展示如何使用各种手动缓存清理方法,适用于以下场景:
//! 1. 自动清理不生效时的手动干预
//! 2. 数据字段升级后需要清理旧缓存
//! 3. 内存紧张时的主动清理
//! 4. 调试和监控缓存状态

use rat_quickdb::{
    config::{DatabaseConfigBuilder, GlobalConfig, AppConfigBuilder, LoggingConfigBuilder},
    manager::PoolManager,
    types::*,
    error::QuickDbResult,
};
use rat_quickdb::{Environment, LogLevel};
// 使用 rat_quickdb 的缓存配置类型
// 不再需要直接使用 rat_memcache,因为缓存功能已集成到 rat_quickdb 中
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use rat_logger::{info, warn, error};
use chrono::Utc;

#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
    id: Option<IdType>,
    name: String,
    email: String,
    age: i32,
}

#[tokio::main]
async fn main() -> QuickDbResult<()> {
    // 初始化日志
    rat_logger::LoggerBuilder::new().add_terminal_with_config(rat_logger::handler::term::TermConfig::default()).init().expect("日志初始化失败");
    
    // 初始化数据库
    let db_config = rat_quickdb::config::DatabaseConfigBuilder::new()
        .db_type(rat_quickdb::types::DatabaseType::SQLite)
        .connection(rat_quickdb::types::ConnectionConfig::SQLite {
            path: ":memory:".to_string(),
            create_if_missing: true,
        })
        .pool(rat_quickdb::types::PoolConfig::builder()
            .min_connections(1)
            .max_connections(5)
            .connection_timeout(30)
            .idle_timeout(300)
            .max_lifetime(3600)
            .build()
            .unwrap()
        )
        .alias("main")
        .id_strategy(rat_quickdb::types::IdStrategy::AutoIncrement)
        .cache(rat_quickdb::types::CacheConfig::default()
            .enabled(true)
            .with_strategy(rat_quickdb::types::CacheStrategy::Lru)
            .with_l1_config(rat_quickdb::types::L1CacheConfig::new()
                .with_max_capacity(1000)
                .with_max_memory_mb(50)
                .enable_stats(true))
            .with_ttl_config(rat_quickdb::types::TtlConfig::new()
                .with_default_ttl_secs(300)
                .with_max_ttl_secs(3600)
                .with_check_interval_secs(60)))
        .build()?;

    let config = GlobalConfig::builder()
        .add_database(db_config)
        .default_database("main")
        .app(
            AppConfigBuilder::new()
                .name("缓存清理示例")
                .version("1.0.0")
                .environment(Environment::Development)
                .debug(true)
                .work_dir(std::env::current_dir()?)
                .build()?
        )
        .logging(
            LoggingConfigBuilder::new()
                .level(LogLevel::Info)
                .console(true)
                .file_path(None::<std::path::PathBuf>)
                .max_file_size(10 * 1024 * 1024)
                .max_files(5)
                .structured(false)
                .build()?
        )
        .build()?;
    
    // 初始化rat_quickdb
    rat_quickdb::init();
    
    // 添加数据库配置
    let db_config = config.get_default_database()?.clone();
    rat_quickdb::add_database(db_config).await?;
    
    // 创建测试数据
    let mut user_ids: Vec<String> = Vec::new();
    for i in 1..=5 {
        let data = HashMap::from([
            ("name".to_string(), DataValue::String(format!("用户{}", i))),
            ("age".to_string(), DataValue::Int(20 + i as i64)),
            ("email".to_string(), DataValue::String(format!("user{}@example.com", i))),
            ("created_at".to_string(), DataValue::DateTime(Utc::now())),
        ]);
        
        let id = rat_quickdb::odm::create("users", data, Some("main")).await?;
        info!("创建用户: ID={}", id);
        let id_str = match id {
            DataValue::String(s) => s,
            DataValue::Int(i) => i.to_string(),
            DataValue::Uuid(u) => u.to_string(),
            _ => panic!("不支持的ID类型: {:?}", id),
        };
        user_ids.push(id_str);
    }
    
    // 填充缓存 - 执行一些查询和记录操作
    let query_options = rat_quickdb::types::QueryOptions::new().with_pagination(rat_quickdb::types::PaginationConfig { skip: 0, limit: 10 });
    
    // 查询用户数据(会缓存查询结果)
    let users = rat_quickdb::odm::find("users", vec![], Some(query_options.clone()), Some("main")).await?;
    info!("查询到用户数据: {} 条", users.len());
    
    // 获取单个用户记录(会缓存记录)
    for user_id in &user_ids {
        let user_doc = rat_quickdb::odm::find_by_id("users", user_id, Some("main")).await?;
        if let Some(_) = user_doc {
            info!("缓存了用户记录: {}", user_id);
        }
    }
    

    
    // 创建一些产品数据用于演示
    for i in 1..=3 {
        let product_data = HashMap::from([
            ("name".to_string(), DataValue::String(format!("产品{}", i))),
            ("price".to_string(), DataValue::Float(99.99 + i as f64)),
            ("category".to_string(), DataValue::String("电子产品".to_string())),
        ]);
        
        let _product_id = rat_quickdb::odm::create("products", product_data, Some("main")).await?;
    }
    
    // 查询产品数据
    let products = rat_quickdb::odm::find("products", vec![], Some(query_options), Some("main")).await?;
    info!("查询到产品数据: {} 条", products.len());
    
    // 按条件查询(会缓存查询结果)
    let conditions = vec![
         rat_quickdb::types::QueryCondition {
             field: "age".to_string(),
             operator: rat_quickdb::types::QueryOperator::Gt,
             value: rat_quickdb::types::DataValue::Int(25)
         }
     ];
    let query_options = rat_quickdb::types::QueryOptions::new().with_pagination(rat_quickdb::types::PaginationConfig { skip: 0, limit: 10 });
    let _filtered_users = rat_quickdb::odm::find("users", conditions, Some(query_options), Some("main")).await?;
    info!("按条件查询完成");
    
    // 展示缓存清理功能
    info!("\n=== 缓存清理功能演示 ===");
    
    // 1. 查看当前缓存键
    info!("\n1. 查看当前缓存键:");
    let cache_keys = rat_quickdb::manager::list_cache_keys("main").await?;
    for (table, keys) in &cache_keys {
        info!("表 '{}' 的缓存键数量: {}", table, keys.len());
        for key in keys {
            info!("  - {}", key);
        }
    }
    
    // 2. 查看指定表的缓存键
    info!("\n2. 查看 users 表的缓存键:");
    let user_cache_keys = rat_quickdb::manager::list_table_cache_keys("main", "users").await?;
    info!("users 表缓存键数量: {}", user_cache_keys.len());
    for key in &user_cache_keys {
        info!("  - {}", key);
    }
    
    // 3. 按模式清理缓存
    info!("\n3. 按模式清理缓存(清理所有查询缓存):");
    let cleared_count = rat_quickdb::manager::clear_cache_by_pattern("main", "*:query:*").await?;
    info!("按模式清理了 {} 个缓存项", cleared_count);
    
    // 验证查询缓存已清理
    let remaining_keys = rat_quickdb::manager::list_table_cache_keys("main", "users").await?;
    info!("清理后剩余缓存键数量: {}", remaining_keys.len());
    
    // 4. 批量清理记录缓存
    info!("\n4. 批量清理指定记录的缓存:");
    let ids_to_clear: Vec<rat_quickdb::types::IdType> = user_ids[0..2].iter().map(|s| rat_quickdb::types::IdType::String(s.clone())).collect(); // 清理前两个用户的缓存
    let cleared_count = rat_quickdb::manager::clear_records_cache_batch("main", "users", &ids_to_clear).await?;
    info!("批量清理了 {} 个记录缓存", cleared_count);
    
    // 5. 清理指定表的查询缓存
    info!("\n5. 清理指定表的查询缓存:");
    // 重新查询以验证缓存已清理
     let query_options = rat_quickdb::types::QueryOptions::new();
     let users = rat_quickdb::odm::find("users", vec![], Some(query_options), Some("main")).await?;
     info!("重新查询到用户数据: {}", users.len());
    let cleared_count = rat_quickdb::manager::clear_cache_by_pattern("main", "users:query:*").await?;
    info!("清理了 {} 个查询缓存", cleared_count);
    
    // 6. 清理指定表的记录缓存
    info!("\n6. 清理指定表的记录缓存:");
    let cleared_count = rat_quickdb::manager::clear_cache_by_pattern("main", "users:record:*").await?;
    info!("清理了 {} 个记录缓存", cleared_count);
    
    // 7. 清理指定表的所有缓存
    info!("\n7. 清理指定表的所有缓存:");
    // 重新填充缓存
    let conditions = vec![];
    let query_options = rat_quickdb::types::QueryOptions::new().with_pagination(rat_quickdb::types::PaginationConfig { skip: 0, limit: 10 });
    let users = rat_quickdb::odm::find("users", conditions, Some(query_options), Some("main")).await?;
    
    for user_id in &user_ids {
        if let Some(user) = rat_quickdb::odm::find_by_id("users", user_id, Some("main")).await? {
            info!("重新查询到用户: ID={}", user_id);
        }
    }
    let query_cleared = rat_quickdb::manager::clear_table_query_cache("main", "users").await?;
     let record_cleared = rat_quickdb::manager::clear_table_record_cache("main", "users").await?;
     let cleared_count = query_cleared + record_cleared;
    info!("清理了 {} 个缓存项(记录+查询)", cleared_count);
    
    // 8. 强制清理过期缓存
    info!("\n8. 强制清理过期缓存:");
    let cleared_count = rat_quickdb::manager::force_cleanup_expired_cache("main").await?;
    info!("强制清理了 {} 个过期缓存项", cleared_count);
    
    // 9. 清理所有缓存
    info!("\n9. 清理所有缓存:");
    rat_quickdb::manager::clear_all_caches().await?;
    info!("已清理所有数据库的缓存");
    
    // 验证缓存已完全清理
    let final_cache_keys = rat_quickdb::manager::list_cache_keys("main").await?;
    info!("\n最终缓存状态:");
    if final_cache_keys.is_empty() {
        info!("✅ 所有缓存已清理完毕");
    } else {
        for (table, keys) in &final_cache_keys {
            info!("表 '{}' 还有 {} 个缓存键", table, keys.len());
        }
    }
    
    info!("\n=== 使用场景示例 ===");
    
    // 场景1:数据字段升级后清理旧缓存
    info!("\n场景1:数据字段升级后清理旧缓存");
    info!("// 假设 User 结构体新增了字段,需要清理旧的缓存数据");
    info!("clear_table_all_cache(\"main\", \"users\").await?;");
    
    // 场景2:内存紧张时的主动清理
    info!("\n场景2:内存紧张时的主动清理");
    info!("// 清理过期缓存释放内存");
    info!("force_cleanup_expired_cache(\"main\").await?;");
    info!("// 或者清理特定模式的缓存");
    info!("clear_cache_by_pattern(\"main\", \"*:query:*\").await?; // 只清理查询缓存");
    
    // 场景3:调试缓存问题
    info!("\n场景3:调试缓存问题");
    info!("// 查看当前缓存状态");
    info!("let cache_keys = list_cache_keys(\"main\").await?;");
    info!("// 查看特定表的缓存");
    info!("let table_keys = list_table_cache_keys(\"main\", \"users\").await?;");
    
    // 场景4:定期维护
    info!("\n场景4:定期维护任务");
    info!("// 可以在定时任务中执行");
    info!("tokio::spawn(async {{");
    info!("    loop {{");
    info!("        tokio::time::sleep(Duration::from_secs(3600)).await; // 每小时");
    info!("        if let Err(e) = force_cleanup_expired_cache(\"main\").await {{");
    info!("            error!(\"清理过期缓存失败: {{}}\", e);");
    info!("        }}");
    info!("    }}");
    info!("}});");
    
    info!("\n✅ 手动缓存清理示例完成!");
    
    Ok(())
}