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 (77693B)


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