exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

pg_preflight.c (4155B)


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