use std::fmt;
use std::future::Future;
use radicle::cob::{ObjectId, TypeName};
use radicle::git::Oid;
use radicle::prelude::RepoId;
use crate::entry::{OperationEntry, TimelineEntry};
use crate::radicle_extra::sql;
pub trait FeedStorage {
type Error: snafu::Error + 'static;
fn get_last_processed_operation(
&self,
rid: &RepoId,
cob_id: &ObjectId,
typename: &TypeName,
) -> impl Future<Output = Result<Option<sql::Oid>, Self::Error>>;
fn insert_timeline_entry(
&mut self,
entry: &TimelineEntry,
) -> impl Future<Output = Result<(), Self::Error>>;
fn operation_exists(
&self,
operation_id: &Oid,
) -> impl Future<Output = Result<bool, Self::Error>>;
fn insert_batch(
&mut self,
entries: &[OperationEntry],
) -> impl Future<Output = Result<(), Self::Error>>;
fn get_stats(&self) -> impl Future<Output = Result<StorageStats, Self::Error>>;
}
#[derive(Debug, Default)]
pub struct StorageStats {
pub total_operations: u64,
pub operations_by_type: std::collections::HashMap<String, u64>,
pub tracked_objects: u64,
}
impl fmt::Display for StorageStats {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "=== Storage Statistics ===")?;
writeln!(f, "Total operations: {}", self.total_operations)?;
for (kind, count) in &self.operations_by_type {
writeln!(f, "{}: {}", kind, count)?;
}
writeln!(f, "Tracked objects: {}", self.tracked_objects)?;
Ok(())
}
}
#[cfg(feature = "postgres")]
pub mod postgres;