Line data Source code
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 137 : reconnect_cb (struct TALER_MERCHANTDB_PostgresContext *pg,
52 : struct GNUNET_PQ_Context *pq)
53 : {
54 137 : struct GNUNET_PQ_ExecuteStatement es[] = {
55 137 : 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 137 : GNUNET_free (pg->current_merchant_id);
64 137 : pg->current_merchant_serial = 0;
65 137 : memset (&pg->current_merchant_pub,
66 : 0,
67 : sizeof (pg->current_merchant_pub));
68 137 : if (GNUNET_OK !=
69 137 : GNUNET_PQ_exec_statements (pq,
70 : es))
71 : {
72 0 : GNUNET_break (0);
73 0 : return;
74 : }
75 137 : 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 136 : do_connect (
88 : const struct GNUNET_CONFIGURATION_Handle *cfg,
89 : bool check_current)
90 : {
91 : struct TALER_MERCHANTDB_PostgresContext *pg;
92 :
93 136 : pg = GNUNET_new (struct TALER_MERCHANTDB_PostgresContext);
94 136 : pg->cfg = cfg;
95 136 : pg->conn = GNUNET_PQ_init (pg->cfg,
96 : "merchantdb-postgres",
97 : &reconnect_cb,
98 : pg);
99 136 : if (NULL == pg->conn)
100 : {
101 0 : TALER_MERCHANTDB_disconnect (pg);
102 0 : return NULL;
103 : }
104 253 : if (check_current &&
105 : (GNUNET_OK !=
106 117 : GNUNET_PQ_check_current (pg->conn,
107 : "merchant-")) )
108 : {
109 0 : 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 0 : TALER_MERCHANTDB_disconnect (pg);
112 0 : return NULL;
113 : }
114 136 : return pg;
115 : }
116 :
117 :
118 : struct TALER_MERCHANTDB_PostgresContext *
119 117 : TALER_MERCHANTDB_connect (
120 : const struct GNUNET_CONFIGURATION_Handle *cfg)
121 : {
122 117 : return do_connect (cfg,
123 : true);
124 : }
125 :
126 :
127 : struct TALER_MERCHANTDB_PostgresContext *
128 19 : TALER_MERCHANTDB_connect_admin (
129 : const struct GNUNET_CONFIGURATION_Handle *cfg)
130 : {
131 19 : return do_connect (cfg,
132 : false);
133 : }
134 :
135 :
136 : void
137 136 : TALER_MERCHANTDB_disconnect (
138 : struct TALER_MERCHANTDB_PostgresContext *pg)
139 : {
140 136 : GNUNET_PQ_disconnect (pg->conn);
141 136 : GNUNET_free (pg->current_merchant_id);
142 136 : GNUNET_free (pg);
143 136 : }
144 :
145 :
146 : /* end of pg.c */
|