LCOV - code coverage report
Current view: top level - auditordb - plugin_auditordb_postgres.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 83 733 11.3 %
Date: 2022-08-25 06:15:09 Functions: 4 61 6.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (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 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 "platform.h"
      23             : #include "taler_pq_lib.h"
      24             : #include "taler_auditordb_plugin.h"
      25             : #include <pthread.h>
      26             : #include <libpq-fe.h>
      27             : 
      28             : 
      29             : #define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \
      30             :                                        __VA_ARGS__)
      31             : 
      32             : 
      33             : /**
      34             :  * Wrapper macro to add the currency from the plugin's state
      35             :  * when fetching amounts from the database.
      36             :  *
      37             :  * @param field name of the database field to fetch amount from
      38             :  * @param[out] amountp pointer to amount to set
      39             :  */
      40             : #define TALER_PQ_RESULT_SPEC_AMOUNT(field,amountp) \
      41             :   TALER_PQ_result_spec_amount (                    \
      42             :     field,pg->currency,amountp)
      43             : 
      44             : /**
      45             :  * Wrapper macro to add the currency from the plugin's state
      46             :  * when fetching amounts from the database.  NBO variant.
      47             :  *
      48             :  * @param field name of the database field to fetch amount from
      49             :  * @param[out] amountp pointer to amount to set
      50             :  */
      51             : #define TALER_PQ_RESULT_SPEC_AMOUNT_NBO(field, \
      52             :                                         amountp) TALER_PQ_result_spec_amount_nbo ( \
      53             :     field,pg->currency,amountp)
      54             : 
      55             : 
      56             : /**
      57             :  * Type of the "cls" argument given to each of the functions in
      58             :  * our API.
      59             :  */
      60             : struct PostgresClosure
      61             : {
      62             : 
      63             :   /**
      64             :    * Postgres connection handle.
      65             :    */
      66             :   struct GNUNET_PQ_Context *conn;
      67             : 
      68             :   /**
      69             :    * Name of the ongoing transaction, used to debug cases where
      70             :    * a transaction is not properly terminated via COMMIT or
      71             :    * ROLLBACK.
      72             :    */
      73             :   const char *transaction_name;
      74             : 
      75             :   /**
      76             :    * Our configuration.
      77             :    */
      78             :   const struct GNUNET_CONFIGURATION_Handle *cfg;
      79             : 
      80             :   /**
      81             :    * Which currency should we assume all amounts to be in?
      82             :    */
      83             :   char *currency;
      84             : };
      85             : 
      86             : 
      87             : /**
      88             :  * Drop all auditor tables OR deletes recoverable auditor state.
      89             :  * This should only be used by testcases or when restarting the
      90             :  * auditor from scratch.
      91             :  *
      92             :  * @param cls the `struct PostgresClosure` with the plugin-specific state
      93             :  * @param drop_exchangelist drop all tables, including schema versioning
      94             :  *        and the exchange and deposit_confirmations table; NOT to be
      95             :  *        used when restarting the auditor
      96             :  * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
      97             :  */
      98             : static enum GNUNET_GenericReturnValue
      99           1 : postgres_drop_tables (void *cls,
     100             :                       bool drop_exchangelist)
     101             : {
     102           1 :   struct PostgresClosure *pc = cls;
     103             :   struct GNUNET_PQ_Context *conn;
     104             :   enum GNUNET_GenericReturnValue ret;
     105             : 
     106           1 :   conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
     107             :                                      "auditordb-postgres",
     108             :                                      NULL,
     109             :                                      NULL,
     110             :                                      NULL);
     111           1 :   if (NULL == conn)
     112           1 :     return GNUNET_SYSERR;
     113           0 :   ret = GNUNET_PQ_exec_sql (conn,
     114             :                             (drop_exchangelist) ? "drop" : "restart");
     115           0 :   GNUNET_PQ_disconnect (conn);
     116           0 :   return ret;
     117             : }
     118             : 
     119             : 
     120             : /**
     121             :  * Create the necessary tables if they are not present
     122             :  *
     123             :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     124             :  * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
     125             :  */
     126             : static enum GNUNET_GenericReturnValue
     127           1 : postgres_create_tables (void *cls)
     128             : {
     129           1 :   struct PostgresClosure *pc = cls;
     130             :   struct GNUNET_PQ_Context *conn;
     131           1 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     132           1 :     GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
     133             :     GNUNET_PQ_EXECUTE_STATEMENT_END
     134             :   };
     135             : 
     136           1 :   conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
     137             :                                      "auditordb-postgres",
     138             :                                      "auditor-",
     139             :                                      es,
     140             :                                      NULL);
     141           1 :   if (NULL == conn)
     142           1 :     return GNUNET_SYSERR;
     143           0 :   GNUNET_PQ_disconnect (conn);
     144           0 :   return GNUNET_OK;
     145             : }
     146             : 
     147             : 
     148             : /**
     149             :  * Connect to the db if the connection does not exist yet.
     150             :  *
     151             :  * @param[in,out] pg the plugin-specific state
     152             :  * @return #GNUNET_OK on success
     153             :  */
     154             : static enum GNUNET_GenericReturnValue
     155           0 : setup_connection (struct PostgresClosure *pg)
     156             : {
     157           0 :   struct GNUNET_PQ_PreparedStatement ps[] = {
     158             :     /* used in #postgres_commit */
     159           0 :     GNUNET_PQ_make_prepare ("do_commit",
     160             :                             "COMMIT",
     161             :                             0),
     162             :     /* used in #postgres_insert_exchange */
     163           0 :     GNUNET_PQ_make_prepare ("auditor_insert_exchange",
     164             :                             "INSERT INTO auditor_exchanges "
     165             :                             "(master_pub"
     166             :                             ",exchange_url"
     167             :                             ") VALUES ($1,$2);",
     168             :                             2),
     169             :     /* used in #postgres_delete_exchange */
     170           0 :     GNUNET_PQ_make_prepare ("auditor_delete_exchange",
     171             :                             "DELETE"
     172             :                             " FROM auditor_exchanges"
     173             :                             " WHERE master_pub=$1;",
     174             :                             1),
     175             :     /* used in #postgres_list_exchanges */
     176           0 :     GNUNET_PQ_make_prepare ("auditor_list_exchanges",
     177             :                             "SELECT"
     178             :                             " master_pub"
     179             :                             ",exchange_url"
     180             :                             " FROM auditor_exchanges",
     181             :                             0),
     182             :     /* used in #postgres_insert_exchange_signkey */
     183           0 :     GNUNET_PQ_make_prepare ("auditor_insert_exchange_signkey",
     184             :                             "INSERT INTO auditor_exchange_signkeys "
     185             :                             "(master_pub"
     186             :                             ",ep_start"
     187             :                             ",ep_expire"
     188             :                             ",ep_end"
     189             :                             ",exchange_pub"
     190             :                             ",master_sig"
     191             :                             ") VALUES ($1,$2,$3,$4,$5,$6);",
     192             :                             6),
     193             :     /* Used in #postgres_insert_deposit_confirmation() */
     194           0 :     GNUNET_PQ_make_prepare ("auditor_deposit_confirmation_insert",
     195             :                             "INSERT INTO deposit_confirmations "
     196             :                             "(master_pub"
     197             :                             ",h_contract_terms"
     198             :                             ",h_extensions"
     199             :                             ",h_wire"
     200             :                             ",exchange_timestamp"
     201             :                             ",wire_deadline"
     202             :                             ",refund_deadline"
     203             :                             ",amount_without_fee_val"
     204             :                             ",amount_without_fee_frac"
     205             :                             ",coin_pub"
     206             :                             ",merchant_pub"
     207             :                             ",exchange_sig"
     208             :                             ",exchange_pub"
     209             :                             ",master_sig" /* master_sig could be normalized... */
     210             :                             ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14);",
     211             :                             14),
     212             :     /* Used in #postgres_get_deposit_confirmations() */
     213           0 :     GNUNET_PQ_make_prepare ("auditor_deposit_confirmation_select",
     214             :                             "SELECT"
     215             :                             " serial_id"
     216             :                             ",h_contract_terms"
     217             :                             ",h_extensions"
     218             :                             ",h_wire"
     219             :                             ",exchange_timestamp"
     220             :                             ",wire_deadline"
     221             :                             ",refund_deadline"
     222             :                             ",amount_without_fee_val"
     223             :                             ",amount_without_fee_frac"
     224             :                             ",coin_pub"
     225             :                             ",merchant_pub"
     226             :                             ",exchange_sig"
     227             :                             ",exchange_pub"
     228             :                             ",master_sig" /* master_sig could be normalized... */
     229             :                             " FROM deposit_confirmations"
     230             :                             " WHERE master_pub=$1"
     231             :                             " AND serial_id>$2",
     232             :                             2),
     233             :     /* Used in #postgres_update_auditor_progress_reserve() */
     234           0 :     GNUNET_PQ_make_prepare ("auditor_progress_update_reserve",
     235             :                             "UPDATE auditor_progress_reserve SET "
     236             :                             " last_reserve_in_serial_id=$1"
     237             :                             ",last_reserve_out_serial_id=$2"
     238             :                             ",last_reserve_recoup_serial_id=$3"
     239             :                             ",last_reserve_close_serial_id=$4"
     240             :                             ",last_purse_merges_serial_id=$5"
     241             :                             ",last_purse_deposits_serial_id=$6"
     242             :                             ",last_account_merges_serial_id=$7"
     243             :                             ",last_history_requests_serial_id=$8"
     244             :                             ",last_close_requests_serial_id=$9"
     245             :                             " WHERE master_pub=$10",
     246             :                             10),
     247             :     /* Used in #postgres_get_auditor_progress_reserve() */
     248           0 :     GNUNET_PQ_make_prepare ("auditor_progress_select_reserve",
     249             :                             "SELECT"
     250             :                             " last_reserve_in_serial_id"
     251             :                             ",last_reserve_out_serial_id"
     252             :                             ",last_reserve_recoup_serial_id"
     253             :                             ",last_reserve_close_serial_id"
     254             :                             ",last_purse_merges_serial_id"
     255             :                             ",last_purse_deposits_serial_id"
     256             :                             ",last_account_merges_serial_id"
     257             :                             ",last_history_requests_serial_id"
     258             :                             ",last_close_requests_serial_id"
     259             :                             " FROM auditor_progress_reserve"
     260             :                             " WHERE master_pub=$1;",
     261             :                             1),
     262             :     /* Used in #postgres_insert_auditor_progress_reserve() */
     263           0 :     GNUNET_PQ_make_prepare ("auditor_progress_insert_reserve",
     264             :                             "INSERT INTO auditor_progress_reserve "
     265             :                             "(master_pub"
     266             :                             ",last_reserve_in_serial_id"
     267             :                             ",last_reserve_out_serial_id"
     268             :                             ",last_reserve_recoup_serial_id"
     269             :                             ",last_reserve_close_serial_id"
     270             :                             ",last_purse_merges_serial_id"
     271             :                             ",last_purse_deposits_serial_id"
     272             :                             ",last_account_merges_serial_id"
     273             :                             ",last_history_requests_serial_id"
     274             :                             ",last_close_requests_serial_id"
     275             :                             ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);",
     276             :                             10),
     277             :     /* Used in #postgres_update_auditor_progress_aggregation() */
     278           0 :     GNUNET_PQ_make_prepare ("auditor_progress_update_aggregation",
     279             :                             "UPDATE auditor_progress_aggregation SET "
     280             :                             " last_wire_out_serial_id=$1"
     281             :                             " WHERE master_pub=$2",
     282             :                             2),
     283             :     /* Used in #postgres_get_auditor_progress_aggregation() */
     284           0 :     GNUNET_PQ_make_prepare ("auditor_progress_select_aggregation",
     285             :                             "SELECT"
     286             :                             " last_wire_out_serial_id"
     287             :                             " FROM auditor_progress_aggregation"
     288             :                             " WHERE master_pub=$1;",
     289             :                             1),
     290             :     /* Used in #postgres_insert_auditor_progress_aggregation() */
     291           0 :     GNUNET_PQ_make_prepare ("auditor_progress_insert_aggregation",
     292             :                             "INSERT INTO auditor_progress_aggregation "
     293             :                             "(master_pub"
     294             :                             ",last_wire_out_serial_id"
     295             :                             ") VALUES ($1,$2);",
     296             :                             2),
     297             :     /* Used in #postgres_update_auditor_progress_deposit_confirmation() */
     298           0 :     GNUNET_PQ_make_prepare ("auditor_progress_update_deposit_confirmation",
     299             :                             "UPDATE auditor_progress_deposit_confirmation SET "
     300             :                             " last_deposit_confirmation_serial_id=$1"
     301             :                             " WHERE master_pub=$2",
     302             :                             2),
     303             :     /* Used in #postgres_get_auditor_progress_deposit_confirmation() */
     304           0 :     GNUNET_PQ_make_prepare ("auditor_progress_select_deposit_confirmation",
     305             :                             "SELECT"
     306             :                             " last_deposit_confirmation_serial_id"
     307             :                             " FROM auditor_progress_deposit_confirmation"
     308             :                             " WHERE master_pub=$1;",
     309             :                             1),
     310             :     /* Used in #postgres_insert_auditor_progress_deposit_confirmation() */
     311           0 :     GNUNET_PQ_make_prepare ("auditor_progress_insert_deposit_confirmation",
     312             :                             "INSERT INTO auditor_progress_deposit_confirmation "
     313             :                             "(master_pub"
     314             :                             ",last_deposit_confirmation_serial_id"
     315             :                             ") VALUES ($1,$2);",
     316             :                             2),
     317             :     /* Used in #postgres_update_auditor_progress_coin() */
     318           0 :     GNUNET_PQ_make_prepare ("auditor_progress_update_coin",
     319             :                             "UPDATE auditor_progress_coin SET "
     320             :                             " last_withdraw_serial_id=$1"
     321             :                             ",last_deposit_serial_id=$2"
     322             :                             ",last_melt_serial_id=$3"
     323             :                             ",last_refund_serial_id=$4"
     324             :                             ",last_recoup_serial_id=$5"
     325             :                             ",last_recoup_refresh_serial_id=$6"
     326             :                             ",last_purse_deposits_serial_id=$7"
     327             :                             ",last_purse_refunds_serial_id=$8"
     328             :                             " WHERE master_pub=$9",
     329             :                             9),
     330             :     /* Used in #postgres_get_auditor_progress_coin() */
     331           0 :     GNUNET_PQ_make_prepare ("auditor_progress_select_coin",
     332             :                             "SELECT"
     333             :                             " last_withdraw_serial_id"
     334             :                             ",last_deposit_serial_id"
     335             :                             ",last_melt_serial_id"
     336             :                             ",last_refund_serial_id"
     337             :                             ",last_recoup_serial_id"
     338             :                             ",last_recoup_refresh_serial_id"
     339             :                             ",last_purse_deposits_serial_id"
     340             :                             ",last_purse_refunds_serial_id"
     341             :                             " FROM auditor_progress_coin"
     342             :                             " WHERE master_pub=$1;",
     343             :                             1),
     344             :     /* Used in #postgres_insert_auditor_progress() */
     345           0 :     GNUNET_PQ_make_prepare ("auditor_progress_insert_coin",
     346             :                             "INSERT INTO auditor_progress_coin "
     347             :                             "(master_pub"
     348             :                             ",last_withdraw_serial_id"
     349             :                             ",last_deposit_serial_id"
     350             :                             ",last_melt_serial_id"
     351             :                             ",last_refund_serial_id"
     352             :                             ",last_recoup_serial_id"
     353             :                             ",last_recoup_refresh_serial_id"
     354             :                             ",last_purse_deposits_serial_id"
     355             :                             ",last_purse_refunds_serial_id"
     356             :                             ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
     357             :                             9),
     358             :     /* Used in #postgres_insert_wire_auditor_account_progress() */
     359           0 :     GNUNET_PQ_make_prepare ("wire_auditor_account_progress_insert",
     360             :                             "INSERT INTO wire_auditor_account_progress "
     361             :                             "(master_pub"
     362             :                             ",account_name"
     363             :                             ",last_wire_reserve_in_serial_id"
     364             :                             ",last_wire_wire_out_serial_id"
     365             :                             ",wire_in_off"
     366             :                             ",wire_out_off"
     367             :                             ") VALUES ($1,$2,$3,$4,$5,$6);",
     368             :                             6),
     369             :     /* Used in #postgres_update_wire_auditor_account_progress() */
     370           0 :     GNUNET_PQ_make_prepare ("wire_auditor_account_progress_update",
     371             :                             "UPDATE wire_auditor_account_progress SET "
     372             :                             " last_wire_reserve_in_serial_id=$1"
     373             :                             ",last_wire_wire_out_serial_id=$2"
     374             :                             ",wire_in_off=$3"
     375             :                             ",wire_out_off=$4"
     376             :                             " WHERE master_pub=$5 AND account_name=$6",
     377             :                             6),
     378             :     /* Used in #postgres_get_wire_auditor_account_progress() */
     379           0 :     GNUNET_PQ_make_prepare ("wire_auditor_account_progress_select",
     380             :                             "SELECT"
     381             :                             " last_wire_reserve_in_serial_id"
     382             :                             ",last_wire_wire_out_serial_id"
     383             :                             ",wire_in_off"
     384             :                             ",wire_out_off"
     385             :                             " FROM wire_auditor_account_progress"
     386             :                             " WHERE master_pub=$1 AND account_name=$2;",
     387             :                             2),
     388             :     /* Used in #postgres_insert_wire_auditor_progress() */
     389           0 :     GNUNET_PQ_make_prepare ("wire_auditor_progress_insert",
     390             :                             "INSERT INTO wire_auditor_progress "
     391             :                             "(master_pub"
     392             :                             ",last_timestamp"
     393             :                             ",last_reserve_close_uuid"
     394             :                             ") VALUES ($1,$2,$3);",
     395             :                             3),
     396             :     /* Used in #postgres_update_wire_auditor_progress() */
     397           0 :     GNUNET_PQ_make_prepare ("wire_auditor_progress_update",
     398             :                             "UPDATE wire_auditor_progress SET "
     399             :                             " last_timestamp=$1"
     400             :                             ",last_reserve_close_uuid=$2"
     401             :                             " WHERE master_pub=$3",
     402             :                             3),
     403             :     /* Used in #postgres_get_wire_auditor_progress() */
     404           0 :     GNUNET_PQ_make_prepare ("wire_auditor_progress_select",
     405             :                             "SELECT"
     406             :                             " last_timestamp"
     407             :                             ",last_reserve_close_uuid"
     408             :                             " FROM wire_auditor_progress"
     409             :                             " WHERE master_pub=$1;",
     410             :                             1),
     411             :     /* Used in #postgres_insert_reserve_info() */
     412           0 :     GNUNET_PQ_make_prepare ("auditor_reserves_insert",
     413             :                             "INSERT INTO auditor_reserves "
     414             :                             "(reserve_pub"
     415             :                             ",master_pub"
     416             :                             ",reserve_balance_val"
     417             :                             ",reserve_balance_frac"
     418             :                             ",withdraw_fee_balance_val"
     419             :                             ",withdraw_fee_balance_frac"
     420             :                             ",expiration_date"
     421             :                             ",origin_account"
     422             :                             ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8);",
     423             :                             8),
     424             :     /* Used in #postgres_update_reserve_info() */
     425           0 :     GNUNET_PQ_make_prepare ("auditor_reserves_update",
     426             :                             "UPDATE auditor_reserves SET"
     427             :                             " reserve_balance_val=$1"
     428             :                             ",reserve_balance_frac=$2"
     429             :                             ",withdraw_fee_balance_val=$3"
     430             :                             ",withdraw_fee_balance_frac=$4"
     431             :                             ",expiration_date=$5"
     432             :                             " WHERE reserve_pub=$6 AND master_pub=$7;",
     433             :                             7),
     434             :     /* Used in #postgres_get_reserve_info() */
     435           0 :     GNUNET_PQ_make_prepare ("auditor_reserves_select",
     436             :                             "SELECT"
     437             :                             " reserve_balance_val"
     438             :                             ",reserve_balance_frac"
     439             :                             ",withdraw_fee_balance_val"
     440             :                             ",withdraw_fee_balance_frac"
     441             :                             ",expiration_date"
     442             :                             ",auditor_reserves_rowid"
     443             :                             ",origin_account"
     444             :                             " FROM auditor_reserves"
     445             :                             " WHERE reserve_pub=$1 AND master_pub=$2;",
     446             :                             2),
     447             :     /* Used in #postgres_del_reserve_info() */
     448           0 :     GNUNET_PQ_make_prepare ("auditor_reserves_delete",
     449             :                             "DELETE"
     450             :                             " FROM auditor_reserves"
     451             :                             " WHERE reserve_pub=$1 AND master_pub=$2;",
     452             :                             2),
     453             :     /* Used in #postgres_insert_reserve_summary() */
     454           0 :     GNUNET_PQ_make_prepare ("auditor_reserve_balance_insert",
     455             :                             "INSERT INTO auditor_reserve_balance"
     456             :                             "(master_pub"
     457             :                             ",reserve_balance_val"
     458             :                             ",reserve_balance_frac"
     459             :                             ",withdraw_fee_balance_val"
     460             :                             ",withdraw_fee_balance_frac"
     461             :                             ",purse_fee_balance_val"
     462             :                             ",purse_fee_balance_frac"
     463             :                             ",history_fee_balance_val"
     464             :                             ",history_fee_balance_frac"
     465             :                             ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)",
     466             :                             9),
     467             :     /* Used in #postgres_update_reserve_summary() */
     468           0 :     GNUNET_PQ_make_prepare ("auditor_reserve_balance_update",
     469             :                             "UPDATE auditor_reserve_balance SET"
     470             :                             " reserve_balance_val=$1"
     471             :                             ",reserve_balance_frac=$2"
     472             :                             ",withdraw_fee_balance_val=$3"
     473             :                             ",withdraw_fee_balance_frac=$4"
     474             :                             ",purse_fee_balance_val=$5"
     475             :                             ",purse_fee_balance_frac=$6"
     476             :                             ",history_fee_balance_val=$7"
     477             :                             ",history_fee_balance_frac=$8"
     478             :                             " WHERE master_pub=$9;",
     479             :                             9),
     480             :     /* Used in #postgres_get_reserve_summary() */
     481           0 :     GNUNET_PQ_make_prepare ("auditor_reserve_balance_select",
     482             :                             "SELECT"
     483             :                             " reserve_balance_val"
     484             :                             ",reserve_balance_frac"
     485             :                             ",withdraw_fee_balance_val"
     486             :                             ",withdraw_fee_balance_frac"
     487             :                             ",purse_fee_balance_val"
     488             :                             ",purse_fee_balance_frac"
     489             :                             ",history_fee_balance_val"
     490             :                             ",history_fee_balance_frac"
     491             :                             " FROM auditor_reserve_balance"
     492             :                             " WHERE master_pub=$1;",
     493             :                             1),
     494             :     /* Used in #postgres_insert_wire_fee_summary() */
     495           0 :     GNUNET_PQ_make_prepare ("auditor_wire_fee_balance_insert",
     496             :                             "INSERT INTO auditor_wire_fee_balance"
     497             :                             "(master_pub"
     498             :                             ",wire_fee_balance_val"
     499             :                             ",wire_fee_balance_frac"
     500             :                             ") VALUES ($1,$2,$3)",
     501             :                             3),
     502             :     /* Used in #postgres_update_wire_fee_summary() */
     503           0 :     GNUNET_PQ_make_prepare ("auditor_wire_fee_balance_update",
     504             :                             "UPDATE auditor_wire_fee_balance SET"
     505             :                             " wire_fee_balance_val=$1"
     506             :                             ",wire_fee_balance_frac=$2"
     507             :                             " WHERE master_pub=$3;",
     508             :                             3),
     509             :     /* Used in #postgres_get_wire_fee_summary() */
     510           0 :     GNUNET_PQ_make_prepare ("auditor_wire_fee_balance_select",
     511             :                             "SELECT"
     512             :                             " wire_fee_balance_val"
     513             :                             ",wire_fee_balance_frac"
     514             :                             " FROM auditor_wire_fee_balance"
     515             :                             " WHERE master_pub=$1;",
     516             :                             1),
     517             :     /* Used in #postgres_insert_denomination_balance() */
     518           0 :     GNUNET_PQ_make_prepare ("auditor_denomination_pending_insert",
     519             :                             "INSERT INTO auditor_denomination_pending "
     520             :                             "(denom_pub_hash"
     521             :                             ",denom_balance_val"
     522             :                             ",denom_balance_frac"
     523             :                             ",denom_loss_val"
     524             :                             ",denom_loss_frac"
     525             :                             ",num_issued"
     526             :                             ",denom_risk_val"
     527             :                             ",denom_risk_frac"
     528             :                             ",recoup_loss_val"
     529             :                             ",recoup_loss_frac"
     530             :                             ") VALUES ("
     531             :                             "$1,$2,$3,$4,$5,$6,$7,$8,$9,$10"
     532             :                             ");",
     533             :                             10),
     534             :     /* Used in #postgres_update_denomination_balance() */
     535           0 :     GNUNET_PQ_make_prepare ("auditor_denomination_pending_update",
     536             :                             "UPDATE auditor_denomination_pending SET"
     537             :                             " denom_balance_val=$1"
     538             :                             ",denom_balance_frac=$2"
     539             :                             ",denom_loss_val=$3"
     540             :                             ",denom_loss_frac=$4"
     541             :                             ",num_issued=$5"
     542             :                             ",denom_risk_val=$6"
     543             :                             ",denom_risk_frac=$7"
     544             :                             ",recoup_loss_val=$8"
     545             :                             ",recoup_loss_frac=$9"
     546             :                             " WHERE denom_pub_hash=$10",
     547             :                             10),
     548             :     /* Used in #postgres_get_denomination_balance() */
     549           0 :     GNUNET_PQ_make_prepare ("auditor_denomination_pending_select",
     550             :                             "SELECT"
     551             :                             " denom_balance_val"
     552             :                             ",denom_balance_frac"
     553             :                             ",denom_loss_val"
     554             :                             ",denom_loss_frac"
     555             :                             ",num_issued"
     556             :                             ",denom_risk_val"
     557             :                             ",denom_risk_frac"
     558             :                             ",recoup_loss_val"
     559             :                             ",recoup_loss_frac"
     560             :                             " FROM auditor_denomination_pending"
     561             :                             " WHERE denom_pub_hash=$1",
     562             :                             1),
     563             :     /* Used in #postgres_insert_balance_summary() */
     564           0 :     GNUNET_PQ_make_prepare ("auditor_balance_summary_insert",
     565             :                             "INSERT INTO auditor_balance_summary "
     566             :                             "(master_pub"
     567             :                             ",denom_balance_val"
     568             :                             ",denom_balance_frac"
     569             :                             ",deposit_fee_balance_val"
     570             :                             ",deposit_fee_balance_frac"
     571             :                             ",melt_fee_balance_val"
     572             :                             ",melt_fee_balance_frac"
     573             :                             ",refund_fee_balance_val"
     574             :                             ",refund_fee_balance_frac"
     575             :                             ",risk_val"
     576             :                             ",risk_frac"
     577             :                             ",loss_val"
     578             :                             ",loss_frac"
     579             :                             ",irregular_recoup_val"
     580             :                             ",irregular_recoup_frac"
     581             :                             ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,"
     582             :                             "          $11,$12,$13,$14,$15);",
     583             :                             15),
     584             :     /* Used in #postgres_update_balance_summary() */
     585           0 :     GNUNET_PQ_make_prepare ("auditor_balance_summary_update",
     586             :                             "UPDATE auditor_balance_summary SET"
     587             :                             " denom_balance_val=$1"
     588             :                             ",denom_balance_frac=$2"
     589             :                             ",deposit_fee_balance_val=$3"
     590             :                             ",deposit_fee_balance_frac=$4"
     591             :                             ",melt_fee_balance_val=$5"
     592             :                             ",melt_fee_balance_frac=$6"
     593             :                             ",refund_fee_balance_val=$7"
     594             :                             ",refund_fee_balance_frac=$8"
     595             :                             ",risk_val=$9"
     596             :                             ",risk_frac=$10"
     597             :                             ",loss_val=$11"
     598             :                             ",loss_frac=$12"
     599             :                             ",irregular_recoup_val=$13"
     600             :                             ",irregular_recoup_frac=$14"
     601             :                             " WHERE master_pub=$15;",
     602             :                             15),
     603             :     /* Used in #postgres_get_balance_summary() */
     604           0 :     GNUNET_PQ_make_prepare ("auditor_balance_summary_select",
     605             :                             "SELECT"
     606             :                             " denom_balance_val"
     607             :                             ",denom_balance_frac"
     608             :                             ",deposit_fee_balance_val"
     609             :                             ",deposit_fee_balance_frac"
     610             :                             ",melt_fee_balance_val"
     611             :                             ",melt_fee_balance_frac"
     612             :                             ",refund_fee_balance_val"
     613             :                             ",refund_fee_balance_frac"
     614             :                             ",risk_val"
     615             :                             ",risk_frac"
     616             :                             ",loss_val"
     617             :                             ",loss_frac"
     618             :                             ",irregular_recoup_val"
     619             :                             ",irregular_recoup_frac"
     620             :                             " FROM auditor_balance_summary"
     621             :                             " WHERE master_pub=$1;",
     622             :                             1),
     623             :     /* Used in #postgres_insert_historic_denom_revenue() */
     624           0 :     GNUNET_PQ_make_prepare ("auditor_historic_denomination_revenue_insert",
     625             :                             "INSERT INTO auditor_historic_denomination_revenue"
     626             :                             "(master_pub"
     627             :                             ",denom_pub_hash"
     628             :                             ",revenue_timestamp"
     629             :                             ",revenue_balance_val"
     630             :                             ",revenue_balance_frac"
     631             :                             ",loss_balance_val"
     632             :                             ",loss_balance_frac"
     633             :                             ") VALUES ($1,$2,$3,$4,$5,$6,$7);",
     634             :                             7),
     635             :     /* Used in #postgres_select_historic_denom_revenue() */
     636           0 :     GNUNET_PQ_make_prepare ("auditor_historic_denomination_revenue_select",
     637             :                             "SELECT"
     638             :                             " denom_pub_hash"
     639             :                             ",revenue_timestamp"
     640             :                             ",revenue_balance_val"
     641             :                             ",revenue_balance_frac"
     642             :                             ",loss_balance_val"
     643             :                             ",loss_balance_frac"
     644             :                             " FROM auditor_historic_denomination_revenue"
     645             :                             " WHERE master_pub=$1;",
     646             :                             1),
     647             :     /* Used in #postgres_insert_historic_reserve_revenue() */
     648           0 :     GNUNET_PQ_make_prepare ("auditor_historic_reserve_summary_insert",
     649             :                             "INSERT INTO auditor_historic_reserve_summary"
     650             :                             "(master_pub"
     651             :                             ",start_date"
     652             :                             ",end_date"
     653             :                             ",reserve_profits_val"
     654             :                             ",reserve_profits_frac"
     655             :                             ") VALUES ($1,$2,$3,$4,$5);",
     656             :                             5),
     657             :     /* Used in #postgres_select_historic_reserve_revenue() */
     658           0 :     GNUNET_PQ_make_prepare ("auditor_historic_reserve_summary_select",
     659             :                             "SELECT"
     660             :                             " start_date"
     661             :                             ",end_date"
     662             :                             ",reserve_profits_val"
     663             :                             ",reserve_profits_frac"
     664             :                             " FROM auditor_historic_reserve_summary"
     665             :                             " WHERE master_pub=$1;",
     666             :                             1),
     667             :     /* Used in #postgres_insert_predicted_result() */
     668           0 :     GNUNET_PQ_make_prepare ("auditor_predicted_result_insert",
     669             :                             "INSERT INTO auditor_predicted_result"
     670             :                             "(master_pub"
     671             :                             ",balance_val"
     672             :                             ",balance_frac"
     673             :                             ",drained_val"
     674             :                             ",drained_frac"
     675             :                             ") VALUES ($1,$2,$3,$4,$5);",
     676             :                             5),
     677             :     /* Used in #postgres_update_predicted_result() */
     678           0 :     GNUNET_PQ_make_prepare ("auditor_predicted_result_update",
     679             :                             "UPDATE auditor_predicted_result SET"
     680             :                             " balance_val=$1"
     681             :                             ",balance_frac=$2"
     682             :                             ",drained_val=$3"
     683             :                             ",drained_frac=$4"
     684             :                             " WHERE master_pub=$5;",
     685             :                             5),
     686             :     /* Used in #postgres_get_predicted_balance() */
     687           0 :     GNUNET_PQ_make_prepare ("auditor_predicted_result_select",
     688             :                             "SELECT"
     689             :                             " balance_val"
     690             :                             ",balance_frac"
     691             :                             ",drained_val"
     692             :                             ",drained_frac"
     693             :                             " FROM auditor_predicted_result"
     694             :                             " WHERE master_pub=$1;",
     695             :                             1),
     696             :     GNUNET_PQ_PREPARED_STATEMENT_END
     697             :   };
     698           0 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     699           0 :     GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
     700             :     GNUNET_PQ_EXECUTE_STATEMENT_END
     701             :   };
     702             :   struct GNUNET_PQ_Context *db_conn;
     703             : 
     704           0 :   if (NULL != pg->conn)
     705             :   {
     706           0 :     GNUNET_PQ_reconnect_if_down (pg->conn);
     707           0 :     return GNUNET_OK;
     708             :   }
     709           0 :   db_conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
     710             :                                         "auditordb-postgres",
     711             :                                         NULL,
     712             :                                         es,
     713             :                                         ps);
     714           0 :   if (NULL == db_conn)
     715           0 :     return GNUNET_SYSERR;
     716           0 :   pg->conn = db_conn;
     717           0 :   return GNUNET_OK;
     718             : }
     719             : 
     720             : 
     721             : /**
     722             :  * Do a pre-flight check that we are not in an uncommitted transaction.
     723             :  * If we are, rollback the previous transaction and output a warning.
     724             :  *
     725             :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     726             :  * @return #GNUNET_OK on success,
     727             :  *         #GNUNET_NO if we rolled back an earlier transaction
     728             :  *         #GNUNET_SYSERR if we have no DB connection
     729             :  */
     730             : static enum GNUNET_GenericReturnValue
     731           0 : postgres_preflight (void *cls)
     732             : {
     733           0 :   struct PostgresClosure *pg = cls;
     734           0 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     735           0 :     GNUNET_PQ_make_execute ("ROLLBACK"),
     736             :     GNUNET_PQ_EXECUTE_STATEMENT_END
     737             :   };
     738             : 
     739           0 :   if (NULL == pg->conn)
     740             :   {
     741           0 :     if (GNUNET_OK !=
     742           0 :         setup_connection (pg))
     743             :     {
     744           0 :       GNUNET_break (0);
     745           0 :       return GNUNET_SYSERR;
     746             :     }
     747             :   }
     748           0 :   if (NULL == pg->transaction_name)
     749           0 :     return GNUNET_OK; /* all good */
     750           0 :   if (GNUNET_OK ==
     751           0 :       GNUNET_PQ_exec_statements (pg->conn,
     752             :                                  es))
     753             :   {
     754           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     755             :                 "BUG: Preflight check rolled back transaction `%s'!\n",
     756             :                 pg->transaction_name);
     757             :   }
     758             :   else
     759             :   {
     760           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     761             :                 "BUG: Preflight check failed to rollback transaction `%s'!\n",
     762             :                 pg->transaction_name);
     763             :   }
     764           0 :   pg->transaction_name = NULL;
     765           0 :   return GNUNET_NO;
     766             : }
     767             : 
     768             : 
     769             : /**
     770             :  * Start a transaction.
     771             :  *
     772             :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     773             :  * @return #GNUNET_OK on success
     774             :  */
     775             : static enum GNUNET_GenericReturnValue
     776           0 : postgres_start (void *cls)
     777             : {
     778           0 :   struct PostgresClosure *pg = cls;
     779           0 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     780           0 :     GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
     781             :     GNUNET_PQ_EXECUTE_STATEMENT_END
     782             :   };
     783             : 
     784           0 :   postgres_preflight (cls);
     785           0 :   if (GNUNET_OK !=
     786           0 :       GNUNET_PQ_exec_statements (pg->conn,
     787             :                                  es))
     788             :   {
     789           0 :     TALER_LOG_ERROR ("Failed to start transaction\n");
     790           0 :     GNUNET_break (0);
     791           0 :     return GNUNET_SYSERR;
     792             :   }
     793           0 :   return GNUNET_OK;
     794             : }
     795             : 
     796             : 
     797             : /**
     798             :  * Roll back the current transaction of a database connection.
     799             :  *
     800             :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     801             :  */
     802             : static void
     803           0 : postgres_rollback (void *cls)
     804             : {
     805           0 :   struct PostgresClosure *pg = cls;
     806           0 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     807           0 :     GNUNET_PQ_make_execute ("ROLLBACK"),
     808             :     GNUNET_PQ_EXECUTE_STATEMENT_END
     809             :   };
     810             : 
     811           0 :   GNUNET_break (GNUNET_OK ==
     812             :                 GNUNET_PQ_exec_statements (pg->conn,
     813             :                                            es));
     814           0 : }
     815             : 
     816             : 
     817             : /**
     818             :  * Commit the current transaction of a database connection.
     819             :  *
     820             :  * @param cls the `struct PostgresClosure` with the plugin-specific state
     821             :  * @return transaction status code
     822             :  */
     823             : enum GNUNET_DB_QueryStatus
     824           0 : postgres_commit (void *cls)
     825             : {
     826           0 :   struct PostgresClosure *pg = cls;
     827           0 :   struct GNUNET_PQ_QueryParam params[] = {
     828             :     GNUNET_PQ_query_param_end
     829             :   };
     830             : 
     831           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
     832             :                                              "do_commit",
     833             :                                              params);
     834             : }
     835             : 
     836             : 
     837             : /**
     838             :  * Function called to perform "garbage collection" on the
     839             :  * database, expiring records we no longer require.
     840             :  *
     841             :  * @param cls closure
     842             :  * @return #GNUNET_OK on success,
     843             :  *         #GNUNET_SYSERR on DB errors
     844             :  */
     845             : static enum GNUNET_GenericReturnValue
     846           0 : postgres_gc (void *cls)
     847             : {
     848           0 :   struct PostgresClosure *pg = cls;
     849           0 :   struct GNUNET_TIME_Absolute now = {0};
     850           0 :   struct GNUNET_PQ_QueryParam params_time[] = {
     851           0 :     GNUNET_PQ_query_param_absolute_time (&now),
     852             :     GNUNET_PQ_query_param_end
     853             :   };
     854             :   struct GNUNET_PQ_Context *conn;
     855             :   enum GNUNET_DB_QueryStatus qs;
     856           0 :   struct GNUNET_PQ_PreparedStatement ps[] = {
     857             : #if 0
     858             :     GNUNET_PQ_make_prepare ("gc_auditor",
     859             :                             "TODO: #4960",
     860             :                             0),
     861             : #endif
     862             :     GNUNET_PQ_PREPARED_STATEMENT_END
     863             :   };
     864           0 :   struct GNUNET_PQ_ExecuteStatement es[] = {
     865           0 :     GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
     866             :     GNUNET_PQ_EXECUTE_STATEMENT_END
     867             :   };
     868             : 
     869           0 :   now = GNUNET_TIME_absolute_get ();
     870           0 :   conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
     871             :                                      "auditordb-postgres",
     872             :                                      NULL,
     873             :                                      es,
     874             :                                      ps);
     875           0 :   if (NULL == conn)
     876           0 :     return GNUNET_SYSERR;
     877           0 :   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     878             :               "TODO: Auditor GC not implemented (#4960)\n");
     879           0 :   qs = GNUNET_PQ_eval_prepared_non_select (conn,
     880             :                                            "gc_auditor",
     881             :                                            params_time);
     882           0 :   GNUNET_PQ_disconnect (conn);
     883           0 :   if (0 > qs)
     884             :   {
     885           0 :     GNUNET_break (0);
     886           0 :     return GNUNET_SYSERR;
     887             :   }
     888           0 :   return GNUNET_OK;
     889             : }
     890             : 
     891             : 
     892             : /**
     893             :  * Insert information about an exchange this auditor will be auditing.
     894             :  *
     895             :  * @param cls the @e cls of this struct with the plugin-specific state
     896             :  * @param master_pub master public key of the exchange
     897             :  * @param exchange_url public (base) URL of the API of the exchange
     898             :  * @return query result status
     899             :  */
     900             : static enum GNUNET_DB_QueryStatus
     901           0 : postgres_insert_exchange (void *cls,
     902             :                           const struct TALER_MasterPublicKeyP *master_pub,
     903             :                           const char *exchange_url)
     904             : {
     905           0 :   struct PostgresClosure *pg = cls;
     906           0 :   struct GNUNET_PQ_QueryParam params[] = {
     907           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
     908           0 :     GNUNET_PQ_query_param_string (exchange_url),
     909             :     GNUNET_PQ_query_param_end
     910             :   };
     911             : 
     912           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
     913             :                                              "auditor_insert_exchange",
     914             :                                              params);
     915             : }
     916             : 
     917             : 
     918             : /**
     919             :  * Delete an exchange from the list of exchanges this auditor is auditing.
     920             :  * Warning: this will cascade and delete all knowledge of this auditor related
     921             :  * to this exchange!
     922             :  *
     923             :  * @param cls the @e cls of this struct with the plugin-specific state
     924             :  * @param master_pub master public key of the exchange
     925             :  * @return query result status
     926             :  */
     927             : static enum GNUNET_DB_QueryStatus
     928           0 : postgres_delete_exchange (void *cls,
     929             :                           const struct TALER_MasterPublicKeyP *master_pub)
     930             : {
     931           0 :   struct PostgresClosure *pg = cls;
     932           0 :   struct GNUNET_PQ_QueryParam params[] = {
     933           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
     934             :     GNUNET_PQ_query_param_end
     935             :   };
     936             : 
     937           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
     938             :                                              "auditor_delete_exchange",
     939             :                                              params);
     940             : }
     941             : 
     942             : 
     943             : /**
     944             :  * Closure for #exchange_info_cb().
     945             :  */
     946             : struct ExchangeInfoContext
     947             : {
     948             : 
     949             :   /**
     950             :    * Function to call for each exchange.
     951             :    */
     952             :   TALER_AUDITORDB_ExchangeCallback cb;
     953             : 
     954             :   /**
     955             :    * Closure for @e cb
     956             :    */
     957             :   void *cb_cls;
     958             : 
     959             :   /**
     960             :    * Query status to return.
     961             :    */
     962             :   enum GNUNET_DB_QueryStatus qs;
     963             : };
     964             : 
     965             : 
     966             : /**
     967             :  * Helper function for #postgres_list_exchanges().
     968             :  * To be called with the results of a SELECT statement
     969             :  * that has returned @a num_results results.
     970             :  *
     971             :  * @param cls closure of type `struct ExchangeInfoContext *`
     972             :  * @param result the postgres result
     973             :  * @param num_results the number of results in @a result
     974             :  */
     975             : static void
     976           0 : exchange_info_cb (void *cls,
     977             :                   PGresult *result,
     978             :                   unsigned int num_results)
     979             : {
     980           0 :   struct ExchangeInfoContext *eic = cls;
     981             : 
     982           0 :   for (unsigned int i = 0; i < num_results; i++)
     983             :   {
     984             :     struct TALER_MasterPublicKeyP master_pub;
     985             :     char *exchange_url;
     986           0 :     struct GNUNET_PQ_ResultSpec rs[] = {
     987           0 :       GNUNET_PQ_result_spec_auto_from_type ("master_pub", &master_pub),
     988           0 :       GNUNET_PQ_result_spec_string ("exchange_url", &exchange_url),
     989             :       GNUNET_PQ_result_spec_end
     990             :     };
     991             : 
     992           0 :     if (GNUNET_OK !=
     993           0 :         GNUNET_PQ_extract_result (result,
     994             :                                   rs,
     995             :                                   i))
     996             :     {
     997           0 :       GNUNET_break (0);
     998           0 :       eic->qs = GNUNET_DB_STATUS_HARD_ERROR;
     999           0 :       return;
    1000             :     }
    1001           0 :     eic->qs = i + 1;
    1002           0 :     eic->cb (eic->cb_cls,
    1003             :              &master_pub,
    1004             :              exchange_url);
    1005           0 :     GNUNET_free (exchange_url);
    1006             :   }
    1007             : }
    1008             : 
    1009             : 
    1010             : /**
    1011             :  * Obtain information about exchanges this auditor is auditing.
    1012             :  *
    1013             :  * @param cls the @e cls of this struct with the plugin-specific state
    1014             :  * @param cb function to call with the results
    1015             :  * @param cb_cls closure for @a cb
    1016             :  * @return query result status
    1017             :  */
    1018             : static enum GNUNET_DB_QueryStatus
    1019           0 : postgres_list_exchanges (void *cls,
    1020             :                          TALER_AUDITORDB_ExchangeCallback cb,
    1021             :                          void *cb_cls)
    1022             : {
    1023           0 :   struct PostgresClosure *pg = cls;
    1024           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1025             :     GNUNET_PQ_query_param_end
    1026             :   };
    1027           0 :   struct ExchangeInfoContext eic = {
    1028             :     .cb = cb,
    1029             :     .cb_cls = cb_cls
    1030             :   };
    1031             :   enum GNUNET_DB_QueryStatus qs;
    1032             : 
    1033           0 :   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
    1034             :                                              "auditor_list_exchanges",
    1035             :                                              params,
    1036             :                                              &exchange_info_cb,
    1037             :                                              &eic);
    1038           0 :   if (qs > 0)
    1039           0 :     return eic.qs;
    1040           0 :   GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
    1041           0 :   return qs;
    1042             : }
    1043             : 
    1044             : 
    1045             : /**
    1046             :  * Insert information about a signing key of the exchange.
    1047             :  *
    1048             :  * @param cls the @e cls of this struct with the plugin-specific state
    1049             :  * @param sk signing key information to store
    1050             :  * @return query result status
    1051             :  */
    1052             : static enum GNUNET_DB_QueryStatus
    1053           0 : postgres_insert_exchange_signkey (
    1054             :   void *cls,
    1055             :   const struct TALER_AUDITORDB_ExchangeSigningKey *sk)
    1056             : {
    1057           0 :   struct PostgresClosure *pg = cls;
    1058           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1059           0 :     GNUNET_PQ_query_param_auto_from_type (&sk->master_public_key),
    1060           0 :     GNUNET_PQ_query_param_timestamp (&sk->ep_start),
    1061           0 :     GNUNET_PQ_query_param_timestamp (&sk->ep_expire),
    1062           0 :     GNUNET_PQ_query_param_timestamp (&sk->ep_end),
    1063           0 :     GNUNET_PQ_query_param_auto_from_type (&sk->exchange_pub),
    1064           0 :     GNUNET_PQ_query_param_auto_from_type (&sk->master_sig),
    1065             :     GNUNET_PQ_query_param_end
    1066             :   };
    1067             : 
    1068           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1069             :                                              "auditor_insert_exchange_signkey",
    1070             :                                              params);
    1071             : }
    1072             : 
    1073             : 
    1074             : /**
    1075             :  * Insert information about a deposit confirmation into the database.
    1076             :  *
    1077             :  * @param cls the @e cls of this struct with the plugin-specific state
    1078             :  * @param dc deposit confirmation information to store
    1079             :  * @return query result status
    1080             :  */
    1081             : static enum GNUNET_DB_QueryStatus
    1082           0 : postgres_insert_deposit_confirmation (
    1083             :   void *cls,
    1084             :   const struct TALER_AUDITORDB_DepositConfirmation *dc)
    1085             : {
    1086           0 :   struct PostgresClosure *pg = cls;
    1087           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1088           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->master_public_key),
    1089           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->h_contract_terms),
    1090           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->h_extensions),
    1091           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->h_wire),
    1092           0 :     GNUNET_PQ_query_param_timestamp (&dc->exchange_timestamp),
    1093           0 :     GNUNET_PQ_query_param_timestamp (&dc->wire_deadline),
    1094           0 :     GNUNET_PQ_query_param_timestamp (&dc->refund_deadline),
    1095           0 :     TALER_PQ_query_param_amount (&dc->amount_without_fee),
    1096           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub),
    1097           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->merchant),
    1098           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->exchange_sig),
    1099           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->exchange_pub),
    1100           0 :     GNUNET_PQ_query_param_auto_from_type (&dc->master_sig),
    1101             :     GNUNET_PQ_query_param_end
    1102             :   };
    1103             : 
    1104           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1105             :                                              "auditor_deposit_confirmation_insert",
    1106             :                                              params);
    1107             : }
    1108             : 
    1109             : 
    1110             : /**
    1111             :  * Closure for #deposit_confirmation_cb().
    1112             :  */
    1113             : struct DepositConfirmationContext
    1114             : {
    1115             : 
    1116             :   /**
    1117             :    * Master public key that is being used.
    1118             :    */
    1119             :   const struct TALER_MasterPublicKeyP *master_pub;
    1120             : 
    1121             :   /**
    1122             :    * Function to call for each deposit confirmation.
    1123             :    */
    1124             :   TALER_AUDITORDB_DepositConfirmationCallback cb;
    1125             : 
    1126             :   /**
    1127             :    * Closure for @e cb
    1128             :    */
    1129             :   void *cb_cls;
    1130             : 
    1131             :   /**
    1132             :    * Plugin context.
    1133             :    */
    1134             :   struct PostgresClosure *pg;
    1135             : 
    1136             :   /**
    1137             :    * Query status to return.
    1138             :    */
    1139             :   enum GNUNET_DB_QueryStatus qs;
    1140             : };
    1141             : 
    1142             : 
    1143             : /**
    1144             :  * Helper function for #postgres_get_deposit_confirmations().
    1145             :  * To be called with the results of a SELECT statement
    1146             :  * that has returned @a num_results results.
    1147             :  *
    1148             :  * @param cls closure of type `struct DepositConfirmationContext *`
    1149             :  * @param result the postgres result
    1150             :  * @param num_results the number of results in @a result
    1151             :  */
    1152             : static void
    1153           0 : deposit_confirmation_cb (void *cls,
    1154             :                          PGresult *result,
    1155             :                          unsigned int num_results)
    1156             : {
    1157           0 :   struct DepositConfirmationContext *dcc = cls;
    1158           0 :   struct PostgresClosure *pg = dcc->pg;
    1159             : 
    1160           0 :   for (unsigned int i = 0; i < num_results; i++)
    1161             :   {
    1162             :     uint64_t serial_id;
    1163           0 :     struct TALER_AUDITORDB_DepositConfirmation dc = {
    1164           0 :       .master_public_key = *dcc->master_pub
    1165             :     };
    1166           0 :     struct GNUNET_PQ_ResultSpec rs[] = {
    1167           0 :       GNUNET_PQ_result_spec_uint64 ("serial_id",
    1168             :                                     &serial_id),
    1169           0 :       GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
    1170             :                                             &dc.h_contract_terms),
    1171           0 :       GNUNET_PQ_result_spec_auto_from_type ("h_extensions",
    1172             :                                             &dc.h_extensions),
    1173           0 :       GNUNET_PQ_result_spec_auto_from_type ("h_wire",
    1174             :                                             &dc.h_wire),
    1175           0 :       GNUNET_PQ_result_spec_timestamp ("exchange_timestamp",
    1176             :                                        &dc.exchange_timestamp),
    1177           0 :       GNUNET_PQ_result_spec_timestamp ("refund_deadline",
    1178             :                                        &dc.refund_deadline),
    1179           0 :       GNUNET_PQ_result_spec_timestamp ("wire_deadline",
    1180             :                                        &dc.wire_deadline),
    1181           0 :       TALER_PQ_RESULT_SPEC_AMOUNT ("amount_without_fee",
    1182             :                                    &dc.amount_without_fee),
    1183           0 :       GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
    1184             :                                             &dc.coin_pub),
    1185           0 :       GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
    1186             :                                             &dc.merchant),
    1187           0 :       GNUNET_PQ_result_spec_auto_from_type ("exchange_sig",
    1188             :                                             &dc.exchange_sig),
    1189           0 :       GNUNET_PQ_result_spec_auto_from_type ("exchange_pub",
    1190             :                                             &dc.exchange_pub),
    1191           0 :       GNUNET_PQ_result_spec_auto_from_type ("master_sig",
    1192             :                                             &dc.master_sig),
    1193             :       GNUNET_PQ_result_spec_end
    1194             :     };
    1195             : 
    1196           0 :     if (GNUNET_OK !=
    1197           0 :         GNUNET_PQ_extract_result (result,
    1198             :                                   rs,
    1199             :                                   i))
    1200             :     {
    1201           0 :       GNUNET_break (0);
    1202           0 :       dcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
    1203           0 :       return;
    1204             :     }
    1205           0 :     dcc->qs = i + 1;
    1206           0 :     if (GNUNET_OK !=
    1207           0 :         dcc->cb (dcc->cb_cls,
    1208             :                  serial_id,
    1209             :                  &dc))
    1210           0 :       break;
    1211             :   }
    1212             : }
    1213             : 
    1214             : 
    1215             : /**
    1216             :  * Get information about deposit confirmations from the database.
    1217             :  *
    1218             :  * @param cls the @e cls of this struct with the plugin-specific state
    1219             :  * @param master_public_key for which exchange do we want to get deposit confirmations
    1220             :  * @param start_id row/serial ID where to start the iteration (0 from
    1221             :  *                  the start, exclusive, i.e. serial_ids must start from 1)
    1222             :  * @param cb function to call with results
    1223             :  * @param cb_cls closure for @a cb
    1224             :  * @return query result status
    1225             :  */
    1226             : static enum GNUNET_DB_QueryStatus
    1227           0 : postgres_get_deposit_confirmations (
    1228             :   void *cls,
    1229             :   const struct TALER_MasterPublicKeyP *master_public_key,
    1230             :   uint64_t start_id,
    1231             :   TALER_AUDITORDB_DepositConfirmationCallback cb,
    1232             :   void *cb_cls)
    1233             : {
    1234           0 :   struct PostgresClosure *pg = cls;
    1235           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1236           0 :     GNUNET_PQ_query_param_auto_from_type (master_public_key),
    1237           0 :     GNUNET_PQ_query_param_uint64 (&start_id),
    1238             :     GNUNET_PQ_query_param_end
    1239             :   };
    1240           0 :   struct DepositConfirmationContext dcc = {
    1241             :     .master_pub = master_public_key,
    1242             :     .cb = cb,
    1243             :     .cb_cls = cb_cls,
    1244             :     .pg = pg
    1245             :   };
    1246             :   enum GNUNET_DB_QueryStatus qs;
    1247             : 
    1248           0 :   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
    1249             :                                              "auditor_deposit_confirmation_select",
    1250             :                                              params,
    1251             :                                              &deposit_confirmation_cb,
    1252             :                                              &dcc);
    1253           0 :   if (qs > 0)
    1254           0 :     return dcc.qs;
    1255           0 :   GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
    1256           0 :   return qs;
    1257             : }
    1258             : 
    1259             : 
    1260             : /**
    1261             :  * Insert information about the auditor's progress with an exchange's
    1262             :  * data.
    1263             :  *
    1264             :  * @param cls the @e cls of this struct with the plugin-specific state
    1265             :  * @param master_pub master key of the exchange
    1266             :  * @param ppr where is the auditor in processing
    1267             :  * @return transaction status code
    1268             :  */
    1269             : static enum GNUNET_DB_QueryStatus
    1270           0 : postgres_insert_auditor_progress_reserve (
    1271             :   void *cls,
    1272             :   const struct TALER_MasterPublicKeyP *master_pub,
    1273             :   const struct TALER_AUDITORDB_ProgressPointReserve *ppr)
    1274             : {
    1275           0 :   struct PostgresClosure *pg = cls;
    1276           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1277           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1278           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_in_serial_id),
    1279           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_out_serial_id),
    1280           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_recoup_serial_id),
    1281           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_close_serial_id),
    1282           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_purse_merges_serial_id),
    1283           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_purse_deposits_serial_id),
    1284           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_account_merges_serial_id),
    1285           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_history_requests_serial_id),
    1286           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_close_requests_serial_id),
    1287             :     GNUNET_PQ_query_param_end
    1288             :   };
    1289             : 
    1290           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1291             :                                              "auditor_progress_insert_reserve",
    1292             :                                              params);
    1293             : }
    1294             : 
    1295             : 
    1296             : /**
    1297             :  * Update information about the progress of the auditor.  There
    1298             :  * must be an existing record for the exchange.
    1299             :  *
    1300             :  * @param cls the @e cls of this struct with the plugin-specific state
    1301             :  * @param master_pub master key of the exchange
    1302             :  * @param ppr where is the auditor in processing
    1303             :  * @return transaction status code
    1304             :  */
    1305             : static enum GNUNET_DB_QueryStatus
    1306           0 : postgres_update_auditor_progress_reserve (
    1307             :   void *cls,
    1308             :   const struct TALER_MasterPublicKeyP *master_pub,
    1309             :   const struct TALER_AUDITORDB_ProgressPointReserve *ppr)
    1310             : {
    1311           0 :   struct PostgresClosure *pg = cls;
    1312           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1313           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_in_serial_id),
    1314           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_out_serial_id),
    1315           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_recoup_serial_id),
    1316           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_close_serial_id),
    1317           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_purse_merges_serial_id),
    1318           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_purse_deposits_serial_id),
    1319           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_account_merges_serial_id),
    1320           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_history_requests_serial_id),
    1321           0 :     GNUNET_PQ_query_param_uint64 (&ppr->last_close_requests_serial_id),
    1322           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1323             :     GNUNET_PQ_query_param_end
    1324             :   };
    1325             : 
    1326           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1327             :                                              "auditor_progress_update_reserve",
    1328             :                                              params);
    1329             : }
    1330             : 
    1331             : 
    1332             : /**
    1333             :  * Get information about the progress of the auditor.
    1334             :  *
    1335             :  * @param cls the @e cls of this struct with the plugin-specific state
    1336             :  * @param master_pub master key of the exchange
    1337             :  * @param[out] ppr set to where the auditor is in processing
    1338             :  * @return transaction status code
    1339             :  */
    1340             : static enum GNUNET_DB_QueryStatus
    1341           0 : postgres_get_auditor_progress_reserve (
    1342             :   void *cls,
    1343             :   const struct TALER_MasterPublicKeyP *master_pub,
    1344             :   struct TALER_AUDITORDB_ProgressPointReserve *ppr)
    1345             : {
    1346           0 :   struct PostgresClosure *pg = cls;
    1347           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1348           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1349             :     GNUNET_PQ_query_param_end
    1350             :   };
    1351           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    1352           0 :     GNUNET_PQ_result_spec_uint64 ("last_reserve_in_serial_id",
    1353             :                                   &ppr->last_reserve_in_serial_id),
    1354           0 :     GNUNET_PQ_result_spec_uint64 ("last_reserve_out_serial_id",
    1355             :                                   &ppr->last_reserve_out_serial_id),
    1356           0 :     GNUNET_PQ_result_spec_uint64 ("last_reserve_recoup_serial_id",
    1357             :                                   &ppr->last_reserve_recoup_serial_id),
    1358           0 :     GNUNET_PQ_result_spec_uint64 ("last_reserve_close_serial_id",
    1359             :                                   &ppr->last_reserve_close_serial_id),
    1360           0 :     GNUNET_PQ_result_spec_uint64 ("last_purse_merges_serial_id",
    1361             :                                   &ppr->last_purse_merges_serial_id),
    1362           0 :     GNUNET_PQ_result_spec_uint64 ("last_purse_deposits_serial_id",
    1363             :                                   &ppr->last_purse_deposits_serial_id),
    1364           0 :     GNUNET_PQ_result_spec_uint64 ("last_account_merges_serial_id",
    1365             :                                   &ppr->last_account_merges_serial_id),
    1366           0 :     GNUNET_PQ_result_spec_uint64 ("last_history_requests_serial_id",
    1367             :                                   &ppr->last_history_requests_serial_id),
    1368           0 :     GNUNET_PQ_result_spec_uint64 ("last_close_requests_serial_id",
    1369             :                                   &ppr->last_close_requests_serial_id),
    1370             :     GNUNET_PQ_result_spec_end
    1371             :   };
    1372             : 
    1373           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    1374             :                                                    "auditor_progress_select_reserve",
    1375             :                                                    params,
    1376             :                                                    rs);
    1377             : }
    1378             : 
    1379             : 
    1380             : /**
    1381             :  * Insert information about the auditor's progress with an exchange's
    1382             :  * data.
    1383             :  *
    1384             :  * @param cls the @e cls of this struct with the plugin-specific state
    1385             :  * @param master_pub master key of the exchange
    1386             :  * @param ppa where is the auditor in processing
    1387             :  * @return transaction status code
    1388             :  */
    1389             : static enum GNUNET_DB_QueryStatus
    1390           0 : postgres_insert_auditor_progress_aggregation (
    1391             :   void *cls,
    1392             :   const struct TALER_MasterPublicKeyP *master_pub,
    1393             :   const struct TALER_AUDITORDB_ProgressPointAggregation *ppa)
    1394             : {
    1395           0 :   struct PostgresClosure *pg = cls;
    1396           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1397           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1398           0 :     GNUNET_PQ_query_param_uint64 (&ppa->last_wire_out_serial_id),
    1399             :     GNUNET_PQ_query_param_end
    1400             :   };
    1401             : 
    1402           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1403             :                                              "auditor_progress_insert_aggregation",
    1404             :                                              params);
    1405             : }
    1406             : 
    1407             : 
    1408             : /**
    1409             :  * Update information about the progress of the auditor.  There
    1410             :  * must be an existing record for the exchange.
    1411             :  *
    1412             :  * @param cls the @e cls of this struct with the plugin-specific state
    1413             :  * @param master_pub master key of the exchange
    1414             :  * @param ppa where is the auditor in processing
    1415             :  * @return transaction status code
    1416             :  */
    1417             : static enum GNUNET_DB_QueryStatus
    1418           0 : postgres_update_auditor_progress_aggregation (
    1419             :   void *cls,
    1420             :   const struct TALER_MasterPublicKeyP *master_pub,
    1421             :   const struct TALER_AUDITORDB_ProgressPointAggregation *ppa)
    1422             : {
    1423           0 :   struct PostgresClosure *pg = cls;
    1424           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1425           0 :     GNUNET_PQ_query_param_uint64 (&ppa->last_wire_out_serial_id),
    1426           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1427             :     GNUNET_PQ_query_param_end
    1428             :   };
    1429             : 
    1430           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1431             :                                              "auditor_progress_update_aggregation",
    1432             :                                              params);
    1433             : }
    1434             : 
    1435             : 
    1436             : /**
    1437             :  * Get information about the progress of the auditor.
    1438             :  *
    1439             :  * @param cls the @e cls of this struct with the plugin-specific state
    1440             :  * @param master_pub master key of the exchange
    1441             :  * @param[out] ppa set to where the auditor is in processing
    1442             :  * @return transaction status code
    1443             :  */
    1444             : static enum GNUNET_DB_QueryStatus
    1445           0 : postgres_get_auditor_progress_aggregation (
    1446             :   void *cls,
    1447             :   const struct TALER_MasterPublicKeyP *master_pub,
    1448             :   struct TALER_AUDITORDB_ProgressPointAggregation *ppa)
    1449             : {
    1450           0 :   struct PostgresClosure *pg = cls;
    1451           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1452           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1453             :     GNUNET_PQ_query_param_end
    1454             :   };
    1455           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    1456           0 :     GNUNET_PQ_result_spec_uint64 ("last_wire_out_serial_id",
    1457             :                                   &ppa->last_wire_out_serial_id),
    1458             :     GNUNET_PQ_result_spec_end
    1459             :   };
    1460             : 
    1461           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    1462             :                                                    "auditor_progress_select_aggregation",
    1463             :                                                    params,
    1464             :                                                    rs);
    1465             : }
    1466             : 
    1467             : 
    1468             : /**
    1469             :  * Insert information about the auditor's progress with an exchange's
    1470             :  * data.
    1471             :  *
    1472             :  * @param cls the @e cls of this struct with the plugin-specific state
    1473             :  * @param master_pub master key of the exchange
    1474             :  * @param ppdc where is the auditor in processing
    1475             :  * @return transaction status code
    1476             :  */
    1477             : static enum GNUNET_DB_QueryStatus
    1478           0 : postgres_insert_auditor_progress_deposit_confirmation (
    1479             :   void *cls,
    1480             :   const struct TALER_MasterPublicKeyP *master_pub,
    1481             :   const struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc)
    1482             : {
    1483           0 :   struct PostgresClosure *pg = cls;
    1484           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1485           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1486           0 :     GNUNET_PQ_query_param_uint64 (&ppdc->last_deposit_confirmation_serial_id),
    1487             :     GNUNET_PQ_query_param_end
    1488             :   };
    1489             : 
    1490           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1491             :                                              "auditor_progress_insert_deposit_confirmation",
    1492             :                                              params);
    1493             : }
    1494             : 
    1495             : 
    1496             : /**
    1497             :  * Update information about the progress of the auditor.  There
    1498             :  * must be an existing record for the exchange.
    1499             :  *
    1500             :  * @param cls the @e cls of this struct with the plugin-specific state
    1501             :  * @param master_pub master key of the exchange
    1502             :  * @param ppdc where is the auditor in processing
    1503             :  * @return transaction status code
    1504             :  */
    1505             : static enum GNUNET_DB_QueryStatus
    1506           0 : postgres_update_auditor_progress_deposit_confirmation (
    1507             :   void *cls,
    1508             :   const struct TALER_MasterPublicKeyP *master_pub,
    1509             :   const struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc)
    1510             : {
    1511           0 :   struct PostgresClosure *pg = cls;
    1512           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1513           0 :     GNUNET_PQ_query_param_uint64 (&ppdc->last_deposit_confirmation_serial_id),
    1514           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1515             :     GNUNET_PQ_query_param_end
    1516             :   };
    1517             : 
    1518           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1519             :                                              "auditor_progress_update_deposit_confirmation",
    1520             :                                              params);
    1521             : }
    1522             : 
    1523             : 
    1524             : /**
    1525             :  * Get information about the progress of the auditor.
    1526             :  *
    1527             :  * @param cls the @e cls of this struct with the plugin-specific state
    1528             :  * @param master_pub master key of the exchange
    1529             :  * @param[out] ppdc set to where the auditor is in processing
    1530             :  * @return transaction status code
    1531             :  */
    1532             : static enum GNUNET_DB_QueryStatus
    1533           0 : postgres_get_auditor_progress_deposit_confirmation (
    1534             :   void *cls,
    1535             :   const struct TALER_MasterPublicKeyP *master_pub,
    1536             :   struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc)
    1537             : {
    1538           0 :   struct PostgresClosure *pg = cls;
    1539           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1540           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1541             :     GNUNET_PQ_query_param_end
    1542             :   };
    1543           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    1544           0 :     GNUNET_PQ_result_spec_uint64 ("last_deposit_confirmation_serial_id",
    1545             :                                   &ppdc->last_deposit_confirmation_serial_id),
    1546             :     GNUNET_PQ_result_spec_end
    1547             :   };
    1548             : 
    1549           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    1550             :                                                    "auditor_progress_select_deposit_confirmation",
    1551             :                                                    params,
    1552             :                                                    rs);
    1553             : }
    1554             : 
    1555             : 
    1556             : /**
    1557             :  * Insert information about the auditor's progress with an exchange's
    1558             :  * data.
    1559             :  *
    1560             :  * @param cls the @e cls of this struct with the plugin-specific state
    1561             :  * @param master_pub master key of the exchange
    1562             :  * @param ppc where is the auditor in processing
    1563             :  * @return transaction status code
    1564             :  */
    1565             : static enum GNUNET_DB_QueryStatus
    1566           0 : postgres_insert_auditor_progress_coin (
    1567             :   void *cls,
    1568             :   const struct TALER_MasterPublicKeyP *master_pub,
    1569             :   const struct TALER_AUDITORDB_ProgressPointCoin *ppc)
    1570             : {
    1571           0 :   struct PostgresClosure *pg = cls;
    1572           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1573           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1574           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_withdraw_serial_id),
    1575           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_deposit_serial_id),
    1576           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_melt_serial_id),
    1577           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_refund_serial_id),
    1578           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
    1579           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
    1580           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
    1581           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_purse_refunds_serial_id),
    1582             :     GNUNET_PQ_query_param_end
    1583             :   };
    1584             : 
    1585           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1586             :                                              "auditor_progress_insert_coin",
    1587             :                                              params);
    1588             : }
    1589             : 
    1590             : 
    1591             : /**
    1592             :  * Update information about the progress of the auditor.  There
    1593             :  * must be an existing record for the exchange.
    1594             :  *
    1595             :  * @param cls the @e cls of this struct with the plugin-specific state
    1596             :  * @param master_pub master key of the exchange
    1597             :  * @param ppc where is the auditor in processing
    1598             :  * @return transaction status code
    1599             :  */
    1600             : static enum GNUNET_DB_QueryStatus
    1601           0 : postgres_update_auditor_progress_coin (
    1602             :   void *cls,
    1603             :   const struct TALER_MasterPublicKeyP *master_pub,
    1604             :   const struct TALER_AUDITORDB_ProgressPointCoin *ppc)
    1605             : {
    1606           0 :   struct PostgresClosure *pg = cls;
    1607           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1608           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_withdraw_serial_id),
    1609           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_deposit_serial_id),
    1610           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_melt_serial_id),
    1611           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_refund_serial_id),
    1612           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
    1613           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
    1614           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
    1615           0 :     GNUNET_PQ_query_param_uint64 (&ppc->last_purse_refunds_serial_id),
    1616           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1617             :     GNUNET_PQ_query_param_end
    1618             :   };
    1619             : 
    1620           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1621             :                                              "auditor_progress_update_coin",
    1622             :                                              params);
    1623             : }
    1624             : 
    1625             : 
    1626             : /**
    1627             :  * Get information about the progress of the auditor.
    1628             :  *
    1629             :  * @param cls the @e cls of this struct with the plugin-specific state
    1630             :  * @param master_pub master key of the exchange
    1631             :  * @param[out] ppc set to where the auditor is in processing
    1632             :  * @return transaction status code
    1633             :  */
    1634             : static enum GNUNET_DB_QueryStatus
    1635           0 : postgres_get_auditor_progress_coin (
    1636             :   void *cls,
    1637             :   const struct TALER_MasterPublicKeyP *master_pub,
    1638             :   struct TALER_AUDITORDB_ProgressPointCoin *ppc)
    1639             : {
    1640           0 :   struct PostgresClosure *pg = cls;
    1641           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1642           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1643             :     GNUNET_PQ_query_param_end
    1644             :   };
    1645           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    1646           0 :     GNUNET_PQ_result_spec_uint64 ("last_withdraw_serial_id",
    1647             :                                   &ppc->last_withdraw_serial_id),
    1648           0 :     GNUNET_PQ_result_spec_uint64 ("last_deposit_serial_id",
    1649             :                                   &ppc->last_deposit_serial_id),
    1650           0 :     GNUNET_PQ_result_spec_uint64 ("last_melt_serial_id",
    1651             :                                   &ppc->last_melt_serial_id),
    1652           0 :     GNUNET_PQ_result_spec_uint64 ("last_refund_serial_id",
    1653             :                                   &ppc->last_refund_serial_id),
    1654           0 :     GNUNET_PQ_result_spec_uint64 ("last_recoup_serial_id",
    1655             :                                   &ppc->last_recoup_serial_id),
    1656           0 :     GNUNET_PQ_result_spec_uint64 ("last_recoup_refresh_serial_id",
    1657             :                                   &ppc->last_recoup_refresh_serial_id),
    1658           0 :     GNUNET_PQ_result_spec_uint64 ("last_purse_deposits_serial_id",
    1659             :                                   &ppc->last_purse_deposits_serial_id),
    1660           0 :     GNUNET_PQ_result_spec_uint64 ("last_purse_refunds_serial_id",
    1661             :                                   &ppc->last_purse_refunds_serial_id),
    1662             :     GNUNET_PQ_result_spec_end
    1663             :   };
    1664             : 
    1665           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    1666             :                                                    "auditor_progress_select_coin",
    1667             :                                                    params,
    1668             :                                                    rs);
    1669             : }
    1670             : 
    1671             : 
    1672             : /**
    1673             :  * Insert information about the auditor's progress with an exchange's
    1674             :  * data.
    1675             :  *
    1676             :  * @param cls the @e cls of this struct with the plugin-specific state
    1677             :  * @param master_pub master key of the exchange
    1678             :  * @param account_name name of the wire account we are auditing
    1679             :  * @param pp how far are we in the auditor's tables
    1680             :  * @param in_wire_off how far are we in the incoming wire transfers
    1681             :  * @param out_wire_off how far are we in the outgoing wire transfers
    1682             :  * @return transaction status code
    1683             :  */
    1684             : static enum GNUNET_DB_QueryStatus
    1685           0 : postgres_insert_wire_auditor_account_progress (
    1686             :   void *cls,
    1687             :   const struct TALER_MasterPublicKeyP *master_pub,
    1688             :   const char *account_name,
    1689             :   const struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
    1690             :   uint64_t in_wire_off,
    1691             :   uint64_t out_wire_off)
    1692             : {
    1693           0 :   struct PostgresClosure *pg = cls;
    1694           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1695           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1696           0 :     GNUNET_PQ_query_param_string (account_name),
    1697           0 :     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
    1698           0 :     GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id),
    1699           0 :     GNUNET_PQ_query_param_uint64 (&in_wire_off),
    1700           0 :     GNUNET_PQ_query_param_uint64 (&out_wire_off),
    1701             :     GNUNET_PQ_query_param_end
    1702             :   };
    1703             : 
    1704           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1705             :                                              "wire_auditor_account_progress_insert",
    1706             :                                              params);
    1707             : }
    1708             : 
    1709             : 
    1710             : /**
    1711             :  * Update information about the progress of the auditor.  There
    1712             :  * must be an existing record for the exchange.
    1713             :  *
    1714             :  * @param cls the @e cls of this struct with the plugin-specific state
    1715             :  * @param master_pub master key of the exchange
    1716             :  * @param account_name name of the wire account we are auditing
    1717             :  * @param pp where is the auditor in processing
    1718             :  * @param in_wire_off how far are we in the incoming wire transaction history
    1719             :  * @param out_wire_off how far are we in the outgoing wire transaction history
    1720             :  * @return transaction status code
    1721             :  */
    1722             : static enum GNUNET_DB_QueryStatus
    1723           0 : postgres_update_wire_auditor_account_progress (
    1724             :   void *cls,
    1725             :   const struct TALER_MasterPublicKeyP *master_pub,
    1726             :   const char *account_name,
    1727             :   const struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
    1728             :   uint64_t in_wire_off,
    1729             :   uint64_t out_wire_off)
    1730             : {
    1731           0 :   struct PostgresClosure *pg = cls;
    1732           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1733           0 :     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
    1734           0 :     GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id),
    1735           0 :     GNUNET_PQ_query_param_uint64 (&in_wire_off),
    1736           0 :     GNUNET_PQ_query_param_uint64 (&out_wire_off),
    1737           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1738           0 :     GNUNET_PQ_query_param_string (account_name),
    1739             :     GNUNET_PQ_query_param_end
    1740             :   };
    1741             : 
    1742           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1743             :                                              "wire_auditor_account_progress_update",
    1744             :                                              params);
    1745             : }
    1746             : 
    1747             : 
    1748             : /**
    1749             :  * Get information about the progress of the auditor.
    1750             :  *
    1751             :  * @param cls the @e cls of this struct with the plugin-specific state
    1752             :  * @param master_pub master key of the exchange
    1753             :  * @param account_name name of the wire account we are auditing
    1754             :  * @param[out] pp where is the auditor in processing
    1755             :  * @param[out] in_wire_off how far are we in the incoming wire transaction history
    1756             :  * @param[out] out_wire_off how far are we in the outgoing wire transaction history
    1757             :  * @return transaction status code
    1758             :  */
    1759             : static enum GNUNET_DB_QueryStatus
    1760           0 : postgres_get_wire_auditor_account_progress (
    1761             :   void *cls,
    1762             :   const struct TALER_MasterPublicKeyP *master_pub,
    1763             :   const char *account_name,
    1764             :   struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
    1765             :   uint64_t *in_wire_off,
    1766             :   uint64_t *out_wire_off)
    1767             : {
    1768           0 :   struct PostgresClosure *pg = cls;
    1769           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1770           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1771           0 :     GNUNET_PQ_query_param_string (account_name),
    1772             :     GNUNET_PQ_query_param_end
    1773             :   };
    1774           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    1775           0 :     GNUNET_PQ_result_spec_uint64 ("last_wire_reserve_in_serial_id",
    1776             :                                   &pp->last_reserve_in_serial_id),
    1777           0 :     GNUNET_PQ_result_spec_uint64 ("last_wire_wire_out_serial_id",
    1778             :                                   &pp->last_wire_out_serial_id),
    1779           0 :     GNUNET_PQ_result_spec_uint64 ("wire_in_off",
    1780             :                                   in_wire_off),
    1781           0 :     GNUNET_PQ_result_spec_uint64 ("wire_out_off",
    1782             :                                   out_wire_off),
    1783             :     GNUNET_PQ_result_spec_end
    1784             :   };
    1785             : 
    1786           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    1787             :                                                    "wire_auditor_account_progress_select",
    1788             :                                                    params,
    1789             :                                                    rs);
    1790             : }
    1791             : 
    1792             : 
    1793             : /**
    1794             :  * Insert information about the auditor's progress with an exchange's
    1795             :  * data.
    1796             :  *
    1797             :  * @param cls the @e cls of this struct with the plugin-specific state
    1798             :  * @param master_pub master key of the exchange
    1799             :  * @param pp where is the auditor in processing
    1800             :  * @return transaction status code
    1801             :  */
    1802             : static enum GNUNET_DB_QueryStatus
    1803           0 : postgres_insert_wire_auditor_progress (
    1804             :   void *cls,
    1805             :   const struct TALER_MasterPublicKeyP *master_pub,
    1806             :   const struct TALER_AUDITORDB_WireProgressPoint *pp)
    1807             : {
    1808           0 :   struct PostgresClosure *pg = cls;
    1809           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1810           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1811           0 :     GNUNET_PQ_query_param_timestamp (&pp->last_timestamp),
    1812           0 :     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_close_uuid),
    1813             :     GNUNET_PQ_query_param_end
    1814             :   };
    1815             : 
    1816           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1817             :                                              "wire_auditor_progress_insert",
    1818             :                                              params);
    1819             : }
    1820             : 
    1821             : 
    1822             : /**
    1823             :  * Update information about the progress of the auditor.  There
    1824             :  * must be an existing record for the exchange.
    1825             :  *
    1826             :  * @param cls the @e cls of this struct with the plugin-specific state
    1827             :  * @param master_pub master key of the exchange
    1828             :  * @param pp where is the auditor in processing
    1829             :  * @return transaction status code
    1830             :  */
    1831             : static enum GNUNET_DB_QueryStatus
    1832           0 : postgres_update_wire_auditor_progress (
    1833             :   void *cls,
    1834             :   const struct TALER_MasterPublicKeyP *master_pub,
    1835             :   const struct TALER_AUDITORDB_WireProgressPoint *pp)
    1836             : {
    1837           0 :   struct PostgresClosure *pg = cls;
    1838           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1839           0 :     GNUNET_PQ_query_param_timestamp (&pp->last_timestamp),
    1840           0 :     GNUNET_PQ_query_param_uint64 (&pp->last_reserve_close_uuid),
    1841           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1842             :     GNUNET_PQ_query_param_end
    1843             :   };
    1844             : 
    1845           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1846             :                                              "wire_auditor_progress_update",
    1847             :                                              params);
    1848             : }
    1849             : 
    1850             : 
    1851             : /**
    1852             :  * Get information about the progress of the auditor.
    1853             :  *
    1854             :  * @param cls the @e cls of this struct with the plugin-specific state
    1855             :  * @param master_pub master key of the exchange
    1856             :  * @param[out] pp set to where the auditor is in processing
    1857             :  * @return transaction status code
    1858             :  */
    1859             : static enum GNUNET_DB_QueryStatus
    1860           0 : postgres_get_wire_auditor_progress (
    1861             :   void *cls,
    1862             :   const struct TALER_MasterPublicKeyP *master_pub,
    1863             :   struct TALER_AUDITORDB_WireProgressPoint *pp)
    1864             : {
    1865           0 :   struct PostgresClosure *pg = cls;
    1866           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1867           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1868             :     GNUNET_PQ_query_param_end
    1869             :   };
    1870           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    1871           0 :     GNUNET_PQ_result_spec_timestamp ("last_timestamp",
    1872             :                                      &pp->last_timestamp),
    1873           0 :     GNUNET_PQ_result_spec_uint64 ("last_reserve_close_uuid",
    1874             :                                   &pp->last_reserve_close_uuid),
    1875             :     GNUNET_PQ_result_spec_end
    1876             :   };
    1877             : 
    1878           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    1879             :                                                    "wire_auditor_progress_select",
    1880             :                                                    params,
    1881             :                                                    rs);
    1882             : }
    1883             : 
    1884             : 
    1885             : /**
    1886             :  * Insert information about a reserve.  There must not be an
    1887             :  * existing record for the reserve.
    1888             :  *
    1889             :  * @param cls the @e cls of this struct with the plugin-specific state
    1890             :  * @param reserve_pub public key of the reserve
    1891             :  * @param master_pub master public key of the exchange
    1892             :  * @param reserve_balance amount stored in the reserve
    1893             :  * @param withdraw_fee_balance amount the exchange gained in withdraw fees
    1894             :  *                             due to withdrawals from this reserve
    1895             :  * @param expiration_date expiration date of the reserve
    1896             :  * @param origin_account where did the money in the reserve originally come from
    1897             :  * @return transaction status code
    1898             :  */
    1899             : static enum GNUNET_DB_QueryStatus
    1900           0 : postgres_insert_reserve_info (void *cls,
    1901             :                               const struct TALER_ReservePublicKeyP *reserve_pub,
    1902             :                               const struct TALER_MasterPublicKeyP *master_pub,
    1903             :                               const struct TALER_Amount *reserve_balance,
    1904             :                               const struct TALER_Amount *withdraw_fee_balance,
    1905             :                               struct GNUNET_TIME_Timestamp expiration_date,
    1906             :                               const char *origin_account)
    1907             : {
    1908           0 :   struct PostgresClosure *pg = cls;
    1909           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1910           0 :     GNUNET_PQ_query_param_auto_from_type (reserve_pub),
    1911           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1912           0 :     TALER_PQ_query_param_amount (reserve_balance),
    1913           0 :     TALER_PQ_query_param_amount (withdraw_fee_balance),
    1914           0 :     GNUNET_PQ_query_param_timestamp (&expiration_date),
    1915           0 :     GNUNET_PQ_query_param_string (origin_account),
    1916             :     GNUNET_PQ_query_param_end
    1917             :   };
    1918             : 
    1919           0 :   GNUNET_assert (GNUNET_YES ==
    1920             :                  TALER_amount_cmp_currency (reserve_balance,
    1921             :                                             withdraw_fee_balance));
    1922             : 
    1923           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1924             :                                              "auditor_reserves_insert",
    1925             :                                              params);
    1926             : }
    1927             : 
    1928             : 
    1929             : /**
    1930             :  * Update information about a reserve.  Destructively updates an
    1931             :  * existing record, which must already exist.
    1932             :  *
    1933             :  * @param cls the @e cls of this struct with the plugin-specific state
    1934             :  * @param reserve_pub public key of the reserve
    1935             :  * @param master_pub master public key of the exchange
    1936             :  * @param reserve_balance amount stored in the reserve
    1937             :  * @param withdraw_fee_balance amount the exchange gained in withdraw fees
    1938             :  *                             due to withdrawals from this reserve
    1939             :  * @param expiration_date expiration date of the reserve
    1940             :  * @return transaction status code
    1941             :  */
    1942             : static enum GNUNET_DB_QueryStatus
    1943           0 : postgres_update_reserve_info (void *cls,
    1944             :                               const struct TALER_ReservePublicKeyP *reserve_pub,
    1945             :                               const struct TALER_MasterPublicKeyP *master_pub,
    1946             :                               const struct TALER_Amount *reserve_balance,
    1947             :                               const struct TALER_Amount *withdraw_fee_balance,
    1948             :                               struct GNUNET_TIME_Timestamp expiration_date)
    1949             : {
    1950           0 :   struct PostgresClosure *pg = cls;
    1951           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1952           0 :     TALER_PQ_query_param_amount (reserve_balance),
    1953           0 :     TALER_PQ_query_param_amount (withdraw_fee_balance),
    1954           0 :     GNUNET_PQ_query_param_timestamp (&expiration_date),
    1955           0 :     GNUNET_PQ_query_param_auto_from_type (reserve_pub),
    1956           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1957             :     GNUNET_PQ_query_param_end
    1958             :   };
    1959             : 
    1960           0 :   GNUNET_assert (GNUNET_YES ==
    1961             :                  TALER_amount_cmp_currency (reserve_balance,
    1962             :                                             withdraw_fee_balance));
    1963             : 
    1964           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1965             :                                              "auditor_reserves_update",
    1966             :                                              params);
    1967             : }
    1968             : 
    1969             : 
    1970             : /**
    1971             :  * Delete information about a reserve.
    1972             :  *
    1973             :  * @param cls the @e cls of this struct with the plugin-specific state
    1974             :  * @param reserve_pub public key of the reserve
    1975             :  * @param master_pub master public key of the exchange
    1976             :  * @return transaction status code
    1977             :  */
    1978             : static enum GNUNET_DB_QueryStatus
    1979           0 : postgres_del_reserve_info (void *cls,
    1980             :                            const struct TALER_ReservePublicKeyP *reserve_pub,
    1981             :                            const struct TALER_MasterPublicKeyP *master_pub)
    1982             : {
    1983           0 :   struct PostgresClosure *pg = cls;
    1984           0 :   struct GNUNET_PQ_QueryParam params[] = {
    1985           0 :     GNUNET_PQ_query_param_auto_from_type (reserve_pub),
    1986           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    1987             :     GNUNET_PQ_query_param_end
    1988             :   };
    1989             : 
    1990           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    1991             :                                              "auditor_reserves_delete",
    1992             :                                              params);
    1993             : }
    1994             : 
    1995             : 
    1996             : /**
    1997             :  * Get information about a reserve.
    1998             :  *
    1999             :  * @param cls the @e cls of this struct with the plugin-specific state
    2000             :  * @param reserve_pub public key of the reserve
    2001             :  * @param master_pub master public key of the exchange
    2002             :  * @param[out] rowid which row did we get the information from
    2003             :  * @param[out] reserve_balance amount stored in the reserve
    2004             :  * @param[out] withdraw_fee_balance amount the exchange gained in withdraw fees
    2005             :  *                             due to withdrawals from this reserve
    2006             :  * @param[out] expiration_date expiration date of the reserve
    2007             :  * @param[out] sender_account from where did the money in the reserve originally come from
    2008             :  * @return transaction status code
    2009             :  */
    2010             : static enum GNUNET_DB_QueryStatus
    2011           0 : postgres_get_reserve_info (void *cls,
    2012             :                            const struct TALER_ReservePublicKeyP *reserve_pub,
    2013             :                            const struct TALER_MasterPublicKeyP *master_pub,
    2014             :                            uint64_t *rowid,
    2015             :                            struct TALER_Amount *reserve_balance,
    2016             :                            struct TALER_Amount *withdraw_fee_balance,
    2017             :                            struct GNUNET_TIME_Timestamp *expiration_date,
    2018             :                            char **sender_account)
    2019             : {
    2020           0 :   struct PostgresClosure *pg = cls;
    2021           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2022           0 :     GNUNET_PQ_query_param_auto_from_type (reserve_pub),
    2023           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2024             :     GNUNET_PQ_query_param_end
    2025             :   };
    2026           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    2027           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_balance", reserve_balance),
    2028           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("withdraw_fee_balance", withdraw_fee_balance),
    2029           0 :     GNUNET_PQ_result_spec_timestamp ("expiration_date", expiration_date),
    2030           0 :     GNUNET_PQ_result_spec_uint64 ("auditor_reserves_rowid", rowid),
    2031           0 :     GNUNET_PQ_result_spec_string ("origin_account", sender_account),
    2032             :     GNUNET_PQ_result_spec_end
    2033             :   };
    2034             : 
    2035           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    2036             :                                                    "auditor_reserves_select",
    2037             :                                                    params,
    2038             :                                                    rs);
    2039             : }
    2040             : 
    2041             : 
    2042             : /**
    2043             :  * Insert information about all reserves.  There must not be an
    2044             :  * existing record for the @a master_pub.
    2045             :  *
    2046             :  * @param cls the @e cls of this struct with the plugin-specific state
    2047             :  * @param master_pub master public key of the exchange
    2048             :  * @param reserve_balance amount stored in the reserve
    2049             :  * @param withdraw_fee_balance amount the exchange gained in withdraw fees
    2050             :  * @param purse_fee_balance amount the exchange gained in purse fees
    2051             :  * @param history_fee_balance amount the exchange gained in history fees
    2052             :  * @return transaction status code
    2053             :  */
    2054             : static enum GNUNET_DB_QueryStatus
    2055           0 : postgres_insert_reserve_summary (
    2056             :   void *cls,
    2057             :   const struct TALER_MasterPublicKeyP *master_pub,
    2058             :   const struct TALER_Amount *reserve_balance,
    2059             :   const struct TALER_Amount *withdraw_fee_balance,
    2060             :   const struct TALER_Amount *purse_fee_balance,
    2061             :   const struct TALER_Amount *history_fee_balance)
    2062             : {
    2063           0 :   struct PostgresClosure *pg = cls;
    2064           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2065           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2066           0 :     TALER_PQ_query_param_amount (reserve_balance),
    2067           0 :     TALER_PQ_query_param_amount (withdraw_fee_balance),
    2068           0 :     TALER_PQ_query_param_amount (purse_fee_balance),
    2069           0 :     TALER_PQ_query_param_amount (history_fee_balance),
    2070             :     GNUNET_PQ_query_param_end
    2071             :   };
    2072             : 
    2073           0 :   GNUNET_assert (GNUNET_YES ==
    2074             :                  TALER_amount_cmp_currency (reserve_balance,
    2075             :                                             withdraw_fee_balance));
    2076             : 
    2077           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2078             :                                              "auditor_reserve_balance_insert",
    2079             :                                              params);
    2080             : }
    2081             : 
    2082             : 
    2083             : /**
    2084             :  * Update information about all reserves.  Destructively updates an
    2085             :  * existing record, which must already exist.
    2086             :  *
    2087             :  * @param cls the @e cls of this struct with the plugin-specific state
    2088             :  * @param master_pub master public key of the exchange
    2089             :  * @param reserve_balance amount stored in the reserve
    2090             :  * @param withdraw_fee_balance amount the exchange gained in withdraw fees
    2091             :  *                             due to withdrawals from this reserve
    2092             :  * @param purse_fee_balance amount the exchange gained in purse fees
    2093             :  * @param history_fee_balance amount the exchange gained in history fees
    2094             :  * @return transaction status code
    2095             :  */
    2096             : static enum GNUNET_DB_QueryStatus
    2097           0 : postgres_update_reserve_summary (
    2098             :   void *cls,
    2099             :   const struct TALER_MasterPublicKeyP *master_pub,
    2100             :   const struct TALER_Amount *reserve_balance,
    2101             :   const struct TALER_Amount *withdraw_fee_balance,
    2102             :   const struct TALER_Amount *purse_fee_balance,
    2103             :   const struct TALER_Amount *history_fee_balance)
    2104             : {
    2105           0 :   struct PostgresClosure *pg = cls;
    2106           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2107           0 :     TALER_PQ_query_param_amount (reserve_balance),
    2108           0 :     TALER_PQ_query_param_amount (withdraw_fee_balance),
    2109           0 :     TALER_PQ_query_param_amount (purse_fee_balance),
    2110           0 :     TALER_PQ_query_param_amount (history_fee_balance),
    2111           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2112             :     GNUNET_PQ_query_param_end
    2113             :   };
    2114             : 
    2115           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2116             :                                              "auditor_reserve_balance_update",
    2117             :                                              params);
    2118             : }
    2119             : 
    2120             : 
    2121             : /**
    2122             :  * Get summary information about all reserves.
    2123             :  *
    2124             :  * @param cls the @e cls of this struct with the plugin-specific state
    2125             :  * @param master_pub master public key of the exchange
    2126             :  * @param[out] reserve_balance amount stored in reserves
    2127             :  * @param[out] withdraw_fee_balance amount the exchange gained in withdraw fees
    2128             :  * @param[out] purse_fee_balance amount the exchange gained in purse fees
    2129             :  * @param[out] history_fee_balance amount the exchange gained in history fees
    2130             :  * @return transaction status code
    2131             :  */
    2132             : static enum GNUNET_DB_QueryStatus
    2133           0 : postgres_get_reserve_summary (void *cls,
    2134             :                               const struct TALER_MasterPublicKeyP *master_pub,
    2135             :                               struct TALER_Amount *reserve_balance,
    2136             :                               struct TALER_Amount *withdraw_fee_balance,
    2137             :                               struct TALER_Amount *purse_fee_balance,
    2138             :                               struct TALER_Amount *history_fee_balance)
    2139             : {
    2140           0 :   struct PostgresClosure *pg = cls;
    2141           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2142           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2143             :     GNUNET_PQ_query_param_end
    2144             :   };
    2145           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    2146           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_balance", reserve_balance),
    2147           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("withdraw_fee_balance", withdraw_fee_balance),
    2148           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee_balance", purse_fee_balance),
    2149           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee_balance", history_fee_balance),
    2150             :     GNUNET_PQ_result_spec_end
    2151             :   };
    2152             : 
    2153           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    2154             :                                                    "auditor_reserve_balance_select",
    2155             :                                                    params,
    2156             :                                                    rs);
    2157             : }
    2158             : 
    2159             : 
    2160             : /**
    2161             :  * Insert information about exchange's wire fee balance. There must not be an
    2162             :  * existing record for the same @a master_pub.
    2163             :  *
    2164             :  * @param cls the @e cls of this struct with the plugin-specific state
    2165             :  * @param master_pub master public key of the exchange
    2166             :  * @param wire_fee_balance amount the exchange gained in wire fees
    2167             :  * @return transaction status code
    2168             :  */
    2169             : static enum GNUNET_DB_QueryStatus
    2170           0 : postgres_insert_wire_fee_summary (
    2171             :   void *cls,
    2172             :   const struct TALER_MasterPublicKeyP *master_pub,
    2173             :   const struct TALER_Amount *wire_fee_balance)
    2174             : {
    2175           0 :   struct PostgresClosure *pg = cls;
    2176           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2177           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2178           0 :     TALER_PQ_query_param_amount (wire_fee_balance),
    2179             :     GNUNET_PQ_query_param_end
    2180             :   };
    2181             : 
    2182           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2183             :                                              "auditor_wire_fee_balance_insert",
    2184             :                                              params);
    2185             : }
    2186             : 
    2187             : 
    2188             : /**
    2189             :  * Insert information about exchange's wire fee balance.  Destructively updates an
    2190             :  * existing record, which must already exist.
    2191             :  *
    2192             :  * @param cls the @e cls of this struct with the plugin-specific state
    2193             :  * @param master_pub master public key of the exchange
    2194             :  * @param wire_fee_balance amount the exchange gained in wire fees
    2195             :  * @return transaction status code
    2196             :  */
    2197             : static enum GNUNET_DB_QueryStatus
    2198           0 : postgres_update_wire_fee_summary (
    2199             :   void *cls,
    2200             :   const struct TALER_MasterPublicKeyP *master_pub,
    2201             :   const struct TALER_Amount *wire_fee_balance)
    2202             : {
    2203           0 :   struct PostgresClosure *pg = cls;
    2204           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2205           0 :     TALER_PQ_query_param_amount (wire_fee_balance),
    2206           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2207             :     GNUNET_PQ_query_param_end
    2208             :   };
    2209             : 
    2210           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2211             :                                              "auditor_wire_fee_balance_update",
    2212             :                                              params);
    2213             : }
    2214             : 
    2215             : 
    2216             : /**
    2217             :  * Get summary information about an exchanges wire fee balance.
    2218             :  *
    2219             :  * @param cls the @e cls of this struct with the plugin-specific state
    2220             :  * @param master_pub master public key of the exchange
    2221             :  * @param[out] wire_fee_balance set amount the exchange gained in wire fees
    2222             :  * @return transaction status code
    2223             :  */
    2224             : static enum GNUNET_DB_QueryStatus
    2225           0 : postgres_get_wire_fee_summary (void *cls,
    2226             :                                const struct TALER_MasterPublicKeyP *master_pub,
    2227             :                                struct TALER_Amount *wire_fee_balance)
    2228             : {
    2229           0 :   struct PostgresClosure *pg = cls;
    2230           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2231           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2232             :     GNUNET_PQ_query_param_end
    2233             :   };
    2234           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    2235           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee_balance",
    2236             :                                  wire_fee_balance),
    2237             :     GNUNET_PQ_result_spec_end
    2238             :   };
    2239             : 
    2240           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    2241             :                                                    "auditor_wire_fee_balance_select",
    2242             :                                                    params,
    2243             :                                                    rs);
    2244             : }
    2245             : 
    2246             : 
    2247             : /**
    2248             :  * Insert information about a denomination key's balances.  There
    2249             :  * must not be an existing record for the denomination key.
    2250             :  *
    2251             :  * @param cls the @e cls of this struct with the plugin-specific state
    2252             :  * @param denom_pub_hash hash of the denomination public key
    2253             :  * @param denom_balance value of coins outstanding with this denomination key
    2254             :  * @param denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
    2255             :  * @param denom_risk value of coins issued with this denomination key
    2256             :  * @param recoup_loss losses from recoup (if this denomination was revoked)
    2257             :  * @param num_issued how many coins of this denomination did the exchange blind-sign
    2258             :  * @return transaction status code
    2259             :  */
    2260             : static enum GNUNET_DB_QueryStatus
    2261           0 : postgres_insert_denomination_balance (
    2262             :   void *cls,
    2263             :   const struct TALER_DenominationHashP *denom_pub_hash,
    2264             :   const struct TALER_Amount *denom_balance,
    2265             :   const struct TALER_Amount *denom_loss,
    2266             :   const struct TALER_Amount *denom_risk,
    2267             :   const struct TALER_Amount *recoup_loss,
    2268             :   uint64_t num_issued)
    2269             : {
    2270           0 :   struct PostgresClosure *pg = cls;
    2271           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2272           0 :     GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
    2273           0 :     TALER_PQ_query_param_amount (denom_balance),
    2274           0 :     TALER_PQ_query_param_amount (denom_loss),
    2275           0 :     GNUNET_PQ_query_param_uint64 (&num_issued),
    2276           0 :     TALER_PQ_query_param_amount (denom_risk),
    2277           0 :     TALER_PQ_query_param_amount (recoup_loss),
    2278             :     GNUNET_PQ_query_param_end
    2279             :   };
    2280             : 
    2281           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2282             :                                              "auditor_denomination_pending_insert",
    2283             :                                              params);
    2284             : }
    2285             : 
    2286             : 
    2287             : /**
    2288             :  * Update information about a denomination key's balances.  There
    2289             :  * must be an existing record for the denomination key.
    2290             :  *
    2291             :  * @param cls the @e cls of this struct with the plugin-specific state
    2292             :  * @param denom_pub_hash hash of the denomination public key
    2293             :  * @param denom_balance value of coins outstanding with this denomination key
    2294             :  * @param denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
    2295             : * @param denom_risk value of coins issued with this denomination key
    2296             :  * @param recoup_loss losses from recoup (if this denomination was revoked)
    2297             :  * @param num_issued how many coins of this denomination did the exchange blind-sign
    2298             :  * @return transaction status code
    2299             :  */
    2300             : static enum GNUNET_DB_QueryStatus
    2301           0 : postgres_update_denomination_balance (
    2302             :   void *cls,
    2303             :   const struct TALER_DenominationHashP *denom_pub_hash,
    2304             :   const struct TALER_Amount *denom_balance,
    2305             :   const struct TALER_Amount *denom_loss,
    2306             :   const struct TALER_Amount *denom_risk,
    2307             :   const struct TALER_Amount *recoup_loss,
    2308             :   uint64_t num_issued)
    2309             : {
    2310           0 :   struct PostgresClosure *pg = cls;
    2311           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2312           0 :     TALER_PQ_query_param_amount (denom_balance),
    2313           0 :     TALER_PQ_query_param_amount (denom_loss),
    2314           0 :     GNUNET_PQ_query_param_uint64 (&num_issued),
    2315           0 :     TALER_PQ_query_param_amount (denom_risk),
    2316           0 :     TALER_PQ_query_param_amount (recoup_loss),
    2317           0 :     GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
    2318             :     GNUNET_PQ_query_param_end
    2319             :   };
    2320             : 
    2321           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2322             :                                              "auditor_denomination_pending_update",
    2323             :                                              params);
    2324             : }
    2325             : 
    2326             : 
    2327             : /**
    2328             :  * Get information about a denomination key's balances.
    2329             :  *
    2330             :  * @param cls the @e cls of this struct with the plugin-specific state
    2331             :  * @param denom_pub_hash hash of the denomination public key
    2332             :  * @param[out] denom_balance value of coins outstanding with this denomination key
    2333             :  * @param[out] denom_risk value of coins issued with this denomination key
    2334             :  * @param[out] denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
    2335             :  * @param[out] recoup_loss losses from recoup (if this denomination was revoked)
    2336             :  * @param[out] num_issued how many coins of this denomination did the exchange blind-sign
    2337             :  * @return transaction status code
    2338             :  */
    2339             : static enum GNUNET_DB_QueryStatus
    2340           0 : postgres_get_denomination_balance (
    2341             :   void *cls,
    2342             :   const struct TALER_DenominationHashP *denom_pub_hash,
    2343             :   struct TALER_Amount *denom_balance,
    2344             :   struct TALER_Amount *denom_loss,
    2345             :   struct TALER_Amount *denom_risk,
    2346             :   struct TALER_Amount *recoup_loss,
    2347             :   uint64_t *num_issued)
    2348             : {
    2349           0 :   struct PostgresClosure *pg = cls;
    2350           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2351           0 :     GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
    2352             :     GNUNET_PQ_query_param_end
    2353             :   };
    2354           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    2355           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("denom_balance", denom_balance),
    2356           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("denom_loss", denom_loss),
    2357           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("denom_risk", denom_risk),
    2358           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("recoup_loss", recoup_loss),
    2359           0 :     GNUNET_PQ_result_spec_uint64 ("num_issued", num_issued),
    2360             :     GNUNET_PQ_result_spec_end
    2361             :   };
    2362             : 
    2363           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    2364             :                                                    "auditor_denomination_pending_select",
    2365             :                                                    params,
    2366             :                                                    rs);
    2367             : }
    2368             : 
    2369             : 
    2370             : /**
    2371             :  * Insert information about an exchange's denomination balances.  There
    2372             :  * must not be an existing record for the exchange.
    2373             :  *
    2374             :  * @param cls the @e cls of this struct with the plugin-specific state
    2375             :  * @param master_pub master key of the exchange
    2376             :  * @param denom_balance value of coins outstanding with this denomination key
    2377             :  * @param deposit_fee_balance total deposit fees collected for this DK
    2378             :  * @param melt_fee_balance total melt fees collected for this DK
    2379             :  * @param refund_fee_balance total refund fees collected for this DK
    2380             :  * @param risk maximum risk exposure of the exchange
    2381             :  * @param loss materialized @a risk from recoup
    2382             :  * @param irregular_recoup recoups on non-revoked coins
    2383             :  * @return transaction status code
    2384             :  */
    2385             : static enum GNUNET_DB_QueryStatus
    2386           0 : postgres_insert_balance_summary (
    2387             :   void *cls,
    2388             :   const struct TALER_MasterPublicKeyP *master_pub,
    2389             :   const struct TALER_Amount *denom_balance,
    2390             :   const struct TALER_Amount *deposit_fee_balance,
    2391             :   const struct TALER_Amount *melt_fee_balance,
    2392             :   const struct TALER_Amount *refund_fee_balance,
    2393             :   const struct TALER_Amount *risk,
    2394             :   const struct TALER_Amount *loss,
    2395             :   const struct TALER_Amount *irregular_recoup)
    2396             : {
    2397           0 :   struct PostgresClosure *pg = cls;
    2398           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2399           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2400           0 :     TALER_PQ_query_param_amount (denom_balance),
    2401           0 :     TALER_PQ_query_param_amount (deposit_fee_balance),
    2402           0 :     TALER_PQ_query_param_amount (melt_fee_balance),
    2403           0 :     TALER_PQ_query_param_amount (refund_fee_balance),
    2404           0 :     TALER_PQ_query_param_amount (risk),
    2405           0 :     TALER_PQ_query_param_amount (loss),
    2406           0 :     TALER_PQ_query_param_amount (irregular_recoup),
    2407             :     GNUNET_PQ_query_param_end
    2408             :   };
    2409             : 
    2410           0 :   GNUNET_assert (GNUNET_YES ==
    2411             :                  TALER_amount_cmp_currency (denom_balance,
    2412             :                                             deposit_fee_balance));
    2413           0 :   GNUNET_assert (GNUNET_YES ==
    2414             :                  TALER_amount_cmp_currency (denom_balance,
    2415             :                                             melt_fee_balance));
    2416             : 
    2417           0 :   GNUNET_assert (GNUNET_YES ==
    2418             :                  TALER_amount_cmp_currency (denom_balance,
    2419             :                                             refund_fee_balance));
    2420             : 
    2421           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2422             :                                              "auditor_balance_summary_insert",
    2423             :                                              params);
    2424             : }
    2425             : 
    2426             : 
    2427             : /**
    2428             :  * Update information about an exchange's denomination balances.  There
    2429             :  * must be an existing record for the exchange.
    2430             :  *
    2431             :  * @param cls the @e cls of this struct with the plugin-specific state
    2432             :  * @param master_pub master key of the exchange
    2433             :  * @param denom_balance value of coins outstanding with this denomination key
    2434             :  * @param deposit_fee_balance total deposit fees collected for this DK
    2435             :  * @param melt_fee_balance total melt fees collected for this DK
    2436             :  * @param refund_fee_balance total refund fees collected for this DK
    2437             :  * @param risk maximum risk exposure of the exchange
    2438             :  * @param loss materialized @a risk from recoup
    2439             :  * @param irregular_recoup recoups made on non-revoked coins
    2440             :  * @return transaction status code
    2441             :  */
    2442             : static enum GNUNET_DB_QueryStatus
    2443           0 : postgres_update_balance_summary (
    2444             :   void *cls,
    2445             :   const struct TALER_MasterPublicKeyP *master_pub,
    2446             :   const struct TALER_Amount *denom_balance,
    2447             :   const struct TALER_Amount *deposit_fee_balance,
    2448             :   const struct TALER_Amount *melt_fee_balance,
    2449             :   const struct TALER_Amount *refund_fee_balance,
    2450             :   const struct TALER_Amount *risk,
    2451             :   const struct TALER_Amount *loss,
    2452             :   const struct TALER_Amount *irregular_recoup)
    2453             : {
    2454           0 :   struct PostgresClosure *pg = cls;
    2455           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2456           0 :     TALER_PQ_query_param_amount (denom_balance),
    2457           0 :     TALER_PQ_query_param_amount (deposit_fee_balance),
    2458           0 :     TALER_PQ_query_param_amount (melt_fee_balance),
    2459           0 :     TALER_PQ_query_param_amount (refund_fee_balance),
    2460           0 :     TALER_PQ_query_param_amount (risk),
    2461           0 :     TALER_PQ_query_param_amount (loss),
    2462           0 :     TALER_PQ_query_param_amount (irregular_recoup),
    2463           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2464             :     GNUNET_PQ_query_param_end
    2465             :   };
    2466             : 
    2467           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2468             :                                              "auditor_balance_summary_update",
    2469             :                                              params);
    2470             : }
    2471             : 
    2472             : 
    2473             : /**
    2474             :  * Get information about an exchange's denomination balances.
    2475             :  *
    2476             :  * @param cls the @e cls of this struct with the plugin-specific state
    2477             :  * @param master_pub master key of the exchange
    2478             :  * @param[out] denom_balance value of coins outstanding with this denomination key
    2479             :  * @param[out] deposit_fee_balance total deposit fees collected for this DK
    2480             :  * @param[out] melt_fee_balance total melt fees collected for this DK
    2481             :  * @param[out] refund_fee_balance total refund fees collected for this DK
    2482             :  * @param[out] risk maximum risk exposure of the exchange
    2483             :  * @param[out] loss losses from recoup (on revoked denominations)
    2484             :  * @param[out] irregular_recoup recoups on NOT revoked denominations
    2485             :  * @return transaction status code
    2486             :  */
    2487             : static enum GNUNET_DB_QueryStatus
    2488           0 : postgres_get_balance_summary (void *cls,
    2489             :                               const struct TALER_MasterPublicKeyP *master_pub,
    2490             :                               struct TALER_Amount *denom_balance,
    2491             :                               struct TALER_Amount *deposit_fee_balance,
    2492             :                               struct TALER_Amount *melt_fee_balance,
    2493             :                               struct TALER_Amount *refund_fee_balance,
    2494             :                               struct TALER_Amount *risk,
    2495             :                               struct TALER_Amount *loss,
    2496             :                               struct TALER_Amount *irregular_recoup)
    2497             : {
    2498           0 :   struct PostgresClosure *pg = cls;
    2499           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2500           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2501             :     GNUNET_PQ_query_param_end
    2502             :   };
    2503           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    2504           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("denom_balance", denom_balance),
    2505           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee_balance", deposit_fee_balance),
    2506           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("melt_fee_balance", melt_fee_balance),
    2507           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("refund_fee_balance", refund_fee_balance),
    2508           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("risk", risk),
    2509           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("loss", loss),
    2510           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("irregular_recoup", irregular_recoup),
    2511             :     GNUNET_PQ_result_spec_end
    2512             :   };
    2513             : 
    2514           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    2515             :                                                    "auditor_balance_summary_select",
    2516             :                                                    params,
    2517             :                                                    rs);
    2518             : }
    2519             : 
    2520             : 
    2521             : /**
    2522             :  * Insert information about an exchange's historic
    2523             :  * revenue about a denomination key.
    2524             :  *
    2525             :  * @param cls the @e cls of this struct with the plugin-specific state
    2526             :  * @param master_pub master key of the exchange
    2527             :  * @param denom_pub_hash hash of the denomination key
    2528             :  * @param revenue_timestamp when did this profit get realized
    2529             :  * @param revenue_balance what was the total profit made from
    2530             :  *                        deposit fees, melting fees, refresh fees
    2531             :  *                        and coins that were never returned?
    2532             :  * @param loss_balance total losses suffered by the exchange at the time
    2533             :  * @return transaction status code
    2534             :  */
    2535             : static enum GNUNET_DB_QueryStatus
    2536           0 : postgres_insert_historic_denom_revenue (
    2537             :   void *cls,
    2538             :   const struct TALER_MasterPublicKeyP *master_pub,
    2539             :   const struct TALER_DenominationHashP *denom_pub_hash,
    2540             :   struct GNUNET_TIME_Timestamp revenue_timestamp,
    2541             :   const struct TALER_Amount *revenue_balance,
    2542             :   const struct TALER_Amount *loss_balance)
    2543             : {
    2544           0 :   struct PostgresClosure *pg = cls;
    2545           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2546           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2547           0 :     GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
    2548           0 :     GNUNET_PQ_query_param_timestamp (&revenue_timestamp),
    2549           0 :     TALER_PQ_query_param_amount (revenue_balance),
    2550           0 :     TALER_PQ_query_param_amount (loss_balance),
    2551             :     GNUNET_PQ_query_param_end
    2552             :   };
    2553             : 
    2554           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2555             :                                              "auditor_historic_denomination_revenue_insert",
    2556             :                                              params);
    2557             : }
    2558             : 
    2559             : 
    2560             : /**
    2561             :  * Closure for #historic_denom_revenue_cb().
    2562             :  */
    2563             : struct HistoricDenomRevenueContext
    2564             : {
    2565             :   /**
    2566             :    * Function to call for each result.
    2567             :    */
    2568             :   TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb;
    2569             : 
    2570             :   /**
    2571             :    * Closure for @e cb.
    2572             :    */
    2573             :   void *cb_cls;
    2574             : 
    2575             :   /**
    2576             :    * Plugin context.
    2577             :    */
    2578             :   struct PostgresClosure *pg;
    2579             : 
    2580             :   /**
    2581             :    * Number of results processed.
    2582             :    */
    2583             :   enum GNUNET_DB_QueryStatus qs;
    2584             : };
    2585             : 
    2586             : 
    2587             : /**
    2588             :  * Helper function for #postgres_select_historic_denom_revenue().
    2589             :  * To be called with the results of a SELECT statement
    2590             :  * that has returned @a num_results results.
    2591             :  *
    2592             :  * @param cls closure of type `struct HistoricRevenueContext *`
    2593             :  * @param result the postgres result
    2594             :  * @param num_results the number of results in @a result
    2595             :  */
    2596             : static void
    2597           0 : historic_denom_revenue_cb (void *cls,
    2598             :                            PGresult *result,
    2599             :                            unsigned int num_results)
    2600             : {
    2601           0 :   struct HistoricDenomRevenueContext *hrc = cls;
    2602           0 :   struct PostgresClosure *pg = hrc->pg;
    2603             : 
    2604           0 :   for (unsigned int i = 0; i < num_results; i++)
    2605             :   {
    2606             :     struct TALER_DenominationHashP denom_pub_hash;
    2607             :     struct GNUNET_TIME_Timestamp revenue_timestamp;
    2608             :     struct TALER_Amount revenue_balance;
    2609             :     struct TALER_Amount loss;
    2610           0 :     struct GNUNET_PQ_ResultSpec rs[] = {
    2611           0 :       GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
    2612             :                                             &denom_pub_hash),
    2613           0 :       GNUNET_PQ_result_spec_timestamp ("revenue_timestamp",
    2614             :                                        &revenue_timestamp),
    2615           0 :       TALER_PQ_RESULT_SPEC_AMOUNT ("revenue_balance",
    2616             :                                    &revenue_balance),
    2617           0 :       TALER_PQ_RESULT_SPEC_AMOUNT ("loss_balance",
    2618             :                                    &loss),
    2619             :       GNUNET_PQ_result_spec_end
    2620             :     };
    2621             : 
    2622           0 :     if (GNUNET_OK !=
    2623           0 :         GNUNET_PQ_extract_result (result,
    2624             :                                   rs,
    2625             :                                   i))
    2626             :     {
    2627           0 :       GNUNET_break (0);
    2628           0 :       hrc->qs = GNUNET_DB_STATUS_HARD_ERROR;
    2629           0 :       return;
    2630             :     }
    2631             : 
    2632           0 :     hrc->qs = i + 1;
    2633           0 :     if (GNUNET_OK !=
    2634           0 :         hrc->cb (hrc->cb_cls,
    2635             :                  &denom_pub_hash,
    2636             :                  revenue_timestamp,
    2637             :                  &revenue_balance,
    2638             :                  &loss))
    2639           0 :       break;
    2640             :   }
    2641             : }
    2642             : 
    2643             : 
    2644             : /**
    2645             :  * Obtain all of the historic denomination key revenue
    2646             :  * of the given @a master_pub.
    2647             :  *
    2648             :  * @param cls the @e cls of this struct with the plugin-specific state
    2649             :  * @param master_pub master key of the exchange
    2650             :  * @param cb function to call with the results
    2651             :  * @param cb_cls closure for @a cb
    2652             :  * @return transaction status code
    2653             :  */
    2654             : static enum GNUNET_DB_QueryStatus
    2655           0 : postgres_select_historic_denom_revenue (
    2656             :   void *cls,
    2657             :   const struct TALER_MasterPublicKeyP *master_pub,
    2658             :   TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb,
    2659             :   void *cb_cls)
    2660             : {
    2661           0 :   struct PostgresClosure *pg = cls;
    2662           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2663           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2664             :     GNUNET_PQ_query_param_end
    2665             :   };
    2666           0 :   struct HistoricDenomRevenueContext hrc = {
    2667             :     .cb = cb,
    2668             :     .cb_cls = cb_cls,
    2669             :     .pg = pg
    2670             :   };
    2671             :   enum GNUNET_DB_QueryStatus qs;
    2672             : 
    2673           0 :   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
    2674             :                                              "auditor_historic_denomination_revenue_select",
    2675             :                                              params,
    2676             :                                              &historic_denom_revenue_cb,
    2677             :                                              &hrc);
    2678           0 :   if (qs <= 0)
    2679           0 :     return qs;
    2680           0 :   return hrc.qs;
    2681             : }
    2682             : 
    2683             : 
    2684             : /**
    2685             :  * Insert information about an exchange's historic revenue from reserves.
    2686             :  *
    2687             :  * @param cls the @e cls of this struct with the plugin-specific state
    2688             :  * @param master_pub master key of the exchange
    2689             :  * @param start_time beginning of aggregated time interval
    2690             :  * @param end_time end of aggregated time interval
    2691             :  * @param reserve_profits total profits made
    2692             :  * @return transaction status code
    2693             :  */
    2694             : static enum GNUNET_DB_QueryStatus
    2695           0 : postgres_insert_historic_reserve_revenue (
    2696             :   void *cls,
    2697             :   const struct TALER_MasterPublicKeyP *master_pub,
    2698             :   struct GNUNET_TIME_Timestamp start_time,
    2699             :   struct GNUNET_TIME_Timestamp end_time,
    2700             :   const struct TALER_Amount *reserve_profits)
    2701             : {
    2702           0 :   struct PostgresClosure *pg = cls;
    2703           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2704           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2705           0 :     GNUNET_PQ_query_param_timestamp (&start_time),
    2706           0 :     GNUNET_PQ_query_param_timestamp (&end_time),
    2707           0 :     TALER_PQ_query_param_amount (reserve_profits),
    2708             :     GNUNET_PQ_query_param_end
    2709             :   };
    2710             : 
    2711           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2712             :                                              "auditor_historic_reserve_summary_insert",
    2713             :                                              params);
    2714             : }
    2715             : 
    2716             : 
    2717             : /**
    2718             :  * Closure for #historic_reserve_revenue_cb().
    2719             :  */
    2720             : struct HistoricReserveRevenueContext
    2721             : {
    2722             :   /**
    2723             :    * Function to call for each result.
    2724             :    */
    2725             :   TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb;
    2726             : 
    2727             :   /**
    2728             :    * Closure for @e cb.
    2729             :    */
    2730             :   void *cb_cls;
    2731             : 
    2732             :   /**
    2733             :    * Plugin context.
    2734             :    */
    2735             :   struct PostgresClosure *pg;
    2736             : 
    2737             :   /**
    2738             :    * Number of results processed.
    2739             :    */
    2740             :   enum GNUNET_DB_QueryStatus qs;
    2741             : };
    2742             : 
    2743             : 
    2744             : /**
    2745             :  * Helper function for #postgres_select_historic_reserve_revenue().
    2746             :  * To be called with the results of a SELECT statement
    2747             :  * that has returned @a num_results results.
    2748             :  *
    2749             :  * @param cls closure of type `struct HistoricRevenueContext *`
    2750             :  * @param result the postgres result
    2751             :  * @param num_results the number of results in @a result
    2752             :  */
    2753             : static void
    2754           0 : historic_reserve_revenue_cb (void *cls,
    2755             :                              PGresult *result,
    2756             :                              unsigned int num_results)
    2757             : {
    2758           0 :   struct HistoricReserveRevenueContext *hrc = cls;
    2759           0 :   struct PostgresClosure *pg = hrc->pg;
    2760             : 
    2761           0 :   for (unsigned int i = 0; i < num_results; i++)
    2762             :   {
    2763             :     struct GNUNET_TIME_Timestamp start_date;
    2764             :     struct GNUNET_TIME_Timestamp end_date;
    2765             :     struct TALER_Amount reserve_profits;
    2766           0 :     struct GNUNET_PQ_ResultSpec rs[] = {
    2767           0 :       GNUNET_PQ_result_spec_timestamp ("start_date",
    2768             :                                        &start_date),
    2769           0 :       GNUNET_PQ_result_spec_timestamp ("end_date",
    2770             :                                        &end_date),
    2771           0 :       TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_profits",
    2772             :                                    &reserve_profits),
    2773             :       GNUNET_PQ_result_spec_end
    2774             :     };
    2775             : 
    2776           0 :     if (GNUNET_OK !=
    2777           0 :         GNUNET_PQ_extract_result (result,
    2778             :                                   rs,
    2779             :                                   i))
    2780             :     {
    2781           0 :       GNUNET_break (0);
    2782           0 :       hrc->qs = GNUNET_DB_STATUS_HARD_ERROR;
    2783           0 :       return;
    2784             :     }
    2785           0 :     hrc->qs = i + 1;
    2786           0 :     if (GNUNET_OK !=
    2787           0 :         hrc->cb (hrc->cb_cls,
    2788             :                  start_date,
    2789             :                  end_date,
    2790             :                  &reserve_profits))
    2791           0 :       break;
    2792             :   }
    2793             : }
    2794             : 
    2795             : 
    2796             : /**
    2797             :  * Return information about an exchange's historic revenue from reserves.
    2798             :  *
    2799             :  * @param cls the @e cls of this struct with the plugin-specific state
    2800             :  * @param master_pub master key of the exchange
    2801             :  * @param cb function to call with results
    2802             :  * @param cb_cls closure for @a cb
    2803             :  * @return transaction status code
    2804             :  */
    2805             : static enum GNUNET_DB_QueryStatus
    2806           0 : postgres_select_historic_reserve_revenue (
    2807             :   void *cls,
    2808             :   const struct TALER_MasterPublicKeyP *master_pub,
    2809             :   TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb,
    2810             :   void *cb_cls)
    2811             : {
    2812           0 :   struct PostgresClosure *pg = cls;
    2813           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2814           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2815             :     GNUNET_PQ_query_param_end
    2816             :   };
    2817             :   enum GNUNET_DB_QueryStatus qs;
    2818           0 :   struct HistoricReserveRevenueContext hrc = {
    2819             :     .cb = cb,
    2820             :     .cb_cls = cb_cls,
    2821             :     .pg = pg
    2822             :   };
    2823             : 
    2824           0 :   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
    2825             :                                              "auditor_historic_reserve_summary_select",
    2826             :                                              params,
    2827             :                                              &historic_reserve_revenue_cb,
    2828             :                                              &hrc);
    2829           0 :   if (0 >= qs)
    2830           0 :     return qs;
    2831           0 :   return hrc.qs;
    2832             : }
    2833             : 
    2834             : 
    2835             : /**
    2836             :  * Insert information about the predicted exchange's bank
    2837             :  * account balance.
    2838             :  *
    2839             :  * @param cls the @e cls of this struct with the plugin-specific state
    2840             :  * @param master_pub master key of the exchange
    2841             :  * @param balance what the bank account balance of the exchange should show
    2842             :  * @param drained amount that was drained in profits
    2843             :  * @return transaction status code
    2844             :  */
    2845             : static enum GNUNET_DB_QueryStatus
    2846           0 : postgres_insert_predicted_result (
    2847             :   void *cls,
    2848             :   const struct TALER_MasterPublicKeyP *master_pub,
    2849             :   const struct TALER_Amount *balance,
    2850             :   const struct TALER_Amount *drained)
    2851             : {
    2852           0 :   struct PostgresClosure *pg = cls;
    2853           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2854           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2855           0 :     TALER_PQ_query_param_amount (balance),
    2856           0 :     TALER_PQ_query_param_amount (drained),
    2857             :     GNUNET_PQ_query_param_end
    2858             :   };
    2859             : 
    2860           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2861             :                                              "auditor_predicted_result_insert",
    2862             :                                              params);
    2863             : }
    2864             : 
    2865             : 
    2866             : /**
    2867             :  * Update information about an exchange's predicted balance.  There
    2868             :  * must be an existing record for the exchange.
    2869             :  *
    2870             :  * @param cls the @e cls of this struct with the plugin-specific state
    2871             :  * @param master_pub master key of the exchange
    2872             :  * @param balance what the bank account balance of the exchange should show
    2873             :  * @param drained amount that was drained in profits
    2874             :  * @return transaction status code
    2875             :  */
    2876             : static enum GNUNET_DB_QueryStatus
    2877           0 : postgres_update_predicted_result (
    2878             :   void *cls,
    2879             :   const struct TALER_MasterPublicKeyP *master_pub,
    2880             :   const struct TALER_Amount *balance,
    2881             :   const struct TALER_Amount *drained)
    2882             : {
    2883           0 :   struct PostgresClosure *pg = cls;
    2884           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2885           0 :     TALER_PQ_query_param_amount (balance),
    2886           0 :     TALER_PQ_query_param_amount (drained),
    2887           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2888             :     GNUNET_PQ_query_param_end
    2889             :   };
    2890             : 
    2891           0 :   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    2892             :                                              "auditor_predicted_result_update",
    2893             :                                              params);
    2894             : }
    2895             : 
    2896             : 
    2897             : /**
    2898             :  * Get an exchange's predicted balance.
    2899             :  *
    2900             :  * @param cls the @e cls of this struct with the plugin-specific state
    2901             :  * @param master_pub master key of the exchange
    2902             :  * @param[out] balance expected bank account balance of the exchange
    2903             :  * @param[out] drained amount drained so far
    2904             :  * @return transaction status code
    2905             :  */
    2906             : static enum GNUNET_DB_QueryStatus
    2907           0 : postgres_get_predicted_balance (void *cls,
    2908             :                                 const struct TALER_MasterPublicKeyP *master_pub,
    2909             :                                 struct TALER_Amount *balance,
    2910             :                                 struct TALER_Amount *drained)
    2911             : {
    2912           0 :   struct PostgresClosure *pg = cls;
    2913           0 :   struct GNUNET_PQ_QueryParam params[] = {
    2914           0 :     GNUNET_PQ_query_param_auto_from_type (master_pub),
    2915             :     GNUNET_PQ_query_param_end
    2916             :   };
    2917           0 :   struct GNUNET_PQ_ResultSpec rs[] = {
    2918           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
    2919             :                                  balance),
    2920           0 :     TALER_PQ_RESULT_SPEC_AMOUNT ("drained",
    2921             :                                  drained),
    2922             :     GNUNET_PQ_result_spec_end
    2923             :   };
    2924             : 
    2925           0 :   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    2926             :                                                    "auditor_predicted_result_select",
    2927             :                                                    params,
    2928             :                                                    rs);
    2929             : }
    2930             : 
    2931             : 
    2932             : /**
    2933             :  * Initialize Postgres database subsystem.
    2934             :  *
    2935             :  * @param cls a configuration instance
    2936             :  * @return NULL on error, otherwise a `struct TALER_AUDITORDB_Plugin`
    2937             :  */
    2938             : void *
    2939           1 : libtaler_plugin_auditordb_postgres_init (void *cls)
    2940             : {
    2941           1 :   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
    2942             :   struct PostgresClosure *pg;
    2943             :   struct TALER_AUDITORDB_Plugin *plugin;
    2944             : 
    2945           1 :   pg = GNUNET_new (struct PostgresClosure);
    2946           1 :   pg->cfg = cfg;
    2947           1 :   if (GNUNET_OK !=
    2948           1 :       TALER_config_get_currency (cfg,
    2949             :                                  &pg->currency))
    2950             :   {
    2951           0 :     GNUNET_free (pg);
    2952           0 :     return NULL;
    2953             :   }
    2954           1 :   plugin = GNUNET_new (struct TALER_AUDITORDB_Plugin);
    2955           1 :   plugin->cls = pg;
    2956           1 :   plugin->preflight = &postgres_preflight;
    2957           1 :   plugin->drop_tables = &postgres_drop_tables;
    2958           1 :   plugin->create_tables = &postgres_create_tables;
    2959           1 :   plugin->start = &postgres_start;
    2960           1 :   plugin->commit = &postgres_commit;
    2961           1 :   plugin->rollback = &postgres_rollback;
    2962           1 :   plugin->gc = &postgres_gc;
    2963             : 
    2964           1 :   plugin->insert_exchange = &postgres_insert_exchange;
    2965           1 :   plugin->delete_exchange = &postgres_delete_exchange;
    2966           1 :   plugin->list_exchanges = &postgres_list_exchanges;
    2967           1 :   plugin->insert_exchange_signkey = &postgres_insert_exchange_signkey;
    2968           1 :   plugin->insert_deposit_confirmation = &postgres_insert_deposit_confirmation;
    2969           1 :   plugin->get_deposit_confirmations = &postgres_get_deposit_confirmations;
    2970             : 
    2971           1 :   plugin->get_auditor_progress_reserve = &postgres_get_auditor_progress_reserve;
    2972           1 :   plugin->update_auditor_progress_reserve =
    2973             :     &postgres_update_auditor_progress_reserve;
    2974           1 :   plugin->insert_auditor_progress_reserve =
    2975             :     &postgres_insert_auditor_progress_reserve;
    2976           1 :   plugin->get_auditor_progress_aggregation =
    2977             :     &postgres_get_auditor_progress_aggregation;
    2978           1 :   plugin->update_auditor_progress_aggregation =
    2979             :     &postgres_update_auditor_progress_aggregation;
    2980           1 :   plugin->insert_auditor_progress_aggregation =
    2981             :     &postgres_insert_auditor_progress_aggregation;
    2982           1 :   plugin->get_auditor_progress_deposit_confirmation =
    2983             :     &postgres_get_auditor_progress_deposit_confirmation;
    2984           1 :   plugin->update_auditor_progress_deposit_confirmation =
    2985             :     &postgres_update_auditor_progress_deposit_confirmation;
    2986           1 :   plugin->insert_auditor_progress_deposit_confirmation =
    2987             :     &postgres_insert_auditor_progress_deposit_confirmation;
    2988           1 :   plugin->get_auditor_progress_coin = &postgres_get_auditor_progress_coin;
    2989           1 :   plugin->update_auditor_progress_coin = &postgres_update_auditor_progress_coin;
    2990           1 :   plugin->insert_auditor_progress_coin = &postgres_insert_auditor_progress_coin;
    2991             : 
    2992           1 :   plugin->get_wire_auditor_account_progress =
    2993             :     &postgres_get_wire_auditor_account_progress;
    2994           1 :   plugin->update_wire_auditor_account_progress =
    2995             :     &postgres_update_wire_auditor_account_progress;
    2996           1 :   plugin->insert_wire_auditor_account_progress =
    2997             :     &postgres_insert_wire_auditor_account_progress;
    2998           1 :   plugin->get_wire_auditor_progress = &postgres_get_wire_auditor_progress;
    2999           1 :   plugin->update_wire_auditor_progress = &postgres_update_wire_auditor_progress;
    3000           1 :   plugin->insert_wire_auditor_progress = &postgres_insert_wire_auditor_progress;
    3001             : 
    3002           1 :   plugin->del_reserve_info = &postgres_del_reserve_info;
    3003           1 :   plugin->get_reserve_info = &postgres_get_reserve_info;
    3004           1 :   plugin->update_reserve_info = &postgres_update_reserve_info;
    3005           1 :   plugin->insert_reserve_info = &postgres_insert_reserve_info;
    3006             : 
    3007           1 :   plugin->get_reserve_summary = &postgres_get_reserve_summary;
    3008           1 :   plugin->update_reserve_summary = &postgres_update_reserve_summary;
    3009           1 :   plugin->insert_reserve_summary = &postgres_insert_reserve_summary;
    3010             : 
    3011           1 :   plugin->get_wire_fee_summary = &postgres_get_wire_fee_summary;
    3012           1 :   plugin->update_wire_fee_summary = &postgres_update_wire_fee_summary;
    3013           1 :   plugin->insert_wire_fee_summary = &postgres_insert_wire_fee_summary;
    3014             : 
    3015           1 :   plugin->get_denomination_balance = &postgres_get_denomination_balance;
    3016           1 :   plugin->update_denomination_balance = &postgres_update_denomination_balance;
    3017           1 :   plugin->insert_denomination_balance = &postgres_insert_denomination_balance;
    3018             : 
    3019           1 :   plugin->get_balance_summary = &postgres_get_balance_summary;
    3020           1 :   plugin->update_balance_summary = &postgres_update_balance_summary;
    3021           1 :   plugin->insert_balance_summary = &postgres_insert_balance_summary;
    3022             : 
    3023           1 :   plugin->select_historic_denom_revenue =
    3024             :     &postgres_select_historic_denom_revenue;
    3025           1 :   plugin->insert_historic_denom_revenue =
    3026             :     &postgres_insert_historic_denom_revenue;
    3027             : 
    3028           1 :   plugin->select_historic_reserve_revenue =
    3029             :     &postgres_select_historic_reserve_revenue;
    3030           1 :   plugin->insert_historic_reserve_revenue =
    3031             :     &postgres_insert_historic_reserve_revenue;
    3032             : 
    3033           1 :   plugin->get_predicted_balance = &postgres_get_predicted_balance;
    3034           1 :   plugin->update_predicted_result = &postgres_update_predicted_result;
    3035           1 :   plugin->insert_predicted_result = &postgres_insert_predicted_result;
    3036             : 
    3037           1 :   return plugin;
    3038             : }
    3039             : 
    3040             : 
    3041             : /**
    3042             :  * Shutdown Postgres database subsystem.
    3043             :  *
    3044             :  * @param cls a `struct TALER_AUDITORDB_Plugin`
    3045             :  * @return NULL (always)
    3046             :  */
    3047             : void *
    3048           1 : libtaler_plugin_auditordb_postgres_done (void *cls)
    3049             : {
    3050           1 :   struct TALER_AUDITORDB_Plugin *plugin = cls;
    3051           1 :   struct PostgresClosure *pg = plugin->cls;
    3052             : 
    3053           1 :   if (NULL != pg->conn)
    3054           0 :     GNUNET_PQ_disconnect (pg->conn);
    3055           1 :   GNUNET_free (pg->currency);
    3056           1 :   GNUNET_free (pg);
    3057           1 :   GNUNET_free (plugin);
    3058           1 :   return NULL;
    3059             : }
    3060             : 
    3061             : 
    3062             : /* end of plugin_auditordb_postgres.c */

Generated by: LCOV version 1.14