exchange

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

commit baaaebc76618d9bbde84511afcddf015b7fd96da
parent c4c3844cd45e8011db7eb97f9310abaa84757c8c
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date:   Tue, 11 Nov 2025 15:17:51 +0100

adding TALER_PQ_result_spec_array_amount_with_currency

Diffstat:
Msrc/include/taler/taler_pq_lib.h | 17+++++++++++++++++
Msrc/pq/pq_result_helper.c | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/pq/test_pq.c | 28+++++++++++++++++++++++++++-
3 files changed, 130 insertions(+), 8 deletions(-)

diff --git a/src/include/taler/taler_pq_lib.h b/src/include/taler/taler_pq_lib.h @@ -454,6 +454,23 @@ TALER_PQ_result_spec_array_amount ( /** + * Array of amounts including currency + * + * @param db context of the database connection + * @param name name of the field in the table + * @param[out] num number of elements in @e amounts + * @param[out] amounts where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_array_amount_with_currency ( + struct GNUNET_PQ_Context *db, + const char *name, + size_t *num, + struct TALER_Amount **amounts); + + +/** * Array of public R-values for Clause-Schnorr * * @param db context of the database connection diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c @@ -1163,13 +1163,13 @@ extract_array_generic ( *((void **) dst) = NULL; #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto FAIL; \ - } \ - } while (0) + do { \ + if ((cond)) \ + { \ + GNUNET_break (! (cond)); \ + goto FAIL; \ + } \ + } while (0) col_num = PQfnumber (result, fname); FAIL_IF (0 > col_num); @@ -1252,6 +1252,54 @@ extract_array_generic ( } return GNUNET_OK; } + case TALER_PQ_array_of_amount_currency: + { + struct TALER_Amount *amounts; + if (NULL != dst_size) + *dst_size = sizeof(struct TALER_Amount) * (header.dim); + + amounts = GNUNET_new_array (header.dim, + struct TALER_Amount); + *((void **) dst) = amounts; + + for (uint32_t i = 0; i < header.dim; i++) + { + struct TALER_PQ_AmountCurrencyP ap; + struct TALER_Amount *amount = &amounts[i]; + uint32_t val; + size_t sz; + + GNUNET_memcpy (&val, + in, + sizeof(val)); + sz = ntohl (val); + in += sizeof(val); + + FAIL_IF ( (sz >= sizeof(ap)) || + (sz <= sizeof(ap) - TALER_CURRENCY_LEN) ); + + memset (&ap, + 0, + sizeof(ap)); + GNUNET_memcpy (&ap, + in, + sz); + FAIL_IF (3 != ntohl (ap.cnt)); + + amount->value = GNUNET_ntohll (ap.v); + amount->fraction = ntohl (ap.f); + GNUNET_memcpy (amount->currency, + ap.c, + TALER_CURRENCY_LEN); + + FAIL_IF ('\0' != amount->currency[TALER_CURRENCY_LEN - 1]); + FAIL_IF (amount->value >= TALER_AMOUNT_MAX_VALUE); + FAIL_IF (amount->fraction >= TALER_AMOUNT_FRAC_BASE); + + in += sz; + } + return GNUNET_OK; + } case TALER_PQ_array_of_denom_hash: if (NULL != dst_size) *dst_size = sizeof(struct TALER_DenominationHashP) * (header.dim); @@ -1587,6 +1635,37 @@ TALER_PQ_result_spec_array_amount ( struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_array_amount_with_currency ( + struct GNUNET_PQ_Context *db, + const char *name, + size_t *num, + struct TALER_Amount **amounts) +{ + struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls); + + info->num = num; + info->typ = TALER_PQ_array_of_amount_currency; + info->db = db; + GNUNET_assert (GNUNET_OK == + GNUNET_PQ_get_oid_by_name (db, + "taler_amount_currency", + &info->oid)); + + { + struct GNUNET_PQ_ResultSpec res = { + .conv = extract_array_generic, + .cleaner = &array_cleanup, + .dst = (void *) amounts, + .fname = name, + .cls = info, + }; + + return res; + } +} + + +struct GNUNET_PQ_ResultSpec TALER_PQ_result_spec_array_hash_code ( struct GNUNET_PQ_Context *db, const char *name, diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c @@ -39,17 +39,19 @@ postgres_prepare (struct GNUNET_PQ_Context *db) " tamount" ",json" ",aamount" + ",aamountc" ",tamountc" ",hash" ",hashes" ",cs_r_pubs" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7);"), + "($1, $2, $3, $4, $5, $6, $7, $8);"), GNUNET_PQ_make_prepare ("test_select", "SELECT" " tamount" ",json" ",aamount" + ",aamountc" ",tamountc" ",hash" ",hashes" @@ -73,6 +75,7 @@ run_queries (struct GNUNET_PQ_Context *conn) { struct TALER_Amount tamount; struct TALER_Amount aamount[3]; + struct TALER_Amount aamountc[2]; struct TALER_Amount tamountc; struct GNUNET_HashCode hc = {{0xdeadbeef,0xdeadbeef,0xdeadbeef,0xdeadbeef, @@ -104,6 +107,12 @@ run_queries (struct GNUNET_PQ_Context *conn) TALER_string_to_amount ("EUR:7.7", &tamount)); GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("USD:3.2", + &aamountc[0])); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("CHF:4.5", + &aamountc[1])); + GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("FOO:8.7", &tamountc)); json = json_object (); @@ -123,6 +132,9 @@ run_queries (struct GNUNET_PQ_Context *conn) TALER_PQ_query_param_array_amount (3, aamount, conn), + TALER_PQ_query_param_array_amount_with_currency (2, + aamountc, + conn), TALER_PQ_query_param_amount_with_currency (conn, &tamountc), GNUNET_PQ_query_param_fixed_size (&hc, @@ -164,10 +176,12 @@ run_queries (struct GNUNET_PQ_Context *conn) struct TALER_Amount tamount2; struct TALER_Amount tamountc2; struct TALER_Amount *pamount; + struct TALER_Amount *pamountc; struct GNUNET_HashCode hc2; struct GNUNET_HashCode *hcs2; struct GNUNET_CRYPTO_CSPublicRPairP *out_cs_r_pubs; size_t npamount; + size_t npamountc; size_t nhcs; size_t n_rpubs; json_t *json2; @@ -185,6 +199,10 @@ run_queries (struct GNUNET_PQ_Context *conn) "EUR", &npamount, &pamount), + TALER_PQ_result_spec_array_amount_with_currency (conn, + "aamountc", + &npamountc, + &pamountc), TALER_PQ_result_spec_amount_with_currency ("tamountc", &tamountc2), GNUNET_PQ_result_spec_auto_from_type ("hash", @@ -222,6 +240,13 @@ run_queries (struct GNUNET_PQ_Context *conn) TALER_amount_cmp (&aamount[i], &pamount[i])); } + GNUNET_break (2 == npamountc); + for (size_t i = 0; i < npamountc; i++) + { + GNUNET_break (0 == + TALER_amount_cmp (&aamountc[i], + &pamountc[i])); + } GNUNET_break (0 == TALER_amount_cmp (&tamountc, &tamountc2)); @@ -283,6 +308,7 @@ main (int argc, " tamount taler_amount NOT NULL" ",json VARCHAR NOT NULL" ",aamount taler_amount[]" + ",aamountc taler_amount_currency[]" ",tamountc taler_amount_currency" ",hash gnunet_hashcode" ",hashes gnunet_hashcode[]"