diff options
| -rw-r--r-- | src/include/taler_sq_lib.h | 102 | ||||
| -rw-r--r-- | src/sq/sq_query_helper.c | 216 | ||||
| -rw-r--r-- | src/sq/sq_result_helper.c | 293 | ||||
| -rw-r--r-- | src/sq/test_sq.c | 71 | 
4 files changed, 668 insertions, 14 deletions
| diff --git a/src/include/taler_sq_lib.h b/src/include/taler_sq_lib.h index f6a35225..66bd38c8 100644 --- a/src/include/taler_sq_lib.h +++ b/src/include/taler_sq_lib.h @@ -27,7 +27,7 @@  #include "taler_util.h"  /** - * Generate query parameter for a currency, consisting of the three + * Generate query parameter for a currency, consisting of the   * components "value", "fraction" in this order. The   * types must be a 64-bit integer and a 64-bit integer.   * @@ -36,6 +36,57 @@  struct GNUNET_SQ_QueryParam  TALER_SQ_query_param_amount_nbo (const struct TALER_AmountNBO *x); + +/** + * Generate query parameter for a currency, consisting of the + * components "value", "fraction" in this order. The + * types must be a 64-bit integer and a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_amount (const struct TALER_Amount *x); + + +/** + * Generate query parameter for a JSON object (stored as a string + * in the DB).  Note that @a x must really be a JSON object or array, + * passing just a value (string, integer) is not supported and will + * result in an abort. + * + * @param x pointer to the json object to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_json (const json_t *x); + + +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_SQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); + + +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_SQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_absolute_time_nbo (const struct +                                        GNUNET_TIME_AbsoluteNBO *x); + +  /**   * Currency amount expected.   * @@ -47,6 +98,55 @@ struct GNUNET_SQ_ResultSpec  TALER_SQ_result_spec_amount_nbo (const char *currency,                                   struct TALER_AmountNBO *amount); + +/** + * Currency amount expected. + * + * @param currency 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); + + +/** + * 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); + + +/** + * 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); + + +/** + * 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); + +  #endif  /* TALER_SQ_LIB_H_ */  /* end of include/taler_sq_lib.h */ diff --git a/src/sq/sq_query_helper.c b/src/sq/sq_query_helper.c index 8116622a..8e385355 100644 --- a/src/sq/sq_query_helper.c +++ b/src/sq/sq_query_helper.c @@ -45,6 +45,7 @@ qconv_amount_nbo (void *cls,  {    const struct TALER_AmountNBO *amount = data; +  (void) cls;    GNUNET_assert (sizeof (struct TALER_AmountNBO) == data_len);    if (SQLITE_OK != sqlite3_bind_int64 (stmt,                                         (int) off, @@ -59,7 +60,7 @@ qconv_amount_nbo (void *cls,  /** - * Generate query parameter for a currency, consisting of the three + * Generate query parameter for a currency, consisting of the   * components "value", "fraction" in this order. The   * types must be a 64-bit integer and a 64-bit integer.   * @@ -74,4 +75,217 @@ TALER_SQ_query_param_amount_nbo (const struct TALER_AmountNBO *x)  } +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument, here a `struct TALER_Amount` + * @param data_len number of bytes in @a data (if applicable) + * @param stmt sqlite statement to parameters for + * @param off offset of the argument to bind in @a stmt, numbered from 1, + *            so immediately suitable for passing to `sqlite3_bind`-functions. + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +static int +qconv_amount (void *cls, +              const void *data, +              size_t data_len, +              sqlite3_stmt *stmt, +              unsigned int off) +{ +  const struct TALER_Amount *amount_hbo = data; +  struct TALER_AmountNBO amount; + +  (void) cls; +  GNUNET_assert (sizeof (struct TALER_AmountNBO) == data_len); +  TALER_amount_hton (&amount, +                     amount_hbo); +  return qconv_amount_nbo (cls, +                           &amount, +                           sizeof (struct TALER_AmountNBO), +                           stmt, +                           off); +} + + +/** + * Generate query parameter for a currency, consisting of the + * components "value", "fraction" in this order. The + * types must be a 64-bit integer and a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_amount (const struct TALER_Amount *x) +{ +  struct GNUNET_SQ_QueryParam res = +  { &qconv_amount, NULL, x, sizeof (*x), 2 }; +  return res; +} + + +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument, here a `struct TALER_Amount` + * @param data_len number of bytes in @a data (if applicable) + * @param stmt sqlite statement to parameters for + * @param off offset of the argument to bind in @a stmt, numbered from 1, + *            so immediately suitable for passing to `sqlite3_bind`-functions. + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +static int +qconv_json (void *cls, +            const void *data, +            size_t data_len, +            sqlite3_stmt *stmt, +            unsigned int off) +{ +  const json_t *json = data; +  char *str; + +  (void) cls; +  (void) data_len; +  str = json_dumps (json, JSON_COMPACT); +  if (NULL == str) +    return GNUNET_SYSERR; + +  if (SQLITE_OK != sqlite3_bind_text (stmt, +                                      (int) off, +                                      str, +                                      strlen (str) + 1, +                                      SQLITE_TRANSIENT)) +    return GNUNET_SYSERR; +  GNUNET_free (str); +  return GNUNET_OK; +} + + +/** + * Generate query parameter for a JSON object (stored as a string + * in the DB).  Note that @a x must really be a JSON object or array, + * passing just a value (string, integer) is not supported and will + * result in an abort. + * + * @param x pointer to the json object to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_json (const json_t *x) +{ +  struct GNUNET_SQ_QueryParam res = +  { &qconv_json, NULL, x, sizeof (*x), 1 }; +  return res; +} + + +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument, here a `struct TALER_Amount` + * @param data_len number of bytes in @a data (if applicable) + * @param stmt sqlite statement to parameters for + * @param off offset of the argument to bind in @a stmt, numbered from 1, + *            so immediately suitable for passing to `sqlite3_bind`-functions. + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +static int +qconv_round_time (void *cls, +                  const void *data, +                  size_t data_len, +                  sqlite3_stmt *stmt, +                  unsigned int off) +{ +  const struct GNUNET_TIME_Absolute *at = data; +  struct GNUNET_TIME_Absolute tmp; +  struct GNUNET_TIME_AbsoluteNBO buf; + +  (void) cls; +  GNUNET_assert (sizeof (struct GNUNET_TIME_AbsoluteNBO) == data_len); +  GNUNET_break (NULL == cls); +  tmp = *at; +  GNUNET_assert (GNUNET_OK == +                 GNUNET_TIME_round_abs (&tmp)); +  buf = GNUNET_TIME_absolute_hton (tmp); +  if (SQLITE_OK != sqlite3_bind_int64 (stmt, +                                       (int) off, +                                       (sqlite3_int64) buf.abs_value_us__)) +    return GNUNET_SYSERR; +  return GNUNET_OK; +} + + +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_SQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) +{ +  struct GNUNET_SQ_QueryParam res = +  { &qconv_round_time, NULL, x, sizeof (*x), 1 }; +  return res; +} + + +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument, here a `struct TALER_Amount` + * @param data_len number of bytes in @a data (if applicable) + * @param stmt sqlite statement to parameters for + * @param off offset of the argument to bind in @a stmt, numbered from 1, + *            so immediately suitable for passing to `sqlite3_bind`-functions. + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +static int +qconv_round_time_abs (void *cls, +                      const void *data, +                      size_t data_len, +                      sqlite3_stmt *stmt, +                      unsigned int off) +{ +  const struct GNUNET_TIME_AbsoluteNBO *at = data; +  struct GNUNET_TIME_Absolute tmp; + +  (void) cls; +  GNUNET_assert (sizeof (struct GNUNET_TIME_AbsoluteNBO) == data_len); +  GNUNET_break (NULL == cls); +  tmp = GNUNET_TIME_absolute_ntoh (*at); +  GNUNET_assert (GNUNET_OK == +                 GNUNET_TIME_round_abs (&tmp)); +  if (SQLITE_OK != sqlite3_bind_int64 (stmt, +                                       (int) off, +                                       (sqlite3_int64) at->abs_value_us__)) +    return GNUNET_SYSERR; +  return GNUNET_OK; +} + + +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_SQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +TALER_SQ_query_param_absolute_time_nbo (const struct +                                        GNUNET_TIME_AbsoluteNBO *x) +{ +  struct GNUNET_SQ_QueryParam res = +  { &qconv_round_time_abs, NULL, x, sizeof (*x), 1 }; +  return res; +} + +  /* end of sq/sq_query_helper.c */ diff --git a/src/sq/sq_result_helper.c b/src/sq/sq_result_helper.c index ef36d3e9..d313ed59 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 */ diff --git a/src/sq/test_sq.c b/src/sq/test_sq.c index 85f837e4..308b65b0 100644 --- a/src/sq/test_sq.c +++ b/src/sq/test_sq.c @@ -32,35 +32,58 @@ run_queries (sqlite3 *db)  {    struct TALER_Amount hamount;    struct TALER_AmountNBO namount; +  json_t *json; +  struct GNUNET_TIME_Absolute htime = GNUNET_TIME_absolute_get (); +  struct GNUNET_TIME_AbsoluteNBO ntime;    sqlite3_stmt *test_insert;    sqlite3_stmt *test_select;    struct GNUNET_SQ_PrepareStatement ps[] = {      GNUNET_SQ_make_prepare ("INSERT INTO test_sq (" -                            " namount_val" +                            " hamount_val" +                            ",hamount_frac" +                            ",namount_val"                              ",namount_frac" +                            ",json" +                            ",htime" +                            ",ntime"                              ") VALUES " -                            "($1, $2)", +                            "($1, $2, $3, $4, $5, $6, $7)",                              &test_insert),      GNUNET_SQ_make_prepare ("SELECT" -                            " namount_val" +                            " hamount_val" +                            ",hamount_frac" +                            ",namount_val"                              ",namount_frac" +                            ",json" +                            ",htime" +                            ",ntime"                              " FROM test_sq",                              &test_select),      GNUNET_SQ_PREPARE_END    }; +  int ret = 0;    GNUNET_assert (GNUNET_OK ==                   TALER_string_to_amount ("EUR:1.23",                                           &hamount));    TALER_amount_hton (&namount,                       &hamount); +  json = json_object (); +  json_object_set_new (json, "foo", json_integer (42)); +  GNUNET_assert (NULL != json); +  GNUNET_TIME_round_abs (&htime); +  ntime = GNUNET_TIME_absolute_hton (htime);    GNUNET_assert (GNUNET_OK == GNUNET_SQ_prepare (db,                                                   ps));    {      struct GNUNET_SQ_QueryParam params_insert[] = { +      TALER_SQ_query_param_amount (&hamount),        TALER_SQ_query_param_amount_nbo (&namount), +      TALER_SQ_query_param_json (json), +      TALER_SQ_query_param_absolute_time (&htime), +      TALER_SQ_query_param_absolute_time_nbo (&ntime),        GNUNET_SQ_query_param_end      };      GNUNET_SQ_reset (db, @@ -72,14 +95,23 @@ run_queries (sqlite3 *db)    }    { -    struct TALER_AmountNBO nresult_amount;      struct TALER_Amount result_amount; +    struct TALER_AmountNBO nresult_amount; +    struct TALER_Amount nresult_amount_converted; +    json_t *result_json; +    struct GNUNET_TIME_Absolute hresult_time; +    struct GNUNET_TIME_AbsoluteNBO nresult_time;      struct GNUNET_SQ_QueryParam params_select[] = {        GNUNET_SQ_query_param_end      };      struct GNUNET_SQ_ResultSpec results_select[] = { +      TALER_SQ_result_spec_amount ("EUR", +                                   &result_amount),        TALER_SQ_result_spec_amount_nbo ("EUR",                                         &nresult_amount), +      TALER_SQ_result_spec_json (&result_json), +      TALER_SQ_result_spec_absolute_time (&hresult_time), +      TALER_SQ_result_spec_absolute_time_nbo (&nresult_time),        GNUNET_SQ_result_spec_end      }; @@ -91,21 +123,31 @@ run_queries (sqlite3 *db)      GNUNET_assert (GNUNET_OK == GNUNET_SQ_extract_result (test_select,                                                            results_select)); -    GNUNET_SQ_cleanup_result (results_select); -    sqlite3_finalize (test_select); -    TALER_amount_ntoh (&result_amount, &nresult_amount); +    TALER_amount_ntoh (&nresult_amount_converted, +                       &nresult_amount);      if ((GNUNET_OK != TALER_amount_cmp_currency (&hamount,                                                   &result_amount)) ||          (0 != TALER_amount_cmp (&hamount, -                                &result_amount))) +                                &result_amount)) || +        (GNUNET_OK != TALER_amount_cmp_currency (&hamount, +                                                 &nresult_amount_converted)) || +        (0 != TALER_amount_cmp (&hamount, +                                &nresult_amount_converted)) || +        (1 != json_equal (json, +                          result_json)) || +        (htime.abs_value_us != hresult_time.abs_value_us) || +        (ntime.abs_value_us__ != nresult_time.abs_value_us__))      {        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                    "Result from database doesn't match input\n"); -      return 1; +      ret = 1;      } +    GNUNET_SQ_cleanup_result (results_select); +    sqlite3_finalize (test_select);    } +  json_decref (json); -  return 0; +  return ret;  } @@ -115,8 +157,13 @@ main (int argc,  {    struct GNUNET_SQ_ExecuteStatement es[] = {      GNUNET_SQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_sq (" -                            " namount_val INT8 NOT NULL" -                            ",namount_frac INT4 NOT NULL" +                            " hamount_val INT8 NOT NULL" +                            ",hamount_frac INT8 NOT NULL" +                            ",namount_val INT8 NOT NULL" +                            ",namount_frac INT8 NOT NULL" +                            ",json VARCHAR NOT NULL" +                            ",htime INT8 NOT NULL" +                            ",ntime INT8 NOT NULL"                              ")"),      GNUNET_SQ_EXECUTE_STATEMENT_END    }; | 
