summaryrefslogtreecommitdiff
path: root/src/sq/sq_result_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sq/sq_result_helper.c')
-rw-r--r--src/sq/sq_result_helper.c293
1 files changed, 293 insertions, 0 deletions
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 */