From dcd77749dd1fdf6b0c8183bfbdf4f97bf238ebe4 Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Mon, 20 Mar 2023 09:26:54 +0000 Subject: Add history deletion (#791) * Drop events. I'd still like to do them, but differently * Start adding delete api stuff * Set mailmap * Delete delete delete * Fix tests * Make clippy happy --- atuin-server/src/database.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'atuin-server/src/database.rs') diff --git a/atuin-server/src/database.rs b/atuin-server/src/database.rs index ef6c6d85..7f3e5dac 100644 --- a/atuin-server/src/database.rs +++ b/atuin-server/src/database.rs @@ -4,6 +4,9 @@ use async_trait::async_trait; use chrono::{Datelike, TimeZone}; use chronoutil::RelativeDuration; use sqlx::{postgres::PgPoolOptions, Result}; + +use sqlx::Row; + use tracing::{debug, instrument, warn}; use super::{ @@ -28,6 +31,9 @@ pub trait Database { async fn count_history(&self, user: &User) -> Result; async fn count_history_cached(&self, user: &User) -> Result; + async fn delete_history(&self, user: &User, id: String) -> Result<()>; + async fn deleted_history(&self, user: &User) -> Result>; + async fn count_history_range( &self, user: &User, @@ -141,6 +147,46 @@ impl Database for Postgres { Ok(res.0 as i64) } + async fn delete_history(&self, user: &User, id: String) -> Result<()> { + sqlx::query( + "update history + set deleted_at = $3 + where user_id = $1 + and client_id = $2 + and deleted_at is null", // don't just keep setting it + ) + .bind(user.id) + .bind(id) + .bind(chrono::Utc::now().naive_utc()) + .fetch_all(&self.pool) + .await?; + + Ok(()) + } + + #[instrument(skip_all)] + async fn deleted_history(&self, user: &User) -> Result> { + // 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 = sqlx::query( + "select client_id from history + where user_id = $1 + and deleted_at is not null", + ) + .bind(user.id) + .fetch_all(&self.pool) + .await?; + + let res = res + .iter() + .map(|row| row.get::("client_id")) + .collect(); + + Ok(res) + } + #[instrument(skip_all)] async fn count_history_range( &self, -- cgit v1.3.1