exchange

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

pg_insert_records_by_table.c (82035B)


      1 /*
      2    This file is part of GNUnet
      3    Copyright (C) 2020-2025 Taler Systems SA
      4 
      5    GNUnet is free software: you can redistribute it and/or modify it
      6    under the terms of the GNU Affero General Public License as published
      7    by the Free Software Foundation, either version 3 of the License,
      8    or (at your option) any later version.
      9 
     10    GNUnet is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    Affero General Public License for more details.
     14 
     15    You should have received a copy of the GNU Affero General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18      SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 /**
     21  * @file exchangedb/pg_insert_records_by_table.c
     22  * @brief replicate_records_by_table implementation
     23  * @author Christian Grothoff
     24  * @author Özgür Kesim
     25  */
     26 #include "taler/platform.h"
     27 #include "taler/taler_error_codes.h"
     28 #include "taler/taler_dbevents.h"
     29 #include "taler/taler_pq_lib.h"
     30 #include "pg_insert_records_by_table.h"
     31 #include "pg_helper.h"
     32 #include <gnunet/gnunet_pq_lib.h>
     33 
     34 
     35 /**
     36  * Signature of helper functions of #TEH_PG_insert_records_by_table().
     37  *
     38  * @param pg plugin context
     39  * @param td record to insert
     40  * @return transaction status code
     41  */
     42 typedef enum GNUNET_DB_QueryStatus
     43 (*InsertRecordCallback)(struct PostgresClosure *pg,
     44                         const struct TALER_EXCHANGEDB_TableData *td);
     45 
     46 
     47 /**
     48  * Function called with denominations records to insert into table.
     49  *
     50  * @param pg plugin context
     51  * @param td record to insert
     52  */
     53 static enum GNUNET_DB_QueryStatus
     54 irbt_cb_table_denominations (struct PostgresClosure *pg,
     55                              const struct TALER_EXCHANGEDB_TableData *td)
     56 {
     57   struct TALER_DenominationHashP denom_hash;
     58   struct GNUNET_PQ_QueryParam params[] = {
     59     GNUNET_PQ_query_param_uint64 (&td->serial),
     60     GNUNET_PQ_query_param_auto_from_type (&denom_hash),
     61     GNUNET_PQ_query_param_uint32 (
     62       &td->details.denominations.denom_type),
     63     GNUNET_PQ_query_param_uint32 (
     64       &td->details.denominations.age_mask),
     65     TALER_PQ_query_param_denom_pub (
     66       &td->details.denominations.denom_pub),
     67     GNUNET_PQ_query_param_auto_from_type (
     68       &td->details.denominations.master_sig),
     69     GNUNET_PQ_query_param_timestamp (
     70       &td->details.denominations.valid_from),
     71     GNUNET_PQ_query_param_timestamp (
     72       &td->details.denominations.expire_withdraw),
     73     GNUNET_PQ_query_param_timestamp (
     74       &td->details.denominations.expire_deposit),
     75     GNUNET_PQ_query_param_timestamp (
     76       &td->details.denominations.expire_legal),
     77     TALER_PQ_query_param_amount (
     78       pg->conn,
     79       &td->details.denominations.coin),
     80     TALER_PQ_query_param_amount (
     81       pg->conn,
     82       &td->details.denominations.fees.withdraw),
     83     TALER_PQ_query_param_amount (
     84       pg->conn,
     85       &td->details.denominations.fees.deposit),
     86     TALER_PQ_query_param_amount (
     87       pg->conn,
     88       &td->details.denominations.fees.refresh),
     89     TALER_PQ_query_param_amount (
     90       pg->conn,
     91       &td->details.denominations.fees.refund),
     92     GNUNET_PQ_query_param_end
     93   };
     94 
     95   PREPARE (pg,
     96            "insert_into_table_denominations",
     97            "INSERT INTO denominations"
     98            "(denominations_serial"
     99            ",denom_pub_hash"
    100            ",denom_type"
    101            ",age_mask"
    102            ",denom_pub"
    103            ",master_sig"
    104            ",valid_from"
    105            ",expire_withdraw"
    106            ",expire_deposit"
    107            ",expire_legal"
    108            ",coin"
    109            ",fee_withdraw"
    110            ",fee_deposit"
    111            ",fee_refresh"
    112            ",fee_refund"
    113            ") VALUES "
    114            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
    115            " $11, $12, $13, $14, $15);");
    116 
    117   TALER_denom_pub_hash (
    118     &td->details.denominations.denom_pub,
    119     &denom_hash);
    120 
    121   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    122                                              "insert_into_table_denominations",
    123                                              params);
    124 }
    125 
    126 
    127 /**
    128  * Function called with denomination_revocations records to insert into table.
    129  *
    130  * @param pg plugin context
    131  * @param td record to insert
    132  */
    133 static enum GNUNET_DB_QueryStatus
    134 irbt_cb_table_denomination_revocations (
    135   struct PostgresClosure *pg,
    136   const struct TALER_EXCHANGEDB_TableData *td)
    137 {
    138   struct GNUNET_PQ_QueryParam params[] = {
    139     GNUNET_PQ_query_param_uint64 (&td->serial),
    140     GNUNET_PQ_query_param_auto_from_type (
    141       &td->details.denomination_revocations.master_sig),
    142     GNUNET_PQ_query_param_uint64 (
    143       &td->details.denomination_revocations.denominations_serial),
    144     GNUNET_PQ_query_param_end
    145   };
    146 
    147   PREPARE (pg,
    148            "insert_into_table_denomination_revocations",
    149            "INSERT INTO denomination_revocations"
    150            "(denom_revocations_serial_id"
    151            ",master_sig"
    152            ",denominations_serial"
    153            ") VALUES "
    154            "($1, $2, $3);");
    155   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    156                                              "insert_into_table_denomination_revocations",
    157                                              params);
    158 }
    159 
    160 
    161 /**
    162  * Function called with wire target records to insert into table.
    163  *
    164  * @param pg plugin context
    165  * @param td record to insert
    166  */
    167 static enum GNUNET_DB_QueryStatus
    168 irbt_cb_table_wire_targets (struct PostgresClosure *pg,
    169                             const struct TALER_EXCHANGEDB_TableData *td)
    170 {
    171   struct TALER_NormalizedPaytoHashP normalized_payto_hash;
    172   struct TALER_FullPaytoHashP full_payto_hash;
    173   struct GNUNET_PQ_QueryParam params[] = {
    174     GNUNET_PQ_query_param_uint64 (&td->serial),
    175     GNUNET_PQ_query_param_auto_from_type (&full_payto_hash),
    176     GNUNET_PQ_query_param_auto_from_type (&normalized_payto_hash),
    177     GNUNET_PQ_query_param_string (
    178       td->details.wire_targets.full_payto_uri.full_payto),
    179     GNUNET_PQ_query_param_end
    180   };
    181 
    182   TALER_full_payto_hash (
    183     td->details.wire_targets.full_payto_uri,
    184     &full_payto_hash);
    185   TALER_full_payto_normalize_and_hash (
    186     td->details.wire_targets.full_payto_uri,
    187     &normalized_payto_hash);
    188   PREPARE (pg,
    189            "insert_into_table_wire_targets",
    190            "INSERT INTO wire_targets"
    191            "(wire_target_serial_id"
    192            ",wire_target_h_payto"
    193            ",h_normalized_payto"
    194            ",payto_uri"
    195            ") VALUES "
    196            "($1, $2, $3, $4);");
    197   return GNUNET_PQ_eval_prepared_non_select (
    198     pg->conn,
    199     "insert_into_table_wire_targets",
    200     params);
    201 }
    202 
    203 
    204 /**
    205  * Function called with kyc target records to insert into table.
    206  *
    207  * @param pg plugin context
    208  * @param td record to insert
    209  */
    210 static enum GNUNET_DB_QueryStatus
    211 irbt_cb_table_kyc_targets (struct PostgresClosure *pg,
    212                            const struct TALER_EXCHANGEDB_TableData *td)
    213 {
    214   struct GNUNET_PQ_QueryParam params[] = {
    215     GNUNET_PQ_query_param_uint64 (&td->serial),
    216     GNUNET_PQ_query_param_auto_from_type (
    217       &td->details.kyc_targets.h_normalized_payto),
    218     GNUNET_PQ_query_param_auto_from_type (
    219       &td->details.kyc_targets.access_token),
    220     td->details.kyc_targets.no_account
    221     ? GNUNET_PQ_query_param_null ()
    222     : GNUNET_PQ_query_param_auto_from_type (
    223       &td->details.kyc_targets.target_pub),
    224     GNUNET_PQ_query_param_bool (
    225       td->details.kyc_targets.is_wallet),
    226     GNUNET_PQ_query_param_end
    227   };
    228 
    229   PREPARE (pg,
    230            "insert_into_table_kyc_targets",
    231            "INSERT INTO kyc_targets"
    232            "(kyc_target_serial_id"
    233            ",h_normalized_payto"
    234            ",access_token"
    235            ",target_pub"
    236            ",is_wallet"
    237            ") VALUES "
    238            "($1, $2, $3, $4, $5);");
    239   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    240                                              "insert_into_table_kyc_targets",
    241                                              params);
    242 }
    243 
    244 
    245 /**
    246  * Function called with records to insert into table.
    247  *
    248  * @param pg plugin context
    249  * @param td record to insert
    250  */
    251 static enum GNUNET_DB_QueryStatus
    252 irbt_cb_table_legitimization_measures (
    253   struct PostgresClosure *pg,
    254   const struct TALER_EXCHANGEDB_TableData *td)
    255 {
    256   struct GNUNET_PQ_QueryParam params[] = {
    257     GNUNET_PQ_query_param_uint64 (&td->serial),
    258     GNUNET_PQ_query_param_auto_from_type (
    259       &td->details.legitimization_measures.target_token),
    260     GNUNET_PQ_query_param_timestamp (
    261       &td->details.legitimization_measures.start_time),
    262     TALER_PQ_query_param_json (
    263       td->details.legitimization_measures.measures),
    264     GNUNET_PQ_query_param_uint32 (
    265       &td->details.legitimization_measures.display_priority),
    266     GNUNET_PQ_query_param_end
    267   };
    268 
    269   PREPARE (pg,
    270            "insert_into_table_legitimization_measures",
    271            "INSERT INTO legitimization_measures"
    272            "(legitimization_measure_serial_id"
    273            ",access_token"
    274            ",start_time"
    275            ",jmeasures"
    276            ",display_priority"
    277            ") VALUES "
    278            "($1, $2, $3, $4::TEXT::JSONB, $5);");
    279   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    280                                              "insert_into_table_legitimization_measures",
    281                                              params);
    282 }
    283 
    284 
    285 /**
    286  * Function called with records to insert into table.
    287  *
    288  * @param pg plugin context
    289  * @param td record to insert
    290  */
    291 static enum GNUNET_DB_QueryStatus
    292 irbt_cb_table_legitimization_outcomes (
    293   struct PostgresClosure *pg,
    294   const struct TALER_EXCHANGEDB_TableData *td)
    295 {
    296   struct GNUNET_PQ_QueryParam params[] = {
    297     GNUNET_PQ_query_param_uint64 (&td->serial),
    298     GNUNET_PQ_query_param_auto_from_type (
    299       &td->details.legitimization_outcomes.h_payto),
    300     GNUNET_PQ_query_param_timestamp (
    301       &td->details.legitimization_outcomes.decision_time),
    302     GNUNET_PQ_query_param_timestamp (
    303       &td->details.legitimization_outcomes.expiration_time),
    304     TALER_PQ_query_param_json (
    305       td->details.legitimization_outcomes.properties),
    306     GNUNET_PQ_query_param_bool (
    307       td->details.legitimization_outcomes.to_investigate),
    308     TALER_PQ_query_param_json (
    309       td->details.legitimization_outcomes.new_rules),
    310     GNUNET_PQ_query_param_end
    311   };
    312 
    313   PREPARE (pg,
    314            "insert_into_table_legitimization_outcomes",
    315            "INSERT INTO legitimization_outcomes"
    316            "(outcome_serial_id"
    317            ",h_payto"
    318            ",decision_time"
    319            ",expiration_time"
    320            ",jproperties"
    321            ",to_investigate"
    322            ",jnew_rules"
    323            ") VALUES "
    324            "($1, $2, $3, $4, $5::TEXT::JSONB, $6, $7::TEXT::JSONB);");
    325   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    326                                              "insert_into_table_legitimization_outcomes",
    327                                              params);
    328 }
    329 
    330 
    331 /**
    332  * Function called with records to insert into table.
    333  *
    334  * @param pg plugin context
    335  * @param td record to insert
    336  */
    337 static enum GNUNET_DB_QueryStatus
    338 irbt_cb_table_legitimization_processes (
    339   struct PostgresClosure *pg,
    340   const struct TALER_EXCHANGEDB_TableData *td)
    341 {
    342   struct GNUNET_PQ_QueryParam params[] = {
    343     GNUNET_PQ_query_param_uint64 (&td->serial),
    344     GNUNET_PQ_query_param_auto_from_type (
    345       &td->details.legitimization_processes.h_payto),
    346     GNUNET_PQ_query_param_timestamp (
    347       &td->details.legitimization_processes.start_time),
    348     GNUNET_PQ_query_param_timestamp (
    349       &td->details.legitimization_processes.expiration_time),
    350     GNUNET_PQ_query_param_uint64 (
    351       &td->details.legitimization_processes.legitimization_measure_serial_id),
    352     GNUNET_PQ_query_param_uint32 (
    353       &td->details.legitimization_processes.measure_index),
    354     GNUNET_PQ_query_param_string (
    355       td->details.legitimization_processes.provider_name),
    356     GNUNET_PQ_query_param_string (
    357       td->details.legitimization_processes.provider_user_id),
    358     GNUNET_PQ_query_param_string (
    359       td->details.legitimization_processes.provider_legitimization_id),
    360     GNUNET_PQ_query_param_string (
    361       td->details.legitimization_processes.redirect_url),
    362     GNUNET_PQ_query_param_end
    363   };
    364 
    365   PREPARE (pg,
    366            "insert_into_table_legitimization_processes",
    367            "INSERT INTO legitimization_processes"
    368            "(legitimization_process_serial_id"
    369            ",h_payto"
    370            ",start_time"
    371            ",expiration_time"
    372            ",legitimization_measure_serial_id"
    373            ",measure_index"
    374            ",provider_name"
    375            ",provider_user_id"
    376            ",provider_legitimization_id"
    377            ",redirect_url"
    378            ") VALUES "
    379            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
    380   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    381                                              "insert_into_table_legitimization_processes",
    382                                              params);
    383 }
    384 
    385 
    386 /**
    387  * Function called with reserves records to insert into table.
    388  *
    389  * @param pg plugin context
    390  * @param td record to insert
    391  */
    392 static enum GNUNET_DB_QueryStatus
    393 irbt_cb_table_reserves (struct PostgresClosure *pg,
    394                         const struct TALER_EXCHANGEDB_TableData *td)
    395 {
    396   struct GNUNET_PQ_QueryParam params[] = {
    397     GNUNET_PQ_query_param_uint64 (&td->serial),
    398     GNUNET_PQ_query_param_auto_from_type (&td->details.reserves.reserve_pub),
    399     GNUNET_PQ_query_param_timestamp (&td->details.reserves.expiration_date),
    400     GNUNET_PQ_query_param_timestamp (&td->details.reserves.gc_date),
    401     GNUNET_PQ_query_param_end
    402   };
    403 
    404   PREPARE (pg,
    405            "insert_into_table_reserves",
    406            "INSERT INTO reserves"
    407            "(reserve_uuid"
    408            ",reserve_pub"
    409            ",expiration_date"
    410            ",gc_date"
    411            ") VALUES "
    412            "($1, $2, $3, $4);");
    413   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    414                                              "insert_into_table_reserves",
    415                                              params);
    416 }
    417 
    418 
    419 /**
    420  * Function called with reserves_in records to insert into table.
    421  *
    422  * @param pg plugin context
    423  * @param td record to insert
    424  */
    425 static enum GNUNET_DB_QueryStatus
    426 irbt_cb_table_reserves_in (struct PostgresClosure *pg,
    427                            const struct TALER_EXCHANGEDB_TableData *td)
    428 {
    429   struct GNUNET_PQ_QueryParam params[] = {
    430     GNUNET_PQ_query_param_uint64 (&td->serial),
    431     GNUNET_PQ_query_param_uint64 (&td->details.reserves_in.wire_reference),
    432     TALER_PQ_query_param_amount (
    433       pg->conn,
    434       &td->details.reserves_in.credit),
    435     GNUNET_PQ_query_param_auto_from_type (
    436       &td->details.reserves_in.sender_account_h_payto),
    437     GNUNET_PQ_query_param_string (
    438       td->details.reserves_in.exchange_account_section),
    439     GNUNET_PQ_query_param_timestamp (
    440       &td->details.reserves_in.execution_date),
    441     GNUNET_PQ_query_param_auto_from_type (&td->details.reserves_in.reserve_pub),
    442     GNUNET_PQ_query_param_end
    443   };
    444 
    445   PREPARE (pg,
    446            "insert_into_table_reserves_in",
    447            "INSERT INTO reserves_in"
    448            "(reserve_in_serial_id"
    449            ",wire_reference"
    450            ",credit"
    451            ",wire_source_h_payto"
    452            ",exchange_account_section"
    453            ",execution_date"
    454            ",reserve_pub"
    455            ") VALUES "
    456            "($1, $2, $3, $4, $5, $6, $7);");
    457   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    458                                              "insert_into_table_reserves_in",
    459                                              params);
    460 }
    461 
    462 
    463 /**
    464  * Function called with kycauth_in records to insert into table.
    465  *
    466  * @param pg plugin context
    467  * @param td record to insert
    468  */
    469 static enum GNUNET_DB_QueryStatus
    470 irbt_cb_table_kycauths_in (struct PostgresClosure *pg,
    471                            const struct TALER_EXCHANGEDB_TableData *td)
    472 {
    473   struct GNUNET_PQ_QueryParam params[] = {
    474     GNUNET_PQ_query_param_uint64 (&td->serial),
    475     GNUNET_PQ_query_param_uint64 (&td->details.kycauth_in.wire_reference),
    476     TALER_PQ_query_param_amount (
    477       pg->conn,
    478       &td->details.reserves_in.credit),
    479     GNUNET_PQ_query_param_auto_from_type (
    480       &td->details.reserves_in.sender_account_h_payto),
    481     GNUNET_PQ_query_param_string (
    482       td->details.reserves_in.exchange_account_section),
    483     GNUNET_PQ_query_param_timestamp (
    484       &td->details.reserves_in.execution_date),
    485     GNUNET_PQ_query_param_auto_from_type (&td->details.kycauth_in.account_pub),
    486     GNUNET_PQ_query_param_end
    487   };
    488 
    489   PREPARE (pg,
    490            "insert_into_table_kycauth_in",
    491            "INSERT INTO kycauths_in"
    492            "(kycauth_in_serial_id"
    493            ",wire_reference"
    494            ",credit"
    495            ",wire_source_h_payto"
    496            ",exchange_account_section"
    497            ",execution_date"
    498            ",account_pub"
    499            ") VALUES "
    500            "($1, $2, $3, $4, $5, $6, $7);");
    501   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    502                                              "insert_into_table_kycauth_in",
    503                                              params);
    504 }
    505 
    506 
    507 /**
    508  * Function called with reserves_open_requests records to insert into table.
    509  *
    510  * @param pg plugin context
    511  * @param td record to insert
    512  */
    513 static enum GNUNET_DB_QueryStatus
    514 irbt_cb_table_reserves_open_requests (struct PostgresClosure *pg,
    515                                       const struct
    516                                       TALER_EXCHANGEDB_TableData *td)
    517 {
    518   struct GNUNET_PQ_QueryParam params[] = {
    519     GNUNET_PQ_query_param_uint64 (&td->serial),
    520     GNUNET_PQ_query_param_timestamp (
    521       &td->details.reserves_open_requests.expiration_date),
    522     GNUNET_PQ_query_param_auto_from_type (
    523       &td->details.reserves_open_requests.reserve_sig),
    524     TALER_PQ_query_param_amount (
    525       pg->conn,
    526       &td->details.reserves_open_requests.reserve_payment),
    527     GNUNET_PQ_query_param_uint32 (
    528       &td->details.reserves_open_requests.requested_purse_limit),
    529     GNUNET_PQ_query_param_end
    530   };
    531 
    532   PREPARE (pg,
    533            "insert_into_table_reserves_open_requests",
    534            "INSERT INTO reserves_open_requests"
    535            "(open_request_uuid"
    536            ",reserve_pub"
    537            ",request_timestamp"
    538            ",expiration_date"
    539            ",reserve_sig"
    540            ",reserve_payment"
    541            ",requested_purse_limit"
    542            ") VALUES "
    543            "($1, $2, $3, $4, $5, $6, $7);");
    544   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    545                                              "insert_into_table_reserves_open_requests",
    546                                              params);
    547 }
    548 
    549 
    550 /**
    551  * Function called with reserves_open_requests records to insert into table.
    552  *
    553  * @param pg plugin context
    554  * @param td record to insert
    555  */
    556 static enum GNUNET_DB_QueryStatus
    557 irbt_cb_table_reserves_open_deposits (
    558   struct PostgresClosure *pg,
    559   const struct TALER_EXCHANGEDB_TableData *td)
    560 {
    561   struct GNUNET_PQ_QueryParam params[] = {
    562     GNUNET_PQ_query_param_uint64 (&td->serial),
    563     GNUNET_PQ_query_param_auto_from_type (
    564       &td->details.reserves_open_deposits.coin_pub),
    565     GNUNET_PQ_query_param_auto_from_type (
    566       &td->details.reserves_open_deposits.coin_sig),
    567     GNUNET_PQ_query_param_auto_from_type (
    568       &td->details.reserves_open_deposits.reserve_sig),
    569     TALER_PQ_query_param_amount (
    570       pg->conn,
    571       &td->details.reserves_open_deposits.contribution),
    572     GNUNET_PQ_query_param_end
    573   };
    574 
    575   PREPARE (pg,
    576            "insert_into_table_reserves_open_deposits",
    577            "INSERT INTO reserves_open_deposits"
    578            "(reserve_open_deposit_uuid"
    579            ",reserve_sig"
    580            ",reserve_pub"
    581            ",coin_pub"
    582            ",coin_sig"
    583            ",contribution"
    584            ") VALUES "
    585            "($1, $2, $3, $4, $5, $6);");
    586   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    587                                              "insert_into_table_reserves_open_deposits",
    588                                              params);
    589 }
    590 
    591 
    592 /**
    593  * Function called with reserves_close records to insert into table.
    594  *
    595  * @param pg plugin context
    596  * @param td record to insert
    597  */
    598 static enum GNUNET_DB_QueryStatus
    599 irbt_cb_table_reserves_close (struct PostgresClosure *pg,
    600                               const struct TALER_EXCHANGEDB_TableData *td)
    601 {
    602   struct GNUNET_PQ_QueryParam params[] = {
    603     GNUNET_PQ_query_param_uint64 (&td->serial),
    604     GNUNET_PQ_query_param_timestamp (
    605       &td->details.reserves_close.execution_date),
    606     GNUNET_PQ_query_param_auto_from_type (
    607       &td->details.reserves_close.wtid),
    608     GNUNET_PQ_query_param_auto_from_type (
    609       &td->details.reserves_close.sender_account_h_payto),
    610     TALER_PQ_query_param_amount (
    611       pg->conn,
    612       &td->details.reserves_close.amount),
    613     TALER_PQ_query_param_amount (
    614       pg->conn,
    615       &td->details.reserves_close.closing_fee),
    616     GNUNET_PQ_query_param_auto_from_type (
    617       &td->details.reserves_close.reserve_pub),
    618     GNUNET_PQ_query_param_end
    619   };
    620 
    621   PREPARE (pg,
    622            "insert_into_table_reserves_close",
    623            "INSERT INTO reserves_close"
    624            "(close_uuid"
    625            ",execution_date"
    626            ",wtid"
    627            ",wire_target_h_payto"
    628            ",amount"
    629            ",closing_fee"
    630            ",reserve_pub"
    631            ") VALUES "
    632            "($1, $2, $3, $4, $5, $6, $7);");
    633   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    634                                              "insert_into_table_reserves_close",
    635                                              params);
    636 }
    637 
    638 
    639 /**
    640  * Function called with auditors records to insert into table.
    641  *
    642  * @param pg plugin context
    643  * @param td record to insert
    644  */
    645 static enum GNUNET_DB_QueryStatus
    646 irbt_cb_table_auditors (struct PostgresClosure *pg,
    647                         const struct TALER_EXCHANGEDB_TableData *td)
    648 {
    649   struct GNUNET_PQ_QueryParam params[] = {
    650     GNUNET_PQ_query_param_uint64 (&td->serial),
    651     GNUNET_PQ_query_param_auto_from_type (&td->details.auditors.auditor_pub),
    652     GNUNET_PQ_query_param_string (td->details.auditors.auditor_name),
    653     GNUNET_PQ_query_param_string (td->details.auditors.auditor_url),
    654     GNUNET_PQ_query_param_bool (td->details.auditors.is_active),
    655     GNUNET_PQ_query_param_timestamp (&td->details.auditors.last_change),
    656     GNUNET_PQ_query_param_end
    657   };
    658 
    659   PREPARE (pg,
    660            "insert_into_table_auditors",
    661            "INSERT INTO auditors"
    662            "(auditor_uuid"
    663            ",auditor_pub"
    664            ",auditor_name"
    665            ",auditor_url"
    666            ",is_active"
    667            ",last_change"
    668            ") VALUES "
    669            "($1, $2, $3, $4, $5, $6);");
    670   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    671                                              "insert_into_table_auditors",
    672                                              params);
    673 }
    674 
    675 
    676 /**
    677  * Function called with auditor_denom_sigs records to insert into table.
    678  *
    679  * @param pg plugin context
    680  * @param td record to insert
    681  */
    682 static enum GNUNET_DB_QueryStatus
    683 irbt_cb_table_auditor_denom_sigs (struct PostgresClosure *pg,
    684                                   const struct TALER_EXCHANGEDB_TableData *td)
    685 {
    686   struct GNUNET_PQ_QueryParam params[] = {
    687     GNUNET_PQ_query_param_uint64 (&td->serial),
    688     GNUNET_PQ_query_param_uint64 (&td->details.auditor_denom_sigs.auditor_uuid),
    689     GNUNET_PQ_query_param_uint64 (
    690       &td->details.auditor_denom_sigs.denominations_serial),
    691     GNUNET_PQ_query_param_auto_from_type (
    692       &td->details.auditor_denom_sigs.auditor_sig),
    693     GNUNET_PQ_query_param_end
    694   };
    695 
    696   PREPARE (pg,
    697            "insert_into_table_auditor_denom_sigs",
    698            "INSERT INTO auditor_denom_sigs"
    699            "(auditor_denom_serial"
    700            ",auditor_uuid"
    701            ",denominations_serial"
    702            ",auditor_sig"
    703            ") VALUES "
    704            "($1, $2, $3, $4);");
    705   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    706                                              "insert_into_table_auditor_denom_sigs",
    707                                              params);
    708 }
    709 
    710 
    711 /**
    712  * Function called with exchange_sign_keys records to insert into table.
    713  *
    714  * @param pg plugin context
    715  * @param td record to insert
    716  */
    717 static enum GNUNET_DB_QueryStatus
    718 irbt_cb_table_exchange_sign_keys (struct PostgresClosure *pg,
    719                                   const struct TALER_EXCHANGEDB_TableData *td)
    720 {
    721   struct GNUNET_PQ_QueryParam params[] = {
    722     GNUNET_PQ_query_param_uint64 (&td->serial),
    723     GNUNET_PQ_query_param_auto_from_type (
    724       &td->details.exchange_sign_keys.exchange_pub),
    725     GNUNET_PQ_query_param_auto_from_type (
    726       &td->details.exchange_sign_keys.master_sig),
    727     GNUNET_PQ_query_param_timestamp (
    728       &td->details.exchange_sign_keys.meta.start),
    729     GNUNET_PQ_query_param_timestamp (
    730       &td->details.exchange_sign_keys.meta.expire_sign),
    731     GNUNET_PQ_query_param_timestamp (
    732       &td->details.exchange_sign_keys.meta.expire_legal),
    733     GNUNET_PQ_query_param_end
    734   };
    735 
    736   PREPARE (pg,
    737            "insert_into_table_exchange_sign_keys",
    738            "INSERT INTO exchange_sign_keys"
    739            "(esk_serial"
    740            ",exchange_pub"
    741            ",master_sig"
    742            ",valid_from"
    743            ",expire_sign"
    744            ",expire_legal"
    745            ") VALUES "
    746            "($1, $2, $3, $4, $5, $6);");
    747   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    748                                              "insert_into_table_exchange_sign_keys",
    749                                              params);
    750 }
    751 
    752 
    753 /**
    754  * Function called with signkey_revocations records to insert into table.
    755  *
    756  * @param pg plugin context
    757  * @param td record to insert
    758  */
    759 static enum GNUNET_DB_QueryStatus
    760 irbt_cb_table_signkey_revocations (struct PostgresClosure *pg,
    761                                    const struct TALER_EXCHANGEDB_TableData *td)
    762 {
    763   struct GNUNET_PQ_QueryParam params[] = {
    764     GNUNET_PQ_query_param_uint64 (&td->serial),
    765     GNUNET_PQ_query_param_uint64 (&td->details.signkey_revocations.esk_serial),
    766     GNUNET_PQ_query_param_auto_from_type (
    767       &td->details.signkey_revocations.master_sig),
    768     GNUNET_PQ_query_param_end
    769   };
    770 
    771   PREPARE (pg,
    772            "insert_into_table_signkey_revocations",
    773            "INSERT INTO signkey_revocations"
    774            "(signkey_revocations_serial_id"
    775            ",esk_serial"
    776            ",master_sig"
    777            ") VALUES "
    778            "($1, $2, $3);");
    779   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    780                                              "insert_into_table_signkey_revocations",
    781                                              params);
    782 }
    783 
    784 
    785 /**
    786  * Function called with known_coins records to insert into table.
    787  *
    788  * @param pg plugin context
    789  * @param td record to insert
    790  */
    791 static enum GNUNET_DB_QueryStatus
    792 irbt_cb_table_known_coins (struct PostgresClosure *pg,
    793                            const struct TALER_EXCHANGEDB_TableData *td)
    794 {
    795   struct GNUNET_PQ_QueryParam params[] = {
    796     GNUNET_PQ_query_param_uint64 (&td->serial),
    797     GNUNET_PQ_query_param_auto_from_type (
    798       &td->details.known_coins.coin_pub),
    799     TALER_PQ_query_param_denom_sig (
    800       &td->details.known_coins.denom_sig),
    801     GNUNET_PQ_query_param_uint64 (
    802       &td->details.known_coins.denominations_serial),
    803     GNUNET_PQ_query_param_end
    804   };
    805 
    806   PREPARE (pg,
    807            "insert_into_table_known_coins",
    808            "INSERT INTO known_coins"
    809            "(known_coin_id"
    810            ",coin_pub"
    811            ",denom_sig"
    812            ",denominations_serial"
    813            ") VALUES "
    814            "($1, $2, $3, $4);");
    815   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    816                                              "insert_into_table_known_coins",
    817                                              params);
    818 }
    819 
    820 
    821 /**
    822  * Function called with refresh records to insert into table.
    823  *
    824  * @param pg plugin context
    825  * @param td record to insert
    826  */
    827 static enum GNUNET_DB_QueryStatus
    828 irbt_cb_table_refresh (struct PostgresClosure *pg,
    829                        const struct TALER_EXCHANGEDB_TableData *td)
    830 {
    831   struct GNUNET_PQ_QueryParam params[] = {
    832     GNUNET_PQ_query_param_uint64 (&td->serial),
    833     GNUNET_PQ_query_param_auto_from_type (&td->details.refresh.rc),
    834     GNUNET_PQ_query_param_auto_from_type (&td->details.refresh.execution_date),
    835     TALER_PQ_query_param_amount (
    836       pg->conn,
    837       &td->details.refresh.amount_with_fee),
    838     GNUNET_PQ_query_param_auto_from_type (
    839       &td->details.refresh.old_coin_pub),
    840     GNUNET_PQ_query_param_auto_from_type (
    841       &td->details.refresh.old_coin_sig),
    842     GNUNET_PQ_query_param_auto_from_type (
    843       &td->details.refresh.refresh_seed),
    844     GNUNET_PQ_query_param_uint32 (
    845       &td->details.refresh.noreveal_index),
    846     GNUNET_PQ_query_param_auto_from_type (
    847       &td->details.refresh.planchets_h),
    848     GNUNET_PQ_query_param_auto_from_type (
    849       &td->details.refresh.selected_h),
    850     td->details.refresh.no_blinding_seed
    851        ? GNUNET_PQ_query_param_null ()
    852        : GNUNET_PQ_query_param_auto_from_type (
    853       &td->details.refresh.blinding_seed),
    854     td->details.refresh.no_blinding_seed
    855        ? GNUNET_PQ_query_param_null ()
    856        : TALER_PQ_query_param_array_cs_r_pub (
    857       td->details.refresh.num_cs_r_values,
    858       td->details.refresh.cs_r_values,
    859       pg->conn),
    860     td->details.refresh.no_blinding_seed
    861        ? GNUNET_PQ_query_param_null ()
    862        : GNUNET_PQ_query_param_uint64 (
    863       &td->details.refresh.cs_r_choices),
    864     GNUNET_PQ_query_param_array_uint64 (
    865       td->details.refresh.num_coins,
    866       td->details.refresh.denom_serials,
    867       pg->conn),
    868     TALER_PQ_query_param_array_blinded_denom_sig (
    869       td->details.refresh.num_coins,
    870       td->details.refresh.denom_sigs,
    871       pg->conn),
    872     GNUNET_PQ_query_param_end
    873   };
    874 
    875   PREPARE (pg,
    876            "insert_into_table_refresh",
    877            "INSERT INTO refresh"
    878            "(refresh_id"
    879            ",rc"
    880            ",execution_date"
    881            ",amount_with_fee"
    882            ",old_coin_pub"
    883            ",old_coin_sig"
    884            ",refresh_seed"
    885            ",noreveal_index"
    886            ",planchets_h"
    887            ",selected_h"
    888            ",blinding_seed"
    889            ",cs_r_values"
    890            ",cs_r_choices"
    891            ",denom_serials"
    892            ",denom_sigs"
    893            ") VALUES "
    894            "($1, $2, $3, $4, $5, $6,$7,$8,$9,$10,$11,$12,$13,$14,$15);");
    895   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    896                                              "insert_into_table_refresh",
    897                                              params);
    898 }
    899 
    900 
    901 /**
    902  * Function called with batch deposits records to insert into table.
    903  *
    904  * @param pg plugin context
    905  * @param td record to insert
    906  */
    907 static enum GNUNET_DB_QueryStatus
    908 irbt_cb_table_batch_deposits (struct PostgresClosure *pg,
    909                               const struct TALER_EXCHANGEDB_TableData *td)
    910 {
    911   struct GNUNET_PQ_QueryParam params[] = {
    912     GNUNET_PQ_query_param_uint64 (&td->serial),
    913     GNUNET_PQ_query_param_uint64 (&td->details.batch_deposits.shard),
    914     GNUNET_PQ_query_param_auto_from_type (
    915       &td->details.batch_deposits.merchant_pub),
    916     GNUNET_PQ_query_param_timestamp (
    917       &td->details.batch_deposits.wallet_timestamp),
    918     GNUNET_PQ_query_param_timestamp (
    919       &td->details.batch_deposits.exchange_timestamp),
    920     GNUNET_PQ_query_param_timestamp (
    921       &td->details.batch_deposits.refund_deadline),
    922     GNUNET_PQ_query_param_timestamp (&td->details.batch_deposits.wire_deadline),
    923     GNUNET_PQ_query_param_auto_from_type (
    924       &td->details.batch_deposits.h_contract_terms),
    925     td->details.batch_deposits.no_wallet_data_hash
    926     ? GNUNET_PQ_query_param_null ()
    927     : GNUNET_PQ_query_param_auto_from_type (
    928       &td->details.batch_deposits.wallet_data_hash),
    929     GNUNET_PQ_query_param_auto_from_type (
    930       &td->details.batch_deposits.wire_salt),
    931     GNUNET_PQ_query_param_auto_from_type (
    932       &td->details.batch_deposits.wire_target_h_payto),
    933     td->details.batch_deposits.no_policy_details
    934     ? GNUNET_PQ_query_param_null ()
    935     : GNUNET_PQ_query_param_uint64 (
    936       &td->details.batch_deposits.policy_details_serial_id),
    937     GNUNET_PQ_query_param_bool (td->details.batch_deposits.policy_blocked),
    938     TALER_PQ_query_param_amount (
    939       pg->conn,
    940       &td->details.batch_deposits.total_amount),
    941     TALER_PQ_query_param_amount (
    942       pg->conn,
    943       &td->details.batch_deposits.total_without_fee),
    944     GNUNET_PQ_query_param_auto_from_type (
    945       &td->details.batch_deposits.merchant_sig),
    946     GNUNET_PQ_query_param_bool (td->details.batch_deposits.done),
    947     GNUNET_PQ_query_param_end
    948   };
    949 
    950   PREPARE (pg,
    951            "insert_into_table_batch_deposits",
    952            "INSERT INTO batch_deposits"
    953            "(batch_deposit_serial_id"
    954            ",shard"
    955            ",merchant_pub"
    956            ",wallet_timestamp"
    957            ",exchange_timestamp"
    958            ",refund_deadline"
    959            ",wire_deadline"
    960            ",h_contract_terms"
    961            ",wallet_data_hash"
    962            ",wire_salt"
    963            ",wire_target_h_payto"
    964            ",policy_details_serial_id"
    965            ",policy_blocked"
    966            ",total_amount"
    967            ",total_without_fee"
    968            ",merchant_sig"
    969            ",done"
    970            ") VALUES "
    971            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
    972            " $11, $12, $13, $14, $15, $16, $17);");
    973   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
    974                                              "insert_into_table_batch_deposits",
    975                                              params);
    976 }
    977 
    978 
    979 /**
    980  * Function called with deposits records to insert into table.
    981  *
    982  * @param pg plugin context
    983  * @param td record to insert
    984  */
    985 static enum GNUNET_DB_QueryStatus
    986 irbt_cb_table_coin_deposits (struct PostgresClosure *pg,
    987                              const struct TALER_EXCHANGEDB_TableData *td)
    988 {
    989   struct GNUNET_PQ_QueryParam params[] = {
    990     GNUNET_PQ_query_param_uint64 (&td->serial),
    991     GNUNET_PQ_query_param_uint64 (
    992       &td->details.coin_deposits.batch_deposit_serial_id),
    993     GNUNET_PQ_query_param_auto_from_type (
    994       &td->details.coin_deposits.coin_pub),
    995     GNUNET_PQ_query_param_auto_from_type (
    996       &td->details.coin_deposits.coin_sig),
    997     TALER_PQ_query_param_amount (
    998       pg->conn,
    999       &td->details.coin_deposits.amount_with_fee),
   1000     GNUNET_PQ_query_param_end
   1001   };
   1002 
   1003   PREPARE (pg,
   1004            "insert_into_table_coin_deposits",
   1005            "INSERT INTO coin_deposits"
   1006            "(coin_deposit_serial_id"
   1007            ",batch_deposit_serial_id"
   1008            ",coin_pub"
   1009            ",coin_sig"
   1010            ",amount_with_fee"
   1011            ") VALUES "
   1012            "($1, $2, $3, $4, $5);");
   1013   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1014                                              "insert_into_table_coin_deposits",
   1015                                              params);
   1016 }
   1017 
   1018 
   1019 /**
   1020  * Function called with refunds records to insert into table.
   1021  *
   1022  * @param pg plugin context
   1023  * @param td record to insert
   1024  */
   1025 static enum GNUNET_DB_QueryStatus
   1026 irbt_cb_table_refunds (struct PostgresClosure *pg,
   1027                        const struct TALER_EXCHANGEDB_TableData *td)
   1028 {
   1029   struct GNUNET_PQ_QueryParam params[] = {
   1030     GNUNET_PQ_query_param_uint64 (&td->serial),
   1031     GNUNET_PQ_query_param_auto_from_type (&td->details.refunds.coin_pub),
   1032     GNUNET_PQ_query_param_auto_from_type (&td->details.refunds.merchant_sig),
   1033     GNUNET_PQ_query_param_uint64 (&td->details.refunds.rtransaction_id),
   1034     TALER_PQ_query_param_amount (
   1035       pg->conn,
   1036       &td->details.refunds.amount_with_fee),
   1037     GNUNET_PQ_query_param_uint64 (
   1038       &td->details.refunds.batch_deposit_serial_id),
   1039     GNUNET_PQ_query_param_end
   1040   };
   1041 
   1042   PREPARE (pg,
   1043            "insert_into_table_refunds",
   1044            "INSERT INTO refunds"
   1045            "(refund_serial_id"
   1046            ",coin_pub"
   1047            ",merchant_sig"
   1048            ",rtransaction_id"
   1049            ",amount_with_fee"
   1050            ",batch_deposit_serial_id"
   1051            ") VALUES "
   1052            "($1, $2, $3, $4, $5, $6);");
   1053   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1054                                              "insert_into_table_refunds",
   1055                                              params);
   1056 }
   1057 
   1058 
   1059 /**
   1060  * Function called with wire_out records to insert into table.
   1061  *
   1062  * @param pg plugin context
   1063  * @param td record to insert
   1064  */
   1065 static enum GNUNET_DB_QueryStatus
   1066 irbt_cb_table_wire_out (struct PostgresClosure *pg,
   1067                         const struct TALER_EXCHANGEDB_TableData *td)
   1068 {
   1069   struct GNUNET_PQ_QueryParam params[] = {
   1070     GNUNET_PQ_query_param_uint64 (&td->serial),
   1071     GNUNET_PQ_query_param_timestamp (&td->details.wire_out.execution_date),
   1072     GNUNET_PQ_query_param_auto_from_type (&td->details.wire_out.wtid_raw),
   1073     GNUNET_PQ_query_param_auto_from_type (
   1074       &td->details.wire_out.wire_target_h_payto),
   1075     GNUNET_PQ_query_param_string (
   1076       td->details.wire_out.exchange_account_section),
   1077     TALER_PQ_query_param_amount (
   1078       pg->conn,
   1079       &td->details.wire_out.amount),
   1080     GNUNET_PQ_query_param_end
   1081   };
   1082 
   1083   PREPARE (pg,
   1084            "insert_into_table_wire_out",
   1085            "INSERT INTO wire_out"
   1086            "(wireout_uuid"
   1087            ",execution_date"
   1088            ",wtid_raw"
   1089            ",wire_target_h_payto"
   1090            ",exchange_account_section"
   1091            ",amount"
   1092            ") VALUES "
   1093            "($1, $2, $3, $4, $5, $6);");
   1094   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1095                                              "insert_into_table_wire_out",
   1096                                              params);
   1097 }
   1098 
   1099 
   1100 /**
   1101  * Function called with aggregation_tracking records to insert into table.
   1102  *
   1103  * @param pg plugin context
   1104  * @param td record to insert
   1105  */
   1106 static enum GNUNET_DB_QueryStatus
   1107 irbt_cb_table_aggregation_tracking (struct PostgresClosure *pg,
   1108                                     const struct TALER_EXCHANGEDB_TableData *td)
   1109 {
   1110   struct GNUNET_PQ_QueryParam params[] = {
   1111     GNUNET_PQ_query_param_uint64 (&td->serial),
   1112     GNUNET_PQ_query_param_uint64 (
   1113       &td->details.aggregation_tracking.batch_deposit_serial_id),
   1114     GNUNET_PQ_query_param_auto_from_type (
   1115       &td->details.aggregation_tracking.wtid_raw),
   1116     GNUNET_PQ_query_param_end
   1117   };
   1118 
   1119   PREPARE (pg,
   1120            "insert_into_table_aggregation_tracking",
   1121            "INSERT INTO aggregation_tracking"
   1122            "(aggregation_serial_id"
   1123            ",batch_deposit_serial_id"
   1124            ",wtid_raw"
   1125            ") VALUES "
   1126            "($1, $2, $3);");
   1127   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1128                                              "insert_into_table_aggregation_tracking",
   1129                                              params);
   1130 }
   1131 
   1132 
   1133 /**
   1134  * Function called with wire_fee records to insert into table.
   1135  *
   1136  * @param pg plugin context
   1137  * @param td record to insert
   1138  */
   1139 static enum GNUNET_DB_QueryStatus
   1140 irbt_cb_table_wire_fee (struct PostgresClosure *pg,
   1141                         const struct TALER_EXCHANGEDB_TableData *td)
   1142 {
   1143   struct GNUNET_PQ_QueryParam params[] = {
   1144     GNUNET_PQ_query_param_uint64 (&td->serial),
   1145     GNUNET_PQ_query_param_string (td->details.wire_fee.wire_method),
   1146     GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.start_date),
   1147     GNUNET_PQ_query_param_timestamp (&td->details.wire_fee.end_date),
   1148     TALER_PQ_query_param_amount (
   1149       pg->conn,
   1150       &td->details.wire_fee.fees.wire),
   1151     TALER_PQ_query_param_amount (
   1152       pg->conn,
   1153       &td->details.wire_fee.fees.closing),
   1154     GNUNET_PQ_query_param_auto_from_type (&td->details.wire_fee.master_sig),
   1155     GNUNET_PQ_query_param_end
   1156   };
   1157 
   1158   PREPARE (pg,
   1159            "insert_into_table_wire_fee",
   1160            "INSERT INTO wire_fee"
   1161            "(wire_fee_serial"
   1162            ",wire_method"
   1163            ",start_date"
   1164            ",end_date"
   1165            ",wire_fee"
   1166            ",closing_fee"
   1167            ",master_sig"
   1168            ") VALUES "
   1169            "($1, $2, $3, $4, $5, $6, $7);");
   1170   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1171                                              "insert_into_table_wire_fee",
   1172                                              params);
   1173 }
   1174 
   1175 
   1176 /**
   1177  * Function called with wire_fee records to insert into table.
   1178  *
   1179  * @param pg plugin context
   1180  * @param td record to insert
   1181  */
   1182 static enum GNUNET_DB_QueryStatus
   1183 irbt_cb_table_global_fee (struct PostgresClosure *pg,
   1184                           const struct TALER_EXCHANGEDB_TableData *td)
   1185 {
   1186   struct GNUNET_PQ_QueryParam params[] = {
   1187     GNUNET_PQ_query_param_uint64 (
   1188       &td->serial),
   1189     GNUNET_PQ_query_param_timestamp (
   1190       &td->details.global_fee.start_date),
   1191     GNUNET_PQ_query_param_timestamp (
   1192       &td->details.global_fee.end_date),
   1193     TALER_PQ_query_param_amount (
   1194       pg->conn,
   1195       &td->details.global_fee.fees.history),
   1196     TALER_PQ_query_param_amount (
   1197       pg->conn,
   1198       &td->details.global_fee.fees.account),
   1199     TALER_PQ_query_param_amount (
   1200       pg->conn,
   1201       &td->details.global_fee.fees.purse),
   1202     GNUNET_PQ_query_param_relative_time (
   1203       &td->details.global_fee.purse_timeout),
   1204     GNUNET_PQ_query_param_relative_time (
   1205       &td->details.global_fee.history_expiration),
   1206     GNUNET_PQ_query_param_uint32 (
   1207       &td->details.global_fee.purse_account_limit),
   1208     GNUNET_PQ_query_param_auto_from_type (
   1209       &td->details.global_fee.master_sig),
   1210     GNUNET_PQ_query_param_end
   1211   };
   1212 
   1213   PREPARE (pg,
   1214            "insert_into_table_global_fee",
   1215            "INSERT INTO global_fee"
   1216            "(global_fee_serial"
   1217            ",start_date"
   1218            ",end_date"
   1219            ",history_fee"
   1220            ",account_fee"
   1221            ",purse_fee"
   1222            ",purse_timeout"
   1223            ",history_expiration"
   1224            ",purse_account_limit"
   1225            ",master_sig"
   1226            ") VALUES "
   1227            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
   1228   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1229                                              "insert_into_table_global_fee",
   1230                                              params);
   1231 }
   1232 
   1233 
   1234 /**
   1235  * Function called with recoup records to insert into table.
   1236  *
   1237  * @param pg plugin context
   1238  * @param td record to insert
   1239  */
   1240 static enum GNUNET_DB_QueryStatus
   1241 irbt_cb_table_recoup (struct PostgresClosure *pg,
   1242                       const struct TALER_EXCHANGEDB_TableData *td)
   1243 {
   1244   struct GNUNET_PQ_QueryParam params[] = {
   1245     GNUNET_PQ_query_param_uint64 (&td->serial),
   1246     GNUNET_PQ_query_param_auto_from_type (&td->details.recoup.coin_sig),
   1247     GNUNET_PQ_query_param_auto_from_type (&td->details.recoup.coin_blind),
   1248     TALER_PQ_query_param_amount (
   1249       pg->conn,
   1250       &td->details.recoup.amount),
   1251     GNUNET_PQ_query_param_timestamp (&td->details.recoup.timestamp),
   1252     GNUNET_PQ_query_param_auto_from_type (
   1253       &td->details.recoup.coin_pub),
   1254     GNUNET_PQ_query_param_uint64 (&td->details.recoup.withdraw_serial_id),
   1255     GNUNET_PQ_query_param_end
   1256   };
   1257 
   1258   PREPARE (pg,
   1259            "insert_into_table_recoup",
   1260            "INSERT INTO recoup"
   1261            "(recoup_uuid"
   1262            ",coin_sig"
   1263            ",coin_blind"
   1264            ",amount"
   1265            ",recoup_timestamp"
   1266            ",coin_pub"
   1267            ",withdraw_serial_id"
   1268            ") VALUES "
   1269            "($1, $2, $3, $4, $5, $6, $7);");
   1270   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1271                                              "insert_into_table_recoup",
   1272                                              params);
   1273 }
   1274 
   1275 
   1276 /**
   1277  * Function called with recoup_refresh records to insert into table.
   1278  *
   1279  * @param pg plugin context
   1280  * @param td record to insert
   1281  */
   1282 static enum GNUNET_DB_QueryStatus
   1283 irbt_cb_table_recoup_refresh (struct PostgresClosure *pg,
   1284                               const struct TALER_EXCHANGEDB_TableData *td)
   1285 {
   1286   struct GNUNET_PQ_QueryParam params[] = {
   1287     GNUNET_PQ_query_param_uint64 (&td->serial),
   1288     GNUNET_PQ_query_param_auto_from_type (&td->details.recoup_refresh.coin_sig),
   1289     GNUNET_PQ_query_param_auto_from_type (
   1290       &td->details.recoup_refresh.coin_blind),
   1291     TALER_PQ_query_param_amount (
   1292       pg->conn,
   1293       &td->details.recoup_refresh.amount),
   1294     GNUNET_PQ_query_param_timestamp (&td->details.recoup_refresh.timestamp),
   1295     GNUNET_PQ_query_param_uint64 (&td->details.recoup_refresh.known_coin_id),
   1296     GNUNET_PQ_query_param_auto_from_type (
   1297       &td->details.recoup.coin_pub),
   1298     GNUNET_PQ_query_param_uint64 (&td->details.recoup_refresh.rrc_serial),
   1299     GNUNET_PQ_query_param_end
   1300   };
   1301 
   1302   PREPARE (pg,
   1303            "insert_into_table_recoup_refresh",
   1304            "INSERT INTO recoup_refresh"
   1305            "(recoup_refresh_uuid"
   1306            ",coin_sig"
   1307            ",coin_blind"
   1308            ",amount"
   1309            ",recoup_timestamp"
   1310            ",known_coin_id"
   1311            ",coin_pub"
   1312            ",rrc_serial"
   1313            ") VALUES "
   1314            "($1, $2, $3, $4, $5, $6, $7, $8);");
   1315   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1316                                              "insert_into_table_recoup_refresh",
   1317                                              params);
   1318 }
   1319 
   1320 
   1321 /**
   1322  * Function called with extensions records to insert into table.
   1323  *
   1324  * @param pg plugin context
   1325  * @param td record to insert
   1326  */
   1327 static enum GNUNET_DB_QueryStatus
   1328 irbt_cb_table_extensions (struct PostgresClosure *pg,
   1329                           const struct TALER_EXCHANGEDB_TableData *td)
   1330 {
   1331   struct GNUNET_PQ_QueryParam params[] = {
   1332     GNUNET_PQ_query_param_uint64 (&td->serial),
   1333     GNUNET_PQ_query_param_string (td->details.extensions.name),
   1334     NULL == td->details.extensions.manifest ?
   1335     GNUNET_PQ_query_param_null () :
   1336     GNUNET_PQ_query_param_string (td->details.extensions.manifest),
   1337     GNUNET_PQ_query_param_end
   1338   };
   1339 
   1340   PREPARE (pg,
   1341            "insert_into_table_extensions",
   1342            "INSERT INTO extensions"
   1343            "(extension_id"
   1344            ",name"
   1345            ",manifest"
   1346            ") VALUES "
   1347            "($1, $2, $3);");
   1348   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1349                                              "insert_into_table_extensions",
   1350                                              params);
   1351 }
   1352 
   1353 
   1354 /**
   1355  * Function called with policy_details records to insert into table.
   1356  *
   1357  * @param pg plugin context
   1358  * @param td record to insert
   1359  */
   1360 static enum GNUNET_DB_QueryStatus
   1361 irbt_cb_table_policy_details (struct PostgresClosure *pg,
   1362                               const struct TALER_EXCHANGEDB_TableData *td)
   1363 {
   1364   struct GNUNET_PQ_QueryParam params[] = {
   1365     GNUNET_PQ_query_param_uint64 (&td->serial),
   1366     GNUNET_PQ_query_param_auto_from_type (
   1367       &td->details.policy_details.hash_code),
   1368     (td->details.policy_details.no_policy_json)
   1369       ? GNUNET_PQ_query_param_null ()
   1370       : TALER_PQ_query_param_json (td->details.policy_details.policy_json),
   1371     TALER_PQ_query_param_amount (
   1372       pg->conn,
   1373       &td->details.policy_details.commitment),
   1374     TALER_PQ_query_param_amount (
   1375       pg->conn,
   1376       &td->details.policy_details.accumulated_total),
   1377     TALER_PQ_query_param_amount (
   1378       pg->conn,
   1379       &td->details.policy_details.fee),
   1380     TALER_PQ_query_param_amount (pg->conn,
   1381                                  &td->details.policy_details.transferable),
   1382     GNUNET_PQ_query_param_timestamp (&td->details.policy_details.deadline),
   1383     GNUNET_PQ_query_param_uint16 (
   1384       &td->details.policy_details.fulfillment_state),
   1385     (td->details.policy_details.no_fulfillment_id)
   1386       ? GNUNET_PQ_query_param_null ()
   1387       : GNUNET_PQ_query_param_uint64 (
   1388       &td->details.policy_details.fulfillment_id),
   1389     GNUNET_PQ_query_param_end
   1390   };
   1391 
   1392   PREPARE (pg,
   1393            "insert_into_table_policy_details",
   1394            "INSERT INTO policy_details"
   1395            "(policy_details_serial_id"
   1396            ",policy_hash_code"
   1397            ",policy_json"
   1398            ",deadline"
   1399            ",commitment"
   1400            ",accumulated_total"
   1401            ",fee"
   1402            ",transferable"
   1403            ",fulfillment_state"
   1404            ",fulfillment_id"
   1405            ") VALUES "
   1406            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
   1407   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1408                                              "insert_into_table_policy_details",
   1409                                              params);
   1410 }
   1411 
   1412 
   1413 /**
   1414  * Function called with policy_fulfillment records to insert into table.
   1415  *
   1416  * @param pg plugin context
   1417  * @param td record to insert
   1418  */
   1419 static enum GNUNET_DB_QueryStatus
   1420 irbt_cb_table_policy_fulfillments (struct PostgresClosure *pg,
   1421                                    const struct TALER_EXCHANGEDB_TableData *td)
   1422 {
   1423   struct GNUNET_PQ_QueryParam params[] = {
   1424     GNUNET_PQ_query_param_uint64 (&td->serial),
   1425     GNUNET_PQ_query_param_timestamp (
   1426       &td->details.policy_fulfillments.fulfillment_timestamp),
   1427     (NULL == td->details.policy_fulfillments.fulfillment_proof)
   1428       ? GNUNET_PQ_query_param_null ()
   1429       : GNUNET_PQ_query_param_string (
   1430       td->details.policy_fulfillments.fulfillment_proof),
   1431     GNUNET_PQ_query_param_auto_from_type (
   1432       &td->details.policy_fulfillments.h_fulfillment_proof),
   1433     GNUNET_PQ_query_param_fixed_size (
   1434       td->details.policy_fulfillments.policy_hash_codes,
   1435       td->details.policy_fulfillments.policy_hash_codes_count),
   1436     GNUNET_PQ_query_param_end
   1437   };
   1438 
   1439   PREPARE (pg,
   1440            "insert_into_table_policy_fulfillments",
   1441            "INSERT INTO policy_fulfillments "
   1442            "(fulfillment_id"
   1443            ",fulfillment_timestamp"
   1444            ",fulfillment_proof"
   1445            ",h_fulfillment_proof"
   1446            ",policy_hash_codes"
   1447            ") VALUES "
   1448            "($1, $2, $3::TEXT::JSONB, $4, $5);");
   1449   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1450                                              "insert_into_table_policy_fulfillments",
   1451                                              params);
   1452 }
   1453 
   1454 
   1455 /**
   1456  * Function called with purse_requests records to insert into table.
   1457  *
   1458  * @param pg plugin context
   1459  * @param td record to insert
   1460  */
   1461 static enum GNUNET_DB_QueryStatus
   1462 irbt_cb_table_purse_requests (struct PostgresClosure *pg,
   1463                               const struct TALER_EXCHANGEDB_TableData *td)
   1464 {
   1465   struct GNUNET_PQ_QueryParam params[] = {
   1466     GNUNET_PQ_query_param_uint64 (&td->serial),
   1467     GNUNET_PQ_query_param_auto_from_type (
   1468       &td->details.purse_requests.purse_pub),
   1469     GNUNET_PQ_query_param_auto_from_type (
   1470       &td->details.purse_requests.merge_pub),
   1471     GNUNET_PQ_query_param_timestamp (
   1472       &td->details.purse_requests.purse_creation),
   1473     GNUNET_PQ_query_param_timestamp (
   1474       &td->details.purse_requests.purse_expiration),
   1475     GNUNET_PQ_query_param_auto_from_type (
   1476       &td->details.purse_requests.h_contract_terms),
   1477     GNUNET_PQ_query_param_uint32 (&td->details.purse_requests.age_limit),
   1478     GNUNET_PQ_query_param_uint32 (&td->details.purse_requests.flags),
   1479     TALER_PQ_query_param_amount (
   1480       pg->conn,
   1481       &td->details.purse_requests.amount_with_fee),
   1482     TALER_PQ_query_param_amount (
   1483       pg->conn,
   1484       &td->details.purse_requests.purse_fee),
   1485     GNUNET_PQ_query_param_auto_from_type (
   1486       &td->details.purse_requests.purse_sig),
   1487     GNUNET_PQ_query_param_end
   1488   };
   1489 
   1490   PREPARE (pg,
   1491            "insert_into_table_purse_requests",
   1492            "INSERT INTO purse_requests"
   1493            "(purse_requests_serial_id"
   1494            ",purse_pub"
   1495            ",merge_pub"
   1496            ",purse_creation"
   1497            ",purse_expiration"
   1498            ",h_contract_terms"
   1499            ",age_limit"
   1500            ",flags"
   1501            ",amount_with_fee"
   1502            ",purse_fee"
   1503            ",purse_sig"
   1504            ") VALUES "
   1505            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);");
   1506   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1507                                              "insert_into_table_purse_requests",
   1508                                              params);
   1509 }
   1510 
   1511 
   1512 /**
   1513  * Function called with purse_decision records to insert into table.
   1514  *
   1515  * @param pg plugin context
   1516  * @param td record to insert
   1517  */
   1518 static enum GNUNET_DB_QueryStatus
   1519 irbt_cb_table_purse_decision (struct PostgresClosure *pg,
   1520                               const struct TALER_EXCHANGEDB_TableData *td)
   1521 {
   1522   struct GNUNET_PQ_QueryParam params[] = {
   1523     GNUNET_PQ_query_param_uint64 (&td->serial),
   1524     GNUNET_PQ_query_param_auto_from_type (
   1525       &td->details.purse_decision.purse_pub),
   1526     GNUNET_PQ_query_param_timestamp (
   1527       &td->details.purse_decision.action_timestamp),
   1528     GNUNET_PQ_query_param_bool (
   1529       td->details.purse_decision.refunded),
   1530     GNUNET_PQ_query_param_end
   1531   };
   1532 
   1533   PREPARE (pg,
   1534            "insert_into_table_purse_refunds",
   1535            "INSERT INTO purse_refunds"
   1536            "(purse_refunds_serial_id"
   1537            ",purse_pub"
   1538            ",action_timestamp"
   1539            ",refunded"
   1540            ") VALUES "
   1541            "($1, $2, $3, $4);");
   1542   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1543                                              "insert_into_table_purse_decision",
   1544                                              params);
   1545 }
   1546 
   1547 
   1548 /**
   1549  * Function called with purse_merges records to insert into table.
   1550  *
   1551  * @param pg plugin context
   1552  * @param td record to insert
   1553  */
   1554 static enum GNUNET_DB_QueryStatus
   1555 irbt_cb_table_purse_merges (struct PostgresClosure *pg,
   1556                             const struct TALER_EXCHANGEDB_TableData *td)
   1557 {
   1558   struct GNUNET_PQ_QueryParam params[] = {
   1559     GNUNET_PQ_query_param_uint64 (&td->serial),
   1560     GNUNET_PQ_query_param_uint64 (&td->details.purse_merges.partner_serial_id),
   1561     GNUNET_PQ_query_param_auto_from_type (
   1562       &td->details.purse_merges.reserve_pub),
   1563     GNUNET_PQ_query_param_auto_from_type (&td->details.purse_merges.purse_pub),
   1564     GNUNET_PQ_query_param_auto_from_type (&td->details.purse_merges.merge_sig),
   1565     GNUNET_PQ_query_param_timestamp (&td->details.purse_merges.merge_timestamp),
   1566     GNUNET_PQ_query_param_end
   1567   };
   1568 
   1569   PREPARE (pg,
   1570            "insert_into_table_purse_merges",
   1571            "INSERT INTO purse_merges"
   1572            "(purse_merge_request_serial_id"
   1573            ",partner_serial_id"
   1574            ",reserve_pub"
   1575            ",purse_pub"
   1576            ",merge_sig"
   1577            ",merge_timestamp"
   1578            ") VALUES "
   1579            "($1, $2, $3, $4, $5, $6);");
   1580   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1581                                              "insert_into_table_purse_merges",
   1582                                              params);
   1583 }
   1584 
   1585 
   1586 /**
   1587  * Function called with purse_deposits records to insert into table.
   1588  *
   1589  * @param pg plugin context
   1590  * @param td record to insert
   1591  */
   1592 static enum GNUNET_DB_QueryStatus
   1593 irbt_cb_table_purse_deposits (struct PostgresClosure *pg,
   1594                               const struct TALER_EXCHANGEDB_TableData *td)
   1595 {
   1596   struct GNUNET_PQ_QueryParam params[] = {
   1597     GNUNET_PQ_query_param_uint64 (&td->serial),
   1598     GNUNET_PQ_query_param_uint64 (
   1599       &td->details.purse_deposits.partner_serial_id),
   1600     GNUNET_PQ_query_param_auto_from_type (
   1601       &td->details.purse_deposits.purse_pub),
   1602     GNUNET_PQ_query_param_auto_from_type (&td->details.purse_deposits.coin_pub),
   1603     TALER_PQ_query_param_amount (
   1604       pg->conn,
   1605       &td->details.purse_deposits.amount_with_fee),
   1606     GNUNET_PQ_query_param_auto_from_type (&td->details.purse_deposits.coin_sig),
   1607     GNUNET_PQ_query_param_end
   1608   };
   1609 
   1610   PREPARE (pg,
   1611            "insert_into_table_purse_deposits",
   1612            "INSERT INTO purse_deposits"
   1613            "(purse_deposit_serial_id"
   1614            ",partner_serial_id"
   1615            ",purse_pub"
   1616            ",coin_pub"
   1617            ",amount_with_fee"
   1618            ",coin_sig"
   1619            ") VALUES "
   1620            "($1, $2, $3, $4, $5, $6);");
   1621   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1622                                              "insert_into_table_purse_deposits",
   1623                                              params);
   1624 }
   1625 
   1626 
   1627 /**
   1628 x * Function called with account_mergers records to insert into table.
   1629  *
   1630  * @param pg plugin context
   1631  * @param td record to insert
   1632  */
   1633 static enum GNUNET_DB_QueryStatus
   1634 irbt_cb_table_account_mergers (struct PostgresClosure *pg,
   1635                                const struct TALER_EXCHANGEDB_TableData *td)
   1636 {
   1637   struct GNUNET_PQ_QueryParam params[] = {
   1638     GNUNET_PQ_query_param_uint64 (&td->serial),
   1639     GNUNET_PQ_query_param_auto_from_type (
   1640       &td->details.account_merges.reserve_pub),
   1641     GNUNET_PQ_query_param_auto_from_type (
   1642       &td->details.account_merges.reserve_sig),
   1643     GNUNET_PQ_query_param_auto_from_type (
   1644       &td->details.account_merges.purse_pub),
   1645     GNUNET_PQ_query_param_auto_from_type (
   1646       &td->details.account_merges.wallet_h_payto),
   1647     GNUNET_PQ_query_param_end
   1648   };
   1649 
   1650   PREPARE (pg,
   1651            "insert_into_table_account_merges",
   1652            "INSERT INTO account_merges"
   1653            "(account_merge_request_serial_id"
   1654            ",reserve_pub"
   1655            ",reserve_sig"
   1656            ",purse_pub"
   1657            ",wallet_h_payto"
   1658            ") VALUES "
   1659            "($1, $2, $3, $4, $5);");
   1660   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1661                                              "insert_into_table_account_merges",
   1662                                              params);
   1663 }
   1664 
   1665 
   1666 /**
   1667  * Function called with history_requests records to insert into table.
   1668  *
   1669  * @param pg plugin context
   1670  * @param td record to insert
   1671  */
   1672 static enum GNUNET_DB_QueryStatus
   1673 irbt_cb_table_history_requests (struct PostgresClosure *pg,
   1674                                 const struct TALER_EXCHANGEDB_TableData *td)
   1675 {
   1676   struct GNUNET_PQ_QueryParam params[] = {
   1677     GNUNET_PQ_query_param_uint64 (&td->serial),
   1678     GNUNET_PQ_query_param_auto_from_type (
   1679       &td->details.history_requests.reserve_pub),
   1680     GNUNET_PQ_query_param_timestamp (
   1681       &td->details.history_requests.request_timestamp),
   1682     GNUNET_PQ_query_param_auto_from_type (
   1683       &td->details.history_requests.reserve_sig),
   1684     TALER_PQ_query_param_amount (
   1685       pg->conn,
   1686       &td->details.history_requests.history_fee),
   1687     GNUNET_PQ_query_param_end
   1688   };
   1689 
   1690   PREPARE (pg,
   1691            "insert_into_table_history_requests",
   1692            "INSERT INTO history_requests"
   1693            "(history_request_serial_id"
   1694            ",reserve_pub"
   1695            ",request_timestamp"
   1696            ",reserve_sig"
   1697            ",history_fee"
   1698            ") VALUES "
   1699            "($1, $2, $3, $4, $5);");
   1700   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1701                                              "insert_into_table_history_requests",
   1702                                              params);
   1703 }
   1704 
   1705 
   1706 /**
   1707  * Function called with close_requests records to insert into table.
   1708  *
   1709  * @param pg plugin context
   1710  * @param td record to insert
   1711  */
   1712 static enum GNUNET_DB_QueryStatus
   1713 irbt_cb_table_close_requests (struct PostgresClosure *pg,
   1714                               const struct TALER_EXCHANGEDB_TableData *td)
   1715 {
   1716   struct GNUNET_PQ_QueryParam params[] = {
   1717     GNUNET_PQ_query_param_uint64 (&td->serial),
   1718     GNUNET_PQ_query_param_auto_from_type (
   1719       &td->details.close_requests.reserve_pub),
   1720     GNUNET_PQ_query_param_timestamp (
   1721       &td->details.close_requests.close_timestamp),
   1722     GNUNET_PQ_query_param_auto_from_type (
   1723       &td->details.close_requests.reserve_sig),
   1724     TALER_PQ_query_param_amount (
   1725       pg->conn,
   1726       &td->details.close_requests.close),
   1727     TALER_PQ_query_param_amount (
   1728       pg->conn,
   1729       &td->details.close_requests.close_fee),
   1730     GNUNET_PQ_query_param_string (
   1731       td->details.close_requests.payto_uri.full_payto),
   1732     GNUNET_PQ_query_param_end
   1733   };
   1734 
   1735   PREPARE (pg,
   1736            "insert_into_table_close_requests",
   1737            "INSERT INTO close_requests"
   1738            "(close_request_serial_id"
   1739            ",reserve_pub"
   1740            ",close_timestamp"
   1741            ",reserve_sig"
   1742            ",close"
   1743            ",close_fee"
   1744            ",payto_uri"
   1745            ") VALUES "
   1746            "($1, $2, $3, $4, $5, $6, $7);");
   1747   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1748                                              "insert_into_table_close_requests",
   1749                                              params);
   1750 }
   1751 
   1752 
   1753 /**
   1754  * Function called with wads_out records to insert into table.
   1755  *
   1756  * @param pg plugin context
   1757  * @param td record to insert
   1758  */
   1759 static enum GNUNET_DB_QueryStatus
   1760 irbt_cb_table_wads_out (struct PostgresClosure *pg,
   1761                         const struct TALER_EXCHANGEDB_TableData *td)
   1762 {
   1763   struct GNUNET_PQ_QueryParam params[] = {
   1764     GNUNET_PQ_query_param_uint64 (&td->serial),
   1765     GNUNET_PQ_query_param_auto_from_type (&td->details.wads_out.wad_id),
   1766     GNUNET_PQ_query_param_uint64 (&td->details.wads_out.partner_serial_id),
   1767     TALER_PQ_query_param_amount (
   1768       pg->conn,
   1769       &td->details.wads_out.amount),
   1770     GNUNET_PQ_query_param_timestamp (&td->details.wads_out.execution_time),
   1771     GNUNET_PQ_query_param_end
   1772   };
   1773 
   1774   PREPARE (pg,
   1775            "insert_into_table_wads_out",
   1776            "INSERT INTO wads_out"
   1777            "(wad_out_serial_id"
   1778            ",wad_id"
   1779            ",partner_serial_id"
   1780            ",amount"
   1781            ",execution_time"
   1782            ") VALUES "
   1783            "($1, $2, $3, $4, $5);");
   1784   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1785                                              "insert_into_table_wads_out",
   1786                                              params);
   1787 }
   1788 
   1789 
   1790 /**
   1791  * Function called with wads_out_entries records to insert into table.
   1792  *
   1793  * @param pg plugin context
   1794  * @param td record to insert
   1795  */
   1796 static enum GNUNET_DB_QueryStatus
   1797 irbt_cb_table_wads_out_entries (struct PostgresClosure *pg,
   1798                                 const struct TALER_EXCHANGEDB_TableData *td)
   1799 {
   1800   struct GNUNET_PQ_QueryParam params[] = {
   1801     GNUNET_PQ_query_param_uint64 (&td->serial),
   1802     GNUNET_PQ_query_param_uint64 (
   1803       &td->details.wads_out_entries.wad_out_serial_id),
   1804     GNUNET_PQ_query_param_auto_from_type (
   1805       &td->details.wads_out_entries.reserve_pub),
   1806     GNUNET_PQ_query_param_auto_from_type (
   1807       &td->details.wads_out_entries.purse_pub),
   1808     GNUNET_PQ_query_param_auto_from_type (
   1809       &td->details.wads_out_entries.h_contract),
   1810     GNUNET_PQ_query_param_timestamp (
   1811       &td->details.wads_out_entries.purse_expiration),
   1812     GNUNET_PQ_query_param_timestamp (
   1813       &td->details.wads_out_entries.merge_timestamp),
   1814     TALER_PQ_query_param_amount (
   1815       pg->conn,
   1816       &td->details.wads_out_entries.amount_with_fee),
   1817     TALER_PQ_query_param_amount (
   1818       pg->conn,
   1819       &td->details.wads_out_entries.wad_fee),
   1820     TALER_PQ_query_param_amount (
   1821       pg->conn,
   1822       &td->details.wads_out_entries.deposit_fees),
   1823     GNUNET_PQ_query_param_auto_from_type (
   1824       &td->details.wads_out_entries.reserve_sig),
   1825     GNUNET_PQ_query_param_auto_from_type (
   1826       &td->details.wads_out_entries.purse_sig),
   1827     GNUNET_PQ_query_param_end
   1828   };
   1829 
   1830   PREPARE (pg,
   1831            "insert_into_table_wad_out_entries",
   1832            "INSERT INTO wad_out_entries"
   1833            "(wad_out_entry_serial_id"
   1834            ",wad_out_serial_id"
   1835            ",reserve_pub"
   1836            ",purse_pub"
   1837            ",h_contract"
   1838            ",purse_expiration"
   1839            ",merge_timestamp"
   1840            ",amount_with_fee"
   1841            ",wad_fee"
   1842            ",deposit_fees"
   1843            ",reserve_sig"
   1844            ",purse_sig"
   1845            ") VALUES "
   1846            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);");
   1847   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1848                                              "insert_into_table_wads_out_entries",
   1849                                              params);
   1850 }
   1851 
   1852 
   1853 /**
   1854  * Function called with wads_in records to insert into table.
   1855  *
   1856  * @param pg plugin context
   1857  * @param td record to insert
   1858  */
   1859 static enum GNUNET_DB_QueryStatus
   1860 irbt_cb_table_wads_in (struct PostgresClosure *pg,
   1861                        const struct TALER_EXCHANGEDB_TableData *td)
   1862 {
   1863   struct GNUNET_PQ_QueryParam params[] = {
   1864     GNUNET_PQ_query_param_uint64 (&td->serial),
   1865     GNUNET_PQ_query_param_auto_from_type (&td->details.wads_in.wad_id),
   1866     GNUNET_PQ_query_param_string (td->details.wads_in.origin_exchange_url),
   1867     TALER_PQ_query_param_amount (
   1868       pg->conn,
   1869       &td->details.wads_in.amount),
   1870     GNUNET_PQ_query_param_timestamp (&td->details.wads_in.arrival_time),
   1871     GNUNET_PQ_query_param_end
   1872   };
   1873 
   1874   PREPARE (pg,
   1875            "insert_into_table_wads_in",
   1876            "INSERT INTO wads_in"
   1877            "(wad_in_serial_id"
   1878            ",wad_id"
   1879            ",origin_exchange_url"
   1880            ",amount"
   1881            ",arrival_time"
   1882            ") VALUES "
   1883            "($1, $2, $3, $4, $5);");
   1884   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1885                                              "insert_into_table_wads_in",
   1886                                              params);
   1887 }
   1888 
   1889 
   1890 /**
   1891  * Function called with wads_in_entries records to insert into table.
   1892  *
   1893  * @param pg plugin context
   1894  * @param td record to insert
   1895  */
   1896 static enum GNUNET_DB_QueryStatus
   1897 irbt_cb_table_wads_in_entries (struct PostgresClosure *pg,
   1898                                const struct TALER_EXCHANGEDB_TableData *td)
   1899 {
   1900   struct GNUNET_PQ_QueryParam params[] = {
   1901     GNUNET_PQ_query_param_uint64 (&td->serial),
   1902     GNUNET_PQ_query_param_auto_from_type (
   1903       &td->details.wads_in_entries.reserve_pub),
   1904     GNUNET_PQ_query_param_auto_from_type (
   1905       &td->details.wads_in_entries.purse_pub),
   1906     GNUNET_PQ_query_param_auto_from_type (
   1907       &td->details.wads_in_entries.h_contract),
   1908     GNUNET_PQ_query_param_timestamp (
   1909       &td->details.wads_in_entries.purse_expiration),
   1910     GNUNET_PQ_query_param_timestamp (
   1911       &td->details.wads_in_entries.merge_timestamp),
   1912     TALER_PQ_query_param_amount (
   1913       pg->conn,
   1914       &td->details.wads_in_entries.amount_with_fee),
   1915     TALER_PQ_query_param_amount (
   1916       pg->conn,
   1917       &td->details.wads_in_entries.wad_fee),
   1918     TALER_PQ_query_param_amount (
   1919       pg->conn,
   1920       &td->details.wads_in_entries.deposit_fees),
   1921     GNUNET_PQ_query_param_auto_from_type (
   1922       &td->details.wads_in_entries.reserve_sig),
   1923     GNUNET_PQ_query_param_auto_from_type (
   1924       &td->details.wads_in_entries.purse_sig),
   1925     GNUNET_PQ_query_param_end
   1926   };
   1927 
   1928   PREPARE (pg,
   1929            "insert_into_table_wad_in_entries",
   1930            "INSERT INTO wad_in_entries"
   1931            "(wad_in_entry_serial_id"
   1932            ",wad_in_serial_id"
   1933            ",reserve_pub"
   1934            ",purse_pub"
   1935            ",h_contract"
   1936            ",purse_expiration"
   1937            ",merge_timestamp"
   1938            ",amount_with_fee"
   1939            ",wad_fee"
   1940            ",deposit_fees"
   1941            ",reserve_sig"
   1942            ",purse_sig"
   1943            ") VALUES "
   1944            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);");
   1945   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1946                                              "insert_into_table_wads_in_entries",
   1947                                              params);
   1948 }
   1949 
   1950 
   1951 /**
   1952  * Function called with profit_drains records to insert into table.
   1953  *
   1954  * @param pg plugin context
   1955  * @param td record to insert
   1956  */
   1957 static enum GNUNET_DB_QueryStatus
   1958 irbt_cb_table_profit_drains (struct PostgresClosure *pg,
   1959                              const struct TALER_EXCHANGEDB_TableData *td)
   1960 {
   1961   struct GNUNET_PQ_QueryParam params[] = {
   1962     GNUNET_PQ_query_param_uint64 (&td->serial),
   1963     GNUNET_PQ_query_param_auto_from_type (
   1964       &td->details.profit_drains.wtid),
   1965     GNUNET_PQ_query_param_string (
   1966       td->details.profit_drains.account_section),
   1967     GNUNET_PQ_query_param_string (
   1968       td->details.profit_drains.payto_uri.full_payto),
   1969     GNUNET_PQ_query_param_timestamp (
   1970       &td->details.profit_drains.trigger_date),
   1971     TALER_PQ_query_param_amount (
   1972       pg->conn,
   1973       &td->details.profit_drains.amount),
   1974     GNUNET_PQ_query_param_auto_from_type (
   1975       &td->details.profit_drains.master_sig),
   1976     GNUNET_PQ_query_param_end
   1977   };
   1978 
   1979   PREPARE (pg,
   1980            "insert_into_table_profit_drains",
   1981            "INSERT INTO profit_drains"
   1982            "(profit_drain_serial_id"
   1983            ",wtid"
   1984            ",account_section"
   1985            ",payto_uri"
   1986            ",trigger_date"
   1987            ",amount"
   1988            ",master_sig"
   1989            ") VALUES "
   1990            "($1, $2, $3, $4, $5, $6, $7);");
   1991   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   1992                                              "insert_into_table_profit_drains",
   1993                                              params);
   1994 }
   1995 
   1996 
   1997 /**
   1998  * Function called with aml_staff records to insert into table.
   1999  *
   2000  * @param pg plugin context
   2001  * @param td record to insert
   2002  */
   2003 static enum GNUNET_DB_QueryStatus
   2004 irbt_cb_table_aml_staff (struct PostgresClosure *pg,
   2005                          const struct TALER_EXCHANGEDB_TableData *td)
   2006 {
   2007   struct GNUNET_PQ_QueryParam params[] = {
   2008     GNUNET_PQ_query_param_uint64 (&td->serial),
   2009     GNUNET_PQ_query_param_auto_from_type (
   2010       &td->details.aml_staff.decider_pub),
   2011     GNUNET_PQ_query_param_auto_from_type (
   2012       &td->details.aml_staff.master_sig),
   2013     GNUNET_PQ_query_param_string (
   2014       td->details.aml_staff.decider_name),
   2015     GNUNET_PQ_query_param_bool (
   2016       td->details.aml_staff.is_active),
   2017     GNUNET_PQ_query_param_bool (
   2018       td->details.aml_staff.read_only),
   2019     GNUNET_PQ_query_param_timestamp (
   2020       &td->details.aml_staff.last_change),
   2021     GNUNET_PQ_query_param_end
   2022   };
   2023 
   2024   PREPARE (pg,
   2025            "insert_into_table_aml_staff",
   2026            "INSERT INTO aml_staff"
   2027            "(aml_staff_uuid"
   2028            ",decider_pub"
   2029            ",master_sig"
   2030            ",decider_name"
   2031            ",is_active"
   2032            ",read_only"
   2033            ",last_change"
   2034            ") VALUES "
   2035            "($1, $2, $3, $4, $5, $6, $7);");
   2036   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   2037                                              "insert_into_table_aml_staff",
   2038                                              params);
   2039 }
   2040 
   2041 
   2042 /**
   2043  * Function called with kyc_attributes records to insert into table.
   2044  *
   2045  * @param pg plugin context
   2046  * @param td record to insert
   2047  */
   2048 static enum GNUNET_DB_QueryStatus
   2049 irbt_cb_table_kyc_attributes (struct PostgresClosure *pg,
   2050                               const struct TALER_EXCHANGEDB_TableData *td)
   2051 {
   2052   struct GNUNET_PQ_QueryParam params[] = {
   2053     GNUNET_PQ_query_param_uint64 (&td->serial),
   2054     GNUNET_PQ_query_param_auto_from_type (
   2055       &td->details.kyc_attributes.h_payto),
   2056     GNUNET_PQ_query_param_uint64 (
   2057       &td->details.kyc_attributes.legitimization_serial),
   2058     GNUNET_PQ_query_param_timestamp (
   2059       &td->details.kyc_attributes.collection_time),
   2060     GNUNET_PQ_query_param_timestamp (
   2061       &td->details.kyc_attributes.expiration_time),
   2062     GNUNET_PQ_query_param_uint64 (
   2063       &td->details.kyc_attributes.trigger_outcome_serial),
   2064     GNUNET_PQ_query_param_fixed_size (
   2065       &td->details.kyc_attributes.encrypted_attributes,
   2066       td->details.kyc_attributes.encrypted_attributes_size),
   2067     GNUNET_PQ_query_param_end
   2068   };
   2069 
   2070   PREPARE (pg,
   2071            "insert_into_table_kyc_attributes",
   2072            "INSERT INTO kyc_attributes"
   2073            "(kyc_attributes_serial_id"
   2074            ",h_payto"
   2075            ",legitimization_serial"
   2076            ",collection_time"
   2077            ",expiration_time"
   2078            ",trigger_outcome_serial"
   2079            ",encrypted_attributes"
   2080            ") VALUES "
   2081            "($1, $2, $3, $4, $5, $6, $7);");
   2082   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   2083                                              "insert_into_table_kyc_attributes",
   2084                                              params);
   2085 }
   2086 
   2087 
   2088 /**
   2089  * Function called with aml_history records to insert into table.
   2090  *
   2091  * @param pg plugin context
   2092  * @param td record to insert
   2093  */
   2094 static enum GNUNET_DB_QueryStatus
   2095 irbt_cb_table_aml_history (struct PostgresClosure *pg,
   2096                            const struct TALER_EXCHANGEDB_TableData *td)
   2097 {
   2098   struct GNUNET_PQ_QueryParam params[] = {
   2099     GNUNET_PQ_query_param_uint64 (&td->serial),
   2100     GNUNET_PQ_query_param_auto_from_type (
   2101       &td->details.aml_history.h_payto),
   2102     GNUNET_PQ_query_param_uint64 (
   2103       &td->details.aml_history.outcome_serial_id),
   2104     GNUNET_PQ_query_param_string (
   2105       td->details.aml_history.justification),
   2106     GNUNET_PQ_query_param_auto_from_type (
   2107       &td->details.aml_history.decider_pub),
   2108     GNUNET_PQ_query_param_auto_from_type (
   2109       &td->details.aml_history.decider_sig),
   2110     GNUNET_PQ_query_param_end
   2111   };
   2112 
   2113   PREPARE (pg,
   2114            "insert_into_table_aml_history",
   2115            "INSERT INTO aml_history"
   2116            "(aml_history_serial_id"
   2117            ",h_payto"
   2118            ",outcome_serial_id"
   2119            ",justification"
   2120            ",decider_pub"
   2121            ",decider_sig"
   2122            ") VALUES "
   2123            "($1, $2, $3, $4, $5, $6);");
   2124   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   2125                                              "insert_into_table_aml_history",
   2126                                              params);
   2127 }
   2128 
   2129 
   2130 /**
   2131  * Function called with kyc_event records to insert into table.
   2132  *
   2133  * @param pg plugin context
   2134  * @param td record to insert
   2135  */
   2136 static enum GNUNET_DB_QueryStatus
   2137 irbt_cb_table_kyc_events (struct PostgresClosure *pg,
   2138                           const struct TALER_EXCHANGEDB_TableData *td)
   2139 {
   2140   struct GNUNET_PQ_QueryParam params[] = {
   2141     GNUNET_PQ_query_param_uint64 (&td->serial),
   2142     GNUNET_PQ_query_param_timestamp (
   2143       &td->details.kyc_events.event_timestamp),
   2144     GNUNET_PQ_query_param_string (
   2145       td->details.kyc_events.event_type),
   2146     GNUNET_PQ_query_param_end
   2147   };
   2148 
   2149   PREPARE (pg,
   2150            "insert_into_table_kyc_events",
   2151            "INSERT INTO kyc_events"
   2152            "(kyc_event_serial_id"
   2153            ",event_timestamp"
   2154            ",event_type"
   2155            ") VALUES "
   2156            "($1, $2, $3);");
   2157   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   2158                                              "insert_into_table_kyc_events",
   2159                                              params);
   2160 }
   2161 
   2162 
   2163 /**
   2164  * Function called with purse_deletion records to insert into table.
   2165  *
   2166  * @param pg plugin context
   2167  * @param td record to insert
   2168  */
   2169 static enum GNUNET_DB_QueryStatus
   2170 irbt_cb_table_purse_deletion (struct PostgresClosure *pg,
   2171                               const struct TALER_EXCHANGEDB_TableData *td)
   2172 {
   2173   struct GNUNET_PQ_QueryParam params[] = {
   2174     GNUNET_PQ_query_param_uint64 (&td->serial),
   2175     GNUNET_PQ_query_param_auto_from_type (
   2176       &td->details.purse_deletion.purse_pub),
   2177     GNUNET_PQ_query_param_auto_from_type (
   2178       &td->details.purse_deletion.purse_sig),
   2179     GNUNET_PQ_query_param_end
   2180   };
   2181 
   2182   PREPARE (pg,
   2183            "insert_into_table_purse_deletion",
   2184            "INSERT INTO purse_deletion"
   2185            "(purse_deletion_serial_id"
   2186            ",purse_pub"
   2187            ",purse_sig"
   2188            ") VALUES "
   2189            "($1, $2, $3);");
   2190   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
   2191                                              "insert_into_table_purse_deletion",
   2192                                              params);
   2193 }
   2194 
   2195 
   2196 /**
   2197  * Function called with withdraw records to insert into table.
   2198  *
   2199  * @param pg plugin context
   2200  * @param td record to insert
   2201  */
   2202 static enum GNUNET_DB_QueryStatus
   2203 irbt_cb_table_withdraw (
   2204   struct PostgresClosure *pg,
   2205   const struct TALER_EXCHANGEDB_TableData *td)
   2206 {
   2207   struct GNUNET_PQ_QueryParam params[] = {
   2208     GNUNET_PQ_query_param_uint64 (&td->serial),
   2209     GNUNET_PQ_query_param_auto_from_type (
   2210       &td->details.withdraw.planchets_h),
   2211     GNUNET_PQ_query_param_timestamp (
   2212       &td->details.withdraw.execution_date),
   2213     TALER_PQ_query_param_amount (
   2214       pg->conn,
   2215       &td->details.withdraw.amount_with_fee),
   2216     GNUNET_PQ_query_param_auto_from_type (
   2217       &td->details.withdraw.reserve_pub),
   2218     GNUNET_PQ_query_param_auto_from_type (
   2219       &td->details.withdraw.reserve_sig),
   2220     td->details.withdraw.age_proof_required
   2221     ? GNUNET_PQ_query_param_uint16 (
   2222       &td->details.withdraw.max_age)
   2223     : GNUNET_PQ_query_param_null (),
   2224     td->details.withdraw.age_proof_required
   2225     ? GNUNET_PQ_query_param_uint16 (
   2226       &td->details.withdraw.noreveal_index)
   2227     : GNUNET_PQ_query_param_null (),
   2228     td->details.withdraw.age_proof_required
   2229     ? GNUNET_PQ_query_param_auto_from_type (
   2230       &td->details.withdraw.selected_h)
   2231     : GNUNET_PQ_query_param_null (),
   2232     td->details.withdraw.no_blinding_seed
   2233     ? GNUNET_PQ_query_param_null ()
   2234     : GNUNET_PQ_query_param_auto_from_type (
   2235       &td->details.withdraw.blinding_seed),
   2236     (0 < td->details.withdraw.num_cs_r_values)
   2237     ? TALER_PQ_query_param_array_cs_r_pub (
   2238       td->details.withdraw.num_cs_r_values,
   2239       td->details.withdraw.cs_r_values,
   2240       pg->conn)
   2241     : GNUNET_PQ_query_param_null (),
   2242     (0 < td->details.withdraw.num_cs_r_values)
   2243     ? GNUNET_PQ_query_param_uint64 (
   2244       &td->details.withdraw.cs_r_choices)
   2245     : GNUNET_PQ_query_param_null (),
   2246     GNUNET_PQ_query_param_array_uint64 (
   2247       td->details.withdraw.num_coins,
   2248       td->details.withdraw.denom_serials,
   2249       pg->conn),
   2250     TALER_PQ_query_param_array_blinded_denom_sig (
   2251       td->details.withdraw.num_coins,
   2252       td->details.withdraw.denom_sigs,
   2253       pg->conn),
   2254     GNUNET_PQ_query_param_end
   2255   };
   2256   enum GNUNET_DB_QueryStatus qs;
   2257 
   2258   PREPARE (pg,
   2259            "insert_into_table_withdraw",
   2260            "INSERT INTO withdraw"
   2261            "(withdraw_id"
   2262            ",planchets_h"
   2263            ",execution_date"
   2264            ",amount_with_fee"
   2265            ",reserve_pub"
   2266            ",reserve_sig"
   2267            ",max_age"
   2268            ",noreveal_index"
   2269            ",selected_h"
   2270            ",blinding_seed"
   2271            ",cs_r_values"
   2272            ",cs_r_choices"
   2273            ",denom_serials"
   2274            ",denom_sigs"
   2275            ") VALUES "
   2276            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);");
   2277   qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
   2278                                            "insert_into_table_withdraw",
   2279                                            params);
   2280   GNUNET_PQ_cleanup_query_params_closures (params);
   2281   return qs;
   2282 }
   2283 
   2284 
   2285 enum GNUNET_DB_QueryStatus
   2286 TEH_PG_insert_records_by_table (void *cls,
   2287                                 const struct TALER_EXCHANGEDB_TableData *td)
   2288 {
   2289   struct PostgresClosure *pg = cls;
   2290   InsertRecordCallback rh = NULL;
   2291 
   2292   switch (td->table)
   2293   {
   2294   case TALER_EXCHANGEDB_RT_DENOMINATIONS:
   2295     rh = &irbt_cb_table_denominations;
   2296     break;
   2297   case TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS:
   2298     rh = &irbt_cb_table_denomination_revocations;
   2299     break;
   2300   case TALER_EXCHANGEDB_RT_WIRE_TARGETS:
   2301     rh = &irbt_cb_table_wire_targets;
   2302     break;
   2303   case TALER_EXCHANGEDB_RT_KYC_TARGETS:
   2304     rh = &irbt_cb_table_kyc_targets;
   2305     break;
   2306   case TALER_EXCHANGEDB_RT_RESERVES:
   2307     rh = &irbt_cb_table_reserves;
   2308     break;
   2309   case TALER_EXCHANGEDB_RT_RESERVES_IN:
   2310     rh = &irbt_cb_table_reserves_in;
   2311     break;
   2312   case TALER_EXCHANGEDB_RT_KYCAUTHS_IN:
   2313     rh = &irbt_cb_table_kycauths_in;
   2314     break;
   2315   case TALER_EXCHANGEDB_RT_RESERVES_CLOSE:
   2316     rh = &irbt_cb_table_reserves_close;
   2317     break;
   2318   case TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS:
   2319     rh = &irbt_cb_table_reserves_open_requests;
   2320     break;
   2321   case TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS:
   2322     rh = &irbt_cb_table_reserves_open_deposits;
   2323     break;
   2324   case TALER_EXCHANGEDB_RT_AUDITORS:
   2325     rh = &irbt_cb_table_auditors;
   2326     break;
   2327   case TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS:
   2328     rh = &irbt_cb_table_auditor_denom_sigs;
   2329     break;
   2330   case TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS:
   2331     rh = &irbt_cb_table_exchange_sign_keys;
   2332     break;
   2333   case TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS:
   2334     rh = &irbt_cb_table_signkey_revocations;
   2335     break;
   2336   case TALER_EXCHANGEDB_RT_KNOWN_COINS:
   2337     rh = &irbt_cb_table_known_coins;
   2338     break;
   2339   case TALER_EXCHANGEDB_RT_REFRESH:
   2340     rh = &irbt_cb_table_refresh;
   2341     break;
   2342   case TALER_EXCHANGEDB_RT_BATCH_DEPOSITS:
   2343     rh = &irbt_cb_table_batch_deposits;
   2344     break;
   2345   case TALER_EXCHANGEDB_RT_COIN_DEPOSITS:
   2346     rh = &irbt_cb_table_coin_deposits;
   2347     break;
   2348   case TALER_EXCHANGEDB_RT_REFUNDS:
   2349     rh = &irbt_cb_table_refunds;
   2350     break;
   2351   case TALER_EXCHANGEDB_RT_WIRE_OUT:
   2352     rh = &irbt_cb_table_wire_out;
   2353     break;
   2354   case TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING:
   2355     rh = &irbt_cb_table_aggregation_tracking;
   2356     break;
   2357   case TALER_EXCHANGEDB_RT_WIRE_FEE:
   2358     rh = &irbt_cb_table_wire_fee;
   2359     break;
   2360   case TALER_EXCHANGEDB_RT_GLOBAL_FEE:
   2361     rh = &irbt_cb_table_global_fee;
   2362     break;
   2363   case TALER_EXCHANGEDB_RT_RECOUP:
   2364     rh = &irbt_cb_table_recoup;
   2365     break;
   2366   case TALER_EXCHANGEDB_RT_RECOUP_REFRESH:
   2367     rh = &irbt_cb_table_recoup_refresh;
   2368     break;
   2369   case TALER_EXCHANGEDB_RT_EXTENSIONS:
   2370     rh = &irbt_cb_table_extensions;
   2371     break;
   2372   case TALER_EXCHANGEDB_RT_POLICY_DETAILS:
   2373     rh = &irbt_cb_table_policy_details;
   2374     break;
   2375   case TALER_EXCHANGEDB_RT_POLICY_FULFILLMENTS:
   2376     rh = &irbt_cb_table_policy_fulfillments;
   2377     break;
   2378   case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
   2379     rh = &irbt_cb_table_purse_requests;
   2380     break;
   2381   case TALER_EXCHANGEDB_RT_PURSE_DECISION:
   2382     rh = &irbt_cb_table_purse_decision;
   2383     break;
   2384   case TALER_EXCHANGEDB_RT_PURSE_MERGES:
   2385     rh = &irbt_cb_table_purse_merges;
   2386     break;
   2387   case TALER_EXCHANGEDB_RT_PURSE_DEPOSITS:
   2388     rh = &irbt_cb_table_purse_deposits;
   2389     break;
   2390   case TALER_EXCHANGEDB_RT_ACCOUNT_MERGES:
   2391     rh = &irbt_cb_table_account_mergers;
   2392     break;
   2393   case TALER_EXCHANGEDB_RT_HISTORY_REQUESTS:
   2394     rh = &irbt_cb_table_history_requests;
   2395     break;
   2396   case TALER_EXCHANGEDB_RT_CLOSE_REQUESTS:
   2397     rh = &irbt_cb_table_close_requests;
   2398     break;
   2399   case TALER_EXCHANGEDB_RT_WADS_OUT:
   2400     rh = &irbt_cb_table_wads_out;
   2401     break;
   2402   case TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES:
   2403     rh = &irbt_cb_table_wads_out_entries;
   2404     break;
   2405   case TALER_EXCHANGEDB_RT_WADS_IN:
   2406     rh = &irbt_cb_table_wads_in;
   2407     break;
   2408   case TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES:
   2409     rh = &irbt_cb_table_wads_in_entries;
   2410     break;
   2411   case TALER_EXCHANGEDB_RT_PROFIT_DRAINS:
   2412     rh = &irbt_cb_table_profit_drains;
   2413     break;
   2414   case TALER_EXCHANGEDB_RT_AML_STAFF:
   2415     rh = &irbt_cb_table_aml_staff;
   2416     break;
   2417   case TALER_EXCHANGEDB_RT_PURSE_DELETION:
   2418     rh = &irbt_cb_table_purse_deletion;
   2419     break;
   2420   case TALER_EXCHANGEDB_RT_WITHDRAW:
   2421     rh = &irbt_cb_table_withdraw;
   2422     break;
   2423   case TALER_EXCHANGEDB_RT_LEGITIMIZATION_MEASURES:
   2424     rh = &irbt_cb_table_legitimization_measures;
   2425     break;
   2426   case TALER_EXCHANGEDB_RT_LEGITIMIZATION_OUTCOMES:
   2427     rh = &irbt_cb_table_legitimization_outcomes;
   2428     break;
   2429   case TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES:
   2430     rh = &irbt_cb_table_legitimization_processes;
   2431     break;
   2432   case TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES:
   2433     rh = &irbt_cb_table_kyc_attributes;
   2434     break;
   2435   case TALER_EXCHANGEDB_RT_AML_HISTORY:
   2436     rh = &irbt_cb_table_aml_history;
   2437     break;
   2438   case TALER_EXCHANGEDB_RT_KYC_EVENTS:
   2439     rh = &irbt_cb_table_kyc_events;
   2440     break;
   2441   }
   2442   if (NULL == rh)
   2443   {
   2444     GNUNET_break (0);
   2445     return GNUNET_DB_STATUS_HARD_ERROR;
   2446   }
   2447   return rh (pg,
   2448              td);
   2449 }
   2450 
   2451 
   2452 /* end of pg_insert_records_by_table.c */