forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
1//! Analytics and time-series data queries.
2//!
3//! This module handles database operations for generating analytics data,
4//! including sparkline time-series data for record indexing activity.
5
6use super::client::Database;
7use crate::errors::DatabaseError;
8use crate::models::SparklinePoint;
9use std::collections::HashMap;
10
11impl Database {
12 /// Gets sparkline data for multiple slices in a single query batch.
13 ///
14 /// Generates time-bucketed counts of indexed records for visualization.
15 ///
16 /// # Arguments
17 /// * `slice_uris` - Array of slice URIs to get data for
18 /// * `interval` - Time bucket size: "minute", "hour", or "day"
19 /// * `duration_hours` - How many hours of history to include
20 ///
21 /// # Returns
22 /// HashMap mapping slice_uri -> array of (timestamp, count) data points
23 pub async fn get_batch_sparkline_data(
24 &self,
25 slice_uris: &[String],
26 interval: &str,
27 duration_hours: i32,
28 ) -> Result<HashMap<String, Vec<SparklinePoint>>, DatabaseError> {
29 use chrono::{Duration, Utc};
30 let cutoff_time = Utc::now() - Duration::hours(duration_hours as i64);
31
32 let mut sparklines = HashMap::new();
33
34 for slice_uri in slice_uris {
35 let interval_validated = match interval {
36 "minute" => "minute",
37 "day" => "day",
38 _ => "hour",
39 };
40
41 let query = format!(
42 r#"
43 SELECT
44 date_trunc('{}', indexed_at) as bucket,
45 COUNT(*) as count
46 FROM record
47 WHERE indexed_at >= $1
48 AND slice_uri = $2
49 GROUP BY bucket
50 ORDER BY bucket
51 "#,
52 interval_validated
53 );
54
55 let rows =
56 sqlx::query_as::<_, (Option<chrono::DateTime<chrono::Utc>>, Option<i64>)>(&query)
57 .bind(cutoff_time)
58 .bind(slice_uri)
59 .fetch_all(&self.pool)
60 .await?;
61
62 let data_points = rows
63 .into_iter()
64 .map(|(bucket, count)| SparklinePoint {
65 timestamp: bucket.unwrap().to_rfc3339(),
66 count: count.unwrap_or(0),
67 })
68 .collect();
69
70 sparklines.insert(slice_uri.clone(), data_points);
71 }
72
73 Ok(sparklines)
74 }
75}