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


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