From 83319e1782da625a0a323bd5cfbf9b155e929a06 Mon Sep 17 00:00:00 2001 From: Jonathan Buchanan Date: Tue, 2 Jun 2020 14:20:55 -0400 Subject: implemented the other functions for taler_sq_lib --- src/sq/sq_result_helper.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) (limited to 'src/sq/sq_result_helper.c') diff --git a/src/sq/sq_result_helper.c b/src/sq/sq_result_helper.c index ef36d3e90..d313ed599 100644 --- a/src/sq/sq_result_helper.c +++ b/src/sq/sq_result_helper.c @@ -89,4 +89,297 @@ TALER_SQ_result_spec_amount_nbo (const char *currency, } +/** + * Extract amount data from a SQLite database + * + * @param cls closure, a `const char *` giving the currency + * @param result where to extract data from + * @param column column to extract data from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_amount (void *cls, + sqlite3_stmt *result, + unsigned int column, + size_t *dst_size, + void *dst) +{ + struct TALER_Amount *amount = dst; + struct TALER_AmountNBO amount_nbo; + if (GNUNET_YES == extract_amount_nbo (cls, + result, + column, + dst_size, + &amount_nbo)) + { + TALER_amount_ntoh (amount, + &amount_nbo); + return GNUNET_YES; + } + else + { + return GNUNET_SYSERR; + } + +} + + +/** + * Currency amount expected. + * + * @param currency the currency to use for @a amount + * @param[out] amount where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +TALER_SQ_result_spec_amount (const char *currency, + struct TALER_Amount *amount) +{ + struct GNUNET_SQ_ResultSpec res = { + .conv = &extract_amount, + .cls = (void *) currency, + .dst = (void *) amount, + .dst_size = sizeof (struct TALER_Amount), + .num_params = 2 + }; + + return res; +} + + +/** + * Extract amount data from a SQLite database + * + * @param cls closure + * @param result where to extract data from + * @param column column to extract data from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_json (void *cls, + sqlite3_stmt *result, + unsigned int column, + size_t *dst_size, + void *dst) +{ + json_t **j_dst = dst; + const char *res; + json_error_t json_error; + size_t slen; + + (void) cls; + (void) dst_size; + if (SQLITE_TEXT != sqlite3_column_type (result, + column)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + res = (const char *) sqlite3_column_text (result, + column); + slen = strlen (res); + *j_dst = json_loadb (res, + slen, + JSON_REJECT_DUPLICATES, + &json_error); + if (NULL == *j_dst) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse JSON result for column %d: %s (%s)\n", + column, + json_error.text, + json_error.source); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Function called to clean up memory allocated + * by a #GNUNET_SQ_ResultConverter. + * + * @param cls closure + */ +static void +clean_json (void *cls) +{ + json_t **dst = cls; + + (void) cls; + if (NULL != *dst) + { + json_decref (*dst); + *dst = NULL; + } +} + + +/** + * json_t expected. + * + * @param[out] jp where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +TALER_SQ_result_spec_json (json_t **jp) +{ + struct GNUNET_SQ_ResultSpec res = { + .conv = &extract_json, + .cleaner = &clean_json, + .dst = (void *) jp, + .cls = (void *) jp, + .num_params = 1 + }; + + return res; +} + + +/** + * Extract amount data from a SQLite database + * + * @param cls closure + * @param result where to extract data from + * @param column column to extract data from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_round_time (void *cls, + sqlite3_stmt *result, + unsigned int column, + size_t *dst_size, + void *dst) +{ + struct GNUNET_TIME_Absolute *udst = dst; + struct GNUNET_TIME_AbsoluteNBO res; + struct GNUNET_TIME_Absolute tmp; + + (void) cls; + if (SQLITE_INTEGER != sqlite3_column_type (result, + (int) column)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_assert (NULL != dst); + if (sizeof (struct GNUNET_TIME_Absolute) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + res.abs_value_us__ = sqlite3_column_int64 (result, + (int) column); + tmp = GNUNET_TIME_absolute_ntoh (res); + GNUNET_break (GNUNET_OK == + GNUNET_TIME_round_abs (&tmp)); + *udst = tmp; + return GNUNET_OK; +} + + +/** + * Rounded absolute time expected. + * In contrast to #GNUNET_SQ_query_param_absolute_time_nbo(), + * this function ensures that the result is rounded and can + * be converted to JSON. + * + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +TALER_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at) +{ + struct GNUNET_SQ_ResultSpec res = { + .conv = &extract_round_time, + .dst = (void *) at, + .dst_size = sizeof (struct GNUNET_TIME_Absolute), + .num_params = 1 + }; + + return res; +} + + +/** + * Extract amount data from a SQLite database + * + * @param cls closure + * @param result where to extract data from + * @param column column to extract data from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_round_time_nbo (void *cls, + sqlite3_stmt *result, + unsigned int column, + size_t *dst_size, + void *dst) +{ + struct GNUNET_TIME_AbsoluteNBO *udst = dst; + struct GNUNET_TIME_AbsoluteNBO res; + struct GNUNET_TIME_Absolute tmp; + + (void) cls; + if (SQLITE_INTEGER != sqlite3_column_type (result, + (int) column)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_assert (NULL != dst); + if (sizeof (struct GNUNET_TIME_AbsoluteNBO) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + res.abs_value_us__ = sqlite3_column_int64 (result, + (int) column); + tmp = GNUNET_TIME_absolute_ntoh (res); + GNUNET_break (GNUNET_OK == + GNUNET_TIME_round_abs (&tmp)); + *udst = GNUNET_TIME_absolute_hton (tmp); + return GNUNET_OK; +} + + +/** + * Rounded absolute time expected. + * In contrast to #GNUNET_SQ_result_spec_absolute_time_nbo(), + * this function ensures that the result is rounded and can + * be converted to JSON. + * + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +TALER_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at) +{ + struct GNUNET_SQ_ResultSpec res = { + .conv = &extract_round_time_nbo, + .dst = (void *) at, + .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO), + .num_params = 1 + }; + + return res; +} + + /* end of sq/sq_result_helper.c */ -- cgit v1.2.3