exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

sq_result_helper.c (6482B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2020 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 sq/sq_result_helper.c
     18  * @brief functions to initialize parameter arrays
     19  * @author Jonathan Buchanan
     20  */
     21 #include <sqlite3.h>
     22 #include <gnunet/gnunet_util_lib.h>
     23 #include <gnunet/gnunet_sq_lib.h>
     24 #include "taler/taler_sq_lib.h"
     25 #include "taler/taler_util.h"
     26 
     27 
     28 /**
     29  * Extract amount data from a SQLite database
     30  *
     31  * @param cls closure, a `const char *` giving the currency
     32  * @param result where to extract data from
     33  * @param column column to extract data from
     34  * @param[in,out] dst_size where to store size of result, may be NULL
     35  * @param[out] dst where to store the result
     36  * @return
     37  *   #GNUNET_YES if all results could be extracted
     38  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
     39  */
     40 static enum GNUNET_GenericReturnValue
     41 extract_amount (void *cls,
     42                 sqlite3_stmt *result,
     43                 unsigned int column,
     44                 size_t *dst_size,
     45                 void *dst)
     46 {
     47   struct TALER_Amount *amount = dst;
     48   const char *currency = cls;
     49   uint64_t frac;
     50 
     51   if ((sizeof (struct TALER_Amount) != *dst_size) ||
     52       (SQLITE_INTEGER != sqlite3_column_type (result,
     53                                               (int) column)) ||
     54       (SQLITE_INTEGER != sqlite3_column_type (result,
     55                                               (int) column + 1)))
     56   {
     57     GNUNET_break (0);
     58     return GNUNET_SYSERR;
     59   }
     60   GNUNET_strlcpy (amount->currency,
     61                   currency,
     62                   TALER_CURRENCY_LEN);
     63   amount->value = (uint64_t) sqlite3_column_int64 (result,
     64                                                    (int) column);
     65   frac = (uint64_t) sqlite3_column_int64 (result,
     66                                           (int) column + 1);
     67   amount->fraction = (uint32_t) frac;
     68   return GNUNET_YES;
     69 }
     70 
     71 
     72 struct GNUNET_SQ_ResultSpec
     73 TALER_SQ_result_spec_amount (const char *currency,
     74                              struct TALER_Amount *amount)
     75 {
     76   struct GNUNET_SQ_ResultSpec res = {
     77     .conv = &extract_amount,
     78     .cls = (void *) currency,
     79     .dst = (void *) amount,
     80     .dst_size = sizeof (struct TALER_Amount),
     81     .num_params = 2
     82   };
     83 
     84   return res;
     85 }
     86 
     87 
     88 /**
     89  * Extract amount data from a SQLite database
     90  *
     91  * @param cls closure, a `const char *` giving the currency
     92  * @param result where to extract data from
     93  * @param column column to extract data from
     94  * @param[in,out] dst_size where to store size of result, may be NULL
     95  * @param[out] dst where to store the result
     96  * @return
     97  *   #GNUNET_YES if all results could be extracted
     98  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
     99  */
    100 static enum GNUNET_GenericReturnValue
    101 extract_amount_nbo (void *cls,
    102                     sqlite3_stmt *result,
    103                     unsigned int column,
    104                     size_t *dst_size,
    105                     void *dst)
    106 {
    107   struct TALER_AmountNBO *amount = dst;
    108   struct TALER_Amount amount_hbo;
    109   size_t amount_hbo_size = sizeof (struct TALER_Amount);
    110 
    111   (void) cls;
    112   (void) dst_size;
    113   if (GNUNET_YES !=
    114       extract_amount (cls,
    115                       result,
    116                       column,
    117                       &amount_hbo_size,
    118                       &amount_hbo))
    119   {
    120     GNUNET_break (0);
    121     return GNUNET_SYSERR;
    122   }
    123   TALER_amount_hton (amount,
    124                      &amount_hbo);
    125   return GNUNET_YES;
    126 }
    127 
    128 
    129 struct GNUNET_SQ_ResultSpec
    130 TALER_SQ_result_spec_amount_nbo (const char *currency,
    131                                  struct TALER_AmountNBO *amount)
    132 {
    133   struct GNUNET_SQ_ResultSpec res = {
    134     .conv = &extract_amount_nbo,
    135     .cls = (void *) currency,
    136     .dst = (void *) amount,
    137     .dst_size = sizeof (struct TALER_AmountNBO),
    138     .num_params = 2
    139   };
    140 
    141   return res;
    142 }
    143 
    144 
    145 /**
    146  * Extract amount data from a SQLite database
    147  *
    148  * @param cls closure
    149  * @param result where to extract data from
    150  * @param column column to extract data from
    151  * @param[in,out] dst_size where to store size of result, may be NULL
    152  * @param[out] dst where to store the result
    153  * @return
    154  *   #GNUNET_YES if all results could be extracted
    155  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
    156  */
    157 static enum GNUNET_GenericReturnValue
    158 extract_json (void *cls,
    159               sqlite3_stmt *result,
    160               unsigned int column,
    161               size_t *dst_size,
    162               void *dst)
    163 {
    164   json_t **j_dst = dst;
    165   const char *res;
    166   json_error_t json_error;
    167   size_t slen;
    168 
    169   (void) cls;
    170   (void) dst_size;
    171   if (SQLITE_TEXT != sqlite3_column_type (result,
    172                                           column))
    173   {
    174     GNUNET_break (0);
    175     return GNUNET_SYSERR;
    176   }
    177   res = (const char *) sqlite3_column_text (result,
    178                                             column);
    179   slen = strlen (res);
    180   *j_dst = json_loadb (res,
    181                        slen,
    182                        JSON_REJECT_DUPLICATES,
    183                        &json_error);
    184   if (NULL == *j_dst)
    185   {
    186     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    187                 "Failed to parse JSON result for column %d: %s (%s)\n",
    188                 column,
    189                 json_error.text,
    190                 json_error.source);
    191     return GNUNET_SYSERR;
    192   }
    193   return GNUNET_OK;
    194 }
    195 
    196 
    197 /**
    198  * Function called to clean up memory allocated
    199  * by a #GNUNET_SQ_ResultConverter.
    200  *
    201  * @param cls closure
    202  */
    203 static void
    204 clean_json (void *cls)
    205 {
    206   json_t **dst = cls;
    207 
    208   (void) cls;
    209   if (NULL != *dst)
    210   {
    211     json_decref (*dst);
    212     *dst = NULL;
    213   }
    214 }
    215 
    216 
    217 /**
    218  * json_t expected.
    219  *
    220  * @param[out] jp where to store the result
    221  * @return array entry for the result specification to use
    222  */
    223 struct GNUNET_SQ_ResultSpec
    224 TALER_SQ_result_spec_json (json_t **jp)
    225 {
    226   struct GNUNET_SQ_ResultSpec res = {
    227     .conv = &extract_json,
    228     .cleaner = &clean_json,
    229     .dst = (void *) jp,
    230     .cls = (void *) jp,
    231     .num_params = 1
    232   };
    233 
    234   return res;
    235 }
    236 
    237 
    238 /* end of sq/sq_result_helper.c */