challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

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 }