exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

pg_helper.h (4713B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2022 Taler Systems SA
      4 
      5    TALER is free software; you can redistribute it and/or modify it under the
      6    terms of the GNU General Public License as published by the Free Software
      7    Foundation; either version 3, or (at your option) any later version.
      8 
      9    TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License along with
     14    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 /**
     17  * @file pg_helper.h
     18  * @brief shared internal definitions for postgres DB plugin
     19  * @author Christian Grothoff
     20  */
     21 #ifndef PG_HELPER_H
     22 #define PG_HELPER_H
     23 
     24 
     25 /**
     26  * Type of the "cls" argument given to each of the functions in
     27  * our API.
     28  */
     29 struct PostgresClosure
     30 {
     31 
     32   /**
     33    * Our configuration.
     34    */
     35   const struct GNUNET_CONFIGURATION_Handle *cfg;
     36 
     37   /**
     38    * Directory with SQL statements to run to create tables.
     39    */
     40   char *sql_dir;
     41 
     42   /**
     43    * After how long should idle reserves be closed?
     44    */
     45   struct GNUNET_TIME_Relative idle_reserve_expiration_time;
     46 
     47   /**
     48    * After how long should reserves that have seen withdraw operations
     49    * be garbage collected?
     50    */
     51   struct GNUNET_TIME_Relative legal_reserve_expiration_time;
     52 
     53   /**
     54    * What delay should we introduce before ready transactions
     55    * are actually aggregated?
     56    */
     57   struct GNUNET_TIME_Relative aggregator_shift;
     58 
     59   /**
     60    * Which currency should we assume all amounts to be in?
     61    */
     62   char *currency;
     63 
     64   /**
     65    * Our base URL.
     66    */
     67   char *exchange_url;
     68 
     69   /**
     70    * Postgres connection handle.
     71    */
     72   struct GNUNET_PQ_Context *conn;
     73 
     74   /**
     75    * Name of the current transaction, for debugging.
     76    */
     77   const char *transaction_name;
     78 
     79   /**
     80    * Counts how often we have established a fresh @e conn
     81    * to the database. Used to re-prepare statements.
     82    */
     83   unsigned long long prep_gen;
     84 
     85   /**
     86    * Number of purses we allow to be opened concurrently
     87    * for one year per annual fee payment.
     88    */
     89   uint32_t def_purse_limit;
     90 
     91 };
     92 
     93 
     94 /**
     95  * Prepares SQL statement @a sql under @a name for
     96  * connection @a pg once.
     97  * Returns with #GNUNET_DB_STATUS_HARD_ERROR on failure.
     98  *
     99  * @param pg a `struct PostgresClosure`
    100  * @param name name to prepare the statement under
    101  * @param sql actual SQL text
    102  */
    103 #define PREPARE(pg,name,sql)                            \
    104         do {                                            \
    105           static struct {                               \
    106             unsigned long long cnt;                     \
    107             struct PostgresClosure *pg;                 \
    108           } preps_[2]; /* 2 ctrs for taler-auditor-sync*/ \
    109           unsigned int off_ = 0;                        \
    110                                                         \
    111           while ( (NULL != preps_[off_].pg) &&          \
    112                   (pg != preps_[off_].pg) &&            \
    113                   (off_ < sizeof(preps_) / sizeof(*preps_)) ) \
    114           off_++;                                       \
    115           GNUNET_assert (off_ <                         \
    116                          sizeof(preps_) / sizeof(*preps_)); \
    117           if (preps_[off_].cnt < pg->prep_gen)          \
    118           {                                             \
    119             struct GNUNET_PQ_PreparedStatement ps[] = { \
    120               GNUNET_PQ_make_prepare (name, sql),       \
    121               GNUNET_PQ_PREPARED_STATEMENT_END          \
    122             };                                          \
    123                                                         \
    124             if (GNUNET_OK !=                            \
    125                 GNUNET_PQ_prepare_statements (pg->conn, \
    126                                               ps))      \
    127             {                                           \
    128               GNUNET_break (0);                         \
    129               return GNUNET_DB_STATUS_HARD_ERROR;       \
    130             }                                           \
    131             preps_[off_].pg = pg;                       \
    132             preps_[off_].cnt = pg->prep_gen;            \
    133           }                                             \
    134         } while (0)
    135 
    136 
    137 /**
    138  * Wrapper macro to add the currency from the plugin's state
    139  * when fetching amounts from the database.
    140  *
    141  * @param field name of the database field to fetch amount from
    142  * @param[out] amountp pointer to amount to set
    143  */
    144 #define TALER_PQ_RESULT_SPEC_AMOUNT(field, \
    145                                     amountp) TALER_PQ_result_spec_amount ( \
    146           field,pg->currency,amountp)
    147 
    148 
    149 #endif