use std::collections::BTreeMap;
use std::sync::Arc;
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use fakecloud_core::multi_account::{AccountState, MultiAccountState};
pub const TIMESTREAM_SNAPSHOT_SCHEMA_VERSION: u32 = 1;
pub const MAX_RECORDS_PER_TABLE: usize = 100_000;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Database {
pub name: String,
pub arn: String,
#[serde(default)]
pub kms_key_id: Option<String>,
pub table_count: i64,
pub creation_time: f64,
pub last_updated_time: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Table {
pub name: String,
pub database_name: String,
pub arn: String,
pub status: String,
#[serde(default)]
pub retention_properties: Value,
#[serde(default)]
pub magnetic_store_write_properties: Option<Value>,
#[serde(default)]
pub schema: Value,
pub creation_time: f64,
pub last_updated_time: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StoredRecord {
pub time_nanos: i128,
pub dimensions: Vec<(String, String)>,
pub measure_name: String,
pub measure_value: String,
pub measure_value_type: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScheduledQuery {
pub arn: String,
pub name: String,
pub query_string: String,
pub state: String,
pub creation_time: f64,
pub schedule_configuration: Value,
pub notification_configuration: Value,
#[serde(default)]
pub target_configuration: Option<Value>,
#[serde(default)]
pub scheduled_query_execution_role_arn: Option<String>,
#[serde(default)]
pub kms_key_id: Option<String>,
#[serde(default)]
pub error_report_configuration: Option<Value>,
#[serde(default)]
pub previous_invocation_time: Option<f64>,
#[serde(default)]
pub last_run_status: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchLoadTask {
pub task_id: String,
pub status: String,
pub target_database_name: String,
pub target_table_name: String,
pub data_source_configuration: Value,
pub report_configuration: Value,
#[serde(default)]
pub data_model_configuration: Option<Value>,
#[serde(default)]
pub record_version: Option<i64>,
pub creation_time: f64,
pub last_updated_time: f64,
pub resumable_until: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccountSettings {
#[serde(default)]
pub max_query_tcu: Option<i64>,
pub query_pricing_model: String,
#[serde(default)]
pub query_compute: Option<Value>,
}
impl Default for AccountSettings {
fn default() -> Self {
Self {
max_query_tcu: None,
query_pricing_model: "BYTES_SCANNED".to_string(),
query_compute: None,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TimestreamData {
#[serde(default)]
pub account_id: String,
#[serde(default)]
pub region: String,
#[serde(default)]
pub databases: BTreeMap<String, Database>,
#[serde(default)]
pub tables: BTreeMap<String, Table>,
#[serde(default)]
pub records: BTreeMap<String, Vec<StoredRecord>>,
#[serde(default)]
pub scheduled_queries: BTreeMap<String, ScheduledQuery>,
#[serde(default)]
pub batch_load_tasks: BTreeMap<String, BatchLoadTask>,
#[serde(default)]
pub active_queries: BTreeMap<String, f64>,
#[serde(default)]
pub account_settings: AccountSettings,
#[serde(default)]
pub tags: BTreeMap<String, BTreeMap<String, String>>,
}
impl AccountState for TimestreamData {
fn new_for_account(account_id: &str, region: &str, _endpoint: &str) -> Self {
Self {
account_id: account_id.to_string(),
region: region.to_string(),
..Default::default()
}
}
}
pub type SharedTimestreamState = Arc<RwLock<MultiAccountState<TimestreamData>>>;
#[derive(Debug, Serialize, Deserialize)]
pub struct TimestreamSnapshot {
pub schema_version: u32,
pub accounts: MultiAccountState<TimestreamData>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn account_state_seeds_ids() {
let d = TimestreamData::new_for_account("000000000000", "us-east-1", "");
assert_eq!(d.account_id, "000000000000");
assert_eq!(d.region, "us-east-1");
assert!(d.databases.is_empty());
assert_eq!(d.account_settings.query_pricing_model, "BYTES_SCANNED");
}
}