summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-06-10 16:31:29 +0200
committerChristian Grothoff <christian@grothoff.org>2015-06-10 16:31:29 +0200
commitaef3b7c350e34f71425ef403d3e5991aced2eb57 (patch)
tree89df52847c5e52750193bfa87bbf0e62d6b8a0d7 /src
parentd45534c574cad8a001a113358885adf989132f8d (diff)
downloadexchange-aef3b7c350e34f71425ef403d3e5991aced2eb57.tar.gz
exchange-aef3b7c350e34f71425ef403d3e5991aced2eb57.tar.bz2
exchange-aef3b7c350e34f71425ef403d3e5991aced2eb57.zip
implementing pq APIs for #3827, not yet tested or used through
Diffstat (limited to 'src')
-rw-r--r--src/include/taler_pq_lib.h134
-rw-r--r--src/pq/db_pq.c199
-rw-r--r--src/pq/pq_helper.c146
3 files changed, 462 insertions, 17 deletions
diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h
index d030d9b7..6199444e 100644
--- a/src/include/taler_pq_lib.h
+++ b/src/include/taler_pq_lib.h
@@ -75,8 +75,27 @@ enum TALER_PQ_QueryFormat
* We have an absolute time.
* Data points to a `struct GNUNET_TIME_Absolute`, size is only used to check.
*/
- TALER_PQ_QF_TIME_ABSOLUTE
+ TALER_PQ_QF_TIME_ABSOLUTE,
+ /**
+ * We expect an uint16_t (in host byte order).
+ */
+ TALER_PQ_QF_UINT16,
+
+ /**
+ * We expect an uint32_t (in host byte order).
+ */
+ TALER_PQ_QF_UINT32,
+
+ /**
+ * We expect an uint64_t (in host byte order).
+ */
+ TALER_PQ_QF_UINT64,
+
+ /**
+ * We expect a JSON object (json_t).
+ */
+ TALER_PQ_QF_JSON
};
@@ -132,7 +151,7 @@ struct TALER_PQ_QueryParam
* Generate query parameter for a currency, consisting of the three
* components "value", "fraction" and "currency" in this order. The
* types must be a 64-bit integer, 32-bit integer and a
- * TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
+ * #TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
*
* @param x pointer to the query parameter to pass
*/
@@ -144,7 +163,7 @@ TALER_PQ_query_param_amount_nbo(const struct TALER_AmountNBO *x);
* Generate query parameter for a currency, consisting of the three
* components "value", "fraction" and "currency" in this order. The
* types must be a 64-bit integer, 32-bit integer and a
- * TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
+ * #TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
*
* @param x pointer to the query parameter to pass
*/
@@ -183,6 +202,43 @@ TALER_PQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x);
/**
+ * Generate query parameter for an uint16_t in host byte order.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_uint16 (const uint16_t *x);
+
+
+/**
+ * Generate query parameter for an uint32_t in host byte order.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_uint32 (const uint32_t *x);
+
+
+/**
+ * Generate query parameter for an uint16_t in host byte order.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_uint64 (const uint64_t *x);
+
+
+/**
+ * Generate query parameter for a JSON object (stored as a string
+ * in the DB).
+ *
+ * @param x pointer to the json object to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_json (const json_t *x);
+
+
+/**
* Different formats of results that can be extracted.
*/
enum TALER_PQ_ResultFormat
@@ -231,7 +287,27 @@ enum TALER_PQ_ResultFormat
* We expect an absolute time.
* Data points to a `struct GNUNET_TIME_Absolute`, size is only used for checking.
*/
- TALER_PQ_RF_TIME_ABSOLUTE
+ TALER_PQ_RF_TIME_ABSOLUTE,
+
+ /**
+ * We expect an uint16_t (in host byte order).
+ */
+ TALER_PQ_RF_UINT16,
+
+ /**
+ * We expect an uint32_t (in host byte order).
+ */
+ TALER_PQ_RF_UINT32,
+
+ /**
+ * We expect an uint64_t (in host byte order).
+ */
+ TALER_PQ_RF_UINT64,
+
+ /**
+ * We expect a JSON object (json_t).
+ */
+ TALER_PQ_RF_JSON
};
@@ -375,6 +451,54 @@ TALER_PQ_result_spec_absolute_time (const char *name,
/**
+ * uint16_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] u16 where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_uint16 (const char *name,
+ uint16_t *u16);
+
+
+/**
+ * uint32_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] u32 where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_uint32 (const char *name,
+ uint16_t *u32);
+
+
+/**
+ * uint64_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] u64 where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_uint64 (const char *name,
+ uint64_t *u64);
+
+
+/**
+ * json_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] jp where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_json (const char *name,
+ json_t **jp);
+
+
+/**
* Execute a prepared statement.
*
* @param db_conn database connection
@@ -390,7 +514,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
/**
* Extract results from a query result according to the given specification.
- * If colums are NULL, the destination is not modified, and GNUNET_NO
+ * If colums are NULL, the destination is not modified, and #GNUNET_NO
* is returned.
*
* @param result result to process
diff --git a/src/pq/db_pq.c b/src/pq/db_pq.c
index a718c805..693da2f3 100644
--- a/src/pq/db_pq.c
+++ b/src/pq/db_pq.c
@@ -61,6 +61,10 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
case TALER_PQ_QF_RSA_PUBLIC_KEY:
case TALER_PQ_QF_RSA_SIGNATURE:
case TALER_PQ_QF_TIME_ABSOLUTE:
+ case TALER_PQ_QF_UINT16:
+ case TALER_PQ_QF_UINT32:
+ case TALER_PQ_QF_UINT64:
+ case TALER_PQ_QF_JSON:
len++;
break;
default:
@@ -175,7 +179,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
{
const struct GNUNET_TIME_Absolute *at_hbo = x->data;
struct GNUNET_TIME_AbsoluteNBO *at_nbo;
-
+
at_nbo = GNUNET_new (struct GNUNET_TIME_AbsoluteNBO);
scratch[soff++] = at_nbo;
*at_nbo = GNUNET_TIME_absolute_hton (*at_hbo);
@@ -185,6 +189,61 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
off++;
}
break;
+ case TALER_PQ_QF_UINT16:
+ {
+ const uint16_t *u_hbo = x->data;
+ uint16_t *u_nbo;
+
+ u_nbo = GNUNET_new (uint16_t);
+ scratch[soff++] = u_nbo;
+ *u_nbo = htons (*u_hbo);
+ param_values[off] = (void *) u_nbo;
+ param_lengths[off] = sizeof (uint16_t);
+ param_formats[off] = 1;
+ off++;
+ }
+ break;
+ case TALER_PQ_QF_UINT32:
+ {
+ const uint32_t *u_hbo = x->data;
+ uint32_t *u_nbo;
+
+ u_nbo = GNUNET_new (uint32_t);
+ scratch[soff++] = u_nbo;
+ *u_nbo = htonl (*u_hbo);
+ param_values[off] = (void *) u_nbo;
+ param_lengths[off] = sizeof (uint32_t);
+ param_formats[off] = 1;
+ off++;
+ }
+ break;
+ case TALER_PQ_QF_UINT64:
+ {
+ const uint64_t *u_hbo = x->data;
+ uint64_t *u_nbo;
+
+ u_nbo = GNUNET_new (uint64_t);
+ scratch[soff++] = u_nbo;
+ *u_nbo = GNUNET_htonll (*u_hbo);
+ param_values[off] = (void *) u_nbo;
+ param_lengths[off] = sizeof (uint64_t);
+ param_formats[off] = 1;
+ off++;
+ }
+ break;
+ case TALER_PQ_QF_JSON:
+ {
+ const json_t *json = x->data;
+ char *str;
+
+ str = json_dumps (json, JSON_COMPACT);
+ scratch[soff++] = str;
+ param_values[off] = (void *) str;
+ param_lengths[off] = strlen (str);
+ param_formats[off] = 1;
+ off++;
+ }
+ break;
default:
/* format not supported */
GNUNET_assert (0);
@@ -538,7 +597,145 @@ TALER_PQ_extract_result (PGresult *result,
*dst = GNUNET_TIME_absolute_ntoh (*res);
break;
}
+ case TALER_PQ_RF_UINT16:
+ {
+ uint16_t *dst = spec->dst;
+ const uint16_t *res;
+ int fnum;
+
+ fnum = PQfnumber (result,
+ spec->fname);
+ if (fnum < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Field `%s' does not exist in result\n",
+ spec->fname);
+ return GNUNET_SYSERR;
+ }
+ if (PQgetisnull (result,
+ row,
+ fnum))
+ {
+ had_null = GNUNET_YES;
+ continue;
+ }
+ GNUNET_assert (NULL != dst);
+ GNUNET_assert (sizeof (uint16_t) ==
+ spec->dst_size);
+ res = (uint16_t *) PQgetvalue (result,
+ row,
+ fnum);
+ *dst = ntohs (*res);
+ break;
+ }
+ case TALER_PQ_RF_UINT32:
+ {
+ uint32_t *dst = spec->dst;
+ const uint32_t *res;
+ int fnum;
+
+ fnum = PQfnumber (result,
+ spec->fname);
+ if (fnum < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Field `%s' does not exist in result\n",
+ spec->fname);
+ return GNUNET_SYSERR;
+ }
+ if (PQgetisnull (result,
+ row,
+ fnum))
+ {
+ had_null = GNUNET_YES;
+ continue;
+ }
+ GNUNET_assert (NULL != dst);
+ GNUNET_assert (sizeof (uint32_t) ==
+ spec->dst_size);
+ res = (uint32_t *) PQgetvalue (result,
+ row,
+ fnum);
+ *dst = ntohl (*res);
+ break;
+ }
+ case TALER_PQ_RF_UINT64:
+ {
+ uint64_t *dst = spec->dst;
+ const uint64_t *res;
+ int fnum;
+
+ fnum = PQfnumber (result,
+ spec->fname);
+ if (fnum < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Field `%s' does not exist in result\n",
+ spec->fname);
+ return GNUNET_SYSERR;
+ }
+ if (PQgetisnull (result,
+ row,
+ fnum))
+ {
+ had_null = GNUNET_YES;
+ continue;
+ }
+ GNUNET_assert (NULL != dst);
+ GNUNET_assert (sizeof (uint64_t) ==
+ spec->dst_size);
+ res = (uint64_t *) PQgetvalue (result,
+ row,
+ fnum);
+ *dst = GNUNET_ntohll (*res);
+ break;
+ }
+ case TALER_PQ_RF_JSON:
+ {
+ json_t **dst = spec->dst;
+ char *res;
+ int fnum;
+ json_error_t json_error;
+ size_t slen;
+ fnum = PQfnumber (result,
+ spec->fname);
+ if (fnum < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Field `%s' does not exist in result\n",
+ spec->fname);
+ return GNUNET_SYSERR;
+ }
+ if (PQgetisnull (result,
+ row,
+ fnum))
+ {
+ had_null = GNUNET_YES;
+ continue;
+ }
+ GNUNET_assert (NULL != dst);
+ GNUNET_break (0 == spec->dst_size);
+ slen = PQgetlength (result,
+ row,
+ fnum);
+ res = (char *) PQgetvalue (result,
+ row,
+ fnum);
+ *dst = json_loadb (res,
+ slen,
+ JSON_REJECT_DUPLICATES,
+ &json_error);
+ if (NULL == *dst)
+ {
+ TALER_json_warn (json_error);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to parse JSON result for field `%s'\n",
+ spec->fname);
+ return GNUNET_SYSERR;
+ }
+ break;
+ }
default:
GNUNET_assert (0);
break;
diff --git a/src/pq/pq_helper.c b/src/pq/pq_helper.c
index 5da1ced4..01441dec 100644
--- a/src/pq/pq_helper.c
+++ b/src/pq/pq_helper.c
@@ -15,7 +15,7 @@
*/
/**
* @file pq/pq_helper.c
- * @brief functions to initialize parameter arrays
+ * @brief functions to initialize parameter arrays
* @author Christian Grothoff
*/
#include "platform.h"
@@ -39,7 +39,7 @@ TALER_PQ_query_param_amount_nbo (const struct TALER_AmountNBO *x)
{ TALER_PQ_QF_AMOUNT_NBO, x, sizeof (*x) };
return res;
}
-
+
/**
* Generate query parameter for a currency, consisting of the three
@@ -108,6 +108,63 @@ TALER_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
/**
+ * Generate query parameter for an uint16_t in host byte order.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_uint16 (const uint16_t *x)
+{
+ struct TALER_PQ_QueryParam res =
+ { TALER_PQ_QF_UINT16, x, sizeof (*x) };
+ return res;
+}
+
+
+/**
+ * Generate query parameter for an uint32_t in host byte order.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_uint32 (const uint32_t *x)
+{
+ struct TALER_PQ_QueryParam res =
+ { TALER_PQ_QF_UINT32, x, sizeof (*x) };
+ return res;
+}
+
+
+/**
+ * Generate query parameter for an uint16_t in host byte order.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_uint64 (const uint64_t *x)
+{
+ struct TALER_PQ_QueryParam res =
+ { TALER_PQ_QF_UINT64, x, sizeof (*x) };
+ return res;
+}
+
+
+/**
+ * Generate query parameter for a JSON object (stored as a string
+ * in the DB).
+ *
+ * @param x pointer to the json object to pass
+ */
+struct TALER_PQ_QueryParam
+TALER_PQ_query_param_json (const json_t *x)
+{
+ struct TALER_PQ_QueryParam res =
+ { TALER_PQ_QF_JSON, x, 0 };
+ return res;
+}
+
+
+/**
* Variable-size result expected.
*
* @param name name of the field in the table
@@ -120,7 +177,7 @@ TALER_PQ_result_spec_variable_size (const char *name,
void **dst,
size_t *sptr)
{
- struct TALER_PQ_ResultSpec res =
+ struct TALER_PQ_ResultSpec res =
{ TALER_PQ_RF_VARSIZE_BLOB, (void *) (dst), 0, name, sptr };
return res;
}
@@ -137,7 +194,7 @@ struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_amount_nbo (const char *name,
struct TALER_AmountNBO *amount)
{
- struct TALER_PQ_ResultSpec res =
+ struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_AMOUNT_NBO, (void *) amount, sizeof (*amount), name, NULL };
return res;
}
@@ -154,7 +211,7 @@ struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_amount (const char *name,
struct TALER_Amount *amount)
{
- struct TALER_PQ_ResultSpec res =
+ struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_AMOUNT, (void *) amount, sizeof (*amount), name, NULL };
return res;
}
@@ -171,11 +228,11 @@ struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_rsa_public_key (const char *name,
struct GNUNET_CRYPTO_rsa_PublicKey **rsa)
{
- struct TALER_PQ_ResultSpec res =
+ struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_RSA_PUBLIC_KEY, (void *) rsa, 0, name, NULL };
return res;
}
-
+
/**
* RSA signature expected.
@@ -188,12 +245,12 @@ struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_rsa_signature (const char *name,
struct GNUNET_CRYPTO_rsa_Signature **sig)
{
- struct TALER_PQ_ResultSpec res =
+ struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_RSA_SIGNATURE, (void *) sig, 0, (name), NULL };
return res;
}
-
+
/**
* Absolute time expected.
*
@@ -205,10 +262,77 @@ struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_absolute_time (const char *name,
struct GNUNET_TIME_Absolute *at)
{
- struct TALER_PQ_ResultSpec res =
+ struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_TIME_ABSOLUTE, (void *) at, sizeof (*at), (name), NULL };
return res;
}
-
+
+
+/**
+ * uint16_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] u16 where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_uint16 (const char *name,
+ uint16_t *u16)
+{
+ struct TALER_PQ_ResultSpec res =
+ {TALER_PQ_RF_UINT16, (void *) u16, sizeof (*u16), (name), NULL };
+ return res;
+}
+
+
+/**
+ * uint32_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] u32 where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_uint32 (const char *name,
+ uint16_t *u32)
+{
+ struct TALER_PQ_ResultSpec res =
+ {TALER_PQ_RF_UINT32, (void *) u32, sizeof (*u32), (name), NULL };
+ return res;
+}
+
+
+/**
+ * uint64_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] u64 where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_uint64 (const char *name,
+ uint64_t *u64)
+{
+ struct TALER_PQ_ResultSpec res =
+ {TALER_PQ_RF_UINT64, (void *) u64, sizeof (*u64), (name), NULL };
+ return res;
+}
+
+
+/**
+ * json_t expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] jp where to store the result
+ * @return array entry for the result specification to use
+ */
+struct TALER_PQ_ResultSpec
+TALER_PQ_result_spec_json (const char *name,
+ json_t **jp)
+{
+ struct TALER_PQ_ResultSpec res =
+ {TALER_PQ_RF_JSON, (void *) jp, 0, (name), NULL };
+ return res;
+}
/* end of pq_helper.c */