exchange

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

insert_records_by_table.c (82705B)


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