Skip to main content

aimdb_persistence/
backend.rs

1//! Persistence backend trait for AimDB.
2//!
3//! Defines the [`PersistenceBackend`] trait that concrete implementations
4//! (SQLite, Postgres, …) must fulfill.
5
6use core::future::Future;
7use core::pin::Pin;
8
9use serde_json::Value;
10
11use crate::error::PersistenceError;
12
13/// Type alias matching the pattern used throughout aimdb-core (no async_trait).
14pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
15
16/// A stored value returned by [`PersistenceBackend::query`].
17#[derive(Debug, Clone)]
18pub struct StoredValue {
19    /// The record name this value belongs to (e.g. `"accuracy::vienna"`).
20    pub record_name: String,
21    /// The JSON-serialized value.
22    pub value: Value,
23    /// Unix timestamp in milliseconds when the value was persisted.
24    pub stored_at: u64,
25}
26
27/// Parameters for [`PersistenceBackend::query`].
28#[derive(Debug, Clone, Default)]
29pub struct QueryParams {
30    /// For pattern queries: maximum number of results **per matching record**.
31    pub limit_per_record: Option<usize>,
32    /// Only return values stored at or after this timestamp (Unix ms).
33    pub start_time: Option<u64>,
34    /// Only return values stored at or before this timestamp (Unix ms).
35    pub end_time: Option<u64>,
36}
37
38/// Pluggable persistence backend.
39///
40/// Implementations run on a concrete async runtime (e.g. Tokio). The trait
41/// uses manual `BoxFuture` instead of `async_trait` for consistency with the
42/// rest of the AimDB codebase.
43pub trait PersistenceBackend: Send + Sync {
44    /// Store a JSON value for a record.
45    fn store<'a>(
46        &'a self,
47        record_name: &'a str,
48        value: &'a Value,
49        timestamp: u64,
50    ) -> BoxFuture<'a, Result<(), PersistenceError>>;
51
52    /// Query stored values, with optional pattern and time-range support.
53    ///
54    /// `record_pattern` supports `*` as a glob wildcard. For example,
55    /// `"accuracy::*"` matches all records whose name starts with `"accuracy::"`.
56    fn query<'a>(
57        &'a self,
58        record_pattern: &'a str,
59        params: QueryParams,
60    ) -> BoxFuture<'a, Result<Vec<StoredValue>, PersistenceError>>;
61
62    /// Initialize storage (create tables, indexes, …).
63    ///
64    /// Default: no-op. Backends that perform setup eagerly in `::new()`
65    /// (like `SqliteBackend`) do not need to override this.
66    fn initialize(&self) -> BoxFuture<'_, Result<(), PersistenceError>> {
67        Box::pin(async { Ok(()) })
68    }
69
70    /// Delete all rows older than `older_than` (Unix ms).
71    ///
72    /// Called automatically by the retention cleanup task registered during
73    /// `with_persistence()`. Can also be called explicitly.
74    fn cleanup(&self, older_than: u64) -> BoxFuture<'_, Result<u64, PersistenceError>>;
75}