preflight.c (3727B)
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 internal_setup (struct CHALLENGERDB_PostgresContext *pg) 29 { 30 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 struct GNUNET_PQ_ExecuteStatement es[] = { 49 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 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 if (NULL == db_conn) 62 return GNUNET_SYSERR; 63 pg->conn = db_conn; 64 pg->prep_gen++; 65 } 66 if (NULL == pg->transaction_name) 67 GNUNET_PQ_reconnect_if_down (pg->conn); 68 return GNUNET_OK; 69 } 70 71 72 enum GNUNET_GenericReturnValue 73 CHALLENGERDB_preflight (struct CHALLENGERDB_PostgresContext *pg) 74 { 75 struct GNUNET_PQ_ExecuteStatement es[] = { 76 GNUNET_PQ_make_execute ("ROLLBACK"), 77 GNUNET_PQ_EXECUTE_STATEMENT_END 78 }; 79 80 if (NULL == pg->conn) 81 { 82 if (GNUNET_OK != 83 internal_setup (pg)) 84 { 85 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 86 "Failed to ensure DB is initialized\n"); 87 return GNUNET_SYSERR; 88 } 89 } 90 GNUNET_PQ_reconnect_if_down (pg->conn); 91 if (NULL == pg->transaction_name) 92 return GNUNET_OK; /* all good */ 93 if (GNUNET_OK == 94 GNUNET_PQ_exec_statements (pg->conn, 95 es)) 96 { 97 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 98 "BUG: Preflight check rolled back transaction `%s'!\n", 99 pg->transaction_name); 100 } 101 else 102 { 103 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 104 "BUG: Preflight check failed to rollback transaction `%s'!\n", 105 pg->transaction_name); 106 } 107 pg->transaction_name = NULL; 108 return GNUNET_NO; 109 }