LCOV - code coverage report
Current view: top level - auditordb - pg_helper.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 66.7 % 6 4
Test Date: 2026-09-09 15:11:34 Functions: 100.0 % 1 1

            Line data    Source code
       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              : #include "auditordb_lib.h"
      26              : 
      27              : /**
      28              :  * Postgres database connection handle.
      29              :  */
      30              : struct TALER_AUDITORDB_PostgresContext
      31              : {
      32              : 
      33              :   /**
      34              :    * Postgres connection handle.
      35              :    */
      36              :   struct GNUNET_PQ_Context *conn;
      37              : 
      38              :   /**
      39              :    * Name of the ongoing transaction, used to debug cases where
      40              :    * a transaction is not properly terminated via COMMIT or
      41              :    * ROLLBACK.
      42              :    */
      43              :   const char *transaction_name;
      44              : 
      45              :   /**
      46              :    * Our configuration.
      47              :    */
      48              :   const struct GNUNET_CONFIGURATION_Handle *cfg;
      49              :   /**
      50              :    * How often have we connected to the DB so far?
      51              :    */
      52              :   unsigned long long prep_gen;
      53              : 
      54              :   /**
      55              :    * Which currency should we assume all amounts to be in?
      56              :    */
      57              :   char *currency;
      58              : };
      59              : 
      60              : 
      61              : // FIXME: comment
      62              : const char *
      63              : TALER_AUDITORDB_get_deletable_suppressable_table_name (
      64              :   enum TALER_AUDITORDB_DeletableSuppressableTables table);
      65              : 
      66              : 
      67              : /**
      68              :  * Convert the signed @a limit of a monitoring listing into the row
      69              :  * limit to pass to SQL.  The sign selects the iteration direction and
      70              :  * the magnitude the number of rows, but computing `-limit` directly is
      71              :  * undefined behaviour for `INT64_MIN`, and the resulting value would
      72              :  * reach Postgres as `LIMIT -9223372036854775808`, which errors out.
      73              :  * `INT64_MIN` is therefore saturated to `INT64_MAX`.
      74              :  *
      75              :  * @param limit signed limit as given by the caller
      76              :  * @return absolute value of @a limit, without signed overflow
      77              :  */
      78              : static inline uint64_t
      79           10 : TALER_AUDITORDB_abs_limit (int64_t limit)
      80              : {
      81              :   /* Postgres binds INT8 as a *signed* 64-bit integer, so a magnitude
      82              :      above INT64_MAX would reach LIMIT as a negative number. */
      83           10 :   if (INT64_MIN == limit)
      84            0 :     return (uint64_t) INT64_MAX;
      85           10 :   if (limit < 0)
      86            0 :     return (uint64_t) -limit;
      87           10 :   return (uint64_t) limit;
      88              : }
      89              : 
      90              : 
      91              : /**
      92              :  * Prepares SQL statement @a sql under @a name for
      93              :  * connection @a pg once.
      94              :  * Returns with #GNUNET_DB_STATUS_HARD_ERROR on failure.
      95              :  *
      96              :  * @param pg a `struct PostgresClosure`
      97              :  * @param name name to prepare the statement under
      98              :  * @param sql actual SQL text
      99              :  */
     100              : #define PREPARE(pg,name,sql)                            \
     101              :         do {                                            \
     102              :           static struct {                               \
     103              :             unsigned long long cnt;                     \
     104              :             struct TALER_AUDITORDB_PostgresContext *pg;       \
     105              :           } preps_[2]; /* 2 ctrs for taler-auditor-sync*/ \
     106              :           unsigned int off_ = 0;                        \
     107              :                                                         \
     108              :           while ( (NULL != preps_[off_].pg) &&          \
     109              :                   (pg != preps_[off_].pg) &&            \
     110              :                   (off_ < sizeof(preps_) / sizeof(*preps_)) ) \
     111              :           off_++;                                       \
     112              :           GNUNET_assert (off_ <                         \
     113              :                          sizeof(preps_) / sizeof(*preps_)); \
     114              :           if (preps_[off_].cnt < pg->prep_gen)          \
     115              :           {                                             \
     116              :             struct GNUNET_PQ_PreparedStatement ps[] = { \
     117              :               GNUNET_PQ_make_prepare (name, sql),       \
     118              :               GNUNET_PQ_PREPARED_STATEMENT_END          \
     119              :             };                                          \
     120              :                                                         \
     121              :             if (GNUNET_OK !=                            \
     122              :                 GNUNET_PQ_prepare_statements (pg->conn, \
     123              :                                               ps))      \
     124              :             {                                           \
     125              :               GNUNET_break (0);                         \
     126              :               return GNUNET_DB_STATUS_HARD_ERROR;       \
     127              :             }                                           \
     128              :             preps_[off_].pg = pg;                       \
     129              :             preps_[off_].cnt = pg->prep_gen;            \
     130              :           }                                             \
     131              :         } while (0)
     132              : 
     133              : 
     134              : /**
     135              :  * Wrapper macro to add the currency from the plugin's state
     136              :  * when fetching amounts from the database.
     137              :  *
     138              :  * @param field name of the database field to fetch amount from
     139              :  * @param[out] amountp pointer to amount to set
     140              :  */
     141              : #define TALER_PQ_RESULT_SPEC_AMOUNT(field,   \
     142              :                                     amountp) \
     143              :         TALER_PQ_result_spec_amount (        \
     144              :           field,pg->currency,amountp)
     145              : 
     146              : 
     147              : #endif
        

Generated by: LCOV version 2.0-1