//! Projections (spec ยง9.3): tables kept from the ledger in the same //! transaction as each append, and rebuilt from it by `spectra admin //! rebuild`. Every table here must be a function of the events alone; the //! test harness and `spectra admin check` hold them to it. use crate::event::Event; use sqlx::SqliteConnection; /// The projection tables, in the order they are cleared and compared. pub const TABLES: &[&str] = &[ "event_counts", "identities", "agents", "projects", "project_relations", "presence", "sessions", "channels", "messages", "reactions", "inbox", "messages_fts", "briefs", ]; /// Apply one event to every projection. pub async fn apply(conn: &mut SqliteConnection, e: &Event) -> sqlx::Result<()> { sqlx::query("INSERT INTO event_counts (kind, n) VALUES (?, 1) ON CONFLICT(kind) DO UPDATE SET n = n + 1") .bind(&e.kind) .execute(&mut *conn) .await?; crate::principals::project(conn, e).await?; crate::projects::project(conn, e).await?; crate::presence::project(conn, e).await?; crate::conversation::project(conn, e).await?; crate::rules::project(conn, e).await?; Ok(()) }