implement duration specifier for history

This commit is contained in:
csehviktor
2025-07-15 01:34:27 +02:00
parent 6a311246f6
commit 6eb696019a
5 changed files with 68 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
use async_trait::async_trait;
use chrono::Utc;
use chrono::{DateTime, Utc};
use common::StatusMessage;
use std::collections::HashMap;
use tokio::sync::Mutex;
@@ -51,10 +51,25 @@ impl StorageRepository for InMemoryRepository {
Ok(())
}
async fn get_history(&self, agent: &str) -> anyhow::Result<Vec<StatusMessage>> {
async fn get_history(
&self,
agent: &str,
duration: Option<DateTime<Utc>>,
) -> anyhow::Result<Vec<StatusMessage>> {
let messages = self.messages.lock().await;
Ok(messages.get(agent).cloned().unwrap_or_default())
let agent_messages = messages.get(agent).cloned().unwrap_or_default();
let filtered_messages = if let Some(duration) = duration {
agent_messages
.into_iter()
.filter(|msg| msg.timestamp >= duration)
.collect()
} else {
agent_messages
};
Ok(filtered_messages)
}
async fn get_agents(&self) -> anyhow::Result<Vec<UptimeMessage>> {

View File

@@ -65,7 +65,11 @@ impl TryFrom<&Row<'_>> for UptimeStorageModel {
pub trait StorageRepository: Send + Sync {
async fn record_message(&self, message: &StatusMessage) -> anyhow::Result<()>;
async fn record_uptime(&self, agent: &str) -> anyhow::Result<()>;
async fn get_history(&self, agent: &str) -> anyhow::Result<Vec<StatusMessage>>;
async fn get_history(
&self,
agent: &str,
duration: Option<DateTime<Utc>>,
) -> anyhow::Result<Vec<StatusMessage>>;
async fn get_agents(&self) -> anyhow::Result<Vec<UptimeMessage>>;
}

View File

@@ -1,6 +1,6 @@
use anyhow::Ok;
use async_trait::async_trait;
use chrono::Utc;
use chrono::{DateTime, Utc};
use common::StatusMessage;
use rusqlite::Connection;
use std::path::Path;
@@ -92,12 +92,28 @@ impl StorageRepository for SQLiteRepository {
Ok(())
}
async fn get_history(&self, agent: &str) -> anyhow::Result<Vec<StatusMessage>> {
async fn get_history(
&self,
agent: &str,
duration: Option<DateTime<Utc>>,
) -> anyhow::Result<Vec<StatusMessage>> {
let conn = self.conn.lock().await;
let mut stmt =
conn.prepare("SELECT agent_id, message, timestamp FROM messages WHERE agent_id = ?")?;
let rows = stmt.query_map([agent], |row| {
let (sql, params) = if let Some(duration) = duration {
(
"SELECT agent_id, message, timestamp FROM messages WHERE agent_id = ? AND timestamp <= ?",
vec![agent.to_string(), duration.to_rfc3339()],
)
} else {
(
"SELECT agent_id, message, timestamp FROM messages WHERE agent_id = ?",
vec![agent.to_string()],
)
};
let mut stmt = conn.prepare(sql)?;
let rows = stmt.query_map(rusqlite::params_from_iter(params), |row| {
let row: String = row.get::<_, String>(1).unwrap();
StatusMessage::try_from(row).map_err(|e| {