diff --git a/atuin-common/src/api.rs b/atuin-common/src/api.rs index 025464d..5622bd8 100644 --- a/atuin-common/src/api.rs +++ b/atuin-common/src/api.rs @@ -67,6 +67,7 @@ pub struct ErrorResponse<'a> { pub struct IndexResponse { pub homage: String, pub version: String, + pub total_history: i64, } #[derive(Debug, Serialize, Deserialize)] diff --git a/atuin-server-database/src/lib.rs b/atuin-server-database/src/lib.rs index cdff90a..06ecf91 100644 --- a/atuin-server-database/src/lib.rs +++ b/atuin-server-database/src/lib.rs @@ -52,6 +52,7 @@ pub trait Database: Sized + Clone + Send + Sync + 'static { async fn add_user(&self, user: &NewUser) -> DbResult; async fn delete_user(&self, u: &User) -> DbResult<()>; + async fn total_history(&self) -> DbResult; async fn count_history(&self, user: &User) -> DbResult; async fn count_history_cached(&self, user: &User) -> DbResult; diff --git a/atuin-server-postgres/src/lib.rs b/atuin-server-postgres/src/lib.rs index 404188b..fe1363a 100644 --- a/atuin-server-postgres/src/lib.rs +++ b/atuin-server-postgres/src/lib.rs @@ -100,6 +100,21 @@ impl Database for Postgres { Ok(res.0) } + #[instrument(skip_all)] + async fn total_history(&self) -> DbResult { + // The cache is new, and the user might not yet have a cache value. + // They will have one as soon as they post up some new history, but handle that + // edge case. + + let res: (i64,) = sqlx::query_as("select sum(total) from total_history_count_user") + .fetch_optional(&self.pool) + .await + .map_err(fix_error)? + .unwrap_or((0,)); + + Ok(res.0) + } + #[instrument(skip_all)] async fn count_history_cached(&self, user: &User) -> DbResult { let res: (i32,) = sqlx::query_as( diff --git a/atuin-server/src/handlers/mod.rs b/atuin-server/src/handlers/mod.rs index 2bd782d..18b1af8 100644 --- a/atuin-server/src/handlers/mod.rs +++ b/atuin-server/src/handlers/mod.rs @@ -1,5 +1,8 @@ use atuin_common::api::{ErrorResponse, IndexResponse}; -use axum::{response::IntoResponse, Json}; +use atuin_server_database::Database; +use axum::{extract::State, response::IntoResponse, Json}; + +use crate::router::AppState; pub mod history; pub mod record; @@ -8,12 +11,17 @@ pub mod user; const VERSION: &str = env!("CARGO_PKG_VERSION"); -pub async fn index() -> Json { +pub async fn index(state: State>) -> Json { let homage = r#""Through the fathomless deeps of space swims the star turtle Great A'Tuin, bearing on its back the four giant elephants who carry on their shoulders the mass of the Discworld." -- Sir Terry Pratchett"#; + // Error with a -1 response + // It's super unlikley this will happen + let count = state.database.total_history().await.unwrap_or(-1); + Json(IndexResponse { homage: homage.to_string(), version: VERSION.to_string(), + total_history: count, }) }