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


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