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


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