gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-donau] branch master updated (2de49c1 -> 42c9c15)


From: gnunet
Subject: [taler-donau] branch master updated (2de49c1 -> 42c9c15)
Date: Mon, 27 Nov 2023 13:14:40 +0100

This is an automated email from the git hooks/post-receive script.

pius-loosli pushed a change to branch master
in repository donau.

    from 2de49c1  [donau] rename files [lib] adjust methods
     new 310ca15  [build] donaudb: remove benchmarks from Makefile
     new 0f8fc79  [build] src/pq Makefile: fix infamous libtalerutil.la
     new d2bebba  [build] pq: temporarily comment out unused codelines in order 
to build someday
     new 4014b84  [build]  WIP: src/includes donaudb_plugin.h and donaudb_lib.h
     new 42c9c15  [build] WIP src/donaudb/donaudb_plugin.c

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/donaudb/Makefile.am      |   19 -
 src/donaudb/donaudb_plugin.c |    4 +-
 src/include/donaudb_lib.h    |    3 +-
 src/include/donaudb_plugin.h |   16 +-
 src/pq/Makefile.am           |    2 +-
 src/pq/pq_query_helper.c     | 2306 +++++++++++++++++-----------------
 src/pq/pq_result_helper.c    | 2800 +++++++++++++++++++++---------------------
 7 files changed, 2568 insertions(+), 2582 deletions(-)

diff --git a/src/donaudb/Makefile.am b/src/donaudb/Makefile.am
index b2e0f98..53369bb 100644
--- a/src/donaudb/Makefile.am
+++ b/src/donaudb/Makefile.am
@@ -53,7 +53,6 @@ check_SCRIPTS = \
 EXTRA_DIST = \
   donaudb.conf \
   donaudb-postgres.conf \
-  bench-db-postgres.conf \
   test-donau-db-postgres.conf \
   $(sqlinputs) \
   $(sql_DATA) \
@@ -270,7 +269,6 @@ lib_LTLIBRARIES = \
   libtalerdonaudb.la
 
 libtalerdonaudb_la_SOURCES = \
-  donaudb_accounts.c \
   donaudb_plugin.c \
   donaudb_transactions.c
 libtalerdonaudb_la_LIBADD = \
@@ -287,13 +285,6 @@ libtalerdonaudb_la_LDFLAGS = \
 check_PROGRAMS = \
   test-donaudb-postgres
 
-noinst_PROGRAMS = \
-  bench-db-postgres\
-  perf_get_link_data-postgres\
-  perf_select_refunds_by_coin-postgres\
-  perf_reserves_in_insert-postgres \
-  perf_deposits_get_ready-postgres
-
 AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export 
PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
 TESTS = \
   $(check_SCRIPTS) \
@@ -311,16 +302,6 @@ test_donaudb_postgres_LDADD = \
   -lgnunetutil \
   $(XLIB)
 
-bench_db_postgres_SOURCES = \
-  bench_db.c
-bench_db_postgres_LDADD = \
-  libtalerdonaudb.la \
-  $(top_builddir)/src/util/libtalerutil.la \
-  $(top_builddir)/src/pq/libtalerpq.la \
-  -lgnunetpq \
-  -lgnunetutil \
-  $(XLIB)
-
 perf_reserves_in_insert_postgres_SOURCES = \
   perf_reserves_in_insert.c
 perf_reserves_in_insert_postgres_LDADD = \
diff --git a/src/donaudb/donaudb_plugin.c b/src/donaudb/donaudb_plugin.c
index ca148d8..d4938eb 100644
--- a/src/donaudb/donaudb_plugin.c
+++ b/src/donaudb/donaudb_plugin.c
@@ -19,8 +19,8 @@
  * @author Christian Grothoff
  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
  */
-#include "platform.h"
-#include "taler_donaudb_plugin.h"
+#include "taler/platform.h"
+#include "donaudb_plugin.h"
 #include <ltdl.h>
 
 
diff --git a/src/include/donaudb_lib.h b/src/include/donaudb_lib.h
index 3cd676d..cdf5d80 100644
--- a/src/include/donaudb_lib.h
+++ b/src/include/donaudb_lib.h
@@ -1,3 +1,4 @@
+/*
 This file is part of TALER
   Copyright (C) 2014 - 2020 Taler Systems SA
 
@@ -14,7 +15,7 @@ You should have received a copy of the GNU General Public 
License along with
                                                TALER; see the file
 COPYING.If not, see <http:                        // www.gnu.org/licenses/>
 *
-// **
+**
 *@file include / taler_donaudb_lib.h
 * @brief IO operations for the
         donau
diff --git a/src/include/donaudb_plugin.h b/src/include/donaudb_plugin.h
index a3054d4..6b64ade 100644
--- a/src/include/donaudb_plugin.h
+++ b/src/include/donaudb_plugin.h
@@ -23,9 +23,10 @@
 #include <jansson.h>
 #include <gnunet/gnunet_util_lib.h>
 #include <gnunet/gnunet_db_lib.h>
-#include "taler_json_lib.h"
-#include "taler_signatures.h"
-#include "taler_extensions_policy.h"
+#include "taler/taler_json_lib.h"
+#include "donau_signatures.h"
+#include "donau_util.h"
+#include "taler/taler_extensions_policy.h"
 
 /**
  * Meta data about a donation unit key.
@@ -45,7 +46,7 @@ struct TALER_DONAUDB_DonationUnitKeyMetaData
   /**
    * Hash code of the donation unit public key.
    */
-  struct TALER_DonationUnitHashP donation_unit_hash;
+  struct DONAU_DonationUnitHashP donation_unit_hash;
 
 };
 
@@ -84,12 +85,12 @@ struct TALER_DONAUDB_DonationUnitKey
    * The private key of the donation unit.  Will be NULL if the private
    * key is not available.
    */
-  struct TALER_DonationUnitPrivateKey donation_unit_priv;
+  // struct TALER_DonationUnitPublicKey donation_unit_priv;
 
   /**
    * Decoded donation unit public key.
    */
-  struct TALER_DonationUnitPublicKey donation_unit_pub;
+  // struct TALER_DonationUnitPublicKey donation_unit_pub;
 
 };
 
@@ -122,3 +123,6 @@ typedef void
   void *cls,
   const struct TALER_DonauPublicKeyP *donau_pub,
   const struct TALER_DONAUDB_SignkeyMetaData *meta);
+
+
+#endif
\ No newline at end of file
diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am
index e81f811..ca85fd2 100644
--- a/src/pq/Makefile.am
+++ b/src/pq/Makefile.am
@@ -13,7 +13,7 @@ libtalerpq_la_SOURCES = \
   pq_query_helper.c \
   pq_result_helper.c
 libtalerpq_la_LIBADD = \
-  $(top_builddir)/src/util/libtalerutil.la  \
+  $(top_builddir)/src/util/libtalerdonauutil.la  \
   -lgnunetutil -ljansson \
   -lgnunetpq \
   -lpq \
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index 949c986..d7ecd6b 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -26,1156 +26,1156 @@
 #include <taler/taler_pq_lib.h>
 
 
-/**
- * Function called to convert input amount into SQL parameter as tuple.
- *
- * @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_currency_tuple (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)
-{
-  struct GNUNET_PQ_Context *db = cls;
-  const struct TALER_Amount *amount = data;
-  size_t sz;
-
-  GNUNET_assert (NULL != db);
-  GNUNET_assert (NULL != amount);
-  GNUNET_assert (1 == param_length);
-  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 oid_f;
-    Oid oid_c;
-    struct TALER_PQ_AmountCurrencyP d;
-
-    GNUNET_assert (GNUNET_OK ==
-                   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_assert (GNUNET_OK ==
-                   GNUNET_PQ_get_oid_by_name (db,
-                                              "varchar",
-                                              &oid_c));
-    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];
-  param_lengths[0] = sz;
-  param_formats[0] = 1;
-
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_amount_with_currency (
-  const struct GNUNET_PQ_Context *db,
-  const struct TALER_Amount *amount)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv_cls = (void *) db,
-    .conv = &qconv_amount_currency_tuple,
-    .data = amount,
-    .size = sizeof (*amount),
-    .num_params = 1,
-  };
-
-  return res;
-}
-
-
-/**
- * Function called to convert input amount into SQL parameter as tuple.
- *
- * @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_tuple (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)
-{
-  struct GNUNET_PQ_Context *db = cls;
-  const struct TALER_Amount *amount = data;
-  size_t sz;
-
-  GNUNET_assert (NULL != db);
-  GNUNET_assert (NULL != amount);
-  GNUNET_assert (1 == param_length);
-  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 oid_f;
-
-    GNUNET_assert (GNUNET_OK ==
-                   GNUNET_PQ_get_oid_by_name (db,
-                                              "int8",
-                                              &oid_v));
-    GNUNET_assert (GNUNET_OK ==
-                   GNUNET_PQ_get_oid_by_name (db,
-                                              "int4",
-                                              &oid_f));
-
-    {
-      struct TALER_PQ_AmountP d
-        = TALER_PQ_make_taler_pq_amount_ (amount,
-                                          oid_v,
-                                          oid_f);
-
-      sz = sizeof(d);
-      out = GNUNET_malloc (sz);
-      scratch[0] = out;
-      GNUNET_memcpy (out,
-                     &d,
-                     sizeof(d));
-    }
-  }
-
-  param_values[0] = scratch[0];
-  param_lengths[0] = sz;
-  param_formats[0] = 1;
-
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_amount (
-  const struct GNUNET_PQ_Context *db,
-  const struct TALER_Amount *amount)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv_cls = (void *) db,
-    .conv = &qconv_amount_tuple,
-    .data = amount,
-    .size = sizeof (*amount),
-    .num_params = 1,
-  };
-
-  return res;
-}
-
-
-/**
- * Function called to convert input argument into SQL parameters.
- *
- * @param cls closure
- * @param data pointer to input argument
- * @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_denom_pub (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_DenominationPublicKey *denom_pub = data;
-  size_t tlen;
-  size_t len;
-  uint32_t be[2];
-  char *buf;
-  void *tbuf;
-
-  (void) cls;
-  (void) data_len;
-  GNUNET_assert (1 == param_length);
-  GNUNET_assert (scratch_length > 0);
-  GNUNET_break (NULL == cls);
-  be[0] = htonl ((uint32_t) denom_pub->cipher);
-  be[1] = htonl (denom_pub->age_mask.bits);
-  switch (denom_pub->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    tlen = GNUNET_CRYPTO_rsa_public_key_encode (
-      denom_pub->details.rsa_public_key,
-      &tbuf);
-    break;
-  case TALER_DENOMINATION_CS:
-    tlen = sizeof (denom_pub->details.cs_public_key);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  len = tlen + sizeof (be);
-  buf = GNUNET_malloc (len);
-  GNUNET_memcpy (buf,
-                 be,
-                 sizeof (be));
-  switch (denom_pub->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   tbuf,
-                   tlen);
-    GNUNET_free (tbuf);
-    break;
-  case TALER_DENOMINATION_CS:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   &denom_pub->details.cs_public_key,
-                   tlen);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-
-  scratch[0] = buf;
-  param_values[0] = (void *) buf;
-  param_lengths[0] = len;
-  param_formats[0] = 1;
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_denom_pub (
-  const struct TALER_DenominationPublicKey *denom_pub)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv = &qconv_denom_pub,
-    .data = denom_pub,
-    .num_params = 1
-  };
-
-  return res;
-}
-
-
-/**
- * Function called to convert input argument into SQL parameters.
- *
- * @param cls closure
- * @param data pointer to input argument
- * @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_denom_sig (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_DenominationSignature *denom_sig = data;
-  size_t tlen;
-  size_t len;
-  uint32_t be[2];
-  char *buf;
-  void *tbuf;
-
-  (void) cls;
-  (void) data_len;
-  GNUNET_assert (1 == param_length);
-  GNUNET_assert (scratch_length > 0);
-  GNUNET_break (NULL == cls);
-  be[0] = htonl ((uint32_t) denom_sig->cipher);
-  be[1] = htonl (0x00); /* magic marker: unblinded */
-  switch (denom_sig->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    tlen = GNUNET_CRYPTO_rsa_signature_encode (
-      denom_sig->details.rsa_signature,
-      &tbuf);
-    break;
-  case TALER_DENOMINATION_CS:
-    tlen = sizeof (denom_sig->details.cs_signature);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  len = tlen + sizeof (be);
-  buf = GNUNET_malloc (len);
-  GNUNET_memcpy (buf,
-                 &be,
-                 sizeof (be));
-  switch (denom_sig->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   tbuf,
-                   tlen);
-    GNUNET_free (tbuf);
-    break;
-  case TALER_DENOMINATION_CS:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   &denom_sig->details.cs_signature,
-                   tlen);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-
-  scratch[0] = buf;
-  param_values[0] = (void *) buf;
-  param_lengths[0] = len;
-  param_formats[0] = 1;
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_denom_sig (
-  const struct TALER_DenominationSignature *denom_sig)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv = &qconv_denom_sig,
-    .data = denom_sig,
-    .num_params = 1
-  };
-
-  return res;
-}
-
-
-/**
- * Function called to convert input argument into SQL parameters.
- *
- * @param cls closure
- * @param data pointer to input argument
- * @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_blinded_denom_sig (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_BlindedDenominationSignature *denom_sig = data;
-  size_t tlen;
-  size_t len;
-  uint32_t be[2];
-  char *buf;
-  void *tbuf;
-
-  (void) cls;
-  (void) data_len;
-  GNUNET_assert (1 == param_length);
-  GNUNET_assert (scratch_length > 0);
-  GNUNET_break (NULL == cls);
-  be[0] = htonl ((uint32_t) denom_sig->cipher);
-  be[1] = htonl (0x01); /* magic marker: blinded */
-  switch (denom_sig->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    tlen = GNUNET_CRYPTO_rsa_signature_encode (
-      denom_sig->details.blinded_rsa_signature,
-      &tbuf);
-    break;
-  case TALER_DENOMINATION_CS:
-    tlen = sizeof (denom_sig->details.blinded_cs_answer);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  len = tlen + sizeof (be);
-  buf = GNUNET_malloc (len);
-  GNUNET_memcpy (buf,
-                 &be,
-                 sizeof (be));
-  switch (denom_sig->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   tbuf,
-                   tlen);
-    GNUNET_free (tbuf);
-    break;
-  case TALER_DENOMINATION_CS:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   &denom_sig->details.blinded_cs_answer,
-                   tlen);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-
-  scratch[0] = buf;
-  param_values[0] = (void *) buf;
-  param_lengths[0] = len;
-  param_formats[0] = 1;
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_blinded_denom_sig (
-  const struct TALER_BlindedDenominationSignature *denom_sig)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv = &qconv_blinded_denom_sig,
-    .data = denom_sig,
-    .num_params = 1
-  };
-
-  return res;
-}
-
-
-/**
- * Function called to convert input argument into SQL parameters.
- *
- * @param cls closure
- * @param data pointer to input argument
- * @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_blinded_planchet (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_BlindedPlanchet *bp = data;
-  size_t tlen;
-  size_t len;
-  uint32_t be[2];
-  char *buf;
-
-  (void) cls;
-  (void) data_len;
-  GNUNET_assert (1 == param_length);
-  GNUNET_assert (scratch_length > 0);
-  GNUNET_break (NULL == cls);
-  be[0] = htonl ((uint32_t) bp->cipher);
-  be[1] = htonl (0x0100); /* magic marker: blinded */
-  switch (bp->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    tlen = bp->details.rsa_blinded_planchet.blinded_msg_size;
-    break;
-  case TALER_DENOMINATION_CS:
-    tlen = sizeof (bp->details.cs_blinded_planchet);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  len = tlen + sizeof (be);
-  buf = GNUNET_malloc (len);
-  GNUNET_memcpy (buf,
-                 &be,
-                 sizeof (be));
-  switch (bp->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   bp->details.rsa_blinded_planchet.blinded_msg,
-                   tlen);
-    break;
-  case TALER_DENOMINATION_CS:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   &bp->details.cs_blinded_planchet,
-                   tlen);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  scratch[0] = buf;
-  param_values[0] = (void *) buf;
-  param_lengths[0] = len;
-  param_formats[0] = 1;
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_blinded_planchet (
-  const struct TALER_BlindedPlanchet *bp)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv = &qconv_blinded_planchet,
-    .data = bp,
-    .num_params = 1
-  };
-
-  return res;
-}
-
-
-/**
- * Function called to convert input argument into SQL parameters.
- *
- * @param cls closure
- * @param data pointer to input argument
- * @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_exchange_withdraw_values (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_ExchangeWithdrawValues *alg_values = data;
-  size_t tlen;
-  size_t len;
-  uint32_t be[2];
-  char *buf;
-
-  (void) cls;
-  (void) data_len;
-  GNUNET_assert (1 == param_length);
-  GNUNET_assert (scratch_length > 0);
-  GNUNET_break (NULL == cls);
-  be[0] = htonl ((uint32_t) alg_values->cipher);
-  be[1] = htonl (0x010000); /* magic marker: EWV */
-  switch (alg_values->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    tlen = 0;
-    break;
-  case TALER_DENOMINATION_CS:
-    tlen = sizeof (struct TALER_DenominationCSPublicRPairP);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  len = tlen + sizeof (be);
-  buf = GNUNET_malloc (len);
-  GNUNET_memcpy (buf,
-                 &be,
-                 sizeof (be));
-  switch (alg_values->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    break;
-  case TALER_DENOMINATION_CS:
-    GNUNET_memcpy (&buf[sizeof (be)],
-                   &alg_values->details.cs_values,
-                   tlen);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-  scratch[0] = buf;
-  param_values[0] = (void *) buf;
-  param_lengths[0] = len;
-  param_formats[0] = 1;
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_exchange_withdraw_values (
-  const struct TALER_ExchangeWithdrawValues *alg_values)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv = &qconv_exchange_withdraw_values,
-    .data = alg_values,
-    .num_params = 1
-  };
-
-  return res;
-}
-
-
-/**
- * Function called to convert input argument into SQL parameters.
- *
- * @param cls closure
- * @param data pointer to input argument, here a `json_t *`
- * @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_json (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 json_t *json = data;
-  char *str;
-
-  (void) cls;
-  (void) data_len;
-  GNUNET_assert (1 == param_length);
-  GNUNET_assert (scratch_length > 0);
-  str = json_dumps (json, JSON_COMPACT);
-  if (NULL == str)
-    return -1;
-  scratch[0] = str;
-  param_values[0] = (void *) str;
-  param_lengths[0] = strlen (str);
-  param_formats[0] = 1;
-  return 1;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_json (const json_t *x)
-{
-  struct GNUNET_PQ_QueryParam res = {
-    .conv = &qconv_json,
-    .data = x,
-    .num_params = 1
-  };
-
-  return res;
-}
-
-
-/** ------------------- Array support  -----------------------------------**/
-
-/**
- * Closure for the array type handlers.
- *
- * May contain sizes information for the data, given (and handled) by the
- * caller.
- */
-struct qconv_array_cls
-{
-  /**
-   * If not null, contains the array of sizes (the size of the array is the
-   * .size field in the ambient GNUNET_PQ_QueryParam struct). We do not free
-   * this memory.
-   *
-   * If not null, this value has precedence over @a sizes, which MUST be NULL 
*/
-  const size_t *sizes;
-
-  /**
-   * If @a size and @a c_sizes are NULL, this field defines the same size
-   * for each element in the array.
-   */
-  size_t same_size;
-
-  /**
-   * If true, the array parameter to the data pointer to the qconv_array is a
-   * continuous byte array of data, either with @a same_size each or sizes
-   * provided bytes by @a sizes;
-   */
-  bool continuous;
-
-  /**
-   * Type of the array elements
-   */
-  enum TALER_PQ_ArrayType typ;
-
-  /**
-   * Oid of the array elements
-   */
-  Oid oid;
-
-  /**
-   * db context, needed for OID-lookup of basis-types
-   */
-  struct GNUNET_PQ_Context *db;
-};
-
-/**
- * Callback to cleanup a qconv_array_cls to be used during
- * GNUNET_PQ_cleanup_query_params_closures
- */
-static void
-qconv_array_cls_cleanup (void *cls)
-{
-  GNUNET_free (cls);
-}
-
-
-/**
- * Function called to convert input argument into SQL parameters for arrays
- *
- * Note: the format for the encoding of arrays for libpq is not very well
- * documented.  We peeked into various sources (postgresql and libpqtypes) for
- * guidance.
- *
- * @param cls Closure of type struct qconv_array_cls*
- * @param data Pointer to first element in the array
- * @param data_len Number of _elements_ in array @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_array (
-  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)
-{
-  struct qconv_array_cls *meta = cls;
-  size_t num = data_len;
-  size_t total_size;
-  const size_t *sizes;
-  bool same_sized;
-  void *elements = NULL;
-  bool noerror = true;
-  /* needed to capture the encoded rsa signatures */
-  void **buffers = NULL;
-  size_t *buffer_lengths = NULL;
-
-  (void) (param_length);
-  (void) (scratch_length);
-
-  GNUNET_assert (NULL != meta);
-  GNUNET_assert (num < INT_MAX);
-
-  sizes = meta->sizes;
-  same_sized = (0 != meta->same_size);
-
-#define RETURN_UNLESS(cond) \
-  do { \
-    if (! (cond)) \
-    { \
-      GNUNET_break ((cond)); \
-      noerror = false; \
-      goto DONE; \
-    } \
-  } while (0)
-
-  /* Calculate sizes and check bounds */
-  {
-    /* num * length-field */
-    size_t x = sizeof(uint32_t);
-    size_t y = x * num;
-    RETURN_UNLESS ((0 == num) || (y / num == x));
-
-    /* size of header */
-    total_size  = x = sizeof(struct GNUNET_PQ_ArrayHeader_P);
-    total_size += y;
-    RETURN_UNLESS (total_size >= x);
-
-    /* sizes of elements */
-    if (same_sized)
-    {
-      x = num * meta->same_size;
-      RETURN_UNLESS ((0 == num) || (x / num == meta->same_size));
-
-      y = total_size;
-      total_size += x;
-      RETURN_UNLESS (total_size >= y);
-    }
-    else  /* sizes are different per element */
-    {
-      switch (meta->typ)
-      {
-      case TALER_PQ_array_of_blinded_denom_sig:
-        {
-          const struct TALER_BlindedDenominationSignature *denom_sigs = data;
-          size_t len;
-
-          buffers  = GNUNET_new_array (num, void *);
-          buffer_lengths  = GNUNET_new_array (num, size_t);
-
-          for (size_t i = 0; i<num; i++)
-          {
-            switch (denom_sigs[i].cipher)
-            {
-            case TALER_DENOMINATION_RSA:
-              len = GNUNET_CRYPTO_rsa_signature_encode (
-                denom_sigs[i].details.blinded_rsa_signature,
-                &buffers[i]);
-              RETURN_UNLESS (len != 0);
-              break;
-            case TALER_DENOMINATION_CS:
-              len = sizeof (denom_sigs[i].details.blinded_cs_answer);
-              break;
-            default:
-              GNUNET_assert (0);
-            }
-
-            /* for the cipher and marker */
-            len += 2 * sizeof(uint32_t);
-            buffer_lengths[i] = len;
-
-            y = total_size;
-            total_size += len;
-            RETURN_UNLESS (total_size >= y);
-          }
-          sizes = buffer_lengths;
-          break;
-        }
-      default:
-        GNUNET_assert (0);
-      }
-    }
-
-    RETURN_UNLESS (INT_MAX > total_size);
-    RETURN_UNLESS (0 != total_size);
-
-    elements = GNUNET_malloc (total_size);
-  }
-
-  /* Write data */
-  {
-    char *out = elements;
-    struct GNUNET_PQ_ArrayHeader_P h = {
-      .ndim = htonl (1),        /* We only support one-dimensional arrays */
-      .has_null = htonl (0),    /* We do not support NULL entries in arrays */
-      .lbound = htonl (1),      /* Default start index value */
-      .dim = htonl (num),
-      .oid = htonl (meta->oid),
-    };
-
-    /* Write header */
-    GNUNET_memcpy (out,
-                   &h,
-                   sizeof(h));
-    out += sizeof(h);
-
-    /* Write elements */
-    for (size_t i = 0; i < num; i++)
-    {
-      size_t sz = same_sized ? meta->same_size : sizes[i];
-
-      *(uint32_t *) out = htonl (sz);
-      out += sizeof(uint32_t);
-      switch (meta->typ)
-      {
-      case TALER_PQ_array_of_amount:
-        {
-          const struct TALER_Amount *amounts = data;
-          Oid oid_v;
-          Oid oid_f;
-
-          GNUNET_assert (GNUNET_OK ==
-                         GNUNET_PQ_get_oid_by_name (meta->db,
-                                                    "int8",
-                                                    &oid_v));
-          GNUNET_assert (GNUNET_OK ==
-                         GNUNET_PQ_get_oid_by_name (meta->db,
-                                                    "int4",
-                                                    &oid_f));
-          {
-            struct TALER_PQ_AmountP am
-              = TALER_PQ_make_taler_pq_amount_ (
-                  &amounts[i],
-                  oid_v,
-                  oid_f);
-
-            GNUNET_memcpy (out,
-                           &am,
-                           sizeof(am));
-          }
-          break;
-        }
-      case TALER_PQ_array_of_blinded_denom_sig:
-        {
-          const struct TALER_BlindedDenominationSignature *denom_sigs = data;
-          uint32_t be[2];
-
-          be[0] = htonl ((uint32_t) denom_sigs[i].cipher);
-          be[1] = htonl (0x01);     /* magic margker: blinded */
-          GNUNET_memcpy (out,
-                         &be,
-                         sizeof(be));
-          out += sizeof(be);
-          sz -= sizeof(be);
-
-          switch (denom_sigs[i].cipher)
-          {
-          case TALER_DENOMINATION_RSA:
-            /* For RSA, 'same_sized' must have been false */
-            GNUNET_assert (NULL != buffers);
-            GNUNET_memcpy (out,
-                           buffers[i],
-                           sz);
-            break;
-          case TALER_DENOMINATION_CS:
-            GNUNET_memcpy (out,
-                           &denom_sigs[i].details.blinded_cs_answer,
-                           sz);
-            break;
-          default:
-            GNUNET_assert (0);
-          }
-          break;
-        }
-      case TALER_PQ_array_of_blinded_coin_hash:
-        {
-          const struct TALER_BlindedCoinHashP *coin_hs = data;
-
-          GNUNET_memcpy (out,
-                         &coin_hs[i],
-                         sizeof(struct TALER_BlindedCoinHashP));
-
-          break;
-        }
-      case TALER_PQ_array_of_denom_hash:
-        {
-          const struct TALER_DenominationHashP *denom_hs = data;
-
-          GNUNET_memcpy (out,
-                         &denom_hs[i],
-                         sizeof(struct TALER_DenominationHashP));
-          break;
-        }
-      default:
-        {
-          GNUNET_assert (0);
-          break;
-        }
-      }
-      out += sz;
-    }
-  }
-  param_values[0] = elements;
-  param_lengths[0] = total_size;
-  param_formats[0] = 1;
-  scratch[0] = elements;
-
-DONE:
-  if (NULL != buffers)
-  {
-    for (size_t i = 0; i<num; i++)
-      GNUNET_free (buffers[i]);
-    GNUNET_free (buffers);
-  }
-  GNUNET_free (buffer_lengths);
-  if (noerror)
-    return 1;
-  return -1;
-}
-
-
-/**
- * Function to generate a typ specific query parameter and corresponding 
closure
- *
- * @param num Number of elements in @a elements
- * @param continuous If true, @a elements is an continuous array of data
- * @param elements Array of @a num elements, either continuous or pointers
- * @param sizes Array of @a num sizes, one per element, may be NULL
- * @param same_size If not 0, all elements in @a elements have this size
- * @param typ Supported internal type of each element in @a elements
- * @param oid Oid of the type to be used in Postgres
- * @param[in,out] db our database handle for looking up OIDs
- * @return Query parameter
- */
-static struct GNUNET_PQ_QueryParam
-query_param_array_generic (
-  unsigned int num,
-  bool continuous,
-  const void *elements,
-  const size_t *sizes,
-  size_t same_size,
-  enum TALER_PQ_ArrayType typ,
-  Oid oid,
-  struct GNUNET_PQ_Context *db)
-{
-  struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls);
-  meta->typ = typ;
-  meta->oid = oid;
-  meta->sizes = sizes;
-  meta->same_size = same_size;
-  meta->continuous = continuous;
-  meta->db = db;
-
-  struct GNUNET_PQ_QueryParam res = {
-    .conv = qconv_array,
-    .conv_cls = meta,
-    .conv_cls_cleanup = qconv_array_cls_cleanup,
-    .data = elements,
-    .size = num,
-    .num_params = 1,
-  };
-
-  return res;
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_array_blinded_denom_sig (
-  size_t num,
-  const struct TALER_BlindedDenominationSignature *denom_sigs,
-  struct GNUNET_PQ_Context *db)
-{
-  Oid oid;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db, "bytea", &oid));
-  return query_param_array_generic (num,
-                                    true,
-                                    denom_sigs,
-                                    NULL,
-                                    0,
-                                    TALER_PQ_array_of_blinded_denom_sig,
-                                    oid,
-                                    NULL);
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_array_blinded_coin_hash (
-  size_t num,
-  const struct TALER_BlindedCoinHashP *coin_hs,
-  struct GNUNET_PQ_Context *db)
-{
-  Oid oid;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db, "bytea", &oid));
-  return query_param_array_generic (num,
-                                    true,
-                                    coin_hs,
-                                    NULL,
-                                    sizeof(struct TALER_BlindedCoinHashP),
-                                    TALER_PQ_array_of_blinded_coin_hash,
-                                    oid,
-                                    NULL);
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_array_denom_hash (
-  size_t num,
-  const struct TALER_DenominationHashP *denom_hs,
-  struct GNUNET_PQ_Context *db)
-{
-  Oid oid;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db, "bytea", &oid));
-  return query_param_array_generic (num,
-                                    true,
-                                    denom_hs,
-                                    NULL,
-                                    sizeof(struct TALER_DenominationHashP),
-                                    TALER_PQ_array_of_denom_hash,
-                                    oid,
-                                    NULL);
-}
-
-
-struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_array_amount (
-  size_t num,
-  const struct TALER_Amount *amounts,
-  struct GNUNET_PQ_Context *db)
-{
-  Oid oid;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db, "taler_amount", &oid));
-  return query_param_array_generic (
-    num,
-    true,
-    amounts,
-    NULL,
-    sizeof(struct TALER_PQ_AmountP),
-    TALER_PQ_array_of_amount,
-    oid,
-    db);
-}
-
-
-/* end of pq/pq_query_helper.c */
+// /**
+//  * Function called to convert input amount into SQL parameter as tuple.
+//  *
+//  * @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_currency_tuple (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)
+// {
+//   struct GNUNET_PQ_Context *db = cls;
+//   const struct TALER_Amount *amount = data;
+//   size_t sz;
+
+//   GNUNET_assert (NULL != db);
+//   GNUNET_assert (NULL != amount);
+//   GNUNET_assert (1 == param_length);
+//   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 oid_f;
+//     Oid oid_c;
+//     struct TALER_PQ_AmountCurrencyP d;
+
+//     GNUNET_assert (GNUNET_OK ==
+//                    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_assert (GNUNET_OK ==
+//                    GNUNET_PQ_get_oid_by_name (db,
+//                                               "varchar",
+//                                               &oid_c));
+//     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];
+//   param_lengths[0] = sz;
+//   param_formats[0] = 1;
+
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_amount_with_currency (
+//   const struct GNUNET_PQ_Context *db,
+//   const struct TALER_Amount *amount)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv_cls = (void *) db,
+//     .conv = &qconv_amount_currency_tuple,
+//     .data = amount,
+//     .size = sizeof (*amount),
+//     .num_params = 1,
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Function called to convert input amount into SQL parameter as tuple.
+//  *
+//  * @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_tuple (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)
+// {
+//   struct GNUNET_PQ_Context *db = cls;
+//   const struct TALER_Amount *amount = data;
+//   size_t sz;
+
+//   GNUNET_assert (NULL != db);
+//   GNUNET_assert (NULL != amount);
+//   GNUNET_assert (1 == param_length);
+//   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 oid_f;
+
+//     GNUNET_assert (GNUNET_OK ==
+//                    GNUNET_PQ_get_oid_by_name (db,
+//                                               "int8",
+//                                               &oid_v));
+//     GNUNET_assert (GNUNET_OK ==
+//                    GNUNET_PQ_get_oid_by_name (db,
+//                                               "int4",
+//                                               &oid_f));
+
+//     {
+//       struct TALER_PQ_AmountP d
+//         = TALER_PQ_make_taler_pq_amount_ (amount,
+//                                           oid_v,
+//                                           oid_f);
+
+//       sz = sizeof(d);
+//       out = GNUNET_malloc (sz);
+//       scratch[0] = out;
+//       GNUNET_memcpy (out,
+//                      &d,
+//                      sizeof(d));
+//     }
+//   }
+
+//   param_values[0] = scratch[0];
+//   param_lengths[0] = sz;
+//   param_formats[0] = 1;
+
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_amount (
+//   const struct GNUNET_PQ_Context *db,
+//   const struct TALER_Amount *amount)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv_cls = (void *) db,
+//     .conv = &qconv_amount_tuple,
+//     .data = amount,
+//     .size = sizeof (*amount),
+//     .num_params = 1,
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Function called to convert input argument into SQL parameters.
+//  *
+//  * @param cls closure
+//  * @param data pointer to input argument
+//  * @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_denom_pub (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_DenominationPublicKey *denom_pub = data;
+//   size_t tlen;
+//   size_t len;
+//   uint32_t be[2];
+//   char *buf;
+//   void *tbuf;
+
+//   (void) cls;
+//   (void) data_len;
+//   GNUNET_assert (1 == param_length);
+//   GNUNET_assert (scratch_length > 0);
+//   GNUNET_break (NULL == cls);
+//   be[0] = htonl ((uint32_t) denom_pub->cipher);
+//   be[1] = htonl (denom_pub->age_mask.bits);
+//   switch (denom_pub->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     tlen = GNUNET_CRYPTO_rsa_public_key_encode (
+//       denom_pub->details.rsa_public_key,
+//       &tbuf);
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     tlen = sizeof (denom_pub->details.cs_public_key);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+//   len = tlen + sizeof (be);
+//   buf = GNUNET_malloc (len);
+//   GNUNET_memcpy (buf,
+//                  be,
+//                  sizeof (be));
+//   switch (denom_pub->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    tbuf,
+//                    tlen);
+//     GNUNET_free (tbuf);
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    &denom_pub->details.cs_public_key,
+//                    tlen);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+
+//   scratch[0] = buf;
+//   param_values[0] = (void *) buf;
+//   param_lengths[0] = len;
+//   param_formats[0] = 1;
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_denom_pub (
+//   const struct TALER_DenominationPublicKey *denom_pub)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv = &qconv_denom_pub,
+//     .data = denom_pub,
+//     .num_params = 1
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Function called to convert input argument into SQL parameters.
+//  *
+//  * @param cls closure
+//  * @param data pointer to input argument
+//  * @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_denom_sig (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_DenominationSignature *denom_sig = data;
+//   size_t tlen;
+//   size_t len;
+//   uint32_t be[2];
+//   char *buf;
+//   void *tbuf;
+
+//   (void) cls;
+//   (void) data_len;
+//   GNUNET_assert (1 == param_length);
+//   GNUNET_assert (scratch_length > 0);
+//   GNUNET_break (NULL == cls);
+//   be[0] = htonl ((uint32_t) denom_sig->cipher);
+//   be[1] = htonl (0x00); /* magic marker: unblinded */
+//   switch (denom_sig->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     tlen = GNUNET_CRYPTO_rsa_signature_encode (
+//       denom_sig->details.rsa_signature,
+//       &tbuf);
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     tlen = sizeof (denom_sig->details.cs_signature);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+//   len = tlen + sizeof (be);
+//   buf = GNUNET_malloc (len);
+//   GNUNET_memcpy (buf,
+//                  &be,
+//                  sizeof (be));
+//   switch (denom_sig->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    tbuf,
+//                    tlen);
+//     GNUNET_free (tbuf);
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    &denom_sig->details.cs_signature,
+//                    tlen);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+
+//   scratch[0] = buf;
+//   param_values[0] = (void *) buf;
+//   param_lengths[0] = len;
+//   param_formats[0] = 1;
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_denom_sig (
+//   const struct TALER_DenominationSignature *denom_sig)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv = &qconv_denom_sig,
+//     .data = denom_sig,
+//     .num_params = 1
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Function called to convert input argument into SQL parameters.
+//  *
+//  * @param cls closure
+//  * @param data pointer to input argument
+//  * @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_blinded_denom_sig (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_BlindedDenominationSignature *denom_sig = data;
+//   size_t tlen;
+//   size_t len;
+//   uint32_t be[2];
+//   char *buf;
+//   void *tbuf;
+
+//   (void) cls;
+//   (void) data_len;
+//   GNUNET_assert (1 == param_length);
+//   GNUNET_assert (scratch_length > 0);
+//   GNUNET_break (NULL == cls);
+//   be[0] = htonl ((uint32_t) denom_sig->cipher);
+//   be[1] = htonl (0x01); /* magic marker: blinded */
+//   switch (denom_sig->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     tlen = GNUNET_CRYPTO_rsa_signature_encode (
+//       denom_sig->details.blinded_rsa_signature,
+//       &tbuf);
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     tlen = sizeof (denom_sig->details.blinded_cs_answer);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+//   len = tlen + sizeof (be);
+//   buf = GNUNET_malloc (len);
+//   GNUNET_memcpy (buf,
+//                  &be,
+//                  sizeof (be));
+//   switch (denom_sig->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    tbuf,
+//                    tlen);
+//     GNUNET_free (tbuf);
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    &denom_sig->details.blinded_cs_answer,
+//                    tlen);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+
+//   scratch[0] = buf;
+//   param_values[0] = (void *) buf;
+//   param_lengths[0] = len;
+//   param_formats[0] = 1;
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_blinded_denom_sig (
+//   const struct TALER_BlindedDenominationSignature *denom_sig)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv = &qconv_blinded_denom_sig,
+//     .data = denom_sig,
+//     .num_params = 1
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Function called to convert input argument into SQL parameters.
+//  *
+//  * @param cls closure
+//  * @param data pointer to input argument
+//  * @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_blinded_planchet (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_BlindedPlanchet *bp = data;
+//   size_t tlen;
+//   size_t len;
+//   uint32_t be[2];
+//   char *buf;
+
+//   (void) cls;
+//   (void) data_len;
+//   GNUNET_assert (1 == param_length);
+//   GNUNET_assert (scratch_length > 0);
+//   GNUNET_break (NULL == cls);
+//   be[0] = htonl ((uint32_t) bp->cipher);
+//   be[1] = htonl (0x0100); /* magic marker: blinded */
+//   switch (bp->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     tlen = bp->details.rsa_blinded_planchet.blinded_msg_size;
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     tlen = sizeof (bp->details.cs_blinded_planchet);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+//   len = tlen + sizeof (be);
+//   buf = GNUNET_malloc (len);
+//   GNUNET_memcpy (buf,
+//                  &be,
+//                  sizeof (be));
+//   switch (bp->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    bp->details.rsa_blinded_planchet.blinded_msg,
+//                    tlen);
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    &bp->details.cs_blinded_planchet,
+//                    tlen);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+//   scratch[0] = buf;
+//   param_values[0] = (void *) buf;
+//   param_lengths[0] = len;
+//   param_formats[0] = 1;
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_blinded_planchet (
+//   const struct TALER_BlindedPlanchet *bp)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv = &qconv_blinded_planchet,
+//     .data = bp,
+//     .num_params = 1
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Function called to convert input argument into SQL parameters.
+//  *
+//  * @param cls closure
+//  * @param data pointer to input argument
+//  * @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_exchange_withdraw_values (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_ExchangeWithdrawValues *alg_values = data;
+//   size_t tlen;
+//   size_t len;
+//   uint32_t be[2];
+//   char *buf;
+
+//   (void) cls;
+//   (void) data_len;
+//   GNUNET_assert (1 == param_length);
+//   GNUNET_assert (scratch_length > 0);
+//   GNUNET_break (NULL == cls);
+//   be[0] = htonl ((uint32_t) alg_values->cipher);
+//   be[1] = htonl (0x010000); /* magic marker: EWV */
+//   switch (alg_values->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     tlen = 0;
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     tlen = sizeof (struct TALER_DenominationCSPublicRPairP);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+//   len = tlen + sizeof (be);
+//   buf = GNUNET_malloc (len);
+//   GNUNET_memcpy (buf,
+//                  &be,
+//                  sizeof (be));
+//   switch (alg_values->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     break;
+//   case TALER_DENOMINATION_CS:
+//     GNUNET_memcpy (&buf[sizeof (be)],
+//                    &alg_values->details.cs_values,
+//                    tlen);
+//     break;
+//   default:
+//     GNUNET_assert (0);
+//   }
+//   scratch[0] = buf;
+//   param_values[0] = (void *) buf;
+//   param_lengths[0] = len;
+//   param_formats[0] = 1;
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_exchange_withdraw_values (
+//   const struct TALER_ExchangeWithdrawValues *alg_values)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv = &qconv_exchange_withdraw_values,
+//     .data = alg_values,
+//     .num_params = 1
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Function called to convert input argument into SQL parameters.
+//  *
+//  * @param cls closure
+//  * @param data pointer to input argument, here a `json_t *`
+//  * @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_json (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 json_t *json = data;
+//   char *str;
+
+//   (void) cls;
+//   (void) data_len;
+//   GNUNET_assert (1 == param_length);
+//   GNUNET_assert (scratch_length > 0);
+//   str = json_dumps (json, JSON_COMPACT);
+//   if (NULL == str)
+//     return -1;
+//   scratch[0] = str;
+//   param_values[0] = (void *) str;
+//   param_lengths[0] = strlen (str);
+//   param_formats[0] = 1;
+//   return 1;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_json (const json_t *x)
+// {
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv = &qconv_json,
+//     .data = x,
+//     .num_params = 1
+//   };
+
+//   return res;
+// }
+
+
+// /** ------------------- Array support  
-----------------------------------**/
+
+// /**
+//  * Closure for the array type handlers.
+//  *
+//  * May contain sizes information for the data, given (and handled) by the
+//  * caller.
+//  */
+// struct qconv_array_cls
+// {
+//   /**
+//    * If not null, contains the array of sizes (the size of the array is the
+//    * .size field in the ambient GNUNET_PQ_QueryParam struct). We do not free
+//    * this memory.
+//    *
+//    * If not null, this value has precedence over @a sizes, which MUST be 
NULL */
+//   const size_t *sizes;
+
+//   /**
+//    * If @a size and @a c_sizes are NULL, this field defines the same size
+//    * for each element in the array.
+//    */
+//   size_t same_size;
+
+//   /**
+//    * If true, the array parameter to the data pointer to the qconv_array is 
a
+//    * continuous byte array of data, either with @a same_size each or sizes
+//    * provided bytes by @a sizes;
+//    */
+//   bool continuous;
+
+//   /**
+//    * Type of the array elements
+//    */
+//   enum TALER_PQ_ArrayType typ;
+
+//   /**
+//    * Oid of the array elements
+//    */
+//   Oid oid;
+
+//   /**
+//    * db context, needed for OID-lookup of basis-types
+//    */
+//   struct GNUNET_PQ_Context *db;
+// };
+
+// /**
+//  * Callback to cleanup a qconv_array_cls to be used during
+//  * GNUNET_PQ_cleanup_query_params_closures
+//  */
+// static void
+// qconv_array_cls_cleanup (void *cls)
+// {
+//   GNUNET_free (cls);
+// }
+
+
+// /**
+//  * Function called to convert input argument into SQL parameters for arrays
+//  *
+//  * Note: the format for the encoding of arrays for libpq is not very well
+//  * documented.  We peeked into various sources (postgresql and libpqtypes) 
for
+//  * guidance.
+//  *
+//  * @param cls Closure of type struct qconv_array_cls*
+//  * @param data Pointer to first element in the array
+//  * @param data_len Number of _elements_ in array @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_array (
+//   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)
+// {
+//   struct qconv_array_cls *meta = cls;
+//   size_t num = data_len;
+//   size_t total_size;
+//   const size_t *sizes;
+//   bool same_sized;
+//   void *elements = NULL;
+//   bool noerror = true;
+//   /* needed to capture the encoded rsa signatures */
+//   void **buffers = NULL;
+//   size_t *buffer_lengths = NULL;
+
+//   (void) (param_length);
+//   (void) (scratch_length);
+
+//   GNUNET_assert (NULL != meta);
+//   GNUNET_assert (num < INT_MAX);
+
+//   sizes = meta->sizes;
+//   same_sized = (0 != meta->same_size);
+
+// #define RETURN_UNLESS(cond) \
+//   do { \
+//     if (! (cond)) \
+//     { \
+//       GNUNET_break ((cond)); \
+//       noerror = false; \
+//       goto DONE; \
+//     } \
+//   } while (0)
+
+//   /* Calculate sizes and check bounds */
+//   {
+//     /* num * length-field */
+//     size_t x = sizeof(uint32_t);
+//     size_t y = x * num;
+//     RETURN_UNLESS ((0 == num) || (y / num == x));
+
+//     /* size of header */
+//     total_size  = x = sizeof(struct GNUNET_PQ_ArrayHeader_P);
+//     total_size += y;
+//     RETURN_UNLESS (total_size >= x);
+
+//     /* sizes of elements */
+//     if (same_sized)
+//     {
+//       x = num * meta->same_size;
+//       RETURN_UNLESS ((0 == num) || (x / num == meta->same_size));
+
+//       y = total_size;
+//       total_size += x;
+//       RETURN_UNLESS (total_size >= y);
+//     }
+//     else  /* sizes are different per element */
+//     {
+//       switch (meta->typ)
+//       {
+//       case TALER_PQ_array_of_blinded_denom_sig:
+//         {
+//           const struct TALER_BlindedDenominationSignature *denom_sigs = 
data;
+//           size_t len;
+
+//           buffers  = GNUNET_new_array (num, void *);
+//           buffer_lengths  = GNUNET_new_array (num, size_t);
+
+//           for (size_t i = 0; i<num; i++)
+//           {
+//             switch (denom_sigs[i].cipher)
+//             {
+//             case TALER_DENOMINATION_RSA:
+//               len = GNUNET_CRYPTO_rsa_signature_encode (
+//                 denom_sigs[i].details.blinded_rsa_signature,
+//                 &buffers[i]);
+//               RETURN_UNLESS (len != 0);
+//               break;
+//             case TALER_DENOMINATION_CS:
+//               len = sizeof (denom_sigs[i].details.blinded_cs_answer);
+//               break;
+//             default:
+//               GNUNET_assert (0);
+//             }
+
+//             /* for the cipher and marker */
+//             len += 2 * sizeof(uint32_t);
+//             buffer_lengths[i] = len;
+
+//             y = total_size;
+//             total_size += len;
+//             RETURN_UNLESS (total_size >= y);
+//           }
+//           sizes = buffer_lengths;
+//           break;
+//         }
+//       default:
+//         GNUNET_assert (0);
+//       }
+//     }
+
+//     RETURN_UNLESS (INT_MAX > total_size);
+//     RETURN_UNLESS (0 != total_size);
+
+//     elements = GNUNET_malloc (total_size);
+//   }
+
+//   /* Write data */
+//   {
+//     char *out = elements;
+//     struct GNUNET_PQ_ArrayHeader_P h = {
+//       .ndim = htonl (1),        /* We only support one-dimensional arrays */
+//       .has_null = htonl (0),    /* We do not support NULL entries in arrays 
*/
+//       .lbound = htonl (1),      /* Default start index value */
+//       .dim = htonl (num),
+//       .oid = htonl (meta->oid),
+//     };
+
+//     /* Write header */
+//     GNUNET_memcpy (out,
+//                    &h,
+//                    sizeof(h));
+//     out += sizeof(h);
+
+//     /* Write elements */
+//     for (size_t i = 0; i < num; i++)
+//     {
+//       size_t sz = same_sized ? meta->same_size : sizes[i];
+
+//       *(uint32_t *) out = htonl (sz);
+//       out += sizeof(uint32_t);
+//       switch (meta->typ)
+//       {
+//       case TALER_PQ_array_of_amount:
+//         {
+//           const struct TALER_Amount *amounts = data;
+//           Oid oid_v;
+//           Oid oid_f;
+
+//           GNUNET_assert (GNUNET_OK ==
+//                          GNUNET_PQ_get_oid_by_name (meta->db,
+//                                                     "int8",
+//                                                     &oid_v));
+//           GNUNET_assert (GNUNET_OK ==
+//                          GNUNET_PQ_get_oid_by_name (meta->db,
+//                                                     "int4",
+//                                                     &oid_f));
+//           {
+//             struct TALER_PQ_AmountP am
+//               = TALER_PQ_make_taler_pq_amount_ (
+//                   &amounts[i],
+//                   oid_v,
+//                   oid_f);
+
+//             GNUNET_memcpy (out,
+//                            &am,
+//                            sizeof(am));
+//           }
+//           break;
+//         }
+//       case TALER_PQ_array_of_blinded_denom_sig:
+//         {
+//           const struct TALER_BlindedDenominationSignature *denom_sigs = 
data;
+//           uint32_t be[2];
+
+//           be[0] = htonl ((uint32_t) denom_sigs[i].cipher);
+//           be[1] = htonl (0x01);     /* magic margker: blinded */
+//           GNUNET_memcpy (out,
+//                          &be,
+//                          sizeof(be));
+//           out += sizeof(be);
+//           sz -= sizeof(be);
+
+//           switch (denom_sigs[i].cipher)
+//           {
+//           case TALER_DENOMINATION_RSA:
+//             /* For RSA, 'same_sized' must have been false */
+//             GNUNET_assert (NULL != buffers);
+//             GNUNET_memcpy (out,
+//                            buffers[i],
+//                            sz);
+//             break;
+//           case TALER_DENOMINATION_CS:
+//             GNUNET_memcpy (out,
+//                            &denom_sigs[i].details.blinded_cs_answer,
+//                            sz);
+//             break;
+//           default:
+//             GNUNET_assert (0);
+//           }
+//           break;
+//         }
+//       case TALER_PQ_array_of_blinded_coin_hash:
+//         {
+//           const struct TALER_BlindedCoinHashP *coin_hs = data;
+
+//           GNUNET_memcpy (out,
+//                          &coin_hs[i],
+//                          sizeof(struct TALER_BlindedCoinHashP));
+
+//           break;
+//         }
+//       case TALER_PQ_array_of_denom_hash:
+//         {
+//           const struct TALER_DenominationHashP *denom_hs = data;
+
+//           GNUNET_memcpy (out,
+//                          &denom_hs[i],
+//                          sizeof(struct TALER_DenominationHashP));
+//           break;
+//         }
+//       default:
+//         {
+//           GNUNET_assert (0);
+//           break;
+//         }
+//       }
+//       out += sz;
+//     }
+//   }
+//   param_values[0] = elements;
+//   param_lengths[0] = total_size;
+//   param_formats[0] = 1;
+//   scratch[0] = elements;
+
+// DONE:
+//   if (NULL != buffers)
+//   {
+//     for (size_t i = 0; i<num; i++)
+//       GNUNET_free (buffers[i]);
+//     GNUNET_free (buffers);
+//   }
+//   GNUNET_free (buffer_lengths);
+//   if (noerror)
+//     return 1;
+//   return -1;
+// }
+
+
+// /**
+//  * Function to generate a typ specific query parameter and corresponding 
closure
+//  *
+//  * @param num Number of elements in @a elements
+//  * @param continuous If true, @a elements is an continuous array of data
+//  * @param elements Array of @a num elements, either continuous or pointers
+//  * @param sizes Array of @a num sizes, one per element, may be NULL
+//  * @param same_size If not 0, all elements in @a elements have this size
+//  * @param typ Supported internal type of each element in @a elements
+//  * @param oid Oid of the type to be used in Postgres
+//  * @param[in,out] db our database handle for looking up OIDs
+//  * @return Query parameter
+//  */
+// static struct GNUNET_PQ_QueryParam
+// query_param_array_generic (
+//   unsigned int num,
+//   bool continuous,
+//   const void *elements,
+//   const size_t *sizes,
+//   size_t same_size,
+//   enum TALER_PQ_ArrayType typ,
+//   Oid oid,
+//   struct GNUNET_PQ_Context *db)
+// {
+//   struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls);
+//   meta->typ = typ;
+//   meta->oid = oid;
+//   meta->sizes = sizes;
+//   meta->same_size = same_size;
+//   meta->continuous = continuous;
+//   meta->db = db;
+
+//   struct GNUNET_PQ_QueryParam res = {
+//     .conv = qconv_array,
+//     .conv_cls = meta,
+//     .conv_cls_cleanup = qconv_array_cls_cleanup,
+//     .data = elements,
+//     .size = num,
+//     .num_params = 1,
+//   };
+
+//   return res;
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_array_blinded_denom_sig (
+//   size_t num,
+//   const struct TALER_BlindedDenominationSignature *denom_sigs,
+//   struct GNUNET_PQ_Context *db)
+// {
+//   Oid oid;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db, "bytea", &oid));
+//   return query_param_array_generic (num,
+//                                     true,
+//                                     denom_sigs,
+//                                     NULL,
+//                                     0,
+//                                     TALER_PQ_array_of_blinded_denom_sig,
+//                                     oid,
+//                                     NULL);
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_array_blinded_coin_hash (
+//   size_t num,
+//   const struct TALER_BlindedCoinHashP *coin_hs,
+//   struct GNUNET_PQ_Context *db)
+// {
+//   Oid oid;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db, "bytea", &oid));
+//   return query_param_array_generic (num,
+//                                     true,
+//                                     coin_hs,
+//                                     NULL,
+//                                     sizeof(struct TALER_BlindedCoinHashP),
+//                                     TALER_PQ_array_of_blinded_coin_hash,
+//                                     oid,
+//                                     NULL);
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_array_denom_hash (
+//   size_t num,
+//   const struct TALER_DenominationHashP *denom_hs,
+//   struct GNUNET_PQ_Context *db)
+// {
+//   Oid oid;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db, "bytea", &oid));
+//   return query_param_array_generic (num,
+//                                     true,
+//                                     denom_hs,
+//                                     NULL,
+//                                     sizeof(struct TALER_DenominationHashP),
+//                                     TALER_PQ_array_of_denom_hash,
+//                                     oid,
+//                                     NULL);
+// }
+
+
+// struct GNUNET_PQ_QueryParam
+// TALER_PQ_query_param_array_amount (
+//   size_t num,
+//   const struct TALER_Amount *amounts,
+//   struct GNUNET_PQ_Context *db)
+// {
+//   Oid oid;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db, "taler_amount", &oid));
+//   return query_param_array_generic (
+//     num,
+//     true,
+//     amounts,
+//     NULL,
+//     sizeof(struct TALER_PQ_AmountP),
+//     TALER_PQ_array_of_amount,
+//     oid,
+//     db);
+// }
+
+
+// /* end of pq/pq_query_helper.c */
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index 95850bc..c710247 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -18,1407 +18,1407 @@
  * @brief functions to initialize parameter arrays
  * @author Christian Grothoff
  */
-#include "platform.h"
+// #include "platform.h"
 #include <gnunet/gnunet_util_lib.h>
-#include "pq_common.h"
-#include "taler_pq_lib.h"
-
-
-/**
- * Extract an amount from a tuple including the currency from a Postgres
- * database @a result at row @a row.
- *
- * @param cls closure; not used
- * @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_currency_tuple (void *cls,
-                               PGresult *result,
-                               int row,
-                               const char *fname,
-                               size_t *dst_size,
-                               void *dst)
-{
-  struct TALER_Amount *r_amount = dst;
-  int col;
-
-  (void) cls;
-  if (sizeof (struct TALER_Amount) != *dst_size)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-
-  /* Set return value to invalid in case we don't finish */
-  memset (r_amount,
-          0,
-          sizeof (struct TALER_Amount));
-  col = PQfnumber (result,
-                   fname);
-  if (col < 0)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Field `%s' does not exist in result\n",
-                fname);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   col))
-  {
-    return GNUNET_NO;
-  }
-
-  /* Parse the tuple */
-  {
-    struct TALER_PQ_AmountCurrencyP ap;
-    const char *in;
-    size_t size;
-
-    size = PQgetlength (result,
-                        row,
-                        col);
-    if ( (size >= sizeof (ap)) ||
-         (size <= sizeof (ap) - TALER_CURRENCY_LEN) )
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Incorrect size of binary field `%s' (got %zu, expected 
(%zu-%zu))\n",
-                  fname,
-                  size,
-                  sizeof (ap) - TALER_CURRENCY_LEN,
-                  sizeof (ap));
-      return GNUNET_SYSERR;
-    }
-
-    in = PQgetvalue (result,
-                     row,
-                     col);
-    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;
-    }
-    /* TODO[oec]: OID-checks? */
-
-    r_amount->value = GNUNET_ntohll (ap.v);
-    r_amount->fraction = ntohl (ap.f);
-    memcpy (r_amount->currency,
-            ap.c,
-            TALER_CURRENCY_LEN);
-    if ('\0' != r_amount->currency[TALER_CURRENCY_LEN - 1])
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid currency (not 0-terminated) in tuple field `%s'\n",
-                  fname);
-      /* be sure nobody uses this by accident */
-      memset (r_amount,
-              0,
-              sizeof (struct TALER_Amount));
-      return GNUNET_SYSERR;
-    }
-  }
-
-  if (r_amount->value >= TALER_AMOUNT_MAX_VALUE)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Value in field `%s' exceeds legal range\n",
-                fname);
-    return GNUNET_SYSERR;
-  }
-  if (r_amount->fraction >= TALER_AMOUNT_FRAC_BASE)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Fraction in field `%s' exceeds legal range\n",
-                fname);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_amount_with_currency (const char *name,
-                                           struct TALER_Amount *amount)
-{
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = &extract_amount_currency_tuple,
-    .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
- * @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_tuple (void *cls,
-                      PGresult *result,
-                      int row,
-                      const char *fname,
-                      size_t *dst_size,
-                      void *dst)
-{
-  struct TALER_Amount *r_amount = dst;
-  const char *currency = cls;
-  int col;
-  size_t len;
-
-  if (sizeof (struct TALER_Amount) != *dst_size)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-
-  /* Set return value to invalid in case we don't finish */
-  memset (r_amount,
-          0,
-          sizeof (struct TALER_Amount));
-  col = PQfnumber (result,
-                   fname);
-  if (col < 0)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Field `%s' does not exist in result\n",
-                fname);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   col))
-  {
-    return GNUNET_NO;
-  }
-
-  /* Parse the tuple */
-  {
-    struct TALER_PQ_AmountP ap;
-    const char *in;
-    size_t size;
-
-    size = PQgetlength (result,
-                        row,
-                        col);
-    if (sizeof(ap) != size)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Incorrect size of binary field `%s' (got %zu, expected 
%zu)\n",
-                  fname,
-                  size,
-                  sizeof(ap));
-      return GNUNET_SYSERR;
-    }
-
-    in = PQgetvalue (result,
-                     row,
-                     col);
-    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;
-    }
-    /* TODO[oec]: OID-checks? */
-
-    r_amount->value = GNUNET_ntohll (ap.v);
-    r_amount->fraction = ntohl (ap.f);
-  }
-
-  if (r_amount->value >= TALER_AMOUNT_MAX_VALUE)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Value in field `%s' exceeds legal range\n",
-                fname);
-    return GNUNET_SYSERR;
-  }
-  if (r_amount->fraction >= TALER_AMOUNT_FRAC_BASE)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Fraction in field `%s' exceeds legal range\n",
-                fname);
-    return GNUNET_SYSERR;
-  }
-
-  len = GNUNET_MIN (TALER_CURRENCY_LEN - 1,
-                    strlen (currency));
-
-  GNUNET_memcpy (r_amount->currency,
-                 currency,
-                 len);
-  return GNUNET_OK;
-}
-
-
-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_tuple,
-    .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
- * @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_json (void *cls,
-              PGresult *result,
-              int row,
-              const char *fname,
-              size_t *dst_size,
-              void *dst)
-{
-  json_t **j_dst = dst;
-  const char *res;
-  int fnum;
-  json_error_t json_error;
-  size_t slen;
-
-  (void) cls;
-  (void) dst_size;
-  fnum = PQfnumber (result,
-                    fname);
-  if (fnum < 0)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Field `%s' does not exist in result\n",
-                fname);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   fnum))
-    return GNUNET_NO;
-  slen = PQgetlength (result,
-                      row,
-                      fnum);
-  res = (const char *) PQgetvalue (result,
-                                   row,
-                                   fnum);
-  *j_dst = json_loadb (res,
-                       slen,
-                       JSON_REJECT_DUPLICATES,
-                       &json_error);
-  if (NULL == *j_dst)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to parse JSON result for field `%s': %s (%s)\n",
-                fname,
-                json_error.text,
-                json_error.source);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Function called to clean up memory allocated
- * by a #GNUNET_PQ_ResultConverter.
- *
- * @param cls closure
- * @param rd result data to clean up
- */
-static void
-clean_json (void *cls,
-            void *rd)
-{
-  json_t **dst = rd;
-
-  (void) cls;
-  if (NULL != *dst)
-  {
-    json_decref (*dst);
-    *dst = NULL;
-  }
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_json (const char *name,
-                           json_t **jp)
-{
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = &extract_json,
-    .cleaner = &clean_json,
-    .dst = (void *) jp,
-    .fname  = name
-  };
-
-  return res;
-}
-
-
-/**
- * Extract data from a Postgres database @a result at row @a row.
- *
- * @param cls closure
- * @param result where to extract data from
- * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
- */
-static enum GNUNET_GenericReturnValue
-extract_denom_pub (void *cls,
-                   PGresult *result,
-                   int row,
-                   const char *fname,
-                   size_t *dst_size,
-                   void *dst)
-{
-  struct TALER_DenominationPublicKey *pk = dst;
-  size_t len;
-  const char *res;
-  int fnum;
-  uint32_t be[2];
-
-  (void) cls;
-  (void) dst_size;
-  fnum = PQfnumber (result,
-                    fname);
-  if (fnum < 0)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   fnum))
-    return GNUNET_NO;
-
-  /* if a field is null, continue but
-   * remember that we now return a different result */
-  len = PQgetlength (result,
-                     row,
-                     fnum);
-  res = PQgetvalue (result,
-                    row,
-                    fnum);
-  if (len < sizeof (be))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_memcpy (be,
-                 res,
-                 sizeof (be));
-  res += sizeof (be);
-  len -= sizeof (be);
-  pk->cipher = ntohl (be[0]);
-  pk->age_mask.bits = ntohl (be[1]);
-  switch (pk->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    pk->details.rsa_public_key
-      = GNUNET_CRYPTO_rsa_public_key_decode (res,
-                                             len);
-    if (NULL == pk->details.rsa_public_key)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    return GNUNET_OK;
-  case TALER_DENOMINATION_CS:
-    if (sizeof (pk->details.cs_public_key) != len)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    GNUNET_memcpy (&pk->details.cs_public_key,
-                   res,
-                   len);
-    return GNUNET_OK;
-  default:
-    GNUNET_break (0);
-  }
-  return GNUNET_SYSERR;
-}
-
-
-/**
- * Function called to clean up memory allocated
- * by a #GNUNET_PQ_ResultConverter.
- *
- * @param cls closure
- * @param rd result data to clean up
- */
-static void
-clean_denom_pub (void *cls,
-                 void *rd)
-{
-  struct TALER_DenominationPublicKey *denom_pub = rd;
-
-  (void) cls;
-  TALER_denom_pub_free (denom_pub);
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_denom_pub (const char *name,
-                                struct TALER_DenominationPublicKey *denom_pub)
-{
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = &extract_denom_pub,
-    .cleaner = &clean_denom_pub,
-    .dst = (void *) denom_pub,
-    .fname = name
-  };
-
-  return res;
-}
-
-
-/**
- * Extract data from a Postgres database @a result at row @a row.
- *
- * @param cls closure
- * @param result where to extract data from
- * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
- */
-static enum GNUNET_GenericReturnValue
-extract_denom_sig (void *cls,
-                   PGresult *result,
-                   int row,
-                   const char *fname,
-                   size_t *dst_size,
-                   void *dst)
-{
-  struct TALER_DenominationSignature *sig = dst;
-  size_t len;
-  const char *res;
-  int fnum;
-  uint32_t be[2];
-
-  (void) cls;
-  (void) dst_size;
-  fnum = PQfnumber (result,
-                    fname);
-  if (fnum < 0)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   fnum))
-    return GNUNET_NO;
-
-  /* if a field is null, continue but
-   * remember that we now return a different result */
-  len = PQgetlength (result,
-                     row,
-                     fnum);
-  res = PQgetvalue (result,
-                    row,
-                    fnum);
-  if (len < sizeof (be))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_memcpy (&be,
-                 res,
-                 sizeof (be));
-  if (0x00 != ntohl (be[1]))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  res += sizeof (be);
-  len -= sizeof (be);
-  sig->cipher = ntohl (be[0]);
-  switch (sig->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    sig->details.rsa_signature
-      = GNUNET_CRYPTO_rsa_signature_decode (res,
-                                            len);
-    if (NULL == sig->details.rsa_signature)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    return GNUNET_OK;
-  case TALER_DENOMINATION_CS:
-    if (sizeof (sig->details.cs_signature) != len)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    GNUNET_memcpy (&sig->details.cs_signature,
-                   res,
-                   len);
-    return GNUNET_OK;
-  default:
-    GNUNET_break (0);
-  }
-  return GNUNET_SYSERR;
-}
-
-
-/**
- * Function called to clean up memory allocated
- * by a #GNUNET_PQ_ResultConverter.
- *
- * @param cls closure
- * @param rd result data to clean up
- */
-static void
-clean_denom_sig (void *cls,
-                 void *rd)
-{
-  struct TALER_DenominationSignature *denom_sig = rd;
-
-  (void) cls;
-  TALER_denom_sig_free (denom_sig);
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_denom_sig (const char *name,
-                                struct TALER_DenominationSignature *denom_sig)
-{
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = &extract_denom_sig,
-    .cleaner = &clean_denom_sig,
-    .dst = (void *) denom_sig,
-    .fname = name
-  };
-
-  return res;
-}
-
-
-/**
- * Extract data from a Postgres database @a result at row @a row.
- *
- * @param cls closure
- * @param result where to extract data from
- * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
- */
-static enum GNUNET_GenericReturnValue
-extract_blinded_denom_sig (void *cls,
-                           PGresult *result,
-                           int row,
-                           const char *fname,
-                           size_t *dst_size,
-                           void *dst)
-{
-  struct TALER_BlindedDenominationSignature *sig = dst;
-  size_t len;
-  const char *res;
-  int fnum;
-  uint32_t be[2];
-
-  (void) cls;
-  (void) dst_size;
-  fnum = PQfnumber (result,
-                    fname);
-  if (fnum < 0)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   fnum))
-    return GNUNET_NO;
-
-  /* if a field is null, continue but
-   * remember that we now return a different result */
-  len = PQgetlength (result,
-                     row,
-                     fnum);
-  res = PQgetvalue (result,
-                    row,
-                    fnum);
-  if (len < sizeof (be))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_memcpy (&be,
-                 res,
-                 sizeof (be));
-  if (0x01 != ntohl (be[1])) /* magic marker: blinded */
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  res += sizeof (be);
-  len -= sizeof (be);
-  sig->cipher = ntohl (be[0]);
-  switch (sig->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    sig->details.blinded_rsa_signature
-      = GNUNET_CRYPTO_rsa_signature_decode (res,
-                                            len);
-    if (NULL == sig->details.blinded_rsa_signature)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    return GNUNET_OK;
-  case TALER_DENOMINATION_CS:
-    if (sizeof (sig->details.blinded_cs_answer) != len)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    GNUNET_memcpy (&sig->details.blinded_cs_answer,
-                   res,
-                   len);
-    return GNUNET_OK;
-  default:
-    GNUNET_break (0);
-  }
-  return GNUNET_SYSERR;
-}
-
-
-/**
- * Function called to clean up memory allocated
- * by a #GNUNET_PQ_ResultConverter.
- *
- * @param cls closure
- * @param rd result data to clean up
- */
-static void
-clean_blinded_denom_sig (void *cls,
-                         void *rd)
-{
-  struct TALER_BlindedDenominationSignature *denom_sig = rd;
-
-  (void) cls;
-  TALER_blinded_denom_sig_free (denom_sig);
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_blinded_denom_sig (
-  const char *name,
-  struct TALER_BlindedDenominationSignature *denom_sig)
-{
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = &extract_blinded_denom_sig,
-    .cleaner = &clean_blinded_denom_sig,
-    .dst = (void *) denom_sig,
-    .fname = name
-  };
-
-  return res;
-}
-
-
-/**
- * Extract data from a Postgres database @a result at row @a row.
- *
- * @param cls closure
- * @param result where to extract data from
- * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
- */
-static enum GNUNET_GenericReturnValue
-extract_blinded_planchet (void *cls,
-                          PGresult *result,
-                          int row,
-                          const char *fname,
-                          size_t *dst_size,
-                          void *dst)
-{
-  struct TALER_BlindedPlanchet *bp = dst;
-  size_t len;
-  const char *res;
-  int fnum;
-  uint32_t be[2];
-
-  (void) cls;
-  (void) dst_size;
-  fnum = PQfnumber (result,
-                    fname);
-  if (fnum < 0)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   fnum))
-    return GNUNET_NO;
-
-  /* if a field is null, continue but
-   * remember that we now return a different result */
-  len = PQgetlength (result,
-                     row,
-                     fnum);
-  res = PQgetvalue (result,
-                    row,
-                    fnum);
-  if (len < sizeof (be))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_memcpy (&be,
-                 res,
-                 sizeof (be));
-  if (0x0100 != ntohl (be[1])) /* magic marker: blinded */
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  res += sizeof (be);
-  len -= sizeof (be);
-  bp->cipher = ntohl (be[0]);
-  switch (bp->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    bp->details.rsa_blinded_planchet.blinded_msg_size
-      = len;
-    bp->details.rsa_blinded_planchet.blinded_msg
-      = GNUNET_memdup (res,
-                       len);
-    return GNUNET_OK;
-  case TALER_DENOMINATION_CS:
-    if (sizeof (bp->details.cs_blinded_planchet) != len)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    GNUNET_memcpy (&bp->details.cs_blinded_planchet,
-                   res,
-                   len);
-    return GNUNET_OK;
-  default:
-    GNUNET_break (0);
-  }
-  return GNUNET_SYSERR;
-}
-
-
-/**
- * Function called to clean up memory allocated
- * by a #GNUNET_PQ_ResultConverter.
- *
- * @param cls closure
- * @param rd result data to clean up
- */
-static void
-clean_blinded_planchet (void *cls,
-                        void *rd)
-{
-  struct TALER_BlindedPlanchet *bp = rd;
-
-  (void) cls;
-  TALER_blinded_planchet_free (bp);
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_blinded_planchet (
-  const char *name,
-  struct TALER_BlindedPlanchet *bp)
-{
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = &extract_blinded_planchet,
-    .cleaner = &clean_blinded_planchet,
-    .dst = (void *) bp,
-    .fname = name
-  };
-
-  return res;
-}
-
-
-/**
- * Extract data from a Postgres database @a result at row @a row.
- *
- * @param cls closure
- * @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_SYSERR if a result was invalid (non-existing field or NULL)
- */
-static enum GNUNET_GenericReturnValue
-extract_exchange_withdraw_values (void *cls,
-                                  PGresult *result,
-                                  int row,
-                                  const char *fname,
-                                  size_t *dst_size,
-                                  void *dst)
-{
-  struct TALER_ExchangeWithdrawValues *alg_values = dst;
-  size_t len;
-  const char *res;
-  int fnum;
-  uint32_t be[2];
-
-  (void) cls;
-  (void) dst_size;
-  fnum = PQfnumber (result,
-                    fname);
-  if (fnum < 0)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (PQgetisnull (result,
-                   row,
-                   fnum))
-    return GNUNET_NO;
-
-  /* if a field is null, continue but
-   * remember that we now return a different result */
-  len = PQgetlength (result,
-                     row,
-                     fnum);
-  res = PQgetvalue (result,
-                    row,
-                    fnum);
-  if (len < sizeof (be))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_memcpy (&be,
-                 res,
-                 sizeof (be));
-  if (0x010000 != ntohl (be[1])) /* magic marker: EWV */
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  res += sizeof (be);
-  len -= sizeof (be);
-  alg_values->cipher = ntohl (be[0]);
-  switch (alg_values->cipher)
-  {
-  case TALER_DENOMINATION_RSA:
-    if (0 != len)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    return GNUNET_OK;
-  case TALER_DENOMINATION_CS:
-    if (sizeof (struct TALER_DenominationCSPublicRPairP) != len)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    GNUNET_memcpy (&alg_values->details.cs_values,
-                   res,
-                   len);
-    return GNUNET_OK;
-  default:
-    GNUNET_break (0);
-  }
-  return GNUNET_SYSERR;
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_exchange_withdraw_values (
-  const char *name,
-  struct TALER_ExchangeWithdrawValues *ewv)
-{
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = &extract_exchange_withdraw_values,
-    .dst = (void *) ewv,
-    .fname = name
-  };
-
-  return res;
-}
-
-
-/**
- * Closure for the array result specifications.  Contains type information
- * for the generic parser extract_array_generic and out-pointers for the 
results.
- */
-struct ArrayResultCls
-{
-  /* Oid of the expected type, must match the oid in the header of the 
PQResult struct */
-  Oid oid;
-
-  /* Target type */
-  enum TALER_PQ_ArrayType typ;
-
-  /* If not 0, defines the expected size of each entry */
-  size_t same_size;
-
-  /* Out-pointer to write the number of elements in the array */
-  size_t *num;
-
-  /* Out-pointer. If @a typ is TALER_PQ_array_of_byte and @a same_size is 0,
-   * allocate and put the array of @a num sizes here. NULL otherwise */
-  size_t **sizes;
-
-  /* DB_connection, needed for OID-lookup for composite types */
-  const struct GNUNET_PQ_Context *db;
-
-  /* Currency information for amount composites */
-  char currency[TALER_CURRENCY_LEN];
-};
-
-/**
- * Extract data from a Postgres database @a result as array of a specific type
- * from row @a row.  The type information and optionally additional
- * out-parameters are given in @a cls which is of type array_result_cls.
- *
- * @param cls closure of type array_result_cls
- * @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_SYSERR if a result was invalid (non-existing field or NULL)
- */
-static enum GNUNET_GenericReturnValue
-extract_array_generic (
-  void *cls,
-  PGresult *result,
-  int row,
-  const char *fname,
-  size_t *dst_size,
-  void *dst)
-{
-  const struct ArrayResultCls *info = cls;
-  int data_sz;
-  char *data;
-  void *out = NULL;
-  struct GNUNET_PQ_ArrayHeader_P header;
-  int col_num;
-
-  GNUNET_assert (NULL != dst);
-  *((void **) dst) = NULL;
-
-  #define FAIL_IF(cond) \
-          do { \
-            if ((cond)) \
-            { \
-              GNUNET_break (! (cond)); \
-              goto FAIL; \
-            } \
-          } while (0)
-
-  col_num = PQfnumber (result, fname);
-  FAIL_IF (0 > col_num);
-
-  data_sz = PQgetlength (result, row, col_num);
-  FAIL_IF (0 > data_sz);
-  FAIL_IF (sizeof(header) > (size_t) data_sz);
-
-  data = PQgetvalue (result, row, col_num);
-  FAIL_IF (NULL == data);
-
-  {
-    struct GNUNET_PQ_ArrayHeader_P *h =
-      (struct GNUNET_PQ_ArrayHeader_P *) data;
-
-    header.ndim = ntohl (h->ndim);
-    header.has_null = ntohl (h->has_null);
-    header.oid = ntohl (h->oid);
-    header.dim = ntohl (h->dim);
-    header.lbound = ntohl (h->lbound);
-
-    FAIL_IF (1 != header.ndim);
-    FAIL_IF (INT_MAX <= header.dim);
-    FAIL_IF (0 != header.has_null);
-    FAIL_IF (1 != header.lbound);
-    FAIL_IF (info->oid != header.oid);
-  }
-
-  if (NULL != info->num)
-    *info->num = header.dim;
-
-  {
-    char *in = data + sizeof(header);
-
-    switch (info->typ)
-    {
-    case TALER_PQ_array_of_amount:
-      {
-        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_AmountP 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);
-
-          /* total size for this array-entry */
-          FAIL_IF (sizeof(ap) > sz);
-
-          GNUNET_memcpy (&ap,
-                         in,
-                         sz);
-          FAIL_IF (2 != ntohl (ap.cnt));
-
-          amount->value = GNUNET_ntohll (ap.v);
-          amount->fraction = ntohl (ap.f);
-          GNUNET_memcpy (amount->currency,
-                         info->currency,
-                         TALER_CURRENCY_LEN);
-
-          in += sizeof(struct TALER_PQ_AmountP);
-        }
-        return GNUNET_OK;
-      }
-    case TALER_PQ_array_of_denom_hash:
-      if (NULL != dst_size)
-        *dst_size = sizeof(struct TALER_DenominationHashP) * (header.dim);
-      out = GNUNET_new_array (header.dim, struct TALER_DenominationHashP);
-      *((void **) dst) = out;
-      for (uint32_t i = 0; i < header.dim; i++)
-      {
-        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 =
-          *(struct TALER_DenominationHashP *) in;
-        in += sz;
-        out += sz;
-      }
-      return GNUNET_OK;
-
-    case TALER_PQ_array_of_blinded_coin_hash:
-      if (NULL != dst_size)
-        *dst_size = sizeof(struct TALER_BlindedCoinHashP) * (header.dim);
-      out = GNUNET_new_array (header.dim, struct TALER_BlindedCoinHashP);
-      *((void **) dst) = out;
-      for (uint32_t i = 0; i < header.dim; i++)
-      {
-        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 =
-          *(struct TALER_BlindedCoinHashP *) in;
-        in += sz;
-        out += sz;
-      }
-      return GNUNET_OK;
-
-    case TALER_PQ_array_of_blinded_denom_sig:
-      {
-        struct TALER_BlindedDenominationSignature *denom_sigs;
-        if (0 == header.dim)
-        {
-          if (NULL != dst_size)
-            *dst_size = 0;
-          break;
-        }
-
-        denom_sigs = GNUNET_new_array (header.dim,
-                                       struct 
TALER_BlindedDenominationSignature);
-        *((void **) dst) = denom_sigs;
-
-        /* copy data */
-        for (uint32_t i = 0; i < header.dim; i++)
-        {
-          struct TALER_BlindedDenominationSignature *denom_sig = 
&denom_sigs[i];
-          uint32_t be[2];
-          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));
-          FAIL_IF (0x01 != ntohl (be[1]));  /* magic marker: blinded */
-
-          in += sizeof(be);
-          sz -= sizeof(be);
-
-          denom_sig->cipher = ntohl (be[0]);
-          switch (denom_sig->cipher)
-          {
-          case TALER_DENOMINATION_RSA:
-            denom_sig->details.blinded_rsa_signature =
-              GNUNET_CRYPTO_rsa_signature_decode (in,
-                                                  sz);
-            FAIL_IF (NULL == denom_sig->details.blinded_rsa_signature);
-            break;
-
-          case TALER_DENOMINATION_CS:
-            FAIL_IF (sizeof(denom_sig->details.blinded_cs_answer) != sz);
-            GNUNET_memcpy (&denom_sig->details.blinded_cs_answer,
-                           in,
-                           sz);
-            break;
-
-          default:
-            FAIL_IF (true);
-          }
-
-          in += sz;
-        }
-        return GNUNET_OK;
-      }
-    default:
-      FAIL_IF (true);
-    }
-  }
-
-FAIL:
-  GNUNET_free (*(void **) dst);
-  return GNUNET_SYSERR;
-  #undef FAIL_IF
-
-}
-
-
-/**
- * Cleanup of the data and closure of an array spec.
- */
-static void
-array_cleanup (void *cls,
-               void *rd)
-{
-
-  struct ArrayResultCls *info = cls;
-  void **dst = rd;
-
-  if ((0 == info->same_size) &&
-      (NULL != info->sizes))
-    GNUNET_free (*(info->sizes));
-
-  GNUNET_free (cls);
-  GNUNET_free (*dst);
-  *dst = NULL;
-}
-
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_array_blinded_denom_sig (
-  struct GNUNET_PQ_Context *db,
-  const char *name,
-  size_t *num,
-  struct TALER_BlindedDenominationSignature **denom_sigs)
-{
-  struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
-
-  info->num = num;
-  info->typ = TALER_PQ_array_of_blinded_denom_sig;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db,
-                                            "bytea",
-                                            &info->oid));
-
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = extract_array_generic,
-    .cleaner = array_cleanup,
-    .dst = (void *) denom_sigs,
-    .fname = name,
-    .cls = info
-  };
-  return res;
-
-};
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_array_blinded_coin_hash (
-  struct GNUNET_PQ_Context *db,
-  const char *name,
-  size_t *num,
-  struct TALER_BlindedCoinHashP **h_coin_evs)
-{
-  struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
-
-  info->num = num;
-  info->typ = TALER_PQ_array_of_blinded_coin_hash;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db,
-                                            "bytea",
-                                            &info->oid));
-
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = extract_array_generic,
-    .cleaner = array_cleanup,
-    .dst = (void *) h_coin_evs,
-    .fname = name,
-    .cls = info
-  };
-  return res;
-
-};
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_array_denom_hash (
-  struct GNUNET_PQ_Context *db,
-  const char *name,
-  size_t *num,
-  struct TALER_DenominationHashP **denom_hs)
-{
-  struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
-
-  info->num = num;
-  info->typ = TALER_PQ_array_of_denom_hash;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db,
-                                            "bytea",
-                                            &info->oid));
-
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = extract_array_generic,
-    .cleaner = array_cleanup,
-    .dst = (void *) denom_hs,
-    .fname = name,
-    .cls = info
-  };
-  return res;
-
-};
-
-struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_array_amount (
-  struct GNUNET_PQ_Context *db,
-  const char *name,
-  const char *currency,
-  size_t *num,
-  struct TALER_Amount **amounts)
-{
-  struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
-
-  info->num = num;
-  info->typ = TALER_PQ_array_of_amount;
-  info->db = db;
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PQ_get_oid_by_name (db,
-                                            "taler_amount",
-                                            &info->oid));
-
-  {
-    size_t clen = GNUNET_MIN (TALER_CURRENCY_LEN - 1,
-                              strlen (currency));
-    GNUNET_memcpy (&info->currency,
-                   currency,
-                   clen);
-  }
-
-  struct GNUNET_PQ_ResultSpec res = {
-    .conv = extract_array_generic,
-    .cleaner = array_cleanup,
-    .dst = (void *) amounts,
-    .fname = name,
-    .cls = info,
-  };
-  return res;
-
-
-}
+// #include "pq_common.h"
+// #include "taler_pq_lib.h"
+
+
+// /**
+//  * Extract an amount from a tuple including the currency from a Postgres
+//  * database @a result at row @a row.
+//  *
+//  * @param cls closure; not used
+//  * @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_currency_tuple (void *cls,
+//                                PGresult *result,
+//                                int row,
+//                                const char *fname,
+//                                size_t *dst_size,
+//                                void *dst)
+// {
+//   struct TALER_Amount *r_amount = dst;
+//   int col;
+
+//   (void) cls;
+//   if (sizeof (struct TALER_Amount) != *dst_size)
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+
+//   /* Set return value to invalid in case we don't finish */
+//   memset (r_amount,
+//           0,
+//           sizeof (struct TALER_Amount));
+//   col = PQfnumber (result,
+//                    fname);
+//   if (col < 0)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Field `%s' does not exist in result\n",
+//                 fname);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    col))
+//   {
+//     return GNUNET_NO;
+//   }
+
+//   /* Parse the tuple */
+//   {
+//     struct TALER_PQ_AmountCurrencyP ap;
+//     const char *in;
+//     size_t size;
+
+//     size = PQgetlength (result,
+//                         row,
+//                         col);
+//     if ( (size >= sizeof (ap)) ||
+//          (size <= sizeof (ap) - TALER_CURRENCY_LEN) )
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Incorrect size of binary field `%s' (got %zu, expected 
(%zu-%zu))\n",
+//                   fname,
+//                   size,
+//                   sizeof (ap) - TALER_CURRENCY_LEN,
+//                   sizeof (ap));
+//       return GNUNET_SYSERR;
+//     }
+
+//     in = PQgetvalue (result,
+//                      row,
+//                      col);
+//     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;
+//     }
+//     /* TODO[oec]: OID-checks? */
+
+//     r_amount->value = GNUNET_ntohll (ap.v);
+//     r_amount->fraction = ntohl (ap.f);
+//     memcpy (r_amount->currency,
+//             ap.c,
+//             TALER_CURRENCY_LEN);
+//     if ('\0' != r_amount->currency[TALER_CURRENCY_LEN - 1])
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Invalid currency (not 0-terminated) in tuple field 
`%s'\n",
+//                   fname);
+//       /* be sure nobody uses this by accident */
+//       memset (r_amount,
+//               0,
+//               sizeof (struct TALER_Amount));
+//       return GNUNET_SYSERR;
+//     }
+//   }
+
+//   if (r_amount->value >= TALER_AMOUNT_MAX_VALUE)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Value in field `%s' exceeds legal range\n",
+//                 fname);
+//     return GNUNET_SYSERR;
+//   }
+//   if (r_amount->fraction >= TALER_AMOUNT_FRAC_BASE)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Fraction in field `%s' exceeds legal range\n",
+//                 fname);
+//     return GNUNET_SYSERR;
+//   }
+//   return GNUNET_OK;
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_amount_with_currency (const char *name,
+//                                            struct TALER_Amount *amount)
+// {
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = &extract_amount_currency_tuple,
+//     .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
+//  * @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_tuple (void *cls,
+//                       PGresult *result,
+//                       int row,
+//                       const char *fname,
+//                       size_t *dst_size,
+//                       void *dst)
+// {
+//   struct TALER_Amount *r_amount = dst;
+//   const char *currency = cls;
+//   int col;
+//   size_t len;
+
+//   if (sizeof (struct TALER_Amount) != *dst_size)
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+
+//   /* Set return value to invalid in case we don't finish */
+//   memset (r_amount,
+//           0,
+//           sizeof (struct TALER_Amount));
+//   col = PQfnumber (result,
+//                    fname);
+//   if (col < 0)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Field `%s' does not exist in result\n",
+//                 fname);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    col))
+//   {
+//     return GNUNET_NO;
+//   }
+
+//   /* Parse the tuple */
+//   {
+//     struct TALER_PQ_AmountP ap;
+//     const char *in;
+//     size_t size;
+
+//     size = PQgetlength (result,
+//                         row,
+//                         col);
+//     if (sizeof(ap) != size)
+//     {
+//       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                   "Incorrect size of binary field `%s' (got %zu, expected 
%zu)\n",
+//                   fname,
+//                   size,
+//                   sizeof(ap));
+//       return GNUNET_SYSERR;
+//     }
+
+//     in = PQgetvalue (result,
+//                      row,
+//                      col);
+//     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;
+//     }
+//     /* TODO[oec]: OID-checks? */
+
+//     r_amount->value = GNUNET_ntohll (ap.v);
+//     r_amount->fraction = ntohl (ap.f);
+//   }
+
+//   if (r_amount->value >= TALER_AMOUNT_MAX_VALUE)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Value in field `%s' exceeds legal range\n",
+//                 fname);
+//     return GNUNET_SYSERR;
+//   }
+//   if (r_amount->fraction >= TALER_AMOUNT_FRAC_BASE)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Fraction in field `%s' exceeds legal range\n",
+//                 fname);
+//     return GNUNET_SYSERR;
+//   }
+
+//   len = GNUNET_MIN (TALER_CURRENCY_LEN - 1,
+//                     strlen (currency));
+
+//   GNUNET_memcpy (r_amount->currency,
+//                  currency,
+//                  len);
+//   return GNUNET_OK;
+// }
+
+
+// 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_tuple,
+//     .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
+//  * @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_json (void *cls,
+//               PGresult *result,
+//               int row,
+//               const char *fname,
+//               size_t *dst_size,
+//               void *dst)
+// {
+//   json_t **j_dst = dst;
+//   const char *res;
+//   int fnum;
+//   json_error_t json_error;
+//   size_t slen;
+
+//   (void) cls;
+//   (void) dst_size;
+//   fnum = PQfnumber (result,
+//                     fname);
+//   if (fnum < 0)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Field `%s' does not exist in result\n",
+//                 fname);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    fnum))
+//     return GNUNET_NO;
+//   slen = PQgetlength (result,
+//                       row,
+//                       fnum);
+//   res = (const char *) PQgetvalue (result,
+//                                    row,
+//                                    fnum);
+//   *j_dst = json_loadb (res,
+//                        slen,
+//                        JSON_REJECT_DUPLICATES,
+//                        &json_error);
+//   if (NULL == *j_dst)
+//   {
+//     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+//                 "Failed to parse JSON result for field `%s': %s (%s)\n",
+//                 fname,
+//                 json_error.text,
+//                 json_error.source);
+//     return GNUNET_SYSERR;
+//   }
+//   return GNUNET_OK;
+// }
+
+
+// /**
+//  * Function called to clean up memory allocated
+//  * by a #GNUNET_PQ_ResultConverter.
+//  *
+//  * @param cls closure
+//  * @param rd result data to clean up
+//  */
+// static void
+// clean_json (void *cls,
+//             void *rd)
+// {
+//   json_t **dst = rd;
+
+//   (void) cls;
+//   if (NULL != *dst)
+//   {
+//     json_decref (*dst);
+//     *dst = NULL;
+//   }
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_json (const char *name,
+//                            json_t **jp)
+// {
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = &extract_json,
+//     .cleaner = &clean_json,
+//     .dst = (void *) jp,
+//     .fname  = name
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Extract data from a Postgres database @a result at row @a row.
+//  *
+//  * @param cls closure
+//  * @param result where to extract data from
+//  * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
+//  */
+// static enum GNUNET_GenericReturnValue
+// extract_denom_pub (void *cls,
+//                    PGresult *result,
+//                    int row,
+//                    const char *fname,
+//                    size_t *dst_size,
+//                    void *dst)
+// {
+//   struct TALER_DenominationPublicKey *pk = dst;
+//   size_t len;
+//   const char *res;
+//   int fnum;
+//   uint32_t be[2];
+
+//   (void) cls;
+//   (void) dst_size;
+//   fnum = PQfnumber (result,
+//                     fname);
+//   if (fnum < 0)
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    fnum))
+//     return GNUNET_NO;
+
+//   /* if a field is null, continue but
+//    * remember that we now return a different result */
+//   len = PQgetlength (result,
+//                      row,
+//                      fnum);
+//   res = PQgetvalue (result,
+//                     row,
+//                     fnum);
+//   if (len < sizeof (be))
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   GNUNET_memcpy (be,
+//                  res,
+//                  sizeof (be));
+//   res += sizeof (be);
+//   len -= sizeof (be);
+//   pk->cipher = ntohl (be[0]);
+//   pk->age_mask.bits = ntohl (be[1]);
+//   switch (pk->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     pk->details.rsa_public_key
+//       = GNUNET_CRYPTO_rsa_public_key_decode (res,
+//                                              len);
+//     if (NULL == pk->details.rsa_public_key)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     return GNUNET_OK;
+//   case TALER_DENOMINATION_CS:
+//     if (sizeof (pk->details.cs_public_key) != len)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     GNUNET_memcpy (&pk->details.cs_public_key,
+//                    res,
+//                    len);
+//     return GNUNET_OK;
+//   default:
+//     GNUNET_break (0);
+//   }
+//   return GNUNET_SYSERR;
+// }
+
+
+// /**
+//  * Function called to clean up memory allocated
+//  * by a #GNUNET_PQ_ResultConverter.
+//  *
+//  * @param cls closure
+//  * @param rd result data to clean up
+//  */
+// static void
+// clean_denom_pub (void *cls,
+//                  void *rd)
+// {
+//   struct TALER_DenominationPublicKey *denom_pub = rd;
+
+//   (void) cls;
+//   TALER_denom_pub_free (denom_pub);
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_denom_pub (const char *name,
+//                                 struct TALER_DenominationPublicKey 
*denom_pub)
+// {
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = &extract_denom_pub,
+//     .cleaner = &clean_denom_pub,
+//     .dst = (void *) denom_pub,
+//     .fname = name
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Extract data from a Postgres database @a result at row @a row.
+//  *
+//  * @param cls closure
+//  * @param result where to extract data from
+//  * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
+//  */
+// static enum GNUNET_GenericReturnValue
+// extract_denom_sig (void *cls,
+//                    PGresult *result,
+//                    int row,
+//                    const char *fname,
+//                    size_t *dst_size,
+//                    void *dst)
+// {
+//   struct TALER_DenominationSignature *sig = dst;
+//   size_t len;
+//   const char *res;
+//   int fnum;
+//   uint32_t be[2];
+
+//   (void) cls;
+//   (void) dst_size;
+//   fnum = PQfnumber (result,
+//                     fname);
+//   if (fnum < 0)
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    fnum))
+//     return GNUNET_NO;
+
+//   /* if a field is null, continue but
+//    * remember that we now return a different result */
+//   len = PQgetlength (result,
+//                      row,
+//                      fnum);
+//   res = PQgetvalue (result,
+//                     row,
+//                     fnum);
+//   if (len < sizeof (be))
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   GNUNET_memcpy (&be,
+//                  res,
+//                  sizeof (be));
+//   if (0x00 != ntohl (be[1]))
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   res += sizeof (be);
+//   len -= sizeof (be);
+//   sig->cipher = ntohl (be[0]);
+//   switch (sig->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     sig->details.rsa_signature
+//       = GNUNET_CRYPTO_rsa_signature_decode (res,
+//                                             len);
+//     if (NULL == sig->details.rsa_signature)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     return GNUNET_OK;
+//   case TALER_DENOMINATION_CS:
+//     if (sizeof (sig->details.cs_signature) != len)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     GNUNET_memcpy (&sig->details.cs_signature,
+//                    res,
+//                    len);
+//     return GNUNET_OK;
+//   default:
+//     GNUNET_break (0);
+//   }
+//   return GNUNET_SYSERR;
+// }
+
+
+// /**
+//  * Function called to clean up memory allocated
+//  * by a #GNUNET_PQ_ResultConverter.
+//  *
+//  * @param cls closure
+//  * @param rd result data to clean up
+//  */
+// static void
+// clean_denom_sig (void *cls,
+//                  void *rd)
+// {
+//   struct TALER_DenominationSignature *denom_sig = rd;
+
+//   (void) cls;
+//   TALER_denom_sig_free (denom_sig);
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_denom_sig (const char *name,
+//                                 struct TALER_DenominationSignature 
*denom_sig)
+// {
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = &extract_denom_sig,
+//     .cleaner = &clean_denom_sig,
+//     .dst = (void *) denom_sig,
+//     .fname = name
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Extract data from a Postgres database @a result at row @a row.
+//  *
+//  * @param cls closure
+//  * @param result where to extract data from
+//  * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
+//  */
+// static enum GNUNET_GenericReturnValue
+// extract_blinded_denom_sig (void *cls,
+//                            PGresult *result,
+//                            int row,
+//                            const char *fname,
+//                            size_t *dst_size,
+//                            void *dst)
+// {
+//   struct TALER_BlindedDenominationSignature *sig = dst;
+//   size_t len;
+//   const char *res;
+//   int fnum;
+//   uint32_t be[2];
+
+//   (void) cls;
+//   (void) dst_size;
+//   fnum = PQfnumber (result,
+//                     fname);
+//   if (fnum < 0)
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    fnum))
+//     return GNUNET_NO;
+
+//   /* if a field is null, continue but
+//    * remember that we now return a different result */
+//   len = PQgetlength (result,
+//                      row,
+//                      fnum);
+//   res = PQgetvalue (result,
+//                     row,
+//                     fnum);
+//   if (len < sizeof (be))
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   GNUNET_memcpy (&be,
+//                  res,
+//                  sizeof (be));
+//   if (0x01 != ntohl (be[1])) /* magic marker: blinded */
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   res += sizeof (be);
+//   len -= sizeof (be);
+//   sig->cipher = ntohl (be[0]);
+//   switch (sig->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     sig->details.blinded_rsa_signature
+//       = GNUNET_CRYPTO_rsa_signature_decode (res,
+//                                             len);
+//     if (NULL == sig->details.blinded_rsa_signature)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     return GNUNET_OK;
+//   case TALER_DENOMINATION_CS:
+//     if (sizeof (sig->details.blinded_cs_answer) != len)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     GNUNET_memcpy (&sig->details.blinded_cs_answer,
+//                    res,
+//                    len);
+//     return GNUNET_OK;
+//   default:
+//     GNUNET_break (0);
+//   }
+//   return GNUNET_SYSERR;
+// }
+
+
+// /**
+//  * Function called to clean up memory allocated
+//  * by a #GNUNET_PQ_ResultConverter.
+//  *
+//  * @param cls closure
+//  * @param rd result data to clean up
+//  */
+// static void
+// clean_blinded_denom_sig (void *cls,
+//                          void *rd)
+// {
+//   struct TALER_BlindedDenominationSignature *denom_sig = rd;
+
+//   (void) cls;
+//   TALER_blinded_denom_sig_free (denom_sig);
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_blinded_denom_sig (
+//   const char *name,
+//   struct TALER_BlindedDenominationSignature *denom_sig)
+// {
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = &extract_blinded_denom_sig,
+//     .cleaner = &clean_blinded_denom_sig,
+//     .dst = (void *) denom_sig,
+//     .fname = name
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Extract data from a Postgres database @a result at row @a row.
+//  *
+//  * @param cls closure
+//  * @param result where to extract data from
+//  * @param row the 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_SYSERR if a result was invalid (non-existing field or NULL)
+//  */
+// static enum GNUNET_GenericReturnValue
+// extract_blinded_planchet (void *cls,
+//                           PGresult *result,
+//                           int row,
+//                           const char *fname,
+//                           size_t *dst_size,
+//                           void *dst)
+// {
+//   struct TALER_BlindedPlanchet *bp = dst;
+//   size_t len;
+//   const char *res;
+//   int fnum;
+//   uint32_t be[2];
+
+//   (void) cls;
+//   (void) dst_size;
+//   fnum = PQfnumber (result,
+//                     fname);
+//   if (fnum < 0)
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    fnum))
+//     return GNUNET_NO;
+
+//   /* if a field is null, continue but
+//    * remember that we now return a different result */
+//   len = PQgetlength (result,
+//                      row,
+//                      fnum);
+//   res = PQgetvalue (result,
+//                     row,
+//                     fnum);
+//   if (len < sizeof (be))
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   GNUNET_memcpy (&be,
+//                  res,
+//                  sizeof (be));
+//   if (0x0100 != ntohl (be[1])) /* magic marker: blinded */
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   res += sizeof (be);
+//   len -= sizeof (be);
+//   bp->cipher = ntohl (be[0]);
+//   switch (bp->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     bp->details.rsa_blinded_planchet.blinded_msg_size
+//       = len;
+//     bp->details.rsa_blinded_planchet.blinded_msg
+//       = GNUNET_memdup (res,
+//                        len);
+//     return GNUNET_OK;
+//   case TALER_DENOMINATION_CS:
+//     if (sizeof (bp->details.cs_blinded_planchet) != len)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     GNUNET_memcpy (&bp->details.cs_blinded_planchet,
+//                    res,
+//                    len);
+//     return GNUNET_OK;
+//   default:
+//     GNUNET_break (0);
+//   }
+//   return GNUNET_SYSERR;
+// }
+
+
+// /**
+//  * Function called to clean up memory allocated
+//  * by a #GNUNET_PQ_ResultConverter.
+//  *
+//  * @param cls closure
+//  * @param rd result data to clean up
+//  */
+// static void
+// clean_blinded_planchet (void *cls,
+//                         void *rd)
+// {
+//   struct TALER_BlindedPlanchet *bp = rd;
+
+//   (void) cls;
+//   TALER_blinded_planchet_free (bp);
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_blinded_planchet (
+//   const char *name,
+//   struct TALER_BlindedPlanchet *bp)
+// {
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = &extract_blinded_planchet,
+//     .cleaner = &clean_blinded_planchet,
+//     .dst = (void *) bp,
+//     .fname = name
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Extract data from a Postgres database @a result at row @a row.
+//  *
+//  * @param cls closure
+//  * @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_SYSERR if a result was invalid (non-existing field or NULL)
+//  */
+// static enum GNUNET_GenericReturnValue
+// extract_exchange_withdraw_values (void *cls,
+//                                   PGresult *result,
+//                                   int row,
+//                                   const char *fname,
+//                                   size_t *dst_size,
+//                                   void *dst)
+// {
+//   struct TALER_ExchangeWithdrawValues *alg_values = dst;
+//   size_t len;
+//   const char *res;
+//   int fnum;
+//   uint32_t be[2];
+
+//   (void) cls;
+//   (void) dst_size;
+//   fnum = PQfnumber (result,
+//                     fname);
+//   if (fnum < 0)
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   if (PQgetisnull (result,
+//                    row,
+//                    fnum))
+//     return GNUNET_NO;
+
+//   /* if a field is null, continue but
+//    * remember that we now return a different result */
+//   len = PQgetlength (result,
+//                      row,
+//                      fnum);
+//   res = PQgetvalue (result,
+//                     row,
+//                     fnum);
+//   if (len < sizeof (be))
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   GNUNET_memcpy (&be,
+//                  res,
+//                  sizeof (be));
+//   if (0x010000 != ntohl (be[1])) /* magic marker: EWV */
+//   {
+//     GNUNET_break (0);
+//     return GNUNET_SYSERR;
+//   }
+//   res += sizeof (be);
+//   len -= sizeof (be);
+//   alg_values->cipher = ntohl (be[0]);
+//   switch (alg_values->cipher)
+//   {
+//   case TALER_DENOMINATION_RSA:
+//     if (0 != len)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     return GNUNET_OK;
+//   case TALER_DENOMINATION_CS:
+//     if (sizeof (struct TALER_DenominationCSPublicRPairP) != len)
+//     {
+//       GNUNET_break (0);
+//       return GNUNET_SYSERR;
+//     }
+//     GNUNET_memcpy (&alg_values->details.cs_values,
+//                    res,
+//                    len);
+//     return GNUNET_OK;
+//   default:
+//     GNUNET_break (0);
+//   }
+//   return GNUNET_SYSERR;
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_exchange_withdraw_values (
+//   const char *name,
+//   struct TALER_ExchangeWithdrawValues *ewv)
+// {
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = &extract_exchange_withdraw_values,
+//     .dst = (void *) ewv,
+//     .fname = name
+//   };
+
+//   return res;
+// }
+
+
+// /**
+//  * Closure for the array result specifications.  Contains type information
+//  * for the generic parser extract_array_generic and out-pointers for the 
results.
+//  */
+// struct ArrayResultCls
+// {
+//   /* Oid of the expected type, must match the oid in the header of the 
PQResult struct */
+//   Oid oid;
+
+//   /* Target type */
+//   enum TALER_PQ_ArrayType typ;
+
+//   /* If not 0, defines the expected size of each entry */
+//   size_t same_size;
+
+//   /* Out-pointer to write the number of elements in the array */
+//   size_t *num;
+
+//   /* Out-pointer. If @a typ is TALER_PQ_array_of_byte and @a same_size is 0,
+//    * allocate and put the array of @a num sizes here. NULL otherwise */
+//   size_t **sizes;
+
+//   /* DB_connection, needed for OID-lookup for composite types */
+//   const struct GNUNET_PQ_Context *db;
+
+//   /* Currency information for amount composites */
+//   char currency[TALER_CURRENCY_LEN];
+// };
+
+// /**
+//  * Extract data from a Postgres database @a result as array of a specific 
type
+//  * from row @a row.  The type information and optionally additional
+//  * out-parameters are given in @a cls which is of type array_result_cls.
+//  *
+//  * @param cls closure of type array_result_cls
+//  * @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_SYSERR if a result was invalid (non-existing field or NULL)
+//  */
+// static enum GNUNET_GenericReturnValue
+// extract_array_generic (
+//   void *cls,
+//   PGresult *result,
+//   int row,
+//   const char *fname,
+//   size_t *dst_size,
+//   void *dst)
+// {
+//   const struct ArrayResultCls *info = cls;
+//   int data_sz;
+//   char *data;
+//   void *out = NULL;
+//   struct GNUNET_PQ_ArrayHeader_P header;
+//   int col_num;
+
+//   GNUNET_assert (NULL != dst);
+//   *((void **) dst) = NULL;
+
+//   #define FAIL_IF(cond) \
+//           do { \
+//             if ((cond)) \
+//             { \
+//               GNUNET_break (! (cond)); \
+//               goto FAIL; \
+//             } \
+//           } while (0)
+
+//   col_num = PQfnumber (result, fname);
+//   FAIL_IF (0 > col_num);
+
+//   data_sz = PQgetlength (result, row, col_num);
+//   FAIL_IF (0 > data_sz);
+//   FAIL_IF (sizeof(header) > (size_t) data_sz);
+
+//   data = PQgetvalue (result, row, col_num);
+//   FAIL_IF (NULL == data);
+
+//   {
+//     struct GNUNET_PQ_ArrayHeader_P *h =
+//       (struct GNUNET_PQ_ArrayHeader_P *) data;
+
+//     header.ndim = ntohl (h->ndim);
+//     header.has_null = ntohl (h->has_null);
+//     header.oid = ntohl (h->oid);
+//     header.dim = ntohl (h->dim);
+//     header.lbound = ntohl (h->lbound);
+
+//     FAIL_IF (1 != header.ndim);
+//     FAIL_IF (INT_MAX <= header.dim);
+//     FAIL_IF (0 != header.has_null);
+//     FAIL_IF (1 != header.lbound);
+//     FAIL_IF (info->oid != header.oid);
+//   }
+
+//   if (NULL != info->num)
+//     *info->num = header.dim;
+
+//   {
+//     char *in = data + sizeof(header);
+
+//     switch (info->typ)
+//     {
+//     case TALER_PQ_array_of_amount:
+//       {
+//         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_AmountP 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);
+
+//           /* total size for this array-entry */
+//           FAIL_IF (sizeof(ap) > sz);
+
+//           GNUNET_memcpy (&ap,
+//                          in,
+//                          sz);
+//           FAIL_IF (2 != ntohl (ap.cnt));
+
+//           amount->value = GNUNET_ntohll (ap.v);
+//           amount->fraction = ntohl (ap.f);
+//           GNUNET_memcpy (amount->currency,
+//                          info->currency,
+//                          TALER_CURRENCY_LEN);
+
+//           in += sizeof(struct TALER_PQ_AmountP);
+//         }
+//         return GNUNET_OK;
+//       }
+//     case TALER_PQ_array_of_denom_hash:
+//       if (NULL != dst_size)
+//         *dst_size = sizeof(struct TALER_DenominationHashP) * (header.dim);
+//       out = GNUNET_new_array (header.dim, struct TALER_DenominationHashP);
+//       *((void **) dst) = out;
+//       for (uint32_t i = 0; i < header.dim; i++)
+//       {
+//         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 =
+//           *(struct TALER_DenominationHashP *) in;
+//         in += sz;
+//         out += sz;
+//       }
+//       return GNUNET_OK;
+
+//     case TALER_PQ_array_of_blinded_coin_hash:
+//       if (NULL != dst_size)
+//         *dst_size = sizeof(struct TALER_BlindedCoinHashP) * (header.dim);
+//       out = GNUNET_new_array (header.dim, struct TALER_BlindedCoinHashP);
+//       *((void **) dst) = out;
+//       for (uint32_t i = 0; i < header.dim; i++)
+//       {
+//         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 =
+//           *(struct TALER_BlindedCoinHashP *) in;
+//         in += sz;
+//         out += sz;
+//       }
+//       return GNUNET_OK;
+
+//     case TALER_PQ_array_of_blinded_denom_sig:
+//       {
+//         struct TALER_BlindedDenominationSignature *denom_sigs;
+//         if (0 == header.dim)
+//         {
+//           if (NULL != dst_size)
+//             *dst_size = 0;
+//           break;
+//         }
+
+//         denom_sigs = GNUNET_new_array (header.dim,
+//                                        struct 
TALER_BlindedDenominationSignature);
+//         *((void **) dst) = denom_sigs;
+
+//         /* copy data */
+//         for (uint32_t i = 0; i < header.dim; i++)
+//         {
+//           struct TALER_BlindedDenominationSignature *denom_sig = 
&denom_sigs[i];
+//           uint32_t be[2];
+//           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));
+//           FAIL_IF (0x01 != ntohl (be[1]));  /* magic marker: blinded */
+
+//           in += sizeof(be);
+//           sz -= sizeof(be);
+
+//           denom_sig->cipher = ntohl (be[0]);
+//           switch (denom_sig->cipher)
+//           {
+//           case TALER_DENOMINATION_RSA:
+//             denom_sig->details.blinded_rsa_signature =
+//               GNUNET_CRYPTO_rsa_signature_decode (in,
+//                                                   sz);
+//             FAIL_IF (NULL == denom_sig->details.blinded_rsa_signature);
+//             break;
+
+//           case TALER_DENOMINATION_CS:
+//             FAIL_IF (sizeof(denom_sig->details.blinded_cs_answer) != sz);
+//             GNUNET_memcpy (&denom_sig->details.blinded_cs_answer,
+//                            in,
+//                            sz);
+//             break;
+
+//           default:
+//             FAIL_IF (true);
+//           }
+
+//           in += sz;
+//         }
+//         return GNUNET_OK;
+//       }
+//     default:
+//       FAIL_IF (true);
+//     }
+//   }
+
+// FAIL:
+//   GNUNET_free (*(void **) dst);
+//   return GNUNET_SYSERR;
+//   #undef FAIL_IF
+
+// }
+
+
+// /**
+//  * Cleanup of the data and closure of an array spec.
+//  */
+// static void
+// array_cleanup (void *cls,
+//                void *rd)
+// {
+
+//   struct ArrayResultCls *info = cls;
+//   void **dst = rd;
+
+//   if ((0 == info->same_size) &&
+//       (NULL != info->sizes))
+//     GNUNET_free (*(info->sizes));
+
+//   GNUNET_free (cls);
+//   GNUNET_free (*dst);
+//   *dst = NULL;
+// }
+
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_array_blinded_denom_sig (
+//   struct GNUNET_PQ_Context *db,
+//   const char *name,
+//   size_t *num,
+//   struct TALER_BlindedDenominationSignature **denom_sigs)
+// {
+//   struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
+
+//   info->num = num;
+//   info->typ = TALER_PQ_array_of_blinded_denom_sig;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db,
+//                                             "bytea",
+//                                             &info->oid));
+
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = extract_array_generic,
+//     .cleaner = array_cleanup,
+//     .dst = (void *) denom_sigs,
+//     .fname = name,
+//     .cls = info
+//   };
+//   return res;
+
+// };
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_array_blinded_coin_hash (
+//   struct GNUNET_PQ_Context *db,
+//   const char *name,
+//   size_t *num,
+//   struct TALER_BlindedCoinHashP **h_coin_evs)
+// {
+//   struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
+
+//   info->num = num;
+//   info->typ = TALER_PQ_array_of_blinded_coin_hash;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db,
+//                                             "bytea",
+//                                             &info->oid));
+
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = extract_array_generic,
+//     .cleaner = array_cleanup,
+//     .dst = (void *) h_coin_evs,
+//     .fname = name,
+//     .cls = info
+//   };
+//   return res;
+
+// };
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_array_denom_hash (
+//   struct GNUNET_PQ_Context *db,
+//   const char *name,
+//   size_t *num,
+//   struct TALER_DenominationHashP **denom_hs)
+// {
+//   struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
+
+//   info->num = num;
+//   info->typ = TALER_PQ_array_of_denom_hash;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db,
+//                                             "bytea",
+//                                             &info->oid));
+
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = extract_array_generic,
+//     .cleaner = array_cleanup,
+//     .dst = (void *) denom_hs,
+//     .fname = name,
+//     .cls = info
+//   };
+//   return res;
+
+// };
+
+// struct GNUNET_PQ_ResultSpec
+// TALER_PQ_result_spec_array_amount (
+//   struct GNUNET_PQ_Context *db,
+//   const char *name,
+//   const char *currency,
+//   size_t *num,
+//   struct TALER_Amount **amounts)
+// {
+//   struct ArrayResultCls *info = GNUNET_new (struct ArrayResultCls);
+
+//   info->num = num;
+//   info->typ = TALER_PQ_array_of_amount;
+//   info->db = db;
+//   GNUNET_assert (GNUNET_OK ==
+//                  GNUNET_PQ_get_oid_by_name (db,
+//                                             "taler_amount",
+//                                             &info->oid));
+
+//   {
+//     size_t clen = GNUNET_MIN (TALER_CURRENCY_LEN - 1,
+//                               strlen (currency));
+//     GNUNET_memcpy (&info->currency,
+//                    currency,
+//                    clen);
+//   }
+
+//   struct GNUNET_PQ_ResultSpec res = {
+//     .conv = extract_array_generic,
+//     .cleaner = array_cleanup,
+//     .dst = (void *) amounts,
+//     .fname = name,
+//     .cls = info,
+//   };
+//   return res;
+
+
+// }
 
 
 /* end of pq_result_helper.c */

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]