Line data Source code
1 : /*
2 : This file is part of Challenger
3 : Copyright (C) 2023 Taler Systems SA
4 :
5 : Challenger 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 : Challenger 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 : Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file src/challengerdb/preflight.c
18 : * @brief Implementation of the preflight function for Postgres
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include <taler/taler_pq_lib.h>
23 : #include "challenger-database/preflight.h"
24 : #include "pg_helper.h"
25 :
26 :
27 : static enum GNUNET_GenericReturnValue
28 7 : internal_setup (struct CHALLENGERDB_PostgresContext *pg)
29 : {
30 7 : if (NULL == pg->conn)
31 : {
32 : #if AUTO_EXPLAIN
33 : /* Enable verbose logging to see where queries do not
34 : properly use indices */
35 : struct GNUNET_PQ_ExecuteStatement es[] = {
36 : GNUNET_PQ_make_try_execute ("LOAD 'auto_explain';"),
37 : GNUNET_PQ_make_try_execute ("SET auto_explain.log_min_duration=50;"),
38 : GNUNET_PQ_make_try_execute ("SET auto_explain.log_timing=TRUE;"),
39 : GNUNET_PQ_make_try_execute ("SET auto_explain.log_analyze=TRUE;"),
40 : /* https://wiki.postgresql.org/wiki/Serializable suggests to really
41 : force the default to 'serializable' if SSI is to be used. */
42 : GNUNET_PQ_make_try_execute (
43 : "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;"),
44 : GNUNET_PQ_make_execute ("SET search_path TO challenger;"),
45 : GNUNET_PQ_EXECUTE_STATEMENT_END
46 : };
47 : #else
48 7 : struct GNUNET_PQ_ExecuteStatement es[] = {
49 7 : GNUNET_PQ_make_execute ("SET search_path TO challenger;"),
50 : GNUNET_PQ_EXECUTE_STATEMENT_END
51 : };
52 : #endif
53 : struct GNUNET_PQ_Context *db_conn;
54 :
55 7 : db_conn = GNUNET_PQ_connect_with_cfg2 (pg->cfg,
56 : "challengerdb-postgres",
57 : "challenger-",
58 : es,
59 : NULL,
60 : GNUNET_PQ_FLAG_CHECK_CURRENT);
61 7 : if (NULL == db_conn)
62 0 : return GNUNET_SYSERR;
63 7 : pg->conn = db_conn;
64 7 : pg->prep_gen++;
65 : }
66 7 : if (NULL == pg->transaction_name)
67 7 : GNUNET_PQ_reconnect_if_down (pg->conn);
68 7 : return GNUNET_OK;
69 : }
70 :
71 :
72 : enum GNUNET_GenericReturnValue
73 32 : CHALLENGERDB_preflight (struct CHALLENGERDB_PostgresContext *pg)
74 : {
75 32 : struct GNUNET_PQ_ExecuteStatement es[] = {
76 32 : GNUNET_PQ_make_execute ("ROLLBACK"),
77 : GNUNET_PQ_EXECUTE_STATEMENT_END
78 : };
79 :
80 32 : if (NULL == pg->conn)
81 : {
82 7 : if (GNUNET_OK !=
83 7 : internal_setup (pg))
84 : {
85 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
86 : "Failed to ensure DB is initialized\n");
87 0 : return GNUNET_SYSERR;
88 : }
89 : }
90 32 : GNUNET_PQ_reconnect_if_down (pg->conn);
91 32 : if (NULL == pg->transaction_name)
92 32 : return GNUNET_OK; /* all good */
93 0 : if (GNUNET_OK ==
94 0 : GNUNET_PQ_exec_statements (pg->conn,
95 : es))
96 : {
97 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
98 : "BUG: Preflight check rolled back transaction `%s'!\n",
99 : pg->transaction_name);
100 : }
101 : else
102 : {
103 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
104 : "BUG: Preflight check failed to rollback transaction `%s'!\n",
105 : pg->transaction_name);
106 : }
107 0 : pg->transaction_name = NULL;
108 0 : return GNUNET_NO;
109 : }
|