diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-07-30 12:24:04 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-07-30 12:24:04 +0200 |
commit | 35011bf29b4576b8c63b71538557da1fd3ae657a (patch) | |
tree | 31fa77b7b95fcb96d26383d30aaf0ba0a251f3ea /src/pq | |
parent | b9ecc4113db28da3dce9c5d9c15ac2d0317dc2fd (diff) |
removing old amount logic from libtalerpq
Diffstat (limited to 'src/pq')
-rw-r--r-- | src/pq/pq_query_helper.c | 149 | ||||
-rw-r--r-- | src/pq/pq_result_helper.c | 240 | ||||
-rw-r--r-- | src/pq/test_pq.c | 108 |
3 files changed, 47 insertions, 450 deletions
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 3b33e336c..a216e6470 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -29,128 +29,6 @@ /** - * 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[out] param_values SQL data to set - * @param[out] param_lengths SQL length data to set - * @param[out] param_formats SQL format data to set - * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays - * @param[out] scratch buffer for dynamic allocations (to be done via GNUNET_malloc() - * @param scratch_length number of entries left in @a scratch - * @return -1 on error, number of offsets used in @a scratch otherwise - */ -static int -qconv_amount_nbo (void *cls, - const void *data, - size_t data_len, - void *param_values[], - int param_lengths[], - int param_formats[], - unsigned int param_length, - void *scratch[], - unsigned int scratch_length) -{ - const struct TALER_AmountNBO *amount = data; - unsigned int off = 0; - - (void) cls; - (void) scratch; - (void) scratch_length; - GNUNET_assert (sizeof (struct TALER_AmountNBO) == data_len); - GNUNET_assert (2 == param_length); - param_values[off] = (void *) &amount->value; - param_lengths[off] = sizeof (amount->value); - param_formats[off] = 1; - off++; - param_values[off] = (void *) &amount->fraction; - param_lengths[off] = sizeof (amount->fraction); - param_formats[off] = 1; - return 0; -} - - -struct GNUNET_PQ_QueryParam -TALER_PQ_query_param_amount_nbo (const struct TALER_AmountNBO *x) -{ - struct GNUNET_PQ_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[out] param_values SQL data to set - * @param[out] param_lengths SQL length data to set - * @param[out] param_formats SQL format data to set - * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays - * @param[out] scratch buffer for dynamic allocations (to be done via GNUNET_malloc() - * @param scratch_length number of entries left in @a scratch - * @return -1 on error, number of offsets used in @a scratch otherwise - */ -static int -qconv_amount (void *cls, - const void *data, - size_t data_len, - void *param_values[], - int param_lengths[], - int param_formats[], - unsigned int param_length, - void *scratch[], - unsigned int scratch_length) -{ - const struct TALER_Amount *amount_hbo = data; - struct TALER_AmountNBO *amount; - - (void) cls; - (void) scratch; - (void) scratch_length; - GNUNET_assert (2 == param_length); - GNUNET_assert (sizeof (struct TALER_AmountNBO) == data_len); - amount = GNUNET_new (struct TALER_AmountNBO); - scratch[0] = amount; - TALER_amount_hton (amount, - amount_hbo); - qconv_amount_nbo (cls, - amount, - sizeof (struct TALER_AmountNBO), - param_values, - param_lengths, - param_formats, - param_length, - &scratch[1], - scratch_length - 1); - return 1; -} - - -struct GNUNET_PQ_QueryParam -TALER_PQ_query_param_amount (const struct TALER_Amount *x) -{ - struct GNUNET_PQ_QueryParam res = { - .conv = &qconv_amount, - .data = x, - .size = sizeof (*x), - .num_params = 2 - }; - - return res; -} - - -/** * Function called to convert input amount into SQL parameter as tuple. * * @param cls closure @@ -185,33 +63,34 @@ qconv_amount_tuple (void *cls, GNUNET_assert (1 <= scratch_length); GNUNET_assert (sizeof (struct TALER_Amount) == data_len); GNUNET_static_assert (sizeof(uint32_t) == sizeof(Oid)); - { char *out; - Oid oid_v, oid_f; + Oid oid_v; + Oid oid_f; + GNUNET_assert (GNUNET_OK == - GNUNET_PQ_get_oid_by_name (db, "int8", &oid_v)); + GNUNET_PQ_get_oid_by_name (db, + "int8", + &oid_v)); GNUNET_assert (GNUNET_OK == - GNUNET_PQ_get_oid_by_name (db, "int4", &oid_f)); + GNUNET_PQ_get_oid_by_name (db, + "int4", + &oid_f)); { - struct TALER_PQ_Amount_P d = MAKE_TALER_PQ_AMOUNT_P (db, - amount, - oid_v, - oid_f); - + struct TALER_PQ_Amount_P d + = MAKE_TALER_PQ_AMOUNT_P (db, + amount, + oid_v, + oid_f); sz = sizeof(uint32_t); /* number of elements in tuple */ sz += sizeof(d); - out = GNUNET_malloc (sz); scratch[0] = out; - *(uint32_t *) out = htonl (2); out += sizeof(uint32_t); - *(struct TALER_PQ_Amount_P*) out = d; } - } param_values[0] = scratch[0]; diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index ed8100a10..5384bf961 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -25,246 +25,6 @@ /** - * Extract a currency amount from a query result according to the - * given specification. - * - * @param result the result to extract the amount from - * @param row which row of the result to extract the amount from (needed as results can have multiple rows) - * @param currency currency to use for @a r_amount_nbo - * @param val_name name of the column with the amount's "value", must include the substring "_val". - * @param frac_name name of the column with the amount's "fractional" value, must include the substring "_frac". - * @param[out] r_amount_nbo where to store the amount, in network byte order - * @return - * #GNUNET_YES if all results could be extracted - * #GNUNET_NO if at least one result was NULL - * #GNUNET_SYSERR if a result was invalid (non-existing field) - */ -static enum GNUNET_GenericReturnValue -extract_amount_nbo_helper (PGresult *result, - int row, - const char *currency, - const char *val_name, - const char *frac_name, - struct TALER_AmountNBO *r_amount_nbo) -{ - int val_num; - int frac_num; - int len; - - /* These checks are simply to check that clients obey by our naming - conventions, and not for any functional reason */ - GNUNET_assert (NULL != - strstr (val_name, - "_val")); - GNUNET_assert (NULL != - strstr (frac_name, - "_frac")); - /* Set return value to invalid in case we don't finish */ - memset (r_amount_nbo, - 0, - sizeof (struct TALER_AmountNBO)); - val_num = PQfnumber (result, - val_name); - frac_num = PQfnumber (result, - frac_name); - if (val_num < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Field `%s' does not exist in result\n", - val_name); - return GNUNET_SYSERR; - } - if (frac_num < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Field `%s' does not exist in result\n", - frac_name); - return GNUNET_SYSERR; - } - if ( (PQgetisnull (result, - row, - val_num)) || - (PQgetisnull (result, - row, - frac_num)) ) - { - return GNUNET_NO; - } - /* Note that Postgres stores value in NBO internally, - so no conversion needed in this case */ - r_amount_nbo->value = *(uint64_t *) PQgetvalue (result, - row, - val_num); - r_amount_nbo->fraction = *(uint32_t *) PQgetvalue (result, - row, - frac_num); - if (GNUNET_ntohll (r_amount_nbo->value) >= TALER_AMOUNT_MAX_VALUE) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Field `%s' exceeds legal range\n", - val_name); - return GNUNET_SYSERR; - } - if (ntohl (r_amount_nbo->fraction) >= TALER_AMOUNT_FRAC_BASE) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Field `%s' exceeds legal range\n", - frac_name); - return GNUNET_SYSERR; - } - len = GNUNET_MIN (TALER_CURRENCY_LEN - 1, - strlen (currency)); - GNUNET_memcpy (r_amount_nbo->currency, - currency, - len); - return GNUNET_OK; -} - - -/** - * Extract data from a Postgres database @a result at row @a row. - * - * @param cls closure, a `const char *` giving the currency - * @param result where to extract data from - * @param row row to extract data from - * @param fname name (or prefix) of the fields to extract 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_NO if at least one result was NULL - * #GNUNET_SYSERR if a result was invalid (non-existing field) - */ -static enum GNUNET_GenericReturnValue -extract_amount_nbo (void *cls, - PGresult *result, - int row, - const char *fname, - size_t *dst_size, - void *dst) -{ - const char *currency = cls; - char *val_name; - char *frac_name; - enum GNUNET_GenericReturnValue ret; - - if (sizeof (struct TALER_AmountNBO) != *dst_size) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - GNUNET_asprintf (&val_name, - "%s_val", - fname); - GNUNET_asprintf (&frac_name, - "%s_frac", - fname); - ret = extract_amount_nbo_helper (result, - row, - currency, - val_name, - frac_name, - dst); - GNUNET_free (val_name); - GNUNET_free (frac_name); - return ret; -} - - -struct GNUNET_PQ_ResultSpec -TALER_PQ_result_spec_amount_nbo (const char *name, - const char *currency, - struct TALER_AmountNBO *amount) -{ - struct GNUNET_PQ_ResultSpec res = { - .conv = &extract_amount_nbo, - .cls = (void *) currency, - .dst = (void *) amount, - .dst_size = sizeof (*amount), - .fname = name - }; - - return res; -} - - -/** - * Extract data from a Postgres database @a result at row @a row. - * - * @param cls closure, a `const char *` giving the currency - * @param result where to extract data from - * @param row row to extract data from - * @param fname name (or prefix) of the fields to extract 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_NO if at least one result was NULL - * #GNUNET_SYSERR if a result was invalid (non-existing field) - */ -static enum GNUNET_GenericReturnValue -extract_amount (void *cls, - PGresult *result, - int row, - const char *fname, - size_t *dst_size, - void *dst) -{ - const char *currency = cls; - struct TALER_Amount *r_amount = dst; - char *val_name; - char *frac_name; - struct TALER_AmountNBO amount_nbo; - enum GNUNET_GenericReturnValue ret; - - if (sizeof (struct TALER_AmountNBO) != *dst_size) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - GNUNET_asprintf (&val_name, - "%s_val", - fname); - GNUNET_asprintf (&frac_name, - "%s_frac", - fname); - ret = extract_amount_nbo_helper (result, - row, - currency, - val_name, - frac_name, - &amount_nbo); - if (GNUNET_OK == ret) - TALER_amount_ntoh (r_amount, - &amount_nbo); - else - memset (r_amount, - 0, - sizeof (struct TALER_Amount)); - GNUNET_free (val_name); - GNUNET_free (frac_name); - return ret; -} - - -struct GNUNET_PQ_ResultSpec -TALER_PQ_result_spec_amount (const char *name, - const char *currency, - struct TALER_Amount *amount) -{ - struct GNUNET_PQ_ResultSpec res = { - .conv = &extract_amount, - .cls = (void *) currency, - .dst = (void *) amount, - .dst_size = sizeof (*amount), - .fname = name - }; - - return res; -} - - -/** * Extract an amount from a tuple from a Postgres database @a result at row @a row. * * @param cls closure, a `const char *` giving the currency diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index 218d9ad2a..71a2d5a00 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015, 2016 Taler Systems SA + (C) 2015, 2016, 2023 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 @@ -29,28 +29,20 @@ * @param db database handle to initialize * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure */ -static int +static enum GNUNET_GenericReturnValue postgres_prepare (struct GNUNET_PQ_Context *db) { struct GNUNET_PQ_PreparedStatement ps[] = { GNUNET_PQ_make_prepare ("test_insert", "INSERT INTO test_pq (" " tamount" - ",hamount_val" - ",hamount_frac" - ",namount_val" - ",namount_frac" ",json" ",aamount" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7);"), + "($1, $2, $3);"), GNUNET_PQ_make_prepare ("test_select", "SELECT" " tamount" - ",hamount_val" - ",hamount_frac" - ",namount_val" - ",namount_frac" ",json" ",aamount" " FROM test_pq;"), @@ -71,17 +63,8 @@ static int run_queries (struct GNUNET_PQ_Context *conn) { struct TALER_Amount tamount; - struct TALER_Amount hamount; - struct TALER_Amount hamount2; - struct TALER_AmountNBO namount; - struct TALER_AmountNBO namount2; struct TALER_Amount aamount[3]; - struct TALER_Amount *pamount; - size_t npamount; - PGresult *result; - int ret; json_t *json; - json_t *json2; GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("EUR:5.3", @@ -95,28 +78,23 @@ run_queries (struct GNUNET_PQ_Context *conn) GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("EUR:7.7", &tamount)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:5.5", - &hamount)); - TALER_amount_hton (&namount, - &hamount); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:4.4", - &hamount)); json = json_object (); - json_object_set_new (json, "foo", json_integer (42)); GNUNET_assert (NULL != json); + GNUNET_assert (0 == + json_object_set_new (json, + "foo", + json_integer (42))); { struct GNUNET_PQ_QueryParam params_insert[] = { - TALER_PQ_query_param_amount_tuple (conn, &tamount), - TALER_PQ_query_param_amount (&hamount), - TALER_PQ_query_param_amount_nbo (&namount), + TALER_PQ_query_param_amount_tuple (conn, + &tamount), TALER_PQ_query_param_json (json), TALER_PQ_query_param_array_amount (3, aamount, conn), GNUNET_PQ_query_param_end }; + PGresult *result; result = GNUNET_PQ_exec_prepared (conn, "test_insert", @@ -130,30 +108,22 @@ run_queries (struct GNUNET_PQ_Context *conn) return 1; } PQclear (result); + json_decref (json); } { + struct TALER_Amount tamount2; + struct TALER_Amount *pamount; + size_t npamount; + json_t *json2; struct GNUNET_PQ_QueryParam params_select[] = { GNUNET_PQ_query_param_end }; - - result = GNUNET_PQ_exec_prepared (conn, - "test_select", - params_select); - if (1 != - PQntuples (result)) - { - GNUNET_break (0); - PQclear (result); - return 1; - } - } - - { struct GNUNET_PQ_ResultSpec results_select[] = { - TALER_PQ_result_spec_amount ("hamount", "EUR", &hamount2), - TALER_PQ_result_spec_amount_nbo ("namount", "EUR", &namount2), - TALER_PQ_result_spec_json ("json", &json2), - TALER_PQ_result_spec_amount_tuple ("tamount", "EUR", &tamount), + TALER_PQ_result_spec_amount_tuple ("tamount", + "EUR", + &tamount2), + TALER_PQ_result_spec_json ("json", + &json2), TALER_PQ_result_spec_array_amount (conn, "aamount", "EUR", @@ -162,23 +132,21 @@ run_queries (struct GNUNET_PQ_Context *conn) GNUNET_PQ_result_spec_end }; - ret = GNUNET_PQ_extract_result (result, - results_select, - 0); - GNUNET_break (0 == - TALER_amount_cmp (&hamount, - &hamount2)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:5.5", - &hamount)); - TALER_amount_ntoh (&hamount2, - &namount2); + if (1 != + GNUNET_PQ_eval_prepared_singleton_select (conn, + "test_select", + params_select, + results_select)) + { + GNUNET_break (0); + return 1; + } GNUNET_break (0 == - TALER_amount_cmp (&hamount, - &hamount2)); + TALER_amount_cmp (&tamount, + &tamount2)); GNUNET_break (42 == - json_integer_value (json_object_get (json2, "foo"))); - + json_integer_value (json_object_get (json2, + "foo"))); GNUNET_break (3 == npamount); for (size_t i = 0; i < 3; i++) { @@ -186,14 +154,8 @@ run_queries (struct GNUNET_PQ_Context *conn) TALER_amount_cmp (&aamount[i], &pamount[i])); } - GNUNET_PQ_cleanup_result (results_select); - PQclear (result); } - json_decref (json); - if (GNUNET_OK != ret) - return 1; - return 0; } @@ -213,10 +175,6 @@ main (int argc, "$$;"), GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_pq (" " tamount taler_amount NOT NULL" - ",hamount_val INT8 NOT NULL" - ",hamount_frac INT4 NOT NULL" - ",namount_val INT8 NOT NULL" - ",namount_frac INT4 NOT NULL" ",json VARCHAR NOT NULL" ",aamount taler_amount[]" ")"), |