/* 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.h * @brief shared internal definitions for postgres DB plugin * @author Christian Grothoff */ #ifndef PG_HELPER_H #define PG_HELPER_H #include /** * Type of the "cls" argument given to each of the functions in * our API. */ struct PostgresClosure { /** * Postgres connection handle. */ struct GNUNET_PQ_Context *conn; /** * Directory with SQL statements to run to create tables. */ char *sql_dir; /** * Underlying configuration. */ const struct GNUNET_CONFIGURATION_Handle *cfg; /** * Name of the currently active transaction, NULL if none is active. */ const char *transaction_name; /** * How many times have we connected to the DB. */ uint64_t prep_gen; }; /** * Prepares SQL statement @a sql under @a name for * connection @a pg once. * Returns with #GNUNET_DB_STATUS_HARD_ERROR on failure. * * @param pg a `struct PostgresClosure` * @param name name to prepare the statement under * @param sql actual SQL text */ #define PREPARE(pg,name,sql) \ do { \ static unsigned long long gen; \ \ if (gen < pg->prep_gen) \ { \ struct GNUNET_PQ_PreparedStatement ps[] = { \ GNUNET_PQ_make_prepare (name, sql), \ GNUNET_PQ_PREPARED_STATEMENT_END \ }; \ \ if (GNUNET_OK != \ GNUNET_PQ_prepare_statements (pg->conn, \ ps)) \ { \ GNUNET_break (0); \ return GNUNET_DB_STATUS_HARD_ERROR; \ } \ gen = pg->prep_gen; \ } \ } while (0) /** * Check that the database connection is still up * and automatically reconnects unless we are * already inside of a transaction. * * @param pg connection to check */ void check_connection (struct PostgresClosure *pg); /** * Do a pre-flight check that we are not in an uncommitted transaction. * If we are, die. * Does not return anything, as we will continue regardless of the outcome. * * @param cls the `struct PostgresClosure` with the plugin-specific state */ void postgres_preflight (void *cls); /** * Start a transaction. * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param name unique name identifying the transaction (for debugging), * must point to a constant * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue TMH_PG_start (void *cls, const char *name); /** * Start a transaction in 'read committed' mode. * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param name unique name identifying the transaction (for debugging), * must point to a constant * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue TMH_PG_start_read_committed (void *cls, const char *name); /** * Roll back the current transaction of a database connection. * * @param cls the `struct PostgresClosure` with the plugin-specific state */ void TMH_PG_rollback (void *cls); /** * Commit the current transaction of a database connection. * * @param cls the `struct PostgresClosure` with the plugin-specific state * @return transaction status code */ enum GNUNET_DB_QueryStatus TMH_PG_commit (void *cls); #endif