sync

Backup service to store encrypted wallet databases (experimental)
Log | Files | Refs | Submodules | README | LICENSE

syncdb_pg.c (4504B)


      1 /*
      2   This file is part of TALER
      3   (C) 2014--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 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 syncdb/syncdb_pg.c
     18  * @brief shared database state and helpers for sync postgres
     19  * @author Christian Grothoff
     20  */
     21 
     22 struct PostgresClosure;
     23 #define GNUNET_PQ_RECONNECT_CALLBACK_CLOSURE \
     24         struct PostgresClosure
     25 #include "syncdb_pg.h"
     26 #include "sync/sync_util.h"
     27 
     28 
     29 /**
     30  * Global database closure.
     31  */
     32 // FIXME: prefix!
     33 struct PostgresClosure *pg;
     34 
     35 
     36 /**
     37  * Function called each time we connect or reconnect to the
     38  * database. Gives the application a chance to run some
     39  * per-connection initialization logic.
     40  *
     41  * @param pg_ database conntext in the auditor
     42  * @param pq database connection handle
     43  */
     44 static void
     45 reconnect_cb (struct PostgresClosure *pg_,
     46               struct GNUNET_PQ_Context *pq)
     47 {
     48 #if AUTO_EXPLAIN
     49   /* Enable verbose logging to see where queries do not
     50      properly use indices */
     51   struct GNUNET_PQ_ExecuteStatement es[] = {
     52     GNUNET_PQ_make_try_execute ("LOAD 'auto_explain';"),
     53     GNUNET_PQ_make_try_execute ("SET auto_explain.log_min_duration=50;"),
     54     GNUNET_PQ_make_try_execute ("SET auto_explain.log_timing=TRUE;"),
     55     GNUNET_PQ_make_try_execute ("SET auto_explain.log_analyze=TRUE;"),
     56     /* https://wiki.postgresql.org/wiki/Serializable suggests to really
     57        force the default to 'serializable' if SSI is to be used. */
     58     GNUNET_PQ_make_try_execute (
     59       "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;"),
     60     GNUNET_PQ_make_try_execute ("SET enable_sort=OFF;"),
     61     GNUNET_PQ_make_try_execute ("SET enable_seqscan=OFF;"),
     62     GNUNET_PQ_make_execute ("SET search_path TO sync;"),
     63     GNUNET_PQ_EXECUTE_STATEMENT_END
     64   };
     65 #else
     66   struct GNUNET_PQ_ExecuteStatement es[] = {
     67     GNUNET_PQ_make_execute ("SET search_path TO sync;"),
     68     GNUNET_PQ_EXECUTE_STATEMENT_END
     69   };
     70 #endif
     71 
     72   if (GNUNET_OK !=
     73       GNUNET_PQ_exec_statements (pq,
     74                                  es))
     75   {
     76     GNUNET_break (0);
     77     return;
     78   }
     79   pg_->prep_gen++;
     80 }
     81 
     82 
     83 /**
     84  * Initialize the database connection.
     85  *
     86  * @param cfg configuration to use
     87  * @param check_current true to check if the database schema is current
     88  * @return NULL on failure
     89  */
     90 static enum GNUNET_GenericReturnValue
     91 do_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
     92          bool check_current)
     93 {
     94   pg = GNUNET_new (struct PostgresClosure);
     95   pg->cfg = cfg;
     96   if (GNUNET_OK !=
     97       GNUNET_CONFIGURATION_get_value_string (cfg,
     98                                              "sync",
     99                                              "CURRENCY",
    100                                              &pg->currency))
    101   {
    102     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    103                                "sync",
    104                                "CURRENCY");
    105     GNUNET_free (pg);
    106     return GNUNET_SYSERR;
    107   }
    108   pg->conn = GNUNET_PQ_init (pg->cfg,
    109                              "syncdb-postgres",
    110                              &reconnect_cb,
    111                              pg);
    112   if (NULL == pg->conn)
    113   {
    114     SYNCDB_fini ();
    115     return GNUNET_NO;
    116   }
    117   if (check_current &&
    118       (GNUNET_OK !=
    119        GNUNET_PQ_check_current (pg->conn,
    120                                 "sync-")) )
    121   {
    122     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    123                 "Database schema is not up-to-date. Try running sync-dbinit or sync-dbconfig!\n");
    124     SYNCDB_fini ();
    125     return GNUNET_NO;
    126   }
    127   return GNUNET_OK;
    128 }
    129 
    130 
    131 enum GNUNET_GenericReturnValue
    132 SYNCDB_init (
    133   const struct GNUNET_CONFIGURATION_Handle *cfg)
    134 {
    135   return do_init (cfg,
    136                   true);
    137 }
    138 
    139 
    140 enum GNUNET_GenericReturnValue
    141 SYNCDB_init_admin (
    142   const struct GNUNET_CONFIGURATION_Handle *cfg)
    143 {
    144   return do_init (cfg,
    145                   false);
    146 }
    147 
    148 
    149 void
    150 SYNCDB_fini (void)
    151 {
    152   if (NULL == pg)
    153     return;
    154   if (NULL != pg->conn)
    155     GNUNET_PQ_disconnect (pg->conn);
    156   GNUNET_free (pg->currency);
    157   GNUNET_free (pg);
    158 }
    159 
    160 
    161 /* end of syncdb_pg.c */