Highly ambitious ATProtocol AppView service and sdks
at main 2.5 kB view raw
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}