/*
  This file is part of Challenger
  (C) 2023 Taler Systems SA

  Challenger is free software; you can redistribute it and/or modify it under the
  terms of the GNU Lesser General Public License as published by the Free Software
  Foundation; either version 3, or (at your option) any later version.

  Challenger 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
  Challenger; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
*/
/**
 * @file src/challengerdb/pg_helper.h
 * @brief database helper definitions
 * @author Christian Grothoff
 */
#ifndef PG_HELPER_H
#define PG_HELPER_H


/**
 * Type of the "cls" argument given to each of the functions in
 * our API.
 */
struct CHALLENGERDB_PostgresContext
{

  /**
   * 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;

};


/**
 * Counts how often we have established a fresh @e conn
 * to the database. Used to re-prepare statements.
 */
extern unsigned long long CH_PG_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 CHALLENGERDB_PostgresContext`
 * @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 < CH_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 = CH_PG_prep_gen_;                      \
          }                                             \
        } while (0)

#endif
