aboutsummaryrefslogtreecommitdiff
path: root/src/pq
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2023-07-30 12:24:04 +0200
committerChristian Grothoff <christian@grothoff.org>2023-07-30 12:24:04 +0200
commit35011bf29b4576b8c63b71538557da1fd3ae657a (patch)
tree31fa77b7b95fcb96d26383d30aaf0ba0a251f3ea /src/pq
parentb9ecc4113db28da3dce9c5d9c15ac2d0317dc2fd (diff)
removing old amount logic from libtalerpq
Diffstat (limited to 'src/pq')
-rw-r--r--src/pq/pq_query_helper.c149
-rw-r--r--src/pq/pq_result_helper.c240
-rw-r--r--src/pq/test_pq.c108
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[]"
")"),