LCOV - code coverage report
Current view: top level - backenddb - iterate_token_family_keys.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.6 % 52 44
Test Date: 2026-09-04 23:42:01 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /*
       2              :    This file is part of TALER
       3              :    Copyright (C) 2024 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 src/backenddb/iterate_token_family_keys.c
      18              :  * @brief Implementation of the iterate_token_family_keys function for Postgres
      19              :  * @author Christian Grothoff
      20              :  */
      21              : #include "platform.h"
      22              : #include <taler/taler_pq_lib.h>
      23              : #include "merchant-database/iterate_token_family_keys.h"
      24              : #include "helper.h"
      25              : 
      26              : 
      27              : /**
      28              :  * Closure for lookup_token_keys_cb().
      29              :  */
      30              : struct Context
      31              : {
      32              :   /**
      33              :    * Postgres handle.
      34              :    */
      35              :   struct TALER_MERCHANTDB_PostgresContext *pg;
      36              : 
      37              :   /**
      38              :    * Function to call on each result.
      39              :    */
      40              :   TALER_MERCHANTDB_TokenKeyCallback cb;
      41              : 
      42              :   /**
      43              :    * Closure for @e cb.
      44              :    */
      45              :   void *cb_cls;
      46              : 
      47              :   /**
      48              :    * Did database result extraction fail?
      49              :    */
      50              :   bool extract_failed;
      51              : };
      52              : 
      53              : 
      54              : /**
      55              :  * Function to be called with the results of a SELECT statement
      56              :  * that has returned @a num_results results about products.
      57              :  *
      58              :  * @param[in,out] cls of type `struct LookupProductsContext *`
      59              :  * @param result the postgres result
      60              :  * @param num_results the number of results in @a result
      61              :  */
      62              : static void
      63            5 : lookup_token_keys_cb (void *cls,
      64              :                       PGresult *result,
      65              :                       unsigned int num_results)
      66              : {
      67            5 :   struct Context *ctx = cls;
      68              : 
      69           10 :   for (unsigned int i = 0; i < num_results; i++)
      70              :   {
      71              :     struct TALER_MERCHANTDB_TokenFamilyKeyDetails details;
      72              :     char *kind;
      73            5 :     struct GNUNET_PQ_ResultSpec rs[] = {
      74            5 :       GNUNET_PQ_result_spec_allow_null (
      75              :         GNUNET_PQ_result_spec_blind_sign_pub ("pub",
      76              :                                               &details.pub.public_key),
      77              :         NULL),
      78            5 :       GNUNET_PQ_result_spec_allow_null (
      79              :         GNUNET_PQ_result_spec_blind_sign_priv ("priv",
      80              :                                                &details.priv.private_key),
      81              :         NULL),
      82            5 :       GNUNET_PQ_result_spec_allow_null (
      83              :         GNUNET_PQ_result_spec_timestamp ("signature_validity_start",
      84              :                                          &details.signature_validity_start),
      85              :         NULL),
      86            5 :       GNUNET_PQ_result_spec_allow_null (
      87              :         GNUNET_PQ_result_spec_timestamp ("signature_validity_end",
      88              :                                          &details.signature_validity_end),
      89              :         NULL),
      90            5 :       GNUNET_PQ_result_spec_allow_null (
      91              :         GNUNET_PQ_result_spec_timestamp ("private_key_deleted_at",
      92              :                                          &details.private_key_deleted_at),
      93              :         NULL),
      94            5 :       GNUNET_PQ_result_spec_string ("slug",
      95              :                                     &details.token_family.slug),
      96            5 :       GNUNET_PQ_result_spec_string ("name",
      97              :                                     &details.token_family.name),
      98            5 :       GNUNET_PQ_result_spec_string ("description",
      99              :                                     &details.token_family.description),
     100            5 :       GNUNET_PQ_result_spec_string ("cipher_choice",
     101              :                                     &details.token_family.cipher_spec),
     102            5 :       TALER_PQ_result_spec_json ("description_i18n",
     103              :                                  &details.token_family.description_i18n),
     104            5 :       GNUNET_PQ_result_spec_timestamp ("valid_after",
     105              :                                        &details.token_family.valid_after),
     106            5 :       GNUNET_PQ_result_spec_timestamp ("valid_before",
     107              :                                        &details.token_family.valid_before),
     108            5 :       GNUNET_PQ_result_spec_relative_time ("duration",
     109              :                                            &details.token_family.duration),
     110            5 :       GNUNET_PQ_result_spec_relative_time ("validity_granularity",
     111              :                                            &details.token_family.
     112              :                                            validity_granularity),
     113            5 :       GNUNET_PQ_result_spec_relative_time ("start_offset",
     114              :                                            &details.token_family.start_offset),
     115            5 :       GNUNET_PQ_result_spec_string ("kind",
     116              :                                     &kind),
     117            5 :       GNUNET_PQ_result_spec_uint64 ("issued",
     118              :                                     &details.token_family.issued),
     119            5 :       GNUNET_PQ_result_spec_uint64 ("used",
     120              :                                     &details.token_family.used),
     121              :       GNUNET_PQ_result_spec_end
     122              :     };
     123              : 
     124            5 :     memset (&details,
     125              :             0,
     126              :             sizeof (details));
     127            5 :     if (GNUNET_OK !=
     128            5 :         GNUNET_PQ_extract_result (result,
     129              :                                   rs,
     130              :                                   i))
     131              :     {
     132            0 :       GNUNET_break (0);
     133            0 :       ctx->extract_failed = true;
     134            0 :       return;
     135              :     }
     136            5 :     if (0 == strcmp (kind,
     137              :                      "discount"))
     138            1 :       details.token_family.kind = TALER_MERCHANTDB_TFK_Discount;
     139            4 :     else if (0 == strcmp (kind,
     140              :                           "subscription"))
     141            4 :       details.token_family.kind = TALER_MERCHANTDB_TFK_Subscription;
     142              :     else
     143              :     {
     144            0 :       GNUNET_break (0);
     145            0 :       GNUNET_free (kind);
     146            0 :       GNUNET_PQ_cleanup_result (rs);
     147            0 :       return;
     148              :     }
     149            5 :     ctx->cb (ctx->cb_cls,
     150              :              &details);
     151            5 :     GNUNET_PQ_cleanup_result (rs);
     152              :   }
     153              : }
     154              : 
     155              : 
     156              : enum GNUNET_DB_QueryStatus
     157            5 : TALER_MERCHANTDB_iterate_token_family_keys (
     158              :   struct TALER_MERCHANTDB_PostgresContext *pg,
     159              :   const char *instance_id,
     160              :   const char *token_family_slug,
     161              :   struct GNUNET_TIME_Timestamp start_time,
     162              :   struct GNUNET_TIME_Timestamp end_time,
     163              :   TALER_MERCHANTDB_TokenKeyCallback cb,
     164              :   void *cb_cls)
     165              : {
     166            5 :   struct GNUNET_PQ_QueryParam params[] = {
     167            5 :     GNUNET_PQ_query_param_string (token_family_slug),
     168            5 :     GNUNET_PQ_query_param_timestamp (&start_time),
     169            5 :     GNUNET_PQ_query_param_timestamp (&end_time),
     170              :     GNUNET_PQ_query_param_end
     171              :   };
     172            5 :   struct Context ctx = {
     173              :     .pg = pg,
     174              :     .cb = cb,
     175              :     .cb_cls = cb_cls
     176              :   };
     177              :   enum GNUNET_DB_QueryStatus qs;
     178              : 
     179            5 :   GNUNET_assert (NULL != pg->current_merchant_id);
     180            5 :   GNUNET_assert (0 == strcmp (instance_id,
     181              :                               pg->current_merchant_id));
     182            5 :   TMH_PQ_prepare_anon (pg,
     183              :                        "SELECT"
     184              :                        " h_pub"
     185              :                        ",mtfk.pub"
     186              :                        ",mtfk.priv"
     187              :                        ",cipher_choice"
     188              :                        ",mtfk.signature_validity_start"
     189              :                        ",mtfk.signature_validity_end"
     190              :                        ",mtfk.private_key_deleted_at"
     191              :                        ",slug"
     192              :                        ",name"
     193              :                        ",description"
     194              :                        ",description_i18n::TEXT"
     195              :                        ",mtf.valid_after"
     196              :                        ",mtf.valid_before"
     197              :                        ",duration"
     198              :                        ",validity_granularity"
     199              :                        ",start_offset"
     200              :                        ",kind"
     201              :                        ",issued"
     202              :                        ",used"
     203              :                        " FROM merchant_token_families mtf"
     204              :                        " LEFT JOIN merchant_token_family_keys mtfk"
     205              :                        "   USING (token_family_serial)"
     206              :                        " WHERE slug=$1"
     207              :                        "   AND COALESCE ($2 <= mtfk.signature_validity_end, TRUE)"
     208              :                        "   AND COALESCE ($3 >= mtfk.signature_validity_start, TRUE);");
     209            5 :   qs = GNUNET_PQ_eval_prepared_multi_select (
     210              :     pg->conn,
     211              :     "",
     212              :     params,
     213              :     &lookup_token_keys_cb,
     214              :     &ctx);
     215            5 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     216              :               "Lookup of MTFK %s with valid [%llu,%llu] got %d\n",
     217              :               token_family_slug,
     218              :               (unsigned long long) start_time.abs_time.abs_value_us,
     219              :               (unsigned long long) end_time.abs_time.abs_value_us,
     220              :               (int) qs);
     221            5 :   if (ctx.extract_failed)
     222            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     223            5 :   return qs;
     224              : }
        

Generated by: LCOV version 2.0-1