merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

pg.c (4200B)


      1 /*
      2   This file is part of TALER
      3   (C) 2014--2025 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Lesser 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 src/backenddb/pg.c
     18  * @brief database helper functions for postgres used by the merchant
     19  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
     20  * @author Christian Grothoff
     21  * @author Marcello Stanisci
     22  * @author Priscilla Huang
     23  * @author Iván Ávalos
     24  */
     25 struct TALER_MERCHANTDB_PostgresContext;
     26 #define GNUNET_PQ_RECONNECT_CALLBACK_CLOSURE \
     27         struct TALER_MERCHANTDB_PostgresContext
     28 #include <gnunet/gnunet_util_lib.h>
     29 #include <gnunet/gnunet_pq_lib.h>
     30 #include <taler/taler_util.h>
     31 #include <taler/taler_pq_lib.h>
     32 #include <taler/taler_json_lib.h>
     33 #include <taler/taler_mhd_lib.h>
     34 #include "merchantdb_lib.h"
     35 #include "helper.h"
     36 
     37 /**
     38  * How many times have we connected to the DB.
     39  */
     40 uint64_t TMH_PG_prep_gen_;
     41 
     42 /**
     43  * Function called each time we connect or reconnect to the
     44  * database. Gives the application a chance to run some
     45  * per-connection initialization logic.
     46  *
     47  * @param pg database context in the merchant backend
     48  * @param pq database connection handle
     49  */
     50 static void
     51 reconnect_cb (struct TALER_MERCHANTDB_PostgresContext *pg,
     52               struct GNUNET_PQ_Context *pq)
     53 {
     54   struct GNUNET_PQ_ExecuteStatement es[] = {
     55     GNUNET_PQ_make_try_execute ("SET search_path TO merchant;"),
     56     GNUNET_PQ_EXECUTE_STATEMENT_END
     57   };
     58 
     59   /* The 'search_path' of the new connection is the one we set above,
     60      so the instance the old connection was routed to is no longer
     61      current; forget it, or TALER_MERCHANTDB_set_instance() would
     62      consider the routing up-to-date and skip re-issuing it. */
     63   GNUNET_free (pg->current_merchant_id);
     64   pg->current_merchant_serial = 0;
     65   memset (&pg->current_merchant_pub,
     66           0,
     67           sizeof (pg->current_merchant_pub));
     68   if (GNUNET_OK !=
     69       GNUNET_PQ_exec_statements (pq,
     70                                  es))
     71   {
     72     GNUNET_break (0);
     73     return;
     74   }
     75   TMH_PG_prep_gen_++;
     76 }
     77 
     78 
     79 /**
     80  * Initialize the database connection.
     81  *
     82  * @param cfg configuration to use
     83  * @param check_current true to check if the database schema is current
     84  * @return NULL on failure
     85  */
     86 static struct TALER_MERCHANTDB_PostgresContext *
     87 do_connect (
     88   const struct GNUNET_CONFIGURATION_Handle *cfg,
     89   bool check_current)
     90 {
     91   struct TALER_MERCHANTDB_PostgresContext *pg;
     92 
     93   pg = GNUNET_new (struct TALER_MERCHANTDB_PostgresContext);
     94   pg->cfg = cfg;
     95   pg->conn = GNUNET_PQ_init (pg->cfg,
     96                              "merchantdb-postgres",
     97                              &reconnect_cb,
     98                              pg);
     99   if (NULL == pg->conn)
    100   {
    101     TALER_MERCHANTDB_disconnect (pg);
    102     return NULL;
    103   }
    104   if (check_current &&
    105       (GNUNET_OK !=
    106        GNUNET_PQ_check_current (pg->conn,
    107                                 "merchant-")) )
    108   {
    109     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    110                 "Database schema is not up-to-date. Try running taler-merchant-dbinit or taler-merchant-dbconfig!\n");
    111     TALER_MERCHANTDB_disconnect (pg);
    112     return NULL;
    113   }
    114   return pg;
    115 }
    116 
    117 
    118 struct TALER_MERCHANTDB_PostgresContext *
    119 TALER_MERCHANTDB_connect (
    120   const struct GNUNET_CONFIGURATION_Handle *cfg)
    121 {
    122   return do_connect (cfg,
    123                      true);
    124 }
    125 
    126 
    127 struct TALER_MERCHANTDB_PostgresContext *
    128 TALER_MERCHANTDB_connect_admin (
    129   const struct GNUNET_CONFIGURATION_Handle *cfg)
    130 {
    131   return do_connect (cfg,
    132                      false);
    133 }
    134 
    135 
    136 void
    137 TALER_MERCHANTDB_disconnect (
    138   struct TALER_MERCHANTDB_PostgresContext *pg)
    139 {
    140   GNUNET_PQ_disconnect (pg->conn);
    141   GNUNET_free (pg->current_merchant_id);
    142   GNUNET_free (pg);
    143 }
    144 
    145 
    146 /* end of pg.c */