Files
agcore/src/memory/store.rs
T
徐涛 c82af60f81 feat(memory): 实现 SqliteStore 持久化
- 新增 src/memory/store/sqlite_store.rs(SqliteStore + 9 个内联测试)
- 基于 rusqlite 0.32(bundled),使用 Arc<Mutex<Connection>> + spawn_blocking
- WAL 模式 + synchronous=NORMAL + busy_timeout=5s + PRAGMA user_version
  schema 版本管理
- created_at 归一化为 UTC 的 RFC 3339 TEXT,字典序等价时间序
- 错误精细映射:SqliteFailure/InvalidQuery → InvalidInput;
  FromSqlConversionFailure → Serialization;其他 → Storage
- 9 个测试覆盖 CRUD、upsert、prefix/since/offset+limit 过滤、
  10 写者 × 10 次并发、持久化 round-trip、trait-box 互换兼容性

依赖:
- rusqlite = { version = "0.32", features = ["bundled"] }
- time 增补 features: parsing, formatting, macros
- dev-dependencies: tempfile = "3"

测试:199 → 200 pass(191 原有 + 9 新增)
2026-07-05 17:13:28 +08:00

63 lines
1.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! MemoryStore 抽象接口与默认实现。
use async_trait::async_trait;
use crate::memory::error::MemoryError;
use crate::memory::types::{MemoryFilter, MemoryItem};
pub mod in_memory;
pub mod sqlite_store;
pub use in_memory::InMemoryStore;
pub use sqlite_store::SqliteStore;
/// 底层记忆存储抽象接口。
///
/// 下游可实现此 trait 以对接持久化后端(JSON 文件、SQLite、Redis 等)。
/// 默认实现 [`InMemoryStore`] 基于进程内 HashMap。
#[async_trait]
pub trait MemoryStore: Send + Sync {
/// 保存/覆盖一个 MemoryItemupsert 语义)。
/// - 如果 id 不存在,则插入新条目
/// - 如果 id 已存在,则覆盖旧条目
async fn save(&self, item: MemoryItem) -> Result<(), MemoryError>;
/// 根据 id 获取一个 MemoryItem。
async fn get(&self, id: &str) -> Result<Option<MemoryItem>, MemoryError>;
/// 根据 id 删除一个 MemoryItem。
async fn delete(&self, id: &str) -> Result<(), MemoryError>;
/// 根据 filter 列出 MemoryItem。
async fn list(&self, filter: &MemoryFilter) -> Result<Vec<MemoryItem>, MemoryError>;
}
/// 淘汰策略。
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum EvictionPolicy {
/// 不淘汰(默认)。
None,
/// 超过存活时间(秒)淘汰。
Ttl { ttl_secs: u64 },
/// 超过容量上限淘汰最旧(基于 created_at)。
Capacity { max_items: usize },
}
/// 淘汰配置。
#[derive(Debug, Clone)]
pub struct EvictionConfig {
pub policy: EvictionPolicy,
/// 每写入 N 条后检查一次淘汰条件。
pub check_interval: usize,
}
impl Default for EvictionConfig {
fn default() -> Self {
Self {
policy: EvictionPolicy::None,
check_interval: 64,
}
}
}