diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-08-21 23:34:44 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-08-21 23:34:44 +0200 |
commit | 250e1997d86c160e1a6603c72b23bf1ec8eafb5d (patch) | |
tree | 9dfdfaab4fd32b14c7fcf35845565e901efed61d /src/pq | |
parent | d1e242aa083cd108aca6e3ceda5f3459c8cebdc4 (diff) |
postgres does not like 0-padding of VARCHAR, implement proper serialization
Diffstat (limited to 'src/pq')
-rw-r--r-- | src/pq/pq_common.c | 32 | ||||
-rw-r--r-- | src/pq/pq_common.h | 8 | ||||
-rw-r--r-- | src/pq/pq_query_helper.c | 29 | ||||
-rw-r--r-- | src/pq/pq_result_helper.c | 30 |
4 files changed, 49 insertions, 50 deletions
diff --git a/src/pq/pq_common.c b/src/pq/pq_common.c index a548a45ca..59ab85f1b 100644 --- a/src/pq/pq_common.c +++ b/src/pq/pq_common.c @@ -40,26 +40,28 @@ TALER_PQ_make_taler_pq_amount_ ( } -struct TALER_PQ_AmountCurrencyP +size_t TALER_PQ_make_taler_pq_amount_currency_ ( const struct TALER_Amount *amount, uint32_t oid_v, uint32_t oid_f, - uint32_t oid_c) + uint32_t oid_c, + struct TALER_PQ_AmountCurrencyP *rval) { - struct TALER_PQ_AmountCurrencyP rval = { - .oid_v = htonl (oid_v), - .oid_f = htonl (oid_f), - .oid_c = htonl (oid_c), - .sz_v = htonl (sizeof((amount)->value)), - .sz_f = htonl (sizeof((amount)->fraction)), - .sz_c = htonl (TALER_CURRENCY_LEN), - .v = GNUNET_htonll ((amount)->value), - .f = htonl ((amount)->fraction), - }; + size_t clen = strlen (amount->currency); - memcpy (rval.c, + GNUNET_assert (clen < TALER_CURRENCY_LEN); + rval->cnt = htonl (3); + rval->oid_v = htonl (oid_v); + rval->oid_f = htonl (oid_f); + rval->oid_c = htonl (oid_c); + rval->sz_v = htonl (sizeof(amount->value)); + rval->sz_f = htonl (sizeof(amount->fraction)); + rval->sz_c = htonl (clen); + rval->v = GNUNET_htonll (amount->value); + rval->f = htonl (amount->fraction); + memcpy (rval->c, amount->currency, - TALER_CURRENCY_LEN); - return rval; + clen); + return sizeof (*rval) - TALER_CURRENCY_LEN + clen; } diff --git a/src/pq/pq_common.h b/src/pq/pq_common.h index 4dc2d3357..dff5e4c89 100644 --- a/src/pq/pq_common.h +++ b/src/pq/pq_common.h @@ -74,6 +74,7 @@ struct TALER_PQ_AmountP */ struct TALER_PQ_AmountCurrencyP { + uint32_t cnt; /* number of OIDs in tuple */ uint32_t oid_v; /* oid of .v */ uint32_t sz_v; /* size of .v */ uint64_t v; /* value */ @@ -119,13 +120,16 @@ TALER_PQ_make_taler_pq_amount_ ( * @param oid_v OID of the INT8 type in postgres * @param oid_f OID of the INT4 type in postgres * @param oid_c OID of the TEXT type in postgres + * @param[out] rval set to encoded @a amount + * @return actual (useful) size of @a rval for Postgres */ -struct TALER_PQ_AmountCurrencyP +size_t TALER_PQ_make_taler_pq_amount_currency_ ( const struct TALER_Amount *amount, uint32_t oid_v, uint32_t oid_f, - uint32_t oid_c); + uint32_t oid_c, + struct TALER_PQ_AmountCurrencyP *rval); #endif /* TALER_PQ_COMMON_H_ */ diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index a1a1070bb..48bbfb522 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -68,6 +68,7 @@ qconv_amount_currency_tuple (void *cls, Oid oid_v; Oid oid_f; Oid oid_c; + struct TALER_PQ_AmountCurrencyP d; GNUNET_assert (GNUNET_OK == GNUNET_PQ_get_oid_by_name (db, @@ -79,24 +80,18 @@ qconv_amount_currency_tuple (void *cls, &oid_f)); GNUNET_assert (GNUNET_OK == GNUNET_PQ_get_oid_by_name (db, - "text", + "varchar", &oid_c)); - - { - struct TALER_PQ_AmountCurrencyP d - = TALER_PQ_make_taler_pq_amount_currency_ (amount, - oid_v, - oid_f, - oid_c); - - sz = sizeof(uint32_t); /* number of elements in tuple */ - sz += sizeof(d); - out = GNUNET_malloc (sz); - scratch[0] = out; - *(uint32_t *) out = htonl (3); - out += sizeof(uint32_t); - *(struct TALER_PQ_AmountCurrencyP*) out = d; - } + sz = TALER_PQ_make_taler_pq_amount_currency_ (amount, + oid_v, + oid_f, + oid_c, + &d); + out = GNUNET_malloc (sz); + memcpy (out, + &d, + sz); + scratch[0] = out; } param_values[0] = scratch[0]; diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 3befbdff1..4b346e8a4 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -79,43 +79,41 @@ extract_amount_currency_tuple (void *cls, /* Parse the tuple */ { - char *in; - uint32_t num; struct TALER_PQ_AmountCurrencyP ap; + const char *in; int size; - const static int expected_size - = sizeof(uint32_t) /* length */ - + sizeof(ap); size = PQgetlength (result, row, col); - if (expected_size != size) + if ( (size >= sizeof (ap)) || + (size <= sizeof (ap) - TALER_CURRENCY_LEN) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Incorrect size of binary field `%s' (got %d, expected %d)\n", + "Incorrect size of binary field `%s' (got %d, expected (%d-%d))\n", fname, size, - expected_size); + (int) (sizeof (ap) - TALER_CURRENCY_LEN), + (int) sizeof (ap)); return GNUNET_SYSERR; } in = PQgetvalue (result, row, col); - - num = ntohl (*(uint32_t *) in); - if (3 != num) + memset (&ap.c, + 0, + TALER_CURRENCY_LEN); + memcpy (&ap, + in, + size); + if (3 != 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); @@ -224,7 +222,7 @@ extract_amount_tuple (void *cls, /* Parse the tuple */ { - char *in; + const char *in; uint32_t num; struct TALER_PQ_AmountP ap; int size; |