LCOV - code coverage report
Current view: top level - backenddb - pg_insert_transfer_details.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 48 61 78.7 %
Date: 2025-06-23 16:22:09 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :    This file is part of TALER
       3             :    Copyright (C) 2022 Taler Systems SA
       4             : 
       5             :    TALER is free software; you can redistribute it and/or modify it under the
       6             :    terms of the GNU General Public License as published by the Free Software
       7             :    Foundation; either version 3, or (at your option) any later version.
       8             : 
       9             :    TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10             :    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11             :    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12             : 
      13             :    You should have received a copy of the GNU General Public License along with
      14             :    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15             :  */
      16             : /**
      17             :  * @file backenddb/pg_insert_transfer_details.c
      18             :  * @brief Implementation of the insert_transfer_details function for Postgres
      19             :  * @author Christian Grothoff
      20             :  */
      21             : #include "platform.h"
      22             : #include <taler/taler_error_codes.h>
      23             : #include <taler/taler_dbevents.h>
      24             : #include <taler/taler_pq_lib.h>
      25             : #include "pg_insert_transfer_details.h"
      26             : #include "pg_helper.h"
      27             : 
      28             : 
      29             : /**
      30             :  * How often do we re-try if we run into a DB serialization error?
      31             :  */
      32             : #define MAX_RETRIES 3
      33             : 
      34             : 
      35             : enum GNUNET_DB_QueryStatus
      36          10 : TMH_PG_insert_transfer_details (
      37             :   void *cls,
      38             :   const char *instance_id,
      39             :   const char *exchange_url,
      40             :   struct TALER_FullPayto payto_uri,
      41             :   const struct TALER_WireTransferIdentifierRawP *wtid,
      42             :   const struct TALER_EXCHANGE_TransferData *td)
      43          10 : {
      44          10 :   struct PostgresClosure *pg = cls;
      45          10 :   unsigned int len = td->details_length;
      46          10 :   struct TALER_Amount coin_values[GNUNET_NZL (len)];
      47          10 :   struct TALER_Amount deposit_fees[GNUNET_NZL (len)];
      48          10 :   const struct TALER_CoinSpendPublicKeyP *coin_pubs[GNUNET_NZL (len)];
      49          10 :   const struct TALER_PrivateContractHashP *contract_terms[GNUNET_NZL (len)];
      50             :   enum GNUNET_DB_QueryStatus qs;
      51             : 
      52          20 :   for (unsigned int i = 0; i<len; i++)
      53             :   {
      54          10 :     const struct TALER_TrackTransferDetails *tdd = &td->details[i];
      55             : 
      56          10 :     coin_values[i] = tdd->coin_value;
      57          10 :     deposit_fees[i] = tdd->coin_fee;
      58          10 :     coin_pubs[i] = &tdd->coin_pub;
      59          10 :     contract_terms[i] = &tdd->h_contract_terms;
      60             :   }
      61             : 
      62          10 :   check_connection (pg);
      63          10 :   PREPARE (pg,
      64             :            "insert_transfer_details",
      65             :            "SELECT"
      66             :            " out_no_instance"
      67             :            ",out_no_account"
      68             :            ",out_no_exchange"
      69             :            ",out_duplicate"
      70             :            ",out_conflict"
      71             :            " FROM merchant_do_insert_transfer_details"
      72             :            " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13);");
      73             : 
      74          10 :   for (unsigned int retries = 0;
      75          10 :        retries < MAX_RETRIES;
      76           0 :        retries++)
      77             :   {
      78          10 :     if (GNUNET_OK !=
      79          10 :         TMH_PG_start (pg,
      80             :                       "insert transfer details"))
      81             :     {
      82           0 :       GNUNET_break (0);
      83           0 :       return GNUNET_DB_STATUS_HARD_ERROR;
      84             :     }
      85             : 
      86             :     {
      87          10 :       struct GNUNET_PQ_QueryParam params[] = {
      88          10 :         GNUNET_PQ_query_param_string (instance_id),
      89          10 :         GNUNET_PQ_query_param_string (exchange_url),
      90          10 :         GNUNET_PQ_query_param_string (payto_uri.full_payto),
      91          10 :         GNUNET_PQ_query_param_auto_from_type (wtid),
      92          10 :         GNUNET_PQ_query_param_timestamp (&td->execution_time),
      93          10 :         GNUNET_PQ_query_param_auto_from_type (&td->exchange_pub),
      94          10 :         GNUNET_PQ_query_param_auto_from_type (&td->exchange_sig),
      95          10 :         TALER_PQ_query_param_amount_with_currency (pg->conn,
      96             :                                                    &td->total_amount),
      97          10 :         TALER_PQ_query_param_amount_with_currency (pg->conn,
      98             :                                                    &td->wire_fee),
      99          10 :         TALER_PQ_query_param_array_amount_with_currency (
     100             :           len,
     101             :           coin_values,
     102             :           pg->conn),
     103          10 :         TALER_PQ_query_param_array_amount_with_currency (
     104             :           len,
     105             :           deposit_fees,
     106             :           pg->conn),
     107          10 :         GNUNET_PQ_query_param_array_ptrs_auto_from_type (
     108             :           len,
     109             :           coin_pubs,
     110             :           pg->conn),
     111          10 :         GNUNET_PQ_query_param_array_ptrs_auto_from_type (
     112             :           len,
     113             :           contract_terms,
     114             :           pg->conn),
     115             :         GNUNET_PQ_query_param_end
     116             :       };
     117             :       bool no_instance;
     118             :       bool no_account;
     119             :       bool no_exchange;
     120             :       bool duplicate;
     121             :       bool conflict;
     122          10 :       struct GNUNET_PQ_ResultSpec rs[] = {
     123          10 :         GNUNET_PQ_result_spec_bool ("out_no_instance",
     124             :                                     &no_instance),
     125          10 :         GNUNET_PQ_result_spec_bool ("out_no_account",
     126             :                                     &no_account),
     127          10 :         GNUNET_PQ_result_spec_bool ("out_no_exchange",
     128             :                                     &no_exchange),
     129          10 :         GNUNET_PQ_result_spec_bool ("out_duplicate",
     130             :                                     &duplicate),
     131          10 :         GNUNET_PQ_result_spec_bool ("out_conflict",
     132             :                                     &conflict),
     133             :         GNUNET_PQ_result_spec_end
     134             :       };
     135             : 
     136          10 :       qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
     137             :                                                      "insert_transfer_details",
     138             :                                                      params,
     139             :                                                      rs);
     140          10 :       GNUNET_PQ_cleanup_query_params_closures (params);
     141          10 :       if (0 >= qs)
     142             :       {
     143           0 :         GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
     144           0 :         TMH_PG_rollback (pg);
     145           0 :         if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
     146           0 :           continue;
     147           0 :         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     148             :                     "'insert_transfer_details' failed with status %d\n",
     149             :                     qs);
     150           0 :         return qs;
     151             :       }
     152          10 :       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     153             :                   "Transfer details inserted: %s%s%s%s%s\n",
     154             :                   no_instance ? "no instance " : "",
     155             :                   no_account ? "no account " : "",
     156             :                   no_exchange ? "no exchange ": "",
     157             :                   duplicate ? "duplicate ": "",
     158             :                   conflict ? "conflict" : "");
     159             :     }
     160             : 
     161          10 :     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     162             :                 "Committing transaction...\n");
     163          10 :     qs = TMH_PG_commit (pg);
     164          10 :     if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     165          10 :       return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
     166           0 :     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
     167           0 :     if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
     168           0 :       break;
     169             :   }
     170           0 :   return qs;
     171             : }

Generated by: LCOV version 1.16