exchange

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

commit 0ac4cb1a4b32d622008bf8e145580df6a3c8ff95
parent 7bc63c3b6b1ca5ec60e1160e107121d568de5d29
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue, 30 Jun 2026 17:04:38 +0200

DCE, in particular libtalersq

Diffstat:
Mmeson.build | 23-----------------------
Msrc/exchange/taler-exchange-httpd.c | 1-
Msrc/exchange/taler-exchange-httpd_configuration.c | 9+++++----
Msrc/exchange/taler-exchange-httpd_get-config.c | 3---
Msrc/exchange/taler-exchange-httpd_get-keys.c | 1+
Msrc/exchange/taler-exchange-httpd_post-melt.c | 35++++-------------------------------
Msrc/exchange/taler-exchange-httpd_post-melt.h | 6------
Msrc/exchangedb/do_withdraw.c | 2+-
Msrc/exchangedb/persist_aml_program_result.c | 5+++++
Msrc/exchangedb/select_kyc_accounts.c | 2--
Msrc/meson.build | 3---
Dsrc/sq/meson.build | 76----------------------------------------------------------------------------
Dsrc/sq/sq_query_helper.c | 174-------------------------------------------------------------------------------
Dsrc/sq/sq_result_helper.c | 238-------------------------------------------------------------------------------
Dsrc/sq/test_sq.c | 215-------------------------------------------------------------------------------
15 files changed, 16 insertions(+), 777 deletions(-)

diff --git a/meson.build b/meson.build @@ -243,29 +243,6 @@ if not get_option('only-doc') required: false, ) - sqlite_dep = dependency('sqlite3', version: '>=3.35.0', required: false) - # FIXME for fallbacks, we need to manually check version - if not sqlite_dep.found() - sqlite_dep = cc.find_library('sqlite3', required: false) - sqlite_version_check = '''#include <sqlite3.h> - int main(int argc, char **argv) { - #if SQLITE_VERSION_NUMBER < 3035000 - #error "SQLite version >= 3.35.0 required" - #endif - return 0; - } - ''' - if not cc.compiles( - sqlite_version_check, - name: 'sqlite version check', - dependencies: sqlite_dep, - ) - error('Sqlite version >= 3.35.0 requried') - endif - endif - - private_config.set10('HAVE_SQLITE', have_gnunetsq and sqlite_dep.found()) - # todo talertwister optional twister_dep = cc.find_library('talertwister', required: false) if twister_dep.found() diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c @@ -2741,7 +2741,6 @@ do_shutdown (void *cls) TEH_resume_keys_requests (true); TEH_batch_deposit_cleanup (); TEH_withdraw_cleanup (); - TEH_melt_cleanup (); TEH_reserves_close_cleanup (); TEH_reserves_purse_cleanup (); TEH_purses_merge_cleanup (); diff --git a/src/exchange/taler-exchange-httpd_configuration.c b/src/exchange/taler-exchange-httpd_configuration.c @@ -103,10 +103,11 @@ TEH_CONFIG_load_denom_data ( "VALUE", &meta->value)) { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "Need amount for option `%s' in section `%s'\n", - "VALUE", - section_name); + GNUNET_log_config_invalid ( + GNUNET_ERROR_TYPE_ERROR, + "VALUE", + section_name, + "amount required"); return GNUNET_SYSERR; } if (0 != strcasecmp (TEH_currency, diff --git a/src/exchange/taler-exchange-httpd_get-config.c b/src/exchange/taler-exchange-httpd_get-config.c @@ -40,9 +40,6 @@ TEH_handler_config (struct TEH_RequestContext *rc, GNUNET_JSON_pack_array_steal ( "wallet_balance_limit_without_kyc", TALER_KYCLOGIC_get_wallet_thresholds ())), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("shopping_url", - TEH_shopping_url)), GNUNET_JSON_pack_object_steal ( "currency_specification", TALER_JSON_currency_specs_to_json (TEH_cspec)), diff --git a/src/exchange/taler-exchange-httpd_get-keys.c b/src/exchange/taler-exchange-httpd_get-keys.c @@ -1795,6 +1795,7 @@ create_krd (struct TEH_KeyStateHandle *ksh, sk = GNUNET_CONTAINER_multipeermap_get ( ksh->signkey_map, (const struct GNUNET_PeerIdentity *) &exchange_pub); + GNUNET_assert (NULL != sk); ksh->signature_expires = GNUNET_TIME_timestamp_min (sk->meta.expire_sign, ksh->signature_expires); } diff --git a/src/exchange/taler-exchange-httpd_post-melt.c b/src/exchange/taler-exchange-httpd_post-melt.c @@ -98,16 +98,10 @@ struct MeltContext { /** - * This struct is kept in a DLL. + * Processing phase we are in. + * The ordering here partially matters, as we progress through + * them by incrementing the phase in the happy path. */ - struct MeltContext *prev; - struct MeltContext *next; - - /** - * Processing phase we are in. - * The ordering here partially matters, as we progress through - * them by incrementing the phase in the happy path. - */ enum MeltPhase { MELT_PHASE_PARSE, @@ -308,27 +302,6 @@ struct MeltContext /** - * All melt context is kept in a DLL. - */ -static struct MeltContext *mc_head; -static struct MeltContext *mc_tail; - -void -TEH_melt_cleanup () -{ - struct MeltContext *mc; - - while (NULL != (mc = mc_head)) - { - GNUNET_CONTAINER_DLL_remove (mc_head, - mc_tail, - mc); - MHD_resume_connection (mc->rc->connection); - } -} - - -/** * Terminate the main loop by returning the final result. * * @param[in,out] mc context to update phase for @@ -628,7 +601,7 @@ phase_parse_request ( { GNUNET_break_op (0); SET_ERROR (mc, - MELT_ERROR_DUPLICATE_TRANSFER_PUB); + MELT_ERROR_DUPLICATE_PLANCHET); return; } } diff --git a/src/exchange/taler-exchange-httpd_post-melt.h b/src/exchange/taler-exchange-httpd_post-melt.h @@ -25,12 +25,6 @@ #include <microhttpd.h> #include "taler-exchange-httpd.h" -/** - * Resume suspended connections, we are shutting down. - */ -void -TEH_melt_cleanup (void); - /** * Handle a "/melt" request. Parses the request into the JSON diff --git a/src/exchangedb/do_withdraw.c b/src/exchangedb/do_withdraw.c @@ -134,7 +134,7 @@ TALER_EXCHANGEDB_do_withdraw ( if (! reserve_found) return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; if ((withdraw->age_proof_required) && - (idempotent && no_noreveal_index)) + (*idempotent && no_noreveal_index)) GNUNET_break (0); return qs; } diff --git a/src/exchangedb/persist_aml_program_result.c b/src/exchangedb/persist_aml_program_result.c @@ -90,6 +90,11 @@ TALER_EXCHANGEDB_persist_aml_program_result ( qs = TALER_EXCHANGEDB_clear_aml_lock ( pg, account_id); + if (qs < 0) + { + GNUNET_break (0); + goto cleanup; + } switch (apr->status) { case TALER_KYCLOGIC_AMLR_FAILURE: diff --git a/src/exchangedb/select_kyc_accounts.c b/src/exchangedb/select_kyc_accounts.c @@ -175,7 +175,6 @@ TALER_EXCHANGEDB_select_kyc_accounts ( ",kt.open_time" ",kt.close_time" ",lo.jproperties ->> 'FILE_NOTE' AS comments" - ",lo.jproperties ->> 'open_date' AS open_time" ",COALESCE(lo.to_investigate,FALSE) AS to_investigate" ",COALESCE((lo.jproperties ->> 'HIGH_RISK_CUSTOMER')::bool,FALSE) AS high_risk" ",wt.payto_uri" @@ -201,7 +200,6 @@ TALER_EXCHANGEDB_select_kyc_accounts ( ",kt.open_time" ",kt.close_time" ",lo.jproperties ->> 'FILE_NOTE' AS comments" - ",lo.jproperties ->> 'open_date' AS open_time" ",COALESCE(lo.to_investigate,FALSE) AS to_investigate" ",COALESCE((lo.jproperties ->> 'HIGH_RISK_CUSTOMER')::bool,FALSE) AS high_risk" ",wt.payto_uri" diff --git a/src/meson.build b/src/meson.build @@ -11,9 +11,6 @@ subdir('util') subdir('json') subdir('curl') subdir('pq') -if sqlite_dep.found() - subdir('sq') -endif subdir('mhd') subdir('templating') subdir('bank-lib') diff --git a/src/sq/meson.build b/src/sq/meson.build @@ -1,76 +0,0 @@ -libtalersq_src = ['sq_query_helper.c', 'sq_result_helper.c'] - -libtalersq = library( - 'talersq', - libtalersq_src, - soversion: solibversions['libtalersq']['soversion'], - version: solibversions['libtalersq']['soversion'], - install_rpath: rpath_option, - dependencies: [ - libtalerutil_dep, - gnunetutil_dep, - gnunetsq_dep, - json_dep, - sqlite_dep, - ], - include_directories: [incdir, configuration_inc], - install: true, - install_dir: get_option('libdir'), -) - -libtalersq_dep = declare_dependency(link_with: libtalersq) -pkg.generate( - libtalersq, - url: 'https://taler.net', - description: 'GNU Taler sqlite wrapper library', -) - -talersq_tests = ['test_sq'] - -talersq_tests_installcheck = [] - -foreach t : talersq_tests - - test_tmp = executable( - t, - ['@0@.c'.format(t)], - dependencies: [ - gnunetutil_dep, - gnunetsq_dep, - libtalersq_dep, - libtalerutil_dep, - json_dep, - sqlite_dep, - ], - include_directories: [incdir, configuration_inc], - build_by_default: false, - install: false, - ) - test( - t, - test_tmp, - workdir: meson.current_build_dir(), - suite: ['sq'], - is_parallel: false, - ) -endforeach - -foreach t : talersq_tests_installcheck - - test_tmp = executable( - t, - ['@0@.c'.format(t)], - dependencies: [gnunetutil_dep, libtalerutil_dep, json_dep], - include_directories: [incdir, configuration_inc], - build_by_default: false, - install: false, - ) - test( - t, - test_tmp, - workdir: meson.current_build_dir(), - suite: ['sq', 'installcheck'], - ) - - -endforeach diff --git a/src/sq/sq_query_helper.c b/src/sq/sq_query_helper.c @@ -1,174 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file sq/sq_query_helper.c - * @brief helper functions for Taler-specific SQLite3 interactions - * @author Jonathan Buchanan - */ -#include <sqlite3.h> -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_sq_lib.h> -#include "taler/taler_sq_lib.h" - - -/** - * 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 enum GNUNET_GenericReturnValue -qconv_amount (void *cls, - const void *data, - size_t data_len, - sqlite3_stmt *stmt, - unsigned int off) -{ - const struct TALER_Amount *amount = data; - - (void) cls; - GNUNET_assert (sizeof (struct TALER_Amount) == data_len); - if (SQLITE_OK != sqlite3_bind_int64 (stmt, - (int) off, - (sqlite3_int64) amount->value)) - return GNUNET_SYSERR; - if (SQLITE_OK != sqlite3_bind_int64 (stmt, - (int) off + 1, - (sqlite3_int64) amount->fraction)) - return GNUNET_SYSERR; - return GNUNET_OK; -} - - -struct GNUNET_SQ_QueryParam -TALER_SQ_query_param_amount (const struct TALER_Amount *x) -{ - struct GNUNET_SQ_QueryParam res = { - .conv = &qconv_amount, - .data = x, - .size = sizeof (*x), - .num_params = 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_AmountNBO` - * @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 enum GNUNET_GenericReturnValue -qconv_amount_nbo (void *cls, - const void *data, - size_t data_len, - sqlite3_stmt *stmt, - unsigned int off) -{ - const struct TALER_AmountNBO *amount = data; - struct TALER_Amount amount_hbo; - - (void) cls; - (void) data_len; - TALER_amount_ntoh (&amount_hbo, - amount); - return qconv_amount (cls, - &amount_hbo, - sizeof (struct TALER_Amount), - stmt, - off); -} - - -struct GNUNET_SQ_QueryParam -TALER_SQ_query_param_amount_nbo (const struct TALER_AmountNBO *x) -{ - struct GNUNET_SQ_QueryParam res = { - .conv = &qconv_amount_nbo, - .data = x, - .size = sizeof (*x), - .num_params = 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 enum GNUNET_GenericReturnValue -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), - SQLITE_TRANSIENT)) - return GNUNET_SYSERR; - GNUNET_free (str); - return GNUNET_OK; -} - - -struct GNUNET_SQ_QueryParam -TALER_SQ_query_param_json (const json_t *x) -{ - struct GNUNET_SQ_QueryParam res = { - .conv = &qconv_json, - .data = x, - .size = sizeof (*x), - .num_params = 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 @@ -1,238 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file sq/sq_result_helper.c - * @brief functions to initialize parameter arrays - * @author Jonathan Buchanan - */ -#include <sqlite3.h> -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_sq_lib.h> -#include "taler/taler_sq_lib.h" -#include "taler/taler_util.h" - - -/** - * 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 enum GNUNET_GenericReturnValue -extract_amount (void *cls, - sqlite3_stmt *result, - unsigned int column, - size_t *dst_size, - void *dst) -{ - struct TALER_Amount *amount = dst; - const char *currency = cls; - uint64_t frac; - - if ((sizeof (struct TALER_Amount) != *dst_size) || - (SQLITE_INTEGER != sqlite3_column_type (result, - (int) column)) || - (SQLITE_INTEGER != sqlite3_column_type (result, - (int) column + 1))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - GNUNET_strlcpy (amount->currency, - currency, - TALER_CURRENCY_LEN); - amount->value = (uint64_t) sqlite3_column_int64 (result, - (int) column); - frac = (uint64_t) sqlite3_column_int64 (result, - (int) column + 1); - amount->fraction = (uint32_t) frac; - return GNUNET_YES; -} - - -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, 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 enum GNUNET_GenericReturnValue -extract_amount_nbo (void *cls, - sqlite3_stmt *result, - unsigned int column, - size_t *dst_size, - void *dst) -{ - struct TALER_AmountNBO *amount = dst; - struct TALER_Amount amount_hbo; - size_t amount_hbo_size = sizeof (struct TALER_Amount); - - (void) cls; - (void) dst_size; - if (GNUNET_YES != - extract_amount (cls, - result, - column, - &amount_hbo_size, - &amount_hbo)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - TALER_amount_hton (amount, - &amount_hbo); - return GNUNET_YES; -} - - -struct GNUNET_SQ_ResultSpec -TALER_SQ_result_spec_amount_nbo (const char *currency, - struct TALER_AmountNBO *amount) -{ - struct GNUNET_SQ_ResultSpec res = { - .conv = &extract_amount_nbo, - .cls = (void *) currency, - .dst = (void *) amount, - .dst_size = sizeof (struct TALER_AmountNBO), - .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 enum GNUNET_GenericReturnValue -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; -} - - -/* end of sq/sq_result_helper.c */ diff --git a/src/sq/test_sq.c b/src/sq/test_sq.c @@ -1,215 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file sq/test_sq.c - * @brief Tests for SQLite3 convenience API - * @author Jonathan Buchanan - */ -#include "platform.h" -#include "taler/taler_sq_lib.h" - - -/** - * Run actual test queries. - * - * @return 0 on success - */ -static int -run_queries (sqlite3 *db) -{ - struct TALER_Amount hamount; - struct TALER_AmountNBO namount; - json_t *json; - sqlite3_stmt *test_insert; - sqlite3_stmt *test_select; - struct GNUNET_SQ_PrepareStatement ps[] = { - GNUNET_SQ_make_prepare ("INSERT INTO test_sq (" - " hamount_val" - ",hamount_frac" - ",namount_val" - ",namount_frac" - ",json" - ") VALUES " - "($1, $2, $3, $4, $5)", - &test_insert), - GNUNET_SQ_make_prepare ("SELECT" - " hamount_val" - ",hamount_frac" - ",namount_val" - ",namount_frac" - ",json" - " 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 (); - GNUNET_assert (NULL != json); - GNUNET_assert (0 == - json_object_set_new (json, - "foo", - json_integer (42))); - GNUNET_assert (NULL != json); - 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), - GNUNET_SQ_query_param_end - }; - GNUNET_SQ_reset (db, - test_insert); - GNUNET_assert (GNUNET_OK == GNUNET_SQ_bind (test_insert, - params_insert)); - GNUNET_assert (SQLITE_DONE == sqlite3_step (test_insert)); - sqlite3_finalize (test_insert); - } - - { - struct TALER_Amount result_amount; - struct TALER_AmountNBO nresult_amount; - struct TALER_Amount nresult_amount_converted; - json_t *result_json; - 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), - GNUNET_SQ_result_spec_end - }; - - GNUNET_SQ_reset (db, - test_select); - GNUNET_assert (GNUNET_OK == GNUNET_SQ_bind (test_select, - params_select)); - GNUNET_assert (SQLITE_ROW == sqlite3_step (test_select)); - - GNUNET_assert (GNUNET_OK == GNUNET_SQ_extract_result (test_select, - results_select)); - 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)) || - (GNUNET_OK != TALER_amount_cmp_currency (&hamount, - &nresult_amount_converted)) || - (0 != TALER_amount_cmp (&hamount, - &nresult_amount_converted)) || - (1 != json_equal (json, - result_json)) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Result from database doesn't match input\n"); - ret = 1; - } - GNUNET_SQ_cleanup_result (results_select); - sqlite3_finalize (test_select); - } - json_decref (json); - - return ret; -} - - -int -main (int argc, - const char *const argv[]) -{ - struct GNUNET_SQ_ExecuteStatement es[] = { - GNUNET_SQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_sq (" - " hamount_val INT8 NOT NULL" - ",hamount_frac INT8 NOT NULL" - ",namount_val INT8 NOT NULL" - ",namount_frac INT8 NOT NULL" - ",json VARCHAR NOT NULL" - ")"), - GNUNET_SQ_EXECUTE_STATEMENT_END - }; - sqlite3 *db; - int ret; - - (void) argc; - (void) argv; - GNUNET_log_setup ("test-pq", - "WARNING", - NULL); - - if (SQLITE_OK != sqlite3_open ("talercheck.db", - &db)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to open SQLite3 database\n"); - return 77; - } - - if (GNUNET_OK != GNUNET_SQ_exec_statements (db, - es)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to create new table\n"); - if ((SQLITE_OK != sqlite3_close (db)) || - (0 != unlink ("talercheck.db"))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to close db or unlink\n"); - } - return 1; - } - - ret = run_queries (db); - - if (SQLITE_OK != - sqlite3_exec (db, - "DROP TABLE test_sq", - NULL, NULL, NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to drop table\n"); - ret = 1; - } - - if (SQLITE_OK != sqlite3_close (db)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to close database\n"); - ret = 1; - } - if (0 != unlink ("talercheck.db")) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to unlink test database file\n"); - ret = 1; - } - return ret; -} - - -/* end of sq/test_sq.c */