gc.rs (2605B)
1 /* 2 * This file is part of LibEuFin. 3 * Copyright (C) 2026 Taler Systems S.A. 4 5 * LibEuFin is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation; either version 3, or 8 * (at your option) any later version. 9 10 * LibEuFin is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General 13 * Public License for more details. 14 15 * You should have received a copy of the GNU Affero General Public 16 * License along with LibEuFin; see the file COPYING. If not, see 17 * <http://www.gnu.org/licenses/> 18 */ 19 20 //! Data access logic for garbage collection 21 22 use jiff::Timestamp; 23 use sqlx::PgPool; 24 use taler_api::db::BindHelper; 25 26 /** Run garbage collection */ 27 pub async fn collect( 28 db: &PgPool, 29 abort_before: &Timestamp, 30 clean_before: &Timestamp, 31 delete_before: &Timestamp, 32 ) -> sqlx::Result<()> { 33 // Abort pending operations 34 sqlx::query( 35 " 36 UPDATE taler_withdrawal_operations SET aborted = true WHERE creation_date < $1 AND NOT confirmation_done AND NOT EXISTS( 37 SELECT FROM prepared_transfers WHERE prepared_transfers.withdrawal_id=taler_withdrawal_operations.withdrawal_id 38 ) 39 " 40 ).bind_timestamp(abort_before).execute(db).await?; 41 42 // Clean aborted operations, expired challenges and expired tokens 43 for stm in [ 44 "DELETE FROM taler_withdrawal_operations WHERE aborted = true AND creation_date < $1 AND NOT EXISTS( 45 SELECT FROM prepared_transfers WHERE prepared_transfers.withdrawal_id=taler_withdrawal_operations.withdrawal_id 46 )", 47 "DELETE FROM tan_challenges WHERE expiration_date < $1", 48 "DELETE FROM bearer_tokens WHERE expiration_time < $1" 49 ] { 50 sqlx::query(stm).bind_timestamp(clean_before).execute(db).await?; 51 } 52 53 // Delete old bank transactions, linked operations are deleted by CASCADE 54 sqlx::query("DELETE FROM bank_account_transactions WHERE transaction_date < $1") 55 .bind_timestamp(delete_before) 56 .execute(db) 57 .await?; 58 59 // Hard delete soft deleted customer without bank transactions, bank account are deleted by CASCADE 60 sqlx::query( 61 "DELETE FROM customers WHERE deleted_at IS NOT NULL AND NOT EXISTS( 62 SELECT FROM bank_account_transactions NATURAL JOIN bank_accounts 63 WHERE owning_customer_id=customer_id 64 )", 65 ) 66 .execute(db) 67 .await?; 68 69 Ok(()) 70 }