aboutsummaryrefslogtreecommitdiff
path: root/src/pq
diff options
context:
space:
mode:
authorÖzgür Kesim <oec-taler@kesim.org>2023-10-10 13:34:47 +0200
committerÖzgür Kesim <oec-taler@kesim.org>2023-10-10 13:34:47 +0200
commit713db415a9bf47ffb665ee16892121829e067168 (patch)
tree38bd1e3a9ae84e7b96c128aae8cd64c92254cf1c /src/pq
parentcbc2beb113c7209ffc629fe683dab7b531f0f1b1 (diff)
[pq] cleanup of amount tuple type handling
- add counter for tuple elements to struct - use GNUNET_memcpy instead of casting also, fix format string in test for age_restriction
Diffstat (limited to 'src/pq')
-rw-r--r--src/pq/pq_common.c1
-rw-r--r--src/pq/pq_common.h21
-rw-r--r--src/pq/pq_query_helper.c30
-rw-r--r--src/pq/pq_result_helper.c97
-rw-r--r--src/pq/test_pq.c25
5 files changed, 98 insertions, 76 deletions
diff --git a/src/pq/pq_common.c b/src/pq/pq_common.c
index 59ab85f1b..8b6f8f22c 100644
--- a/src/pq/pq_common.c
+++ b/src/pq/pq_common.c
@@ -28,6 +28,7 @@ TALER_PQ_make_taler_pq_amount_ (
uint32_t oid_f)
{
struct TALER_PQ_AmountP rval = {
+ .cnt = htonl (2),
.oid_v = htonl (oid_v),
.oid_f = htonl (oid_f),
.sz_v = htonl (sizeof((amount)->value)),
diff --git a/src/pq/pq_common.h b/src/pq/pq_common.h
index dff5e4c89..6172c0bfb 100644
--- a/src/pq/pq_common.h
+++ b/src/pq/pq_common.h
@@ -58,6 +58,7 @@ enum TALER_PQ_ArrayType
*/
struct TALER_PQ_AmountP
{
+ uint32_t cnt; /* # elements in the tuple (== 2) */
uint32_t oid_v; /* oid of .v */
uint32_t sz_v; /* size of .v */
uint64_t v; /* value */
@@ -74,28 +75,16 @@ struct TALER_PQ_AmountP
*/
struct TALER_PQ_AmountCurrencyP
{
- uint32_t cnt; /* number of OIDs in tuple */
+ uint32_t cnt; /* # elements in the tuple (== 3) */
uint32_t oid_v; /* oid of .v */
uint32_t sz_v; /* size of .v */
uint64_t v; /* value */
uint32_t oid_f; /* oid of .f */
uint32_t sz_f; /* size of .f */
uint32_t f; /* fraction */
-
- /**
- * oid of .c
- */
- uint32_t oid_c;
-
- /**
- * size of .c
- */
- uint32_t sz_c;
-
- /**
- * currency
- */
- uint8_t c[TALER_CURRENCY_LEN];
+ uint32_t oid_c; /* oid of .c */
+ uint32_t sz_c; /* size of .c */
+ uint8_t c[TALER_CURRENCY_LEN]; /* currency */
} __attribute__((packed));
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index 46719e6c2..dd6cf6733 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -174,13 +174,12 @@ qconv_amount_tuple (void *cls,
oid_v,
oid_f);
- sz = sizeof(uint32_t); /* number of elements in tuple */
- sz += sizeof(d);
+ sz = sizeof(d);
out = GNUNET_malloc (sz);
scratch[0] = out;
- *(uint32_t *) out = htonl (2);
- out += sizeof(uint32_t);
- *(struct TALER_PQ_AmountP*) out = d;
+ GNUNET_memcpy (out,
+ &d,
+ sizeof(d));
}
}
@@ -841,14 +840,14 @@ qconv_array (
same_sized = (0 != meta->same_size);
#define RETURN_UNLESS(cond) \
- do { \
- if (! (cond)) \
- { \
- GNUNET_break ((cond)); \
- noerror = false; \
- goto DONE; \
- } \
- } while(0)
+ do { \
+ if (! (cond)) \
+ { \
+ GNUNET_break ((cond)); \
+ noerror = false; \
+ goto DONE; \
+ } \
+ } while (0)
/* Calculate sizes and check bounds */
{
@@ -970,9 +969,6 @@ qconv_array (
oid_v,
oid_f);
- *(uint32_t *) out = htonl (2); /* number of elements in tuple */
- out += sizeof(uint32_t);
- sz -= sizeof(uint32_t);
GNUNET_memcpy (out,
&am,
sizeof(am));
@@ -1177,7 +1173,7 @@ TALER_PQ_query_param_array_amount (
true,
amounts,
NULL,
- sizeof(uint32_t) + sizeof(struct TALER_PQ_AmountP),
+ sizeof(struct TALER_PQ_AmountP),
TALER_PQ_array_of_amount,
oid,
db);
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index 4b346e8a4..95850bcc0 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -81,7 +81,7 @@ extract_amount_currency_tuple (void *cls,
{
struct TALER_PQ_AmountCurrencyP ap;
const char *in;
- int size;
+ size_t size;
size = PQgetlength (result,
row,
@@ -90,11 +90,11 @@ extract_amount_currency_tuple (void *cls,
(size <= sizeof (ap) - TALER_CURRENCY_LEN) )
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Incorrect size of binary field `%s' (got %d, expected (%d-%d))\n",
+ "Incorrect size of binary field `%s' (got %zu, expected (%zu-%zu))\n",
fname,
size,
- (int) (sizeof (ap) - TALER_CURRENCY_LEN),
- (int) sizeof (ap));
+ sizeof (ap) - TALER_CURRENCY_LEN,
+ sizeof (ap));
return GNUNET_SYSERR;
}
@@ -222,44 +222,36 @@ extract_amount_tuple (void *cls,
/* Parse the tuple */
{
- const char *in;
- uint32_t num;
struct TALER_PQ_AmountP ap;
- int size;
- const static int expected_size = sizeof(uint32_t) /* length */
- + sizeof(ap);
+ const char *in;
+ size_t size;
size = PQgetlength (result,
row,
col);
-
- if (expected_size != size)
+ if (sizeof(ap) != size)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Incorrect size of binary field `%s' (got %d, expected %d)\n",
+ "Incorrect size of binary field `%s' (got %zu, expected %zu)\n",
fname,
size,
- expected_size);
+ sizeof(ap));
return GNUNET_SYSERR;
}
in = PQgetvalue (result,
row,
col);
-
- num = ntohl (*(uint32_t *) in);
- if (2 != num)
+ memcpy (&ap,
+ in,
+ size);
+ if (2 != ntohl (ap.cnt))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Incorrect number of elements in tuple-field `%s'\n",
fname);
return GNUNET_SYSERR;
}
- in += sizeof(uint32_t);
- memcpy (&ap,
- in,
- sizeof (ap));
-
/* TODO[oec]: OID-checks? */
r_amount->value = GNUNET_ntohll (ap.v);
@@ -1084,13 +1076,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);
@@ -1140,20 +1132,23 @@ extract_array_generic (
{
struct TALER_PQ_AmountP ap;
struct TALER_Amount *amount = &amounts[i];
- size_t sz = ntohl (*(uint32_t *) in);
- in += sizeof(uint32_t);
+ uint32_t val;
+ size_t sz;
+
+ GNUNET_memcpy (&val,
+ in,
+ sizeof(val));
+ sz = ntohl (val);
+ in += sizeof(val);
/* total size for this array-entry */
- FAIL_IF ((sizeof(uint32_t)
- + sizeof(struct TALER_PQ_AmountP))
- > sz);
+ FAIL_IF (sizeof(ap) > sz);
- /* number of elements in composite type*/
- sz = ntohl (*(uint32_t *) in);
- in += sizeof(uint32_t);
- FAIL_IF (2 != sz);
+ GNUNET_memcpy (&ap,
+ in,
+ sz);
+ FAIL_IF (2 != ntohl (ap.cnt));
- ap = *(struct TALER_PQ_AmountP *) in;
amount->value = GNUNET_ntohll (ap.v);
amount->fraction = ntohl (ap.f);
GNUNET_memcpy (amount->currency,
@@ -1171,7 +1166,13 @@ extract_array_generic (
*((void **) dst) = out;
for (uint32_t i = 0; i < header.dim; i++)
{
- size_t sz = ntohl (*(uint32_t *) in);
+ uint32_t val;
+ size_t sz;
+
+ GNUNET_memcpy (&val,
+ in,
+ sizeof(val));
+ sz = ntohl (val);
FAIL_IF (sz != sizeof(struct TALER_DenominationHashP));
in += sizeof(uint32_t);
*(struct TALER_DenominationHashP *) out =
@@ -1188,7 +1189,13 @@ extract_array_generic (
*((void **) dst) = out;
for (uint32_t i = 0; i < header.dim; i++)
{
- size_t sz = ntohl (*(uint32_t *) in);
+ uint32_t val;
+ size_t sz;
+
+ GNUNET_memcpy (&val,
+ in,
+ sizeof(val));
+ sz = ntohl (val);
FAIL_IF (sz != sizeof(struct TALER_BlindedCoinHashP));
in += sizeof(uint32_t);
*(struct TALER_BlindedCoinHashP *) out =
@@ -1217,10 +1224,16 @@ extract_array_generic (
{
struct TALER_BlindedDenominationSignature *denom_sig = &denom_sigs[i];
uint32_t be[2];
- size_t sz = ntohl (*(uint32_t *) in);
- in += sizeof(uint32_t);
+ uint32_t val;
+ size_t sz;
+ GNUNET_memcpy (&val,
+ in,
+ sizeof(val));
+ sz = ntohl (val);
FAIL_IF (sizeof(be) > sz);
+
+ in += sizeof(val);
GNUNET_memcpy (&be,
in,
sizeof(be));
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c
index 03308ba14..237c8a9ef 100644
--- a/src/pq/test_pq.c
+++ b/src/pq/test_pq.c
@@ -38,13 +38,15 @@ postgres_prepare (struct GNUNET_PQ_Context *db)
" tamount"
",json"
",aamount"
+ ",tamountc"
") VALUES "
- "($1, $2, $3);"),
+ "($1, $2, $3, $4);"),
GNUNET_PQ_make_prepare ("test_select",
"SELECT"
" tamount"
",json"
",aamount"
+ ",tamountc"
" FROM test_pq;"),
GNUNET_PQ_PREPARED_STATEMENT_END
};
@@ -64,6 +66,7 @@ run_queries (struct GNUNET_PQ_Context *conn)
{
struct TALER_Amount tamount;
struct TALER_Amount aamount[3];
+ struct TALER_Amount tamountc;
json_t *json;
GNUNET_assert (GNUNET_OK ==
@@ -78,6 +81,9 @@ 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 ("FOO:8.7",
+ &tamountc));
json = json_object ();
GNUNET_assert (NULL != json);
GNUNET_assert (0 ==
@@ -92,6 +98,8 @@ run_queries (struct GNUNET_PQ_Context *conn)
TALER_PQ_query_param_array_amount (3,
aamount,
conn),
+ TALER_PQ_query_param_amount_with_currency (conn,
+ &tamountc),
GNUNET_PQ_query_param_end
};
PGresult *result;
@@ -112,6 +120,7 @@ run_queries (struct GNUNET_PQ_Context *conn)
}
{
struct TALER_Amount tamount2;
+ struct TALER_Amount tamountc2;
struct TALER_Amount *pamount;
size_t npamount;
json_t *json2;
@@ -129,6 +138,8 @@ run_queries (struct GNUNET_PQ_Context *conn)
"EUR",
&npamount,
&pamount),
+ TALER_PQ_result_spec_amount_with_currency ("tamountc",
+ &tamountc2),
GNUNET_PQ_result_spec_end
};
@@ -154,6 +165,9 @@ run_queries (struct GNUNET_PQ_Context *conn)
TALER_amount_cmp (&aamount[i],
&pamount[i]));
}
+ GNUNET_break (0 ==
+ TALER_amount_cmp (&tamountc,
+ &tamountc2));
GNUNET_PQ_cleanup_result (results_select);
}
return 0;
@@ -173,10 +187,19 @@ main (int argc,
" WHEN duplicate_object THEN null;"
" END "
"$$;"),
+ GNUNET_PQ_make_execute ("DO $$ "
+ " BEGIN"
+ " CREATE TYPE taler_amount_currency AS"
+ " (val INT8, frac INT4, curr VARCHAR(12));"
+ " EXCEPTION"
+ " WHEN duplicate_object THEN null;"
+ " END "
+ "$$;"),
GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_pq ("
" tamount taler_amount NOT NULL"
",json VARCHAR NOT NULL"
",aamount taler_amount[]"
+ ",tamountc taler_amount_currency"
")"),
GNUNET_PQ_EXECUTE_STATEMENT_END
};