/* This file is part of TALER Copyright (C) 2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see */ /** * @file pg_helper.c * @brief shared internal definitions for postgres DB plugin * @author Christian Grothoff */ #include "platform.h" #include "pg_helper.h" #include #include #include #include #include #include enum GNUNET_GenericReturnValue TMH_PG_start (void *cls, const char *name) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"), GNUNET_PQ_EXECUTE_STATEMENT_END }; GNUNET_assert (NULL != name); check_connection (pg); postgres_preflight (pg); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting merchant DB transaction `%s'\n", name); if (GNUNET_OK != GNUNET_PQ_exec_statements (pg->conn, es)) { TALER_LOG_ERROR ("Failed to start transaction\n"); GNUNET_break (0); return GNUNET_SYSERR; } pg->transaction_name = name; return GNUNET_OK; } enum GNUNET_GenericReturnValue TMH_PG_start_read_committed (void *cls, const char *name) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL READ COMMITTED"), GNUNET_PQ_EXECUTE_STATEMENT_END }; GNUNET_assert (NULL != name); check_connection (pg); postgres_preflight (pg); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting merchant DB transaction %s (READ COMMITTED)\n", name); if (GNUNET_OK != GNUNET_PQ_exec_statements (pg->conn, es)) { TALER_LOG_ERROR ("Failed to start transaction\n"); GNUNET_break (0); return GNUNET_SYSERR; } pg->transaction_name = name; return GNUNET_OK; } void TMH_PG_rollback (void *cls) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("ROLLBACK"), GNUNET_PQ_EXECUTE_STATEMENT_END }; if (NULL == pg->transaction_name) return; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Rolling back merchant DB transaction `%s'\n", pg->transaction_name); GNUNET_break (GNUNET_OK == GNUNET_PQ_exec_statements (pg->conn, es)); pg->transaction_name = NULL; } enum GNUNET_DB_QueryStatus TMH_PG_commit (void *cls) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus qs; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Committing merchant DB transaction %s\n", pg->transaction_name); check_connection (pg); PREPARE (pg, "merchant_commit", "COMMIT"); qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, "merchant_commit", params); if (qs < 0) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to commit transaction\n"); TMH_PG_rollback (pg); return qs; } pg->transaction_name = NULL; return qs; }