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


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