LCOV - code coverage report
Current view: top level - auditordb - plugin_auditordb_postgres.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 80.6 % 222 179
Test Date: 2026-04-03 22:53:11 Functions: 84.6 % 13 11

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2014-2024 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 plugin_auditordb_postgres.c
      18              :  * @brief Low-level (statement-level) Postgres database access for the auditor
      19              :  * @author Christian Grothoff
      20              :  * @author Gabor X Toth
      21              :  */
      22              : #include "taler/platform.h"
      23              : #include "taler/taler_pq_lib.h"
      24              : #include <pthread.h>
      25              : #include <libpq-fe.h>
      26              : #include "pg_delete_auditor_closure_lag.h"
      27              : #include "pg_delete_early_aggregation.h"
      28              : #include "pg_delete_generic.h"
      29              : #include "pg_delete_pending_deposit.h"
      30              : #include "pg_delete_purse_info.h"
      31              : #include "pg_delete_reserve_in_inconsistency.h"
      32              : #include "pg_del_denomination_balance.h"
      33              : #include "pg_del_reserve_info.h"
      34              : #include "pg_get_auditor_progress.h"
      35              : #include "pg_get_balance.h"
      36              : #include "pg_get_balances.h"
      37              : #include "pg_get_denomination_balance.h"
      38              : #include "pg_get_deposit_confirmations.h"
      39              : #include "pg_get_purse_info.h"
      40              : #include "pg_get_reserve_info.h"
      41              : #include "pg_get_wire_fee_summary.h"
      42              : #include "pg_helper.h"
      43              : #include "pg_insert_auditor_progress.h"
      44              : #include "pg_insert_balance.h"
      45              : #include "pg_insert_denomination_balance.h"
      46              : #include "pg_insert_deposit_confirmation.h"
      47              : #include "pg_insert_early_aggregation.h"
      48              : #include "pg_insert_exchange_signkey.h"
      49              : #include "pg_insert_historic_denom_revenue.h"
      50              : #include "pg_insert_historic_reserve_revenue.h"
      51              : #include "pg_insert_pending_deposit.h"
      52              : #include "pg_insert_purse_info.h"
      53              : #include "pg_insert_reserve_info.h"
      54              : #include "pg_select_reserve_in_inconsistency.h"
      55              : #include "pg_select_historic_denom_revenue.h"
      56              : #include "pg_select_historic_reserve_revenue.h"
      57              : #include "pg_get_progress_points.h"
      58              : #include "pg_select_pending_deposits.h"
      59              : #include "pg_select_purse_expired.h"
      60              : #include "pg_update_generic_suppressed.h"
      61              : #include "pg_update_auditor_progress.h"
      62              : #include "pg_update_denomination_balance.h"
      63              : #include "pg_update_purse_info.h"
      64              : #include "pg_update_reserve_info.h"
      65              : #include "pg_update_wire_fee_summary.h"
      66              : #include "pg_get_amount_arithmetic_inconsistency.h"
      67              : #include "pg_get_coin_inconsistency.h"
      68              : #include "pg_get_row_inconsistency.h"
      69              : #include "pg_update_balance.h"
      70              : #include "pg_select_early_aggregations.h"
      71              : 
      72              : #include "pg_insert_coin_inconsistency.h"
      73              : #include "pg_insert_row_inconsistency.h"
      74              : #include "pg_insert_amount_arithmetic_inconsistency.h"
      75              : 
      76              : #include "pg_get_auditor_closure_lags.h"
      77              : #include "pg_insert_auditor_closure_lags.h"
      78              : 
      79              : #include "pg_get_emergency_by_count.h"
      80              : #include "pg_insert_emergency_by_count.h"
      81              : 
      82              : #include "pg_get_emergency.h"
      83              : #include "pg_insert_emergency.h"
      84              : 
      85              : #include "pg_get_bad_sig_losses.h"
      86              : #include "pg_insert_bad_sig_losses.h"
      87              : 
      88              : #include "pg_get_denomination_key_validity_withdraw_inconsistency.h"
      89              : #include "pg_insert_denomination_key_validity_withdraw_inconsistency.h"
      90              : 
      91              : #include "pg_get_fee_time_inconsistency.h"
      92              : #include "pg_insert_fee_time_inconsistency.h"
      93              : 
      94              : #include "pg_get_purse_not_closed_inconsistencies.h"
      95              : #include "pg_insert_purse_not_closed_inconsistencies.h"
      96              : 
      97              : #include "pg_get_reserve_balance_insufficient_inconsistency.h"
      98              : #include "pg_insert_reserve_balance_insufficient_inconsistency.h"
      99              : 
     100              : #include "pg_get_reserve_in_inconsistency.h"
     101              : #include "pg_lookup_reserve_in_inconsistency.h"
     102              : #include "pg_insert_reserve_in_inconsistency.h"
     103              : 
     104              : #include "pg_get_reserve_not_closed_inconsistency.h"
     105              : #include "pg_insert_reserve_not_closed_inconsistency.h"
     106              : 
     107              : #include "pg_get_denominations_without_sigs.h"
     108              : #include "pg_insert_denominations_without_sigs.h"
     109              : 
     110              : #include "pg_get_misattribution_in_inconsistency.h"
     111              : #include "pg_insert_misattribution_in_inconsistency.h"
     112              : 
     113              : #include "pg_get_reserves.h"
     114              : #include "pg_get_purses.h"
     115              : 
     116              : #include "pg_get_denomination_pending.h"
     117              : #include "pg_insert_denomination_pending.h"
     118              : 
     119              : #include "pg_get_exchange_signkeys.h"
     120              : 
     121              : #include "pg_get_wire_format_inconsistency.h"
     122              : #include "pg_insert_wire_format_inconsistency.h"
     123              : 
     124              : #include "pg_get_wire_out_inconsistency.h"
     125              : #include "pg_insert_wire_out_inconsistency.h"
     126              : #include "pg_delete_wire_out_inconsistency_if_matching.h"
     127              : 
     128              : #include "pg_get_reserve_balance_summary_wrong_inconsistency.h"
     129              : #include "pg_insert_reserve_balance_summary_wrong_inconsistency.h"
     130              : 
     131              : #include "pg_get_row_minor_inconsistencies.h"
     132              : #include "pg_insert_row_minor_inconsistencies.h"
     133              : 
     134              : #define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \
     135              :                                        __VA_ARGS__)
     136              : 
     137              : 
     138              : /**
     139              :  * Drop all auditor tables OR deletes recoverable auditor state.
     140              :  * This should only be used by testcases or when restarting the
     141              :  * auditor from scratch.
     142              :  *
     143              :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     144              :  * @param drop_exchangelist drop all tables, including schema versioning
     145              :  *        and the exchange and deposit_confirmations table; NOT to be
     146              :  *        used when restarting the auditor
     147              :  * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
     148              :  */
     149              : static enum GNUNET_GenericReturnValue
     150            8 : postgres_drop_tables (void *cls,
     151              :                       bool drop_exchangelist)
     152              : {
     153            8 :   struct PostgresClosure *pc = cls;
     154              :   struct GNUNET_PQ_Context *conn;
     155              :   enum GNUNET_GenericReturnValue ret;
     156              : 
     157            8 :   conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
     158              :                                      "auditordb-postgres",
     159              :                                      NULL,
     160              :                                      NULL,
     161              :                                      NULL);
     162            8 :   if (NULL == conn)
     163            0 :     return GNUNET_SYSERR;
     164            8 :   ret = GNUNET_PQ_exec_sql (conn,
     165              :                             (drop_exchangelist) ? "drop" : "restart");
     166            8 :   GNUNET_PQ_disconnect (conn);
     167            8 :   return ret;
     168              : }
     169              : 
     170              : 
     171              : /**
     172              :  * Create the necessary tables if they are not present
     173              :  *
     174              :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     175              :  * @param support_partitions true to support partitioning
     176              :  * @param num_partitions number of partitions to use
     177              :  * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
     178              :  */
     179              : static enum GNUNET_GenericReturnValue
     180            7 : postgres_create_tables (void *cls,
     181              :                         bool support_partitions,
     182              :                         uint32_t num_partitions)
     183              : {
     184            7 :   struct PostgresClosure *pc = cls;
     185            7 :   enum GNUNET_GenericReturnValue ret = GNUNET_OK;
     186              :   struct GNUNET_PQ_Context *conn;
     187            7 :   struct GNUNET_PQ_QueryParam params[] = {
     188              :     support_partitions
     189            0 :     ? GNUNET_PQ_query_param_uint32 (&num_partitions)
     190            7 :     : GNUNET_PQ_query_param_null (),
     191              :     GNUNET_PQ_query_param_end
     192              :   };
     193            7 :   struct GNUNET_PQ_PreparedStatement ps[] = {
     194            7 :     GNUNET_PQ_make_prepare ("create_tables",
     195              :                             "SELECT"
     196              :                             " auditor.do_create_tables"
     197              :                             " ($1);"),
     198              :     GNUNET_PQ_PREPARED_STATEMENT_END
     199              :   };
     200            7 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     201            7 :     GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
     202              :     GNUNET_PQ_EXECUTE_STATEMENT_END
     203              :   };
     204              : 
     205            7 :   conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
     206              :                                      "auditordb-postgres",
     207              :                                      "auditor-",
     208              :                                      es,
     209              :                                      ps);
     210            7 :   if (NULL == conn)
     211              :   {
     212            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     213              :                 "Failed to connect to database\n");
     214            0 :     return GNUNET_SYSERR;
     215              :   }
     216            7 :   if (0 >
     217            7 :       GNUNET_PQ_eval_prepared_non_select (conn,
     218              :                                           "create_tables",
     219              :                                           params))
     220              :   {
     221            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     222              :                 "Failed to run 'create_tables' prepared statement\n");
     223            0 :     ret = GNUNET_SYSERR;
     224              :   }
     225            7 :   if (GNUNET_OK == ret)
     226              :   {
     227            7 :     ret = GNUNET_PQ_exec_sql (conn,
     228              :                               "procedures");
     229            7 :     if (GNUNET_OK != ret)
     230            0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     231              :                   "Failed to load stored procedures\n");
     232              :   }
     233            7 :   GNUNET_PQ_disconnect (conn);
     234            7 :   return ret;
     235              : }
     236              : 
     237              : 
     238              : /**
     239              :  * Register callback to be invoked on events of type @a es.
     240              :  *
     241              :  * @param cls database context to use
     242              :  * @param es specification of the event to listen for
     243              :  * @param timeout how long to wait for the event
     244              :  * @param cb function to call when the event happens, possibly
     245              :  *         mulrewardle times (until cancel is invoked)
     246              :  * @param cb_cls closure for @a cb
     247              :  * @return handle useful to cancel the listener
     248              :  */
     249              : static struct GNUNET_DB_EventHandler *
     250           20 : postgres_event_listen (void *cls,
     251              :                        const struct GNUNET_DB_EventHeaderP *es,
     252              :                        struct GNUNET_TIME_Relative timeout,
     253              :                        GNUNET_DB_EventCallback cb,
     254              :                        void *cb_cls)
     255              : {
     256           20 :   struct PostgresClosure *pg = cls;
     257              : 
     258           20 :   return GNUNET_PQ_event_listen (pg->conn,
     259              :                                  es,
     260              :                                  timeout,
     261              :                                  cb,
     262              :                                  cb_cls);
     263              : }
     264              : 
     265              : 
     266              : /**
     267              :  * Stop notifications.
     268              :  *
     269              :  * @param eh handle to unregister.
     270              :  */
     271              : static void
     272           20 : postgres_event_listen_cancel (struct GNUNET_DB_EventHandler *eh)
     273              : {
     274           20 :   GNUNET_PQ_event_listen_cancel (eh);
     275           20 : }
     276              : 
     277              : 
     278              : /**
     279              :  * Notify all that listen on @a es of an event.
     280              :  *
     281              :  * @param cls database context to use
     282              :  * @param es specification of the event to generate
     283              :  * @param extra additional event data provided
     284              :  * @param extra_size number of bytes in @a extra
     285              :  */
     286              : static void
     287            0 : postgres_event_notify (void *cls,
     288              :                        const struct GNUNET_DB_EventHeaderP *es,
     289              :                        const void *extra,
     290              :                        size_t extra_size)
     291              : {
     292            0 :   struct PostgresClosure *pg = cls;
     293              : 
     294            0 :   return GNUNET_PQ_event_notify (pg->conn,
     295              :                                  es,
     296              :                                  extra,
     297              :                                  extra_size);
     298              : }
     299              : 
     300              : 
     301              : /**
     302              :  * Connect to the db if the connection does not exist yet.
     303              :  *
     304              :  * @param[in,out] pg the plugin-specific state
     305              :  * @return #GNUNET_OK on success
     306              :  */
     307              : static enum GNUNET_GenericReturnValue
     308           27 : setup_connection (struct PostgresClosure *pg)
     309              : {
     310           27 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     311           27 :     GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
     312              :     GNUNET_PQ_EXECUTE_STATEMENT_END
     313              :   };
     314              :   struct GNUNET_PQ_Context *db_conn;
     315              : 
     316           27 :   if (NULL != pg->conn)
     317              :   {
     318            0 :     GNUNET_PQ_reconnect_if_down (pg->conn);
     319            0 :     return GNUNET_OK;
     320              :   }
     321           27 :   db_conn = GNUNET_PQ_connect_with_cfg2 (pg->cfg,
     322              :                                          "auditordb-postgres",
     323              :                                          "auditor-",
     324              :                                          es,
     325              :                                          NULL, /* prepared statements */
     326              :                                          GNUNET_PQ_FLAG_CHECK_CURRENT);
     327           27 :   if (NULL == db_conn)
     328            0 :     return GNUNET_SYSERR;
     329           27 :   pg->conn = db_conn;
     330           27 :   pg->prep_gen++;
     331           27 :   return GNUNET_OK;
     332              : }
     333              : 
     334              : 
     335              : /**
     336              :  * Do a pre-flight check that we are not in an uncommitted transaction.
     337              :  * If we are, rollback the previous transaction and output a warning.
     338              :  *
     339              :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     340              :  * @return #GNUNET_OK on success,
     341              :  *         #GNUNET_NO if we rolled back an earlier transaction
     342              :  *         #GNUNET_SYSERR if we have no DB connection
     343              :  */
     344              : static enum GNUNET_GenericReturnValue
     345           92 : postgres_preflight (void *cls)
     346              : {
     347           92 :   struct PostgresClosure *pg = cls;
     348           92 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     349           92 :     GNUNET_PQ_make_execute ("ROLLBACK"),
     350              :     GNUNET_PQ_EXECUTE_STATEMENT_END
     351              :   };
     352              : 
     353          119 :   if ( (NULL == pg->conn) &&
     354              :        (GNUNET_OK !=
     355           27 :         setup_connection (pg)) )
     356            0 :     return GNUNET_SYSERR;
     357           92 :   if (NULL == pg->transaction_name)
     358           92 :     return GNUNET_OK; /* all good */
     359            0 :   if (GNUNET_OK ==
     360            0 :       GNUNET_PQ_exec_statements (pg->conn,
     361              :                                  es))
     362              :   {
     363            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     364              :                 "BUG: Preflight check rolled back transaction `%s'!\n",
     365              :                 pg->transaction_name);
     366              :   }
     367              :   else
     368              :   {
     369            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     370              :                 "BUG: Preflight check failed to rollback transaction `%s'!\n",
     371              :                 pg->transaction_name);
     372              :   }
     373            0 :   pg->transaction_name = NULL;
     374            0 :   return GNUNET_NO;
     375              : }
     376              : 
     377              : 
     378              : /**
     379              :  * Start a transaction.
     380              :  *
     381              :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     382              :  * @return #GNUNET_OK on success
     383              :  */
     384              : static enum GNUNET_GenericReturnValue
     385           22 : postgres_start (void *cls)
     386              : {
     387           22 :   struct PostgresClosure *pg = cls;
     388           22 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     389           22 :     GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
     390              :     GNUNET_PQ_EXECUTE_STATEMENT_END
     391              :   };
     392              : 
     393           22 :   postgres_preflight (cls);
     394           22 :   if (GNUNET_OK !=
     395           22 :       GNUNET_PQ_exec_statements (pg->conn,
     396              :                                  es))
     397              :   {
     398            0 :     TALER_LOG_ERROR ("Failed to start transaction\n");
     399            0 :     GNUNET_break (0);
     400            0 :     return GNUNET_SYSERR;
     401              :   }
     402           22 :   return GNUNET_OK;
     403              : }
     404              : 
     405              : 
     406              : /**
     407              :  * Roll back the current transaction of a database connection.
     408              :  *
     409              :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     410              :  */
     411              : static void
     412            9 : postgres_rollback (void *cls)
     413              : {
     414            9 :   struct PostgresClosure *pg = cls;
     415            9 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     416            9 :     GNUNET_PQ_make_execute ("ROLLBACK"),
     417              :     GNUNET_PQ_EXECUTE_STATEMENT_END
     418              :   };
     419              : 
     420            9 :   GNUNET_break (GNUNET_OK ==
     421              :                 GNUNET_PQ_exec_statements (pg->conn,
     422              :                                            es));
     423            9 : }
     424              : 
     425              : 
     426              : /**
     427              :  * Commit the current transaction of a database connection.
     428              :  *
     429              :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     430              :  * @return transaction status code
     431              :  */
     432              : static enum GNUNET_DB_QueryStatus
     433           14 : postgres_commit (void *cls)
     434              : {
     435           14 :   struct PostgresClosure *pg = cls;
     436           14 :   struct GNUNET_PQ_QueryParam params[] = {
     437              :     GNUNET_PQ_query_param_end
     438              :   };
     439              : 
     440           14 :   PREPARE (pg,
     441              :            "do_commit",
     442              :            "COMMIT");
     443           14 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
     444              :                                              "do_commit",
     445              :                                              params);
     446              : }
     447              : 
     448              : 
     449              : /**
     450              :  * Function called to perform "garbage collection" on the
     451              :  * database, expiring records we no longer require.
     452              :  *
     453              :  * @param cls closure
     454              :  * @return #GNUNET_OK on success,
     455              :  *         #GNUNET_SYSERR on DB errors
     456              :  */
     457              : static enum GNUNET_GenericReturnValue
     458            0 : postgres_gc (void *cls)
     459              : {
     460            0 :   struct PostgresClosure *pg = cls;
     461              :   /* For now, we hard-code the cut-off date based on the
     462              :      common legal requirement to keep data for 10 years.
     463              :      Might make it configurable in the future. */
     464              :   struct GNUNET_TIME_Absolute cutoff
     465            0 :     = GNUNET_TIME_absolute_subtract (
     466              :         GNUNET_TIME_absolute_get (),
     467              :         GNUNET_TIME_relative_multiply (
     468              :           GNUNET_TIME_UNIT_YEARS,
     469              :           10));
     470            0 :   struct GNUNET_PQ_QueryParam params_time[] = {
     471            0 :     GNUNET_PQ_query_param_absolute_time (&cutoff),
     472              :     GNUNET_PQ_query_param_end
     473              :   };
     474              :   struct GNUNET_PQ_Context *conn;
     475              :   enum GNUNET_DB_QueryStatus qs;
     476            0 :   struct GNUNET_PQ_PreparedStatement ps[] = {
     477            0 :     GNUNET_PQ_make_prepare ("do_gc_auditor",
     478              :                             "CALL"
     479              :                             " auditor.auditor_do_gc_auditor"
     480              :                             " ($1);"),
     481              :     GNUNET_PQ_PREPARED_STATEMENT_END
     482              :   };
     483            0 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     484            0 :     GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
     485              :     GNUNET_PQ_EXECUTE_STATEMENT_END
     486              :   };
     487              : 
     488            0 :   conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
     489              :                                      "auditordb-postgres",
     490              :                                      NULL,
     491              :                                      es,
     492              :                                      ps);
     493            0 :   if (NULL == conn)
     494            0 :     return GNUNET_SYSERR;
     495            0 :   qs = GNUNET_PQ_eval_prepared_non_select (conn,
     496              :                                            "do_gc_auditor",
     497              :                                            params_time);
     498            0 :   GNUNET_PQ_disconnect (conn);
     499            0 :   if (0 > qs)
     500              :   {
     501            0 :     GNUNET_break (0);
     502            0 :     return GNUNET_SYSERR;
     503              :   }
     504            0 :   return GNUNET_OK;
     505              : }
     506              : 
     507              : 
     508              : /**
     509              :  * Initialize Postgres database subsystem.
     510              :  *
     511              :  * @param cls a configuration instance
     512              :  * @return NULL on error, otherwise a `struct TALER_AUDITORDB_Plugin`
     513              :  */
     514              : void *
     515              : libtaler_plugin_auditordb_postgres_init (void *cls);
     516              : 
     517              : /* Declaration used to squash compiler warning */
     518              : void *
     519           32 : libtaler_plugin_auditordb_postgres_init (void *cls)
     520              : {
     521           32 :   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
     522              :   struct PostgresClosure *pg;
     523              :   struct TALER_AUDITORDB_Plugin *plugin;
     524              : 
     525           32 :   pg = GNUNET_new (struct PostgresClosure);
     526           32 :   pg->cfg = cfg;
     527           32 :   if (GNUNET_OK !=
     528           32 :       TALER_config_get_currency (cfg,
     529              :                                  "exchange",
     530              :                                  &pg->currency))
     531              :   {
     532            0 :     GNUNET_free (pg);
     533            0 :     return NULL;
     534              :   }
     535              : 
     536           32 :   plugin = GNUNET_new (struct TALER_AUDITORDB_Plugin);
     537           32 :   plugin->cls = pg;
     538           32 :   plugin->preflight = &postgres_preflight;
     539           32 :   plugin->drop_tables = &postgres_drop_tables;
     540           32 :   plugin->create_tables = &postgres_create_tables;
     541           32 :   plugin->event_listen = &postgres_event_listen;
     542           32 :   plugin->event_listen_cancel = &postgres_event_listen_cancel;
     543           32 :   plugin->event_notify = &postgres_event_notify;
     544           32 :   plugin->start = &postgres_start;
     545           32 :   plugin->commit = &postgres_commit;
     546           32 :   plugin->rollback = &postgres_rollback;
     547           32 :   plugin->gc = &postgres_gc;
     548              : 
     549              :   plugin->get_auditor_progress
     550           32 :     = &TAH_PG_get_auditor_progress;
     551              : 
     552           32 :   plugin->get_balance = &TAH_PG_get_balance;
     553           32 :   plugin->get_balances = &TAH_PG_get_balances;
     554              : 
     555              :   plugin->insert_auditor_progress
     556           32 :     = &TAH_PG_insert_auditor_progress;
     557              :   plugin->insert_balance
     558           32 :     = &TAH_PG_insert_balance;
     559              :   plugin->update_generic_suppressed
     560           32 :     = &TAH_PG_update_generic_suppressed;
     561              :   plugin->delete_generic
     562           32 :     = &TAH_PG_delete_generic;
     563              :   plugin->delete_wire_out_inconsistency_if_matching
     564           32 :     = &TAH_PG_delete_wire_out_inconsistency_if_matching;
     565              : 
     566              :   plugin->delete_auditor_closure_lag
     567           32 :     = &TAH_PG_delete_auditor_closure_lag;
     568              : 
     569              :   plugin->update_auditor_progress
     570           32 :     = &TAH_PG_update_auditor_progress;
     571              :   plugin->insert_deposit_confirmation
     572           32 :     = &TAH_PG_insert_deposit_confirmation;
     573              :   plugin->get_deposit_confirmations
     574           32 :     = &TAH_PG_get_deposit_confirmations;
     575              : 
     576              :   plugin->get_amount_arithmetic_inconsistency
     577           32 :     = &TAH_PG_get_amount_arithmetic_inconsistency;
     578              :   plugin->get_coin_inconsistency
     579           32 :     = &TAH_PG_get_coin_inconsistency;
     580              :   plugin->get_row_inconsistency
     581           32 :     = &TAH_PG_get_row_inconsistency;
     582              : 
     583              : 
     584              :   plugin->insert_amount_arithmetic_inconsistency
     585           32 :     = &TAH_PG_insert_amount_arithmetic_inconsistency;
     586              :   plugin->insert_coin_inconsistency
     587           32 :     = &TAH_PG_insert_coin_inconsistency;
     588              :   plugin->insert_row_inconsistency
     589           32 :     = &TAH_PG_insert_row_inconsistency;
     590              : 
     591              :   plugin->insert_reserve_info
     592           32 :     = &TAH_PG_insert_reserve_info;
     593              :   plugin->update_reserve_info
     594           32 :     = &TAH_PG_update_reserve_info;
     595              :   plugin->get_reserve_info
     596           32 :     = &TAH_PG_get_reserve_info;
     597              :   plugin->del_reserve_info
     598           32 :     = &TAH_PG_del_reserve_info;
     599              : 
     600              :   plugin->insert_pending_deposit
     601           32 :     = &TAH_PG_insert_pending_deposit;
     602              :   plugin->select_pending_deposits
     603           32 :     = &TAH_PG_select_pending_deposits;
     604              :   plugin->delete_pending_deposit
     605           32 :     = &TAH_PG_delete_pending_deposit;
     606              : 
     607              :   plugin->insert_purse_info
     608           32 :     = &TAH_PG_insert_purse_info;
     609              :   plugin->update_purse_info
     610           32 :     = &TAH_PG_update_purse_info;
     611              :   plugin->get_purse_info
     612           32 :     = &TAH_PG_get_purse_info;
     613              :   plugin->delete_purse_info
     614           32 :     = &TAH_PG_delete_purse_info;
     615              :   plugin->select_purse_expired
     616           32 :     = &TAH_PG_select_purse_expired;
     617              : 
     618              :   plugin->insert_denomination_balance
     619           32 :     = &TAH_PG_insert_denomination_balance;
     620              :   plugin->update_denomination_balance
     621           32 :     = &TAH_PG_update_denomination_balance;
     622              :   plugin->del_denomination_balance
     623           32 :     = &TAH_PG_del_denomination_balance;
     624              :   plugin->get_denomination_balance
     625           32 :     = &TAH_PG_get_denomination_balance;
     626              : 
     627              :   plugin->insert_historic_denom_revenue
     628           32 :     = &TAH_PG_insert_historic_denom_revenue;
     629              : 
     630              :   plugin->select_historic_denom_revenue
     631           32 :     = &TAH_PG_select_historic_denom_revenue;
     632              : 
     633              :   plugin->insert_historic_reserve_revenue
     634           32 :     = &TAH_PG_insert_historic_reserve_revenue;
     635              :   plugin->select_historic_reserve_revenue
     636           32 :     = &TAH_PG_select_historic_reserve_revenue;
     637              : 
     638              : 
     639           32 :   plugin->insert_emergency = &TAH_PG_insert_emergency;
     640           32 :   plugin->get_emergency = &TAH_PG_get_emergency;
     641              : 
     642           32 :   plugin->insert_emergency_by_count = &TAH_PG_insert_emergency_by_count;
     643           32 :   plugin->get_emergency_by_count = &TAH_PG_get_emergency_by_count;
     644              : 
     645              : 
     646           32 :   plugin->insert_denomination_key_validity_withdraw_inconsistency =
     647              :     &TAH_PG_insert_denomination_key_validity_withdraw_inconsistency;
     648           32 :   plugin->get_denomination_key_validity_withdraw_inconsistency =
     649              :     &TAH_PG_get_denomination_key_validity_withdraw_inconsistency;
     650              : 
     651           32 :   plugin->insert_purse_not_closed_inconsistencies =
     652              :     &TAH_PG_insert_purse_not_closed_inconsistencies;
     653           32 :   plugin->get_purse_not_closed_inconsistencies =
     654              :     &TAH_PG_get_purse_not_closed_inconsistencies;
     655              : 
     656              : 
     657           32 :   plugin->insert_reserve_balance_insufficient_inconsistency =
     658              :     &TAH_PG_insert_reserve_balance_insufficient_inconsistency;
     659           32 :   plugin->get_reserve_balance_insufficient_inconsistency =
     660              :     &TAH_PG_get_reserve_balance_insufficient_inconsistency;
     661              : 
     662           32 :   plugin->insert_bad_sig_losses = &TAH_PG_insert_bad_sig_losses;
     663           32 :   plugin->get_bad_sig_losses = &TAH_PG_get_bad_sig_losses;
     664              : 
     665           32 :   plugin->insert_auditor_closure_lags = &TAH_PG_insert_auditor_closure_lags;
     666           32 :   plugin->get_auditor_closure_lags = &TAH_PG_get_auditor_closure_lags;
     667              : 
     668           32 :   plugin->insert_reserve_in_inconsistency =
     669              :     &TAH_PG_insert_reserve_in_inconsistency;
     670              :   plugin->get_reserve_in_inconsistency
     671           32 :     = &TAH_PG_get_reserve_in_inconsistency;
     672              :   plugin->lookup_reserve_in_inconsistency
     673           32 :     = &TAH_PG_lookup_reserve_in_inconsistency;
     674              : 
     675           32 :   plugin->insert_reserve_not_closed_inconsistency =
     676              :     &TAH_PG_insert_reserve_not_closed_inconsistency;
     677           32 :   plugin->get_reserve_not_closed_inconsistency =
     678              :     &TAH_PG_get_reserve_not_closed_inconsistency;
     679              : 
     680           32 :   plugin->insert_denominations_without_sigs =
     681              :     &TAH_PG_insert_denominations_without_sigs;
     682           32 :   plugin->get_denominations_without_sigs =
     683              :     &TAH_PG_get_denominations_without_sigs;
     684              : 
     685              :   plugin->get_progress_points
     686           32 :     = &TAH_PG_get_progress_points;
     687              : 
     688              : 
     689           32 :   plugin->insert_misattribution_in_inconsistency =
     690              :     &TAH_PG_insert_misattribution_in_inconsistency;
     691           32 :   plugin->get_misattribution_in_inconsistency =
     692              :     &TAH_PG_get_misattribution_in_inconsistency;
     693              : 
     694           32 :   plugin->get_reserves = &TAH_PG_get_reserves;
     695           32 :   plugin->get_purses = &TAH_PG_get_purses;
     696              : 
     697           32 :   plugin->insert_denomination_pending = &TAH_PG_insert_denomination_pending;
     698           32 :   plugin->get_denomination_pending = &TAH_PG_get_denomination_pending;
     699              : 
     700           32 :   plugin->get_exchange_signkeys = &TAH_PG_get_exchange_signkeys;
     701              : 
     702           32 :   plugin->insert_wire_format_inconsistency =
     703              :     &TAH_PG_insert_wire_format_inconsistency;
     704           32 :   plugin->get_wire_format_inconsistency = &TAH_PG_get_wire_format_inconsistency;
     705              : 
     706              :   plugin->insert_early_aggregation
     707           32 :     = &TAH_PG_insert_early_aggregation;
     708              :   plugin->delete_early_aggregation
     709           32 :     = &TAH_PG_delete_early_aggregation;
     710              : 
     711              :   plugin->insert_wire_out_inconsistency
     712           32 :     = &TAH_PG_insert_wire_out_inconsistency;
     713              :   plugin->get_wire_out_inconsistency
     714           32 :     = &TAH_PG_get_wire_out_inconsistency;
     715              :   plugin->select_reserve_in_inconsistency
     716           32 :     = &TAH_PG_select_reserve_in_inconsistency;
     717              :   plugin->delete_reserve_in_inconsistency
     718           32 :     = &TAH_PG_delete_reserve_in_inconsistency;
     719              :   plugin->select_early_aggregations
     720           32 :     = &TAH_PG_select_early_aggregations;
     721              : 
     722           32 :   plugin->insert_reserve_balance_summary_wrong_inconsistency =
     723              :     &TAH_PG_insert_reserve_balance_summary_wrong_inconsistency;
     724           32 :   plugin->get_reserve_balance_summary_wrong_inconsistency =
     725              :     &TAH_PG_get_reserve_balance_summary_wrong_inconsistency;
     726              : 
     727              : 
     728           32 :   plugin->insert_row_minor_inconsistencies =
     729              :     &TAH_PG_insert_row_minor_inconsistencies;
     730           32 :   plugin->get_row_minor_inconsistencies = &TAH_PG_get_row_minor_inconsistencies;
     731              : 
     732           32 :   plugin->insert_fee_time_inconsistency = &TAH_PG_insert_fee_time_inconsistency;
     733           32 :   plugin->get_fee_time_inconsistency = &TAH_PG_get_fee_time_inconsistency;
     734              : 
     735              :   plugin->update_balance
     736           32 :     = &TAH_PG_update_balance;
     737              : 
     738              :   plugin->insert_exchange_signkey
     739           32 :     = &TAH_PG_insert_exchange_signkey;
     740              : 
     741           32 :   return plugin;
     742              : }
     743              : 
     744              : 
     745              : /**
     746              :  * Shutdown Postgres database subsystem.
     747              :  *
     748              :  * @param cls a `struct TALER_AUDITORDB_Plugin`
     749              :  * @return NULL (always)
     750              :  */
     751              : void *
     752              : libtaler_plugin_auditordb_postgres_done (void *cls);
     753              : 
     754              : /* Declaration used to squash compiler warning */
     755              : void *
     756           32 : libtaler_plugin_auditordb_postgres_done (void *cls)
     757              : {
     758           32 :   struct TALER_AUDITORDB_Plugin *plugin = cls;
     759           32 :   struct PostgresClosure *pg = plugin->cls;
     760              : 
     761           32 :   if (NULL != pg->conn)
     762           27 :     GNUNET_PQ_disconnect (pg->conn);
     763           32 :   GNUNET_free (pg->currency);
     764           32 :   GNUNET_free (pg);
     765           32 :   GNUNET_free (plugin);
     766           32 :   return NULL;
     767              : }
     768              : 
     769              : 
     770              : /* end of plugin_auditordb_postgres.c */
        

Generated by: LCOV version 2.0-1