summaryrefslogtreecommitdiff
path: root/src/auditordb/pg_helper.h
blob: 54ccd59781e6106b9eff35be3e2f415a3cce35ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
   This file is part of TALER
   Copyright (C) 2022 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 <http://www.gnu.org/licenses/>
 */
/**
 * @file pg_helper.h
 * @brief shared internal definitions for postgres DB plugin
 * @author Christian Grothoff
 */
#ifndef PG_HELPER_H
#define PG_HELPER_H


#include "taler_auditordb_plugin.h"


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

  /**
   * Postgres connection handle.
   */
  struct GNUNET_PQ_Context *conn;

  /**
   * Name of the ongoing transaction, used to debug cases where
   * a transaction is not properly terminated via COMMIT or
   * ROLLBACK.
   */
  const char *transaction_name;

  /**
   * Our configuration.
   */
  const struct GNUNET_CONFIGURATION_Handle *cfg;

  /**
   * How often have we connected to the DB so far?
   */
  unsigned long long prep_gen;

  /**
   * Which currency should we assume all amounts to be in?
   */
  char *currency;
};


/**
 * 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 struct {                               \
      unsigned long long cnt;                     \
      struct PostgresClosure *pg;                 \
    } preps[2]; /* 2 ctrs for taler-auditor-sync*/ \
    unsigned int off = 0;                         \
                                                  \
    while ( (NULL != preps[off].pg) &&            \
            (pg != preps[off].pg) &&              \
            (off < sizeof(preps) / sizeof(*preps)) ) \
    off++;                                      \
    GNUNET_assert (off <                          \
                   sizeof(preps) / sizeof(*preps)); \
    if (preps[off].cnt < 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;       \
      }                                           \
      preps[off].pg = pg;                         \
      preps[off].cnt = pg->prep_gen;              \
    }                                             \
  } while (0)


/**
 * Wrapper macro to add the currency from the plugin's state
 * when fetching amounts from the database.
 *
 * @param field name of the database field to fetch amount from
 * @param[out] amountp pointer to amount to set
 */
#define TALER_PQ_RESULT_SPEC_AMOUNT(field, \
                                    amountp) TALER_PQ_result_spec_amount ( \
    field,pg->currency,amountp)


#endif