use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::analyzers::context::AnalyzerContext;
use crate::error::{Result, TermError};
pub mod datafusion_executor;
pub mod in_memory;
pub mod query;
pub mod result_key;
pub use datafusion_executor::{DataFusionQueryExecutor, DataFusionQueryExecutorExt};
pub use in_memory::InMemoryRepository;
pub use query::{MetricsQuery, SortOrder};
pub use result_key::ResultKey;
#[async_trait]
pub trait MetricsRepository: Send + Sync {
async fn save(&self, key: ResultKey, metrics: AnalyzerContext) -> Result<()>;
async fn load(&self) -> MetricsQuery;
async fn delete(&self, key: ResultKey) -> Result<()>;
async fn list_keys(&self) -> Result<Vec<ResultKey>> {
Err(TermError::NotSupported(
"list_keys not implemented for this repository".to_string(),
))
}
async fn get(&self, _key: &ResultKey) -> Result<Option<AnalyzerContext>> {
Ok(None)
}
async fn exists(&self, key: &ResultKey) -> Result<bool> {
let keys = self.list_keys().await?;
Ok(keys.iter().any(|k| k == key))
}
async fn metadata(&self) -> Result<RepositoryMetadata> {
Ok(RepositoryMetadata::default())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct RepositoryMetadata {
pub backend_type: Option<String>,
pub total_metrics: Option<usize>,
pub storage_size_bytes: Option<u64>,
pub config: HashMap<String, String>,
pub last_modified: Option<chrono::DateTime<chrono::Utc>>,
}
impl RepositoryMetadata {
pub fn new(backend_type: impl Into<String>) -> Self {
Self {
backend_type: Some(backend_type.into()),
..Default::default()
}
}
pub fn with_total_metrics(mut self, count: usize) -> Self {
self.total_metrics = Some(count);
self
}
pub fn with_storage_size(mut self, size: u64) -> Self {
self.storage_size_bytes = Some(size);
self
}
pub fn with_config(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.config.insert(key.into(), value.into());
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_repository_metadata_builder() {
let metadata = RepositoryMetadata::new("filesystem")
.with_total_metrics(100)
.with_storage_size(1024 * 1024)
.with_config("path", "/var/metrics");
assert_eq!(metadata.backend_type, Some("filesystem".to_string()));
assert_eq!(metadata.total_metrics, Some(100));
assert_eq!(metadata.storage_size_bytes, Some(1024 * 1024));
assert_eq!(
metadata.config.get("path"),
Some(&"/var/metrics".to_string())
);
}
}