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