gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-exchange] branch master updated: match GNUnet API re


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: match GNUnet API rename, work on #5010
Date: Sun, 11 Jun 2017 01:59:19 +0200

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

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new cad6476  match GNUnet API rename, work on #5010
cad6476 is described below

commit cad64767d9fda2c18106f25ef101c2eb5fce15a1
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun Jun 11 01:59:09 2017 +0200

    match GNUnet API rename, work on #5010
---
 src/exchange/taler-exchange-aggregator.c           |  110 +-
 src/exchange/taler-exchange-httpd_db.c             |    6 +-
 src/exchange/taler-exchange-httpd_keystate.c       |   40 +-
 src/exchange/test_taler_exchange_aggregator.c      |    4 +-
 src/exchangedb/perf_taler_exchangedb_interpreter.c |    9 +-
 src/exchangedb/plugin_exchangedb_postgres.c        | 2670 ++++++++++----------
 src/exchangedb/test_exchangedb.c                   |    6 +-
 src/include/taler_exchangedb_plugin.h              |    3 +-
 8 files changed, 1409 insertions(+), 1439 deletions(-)

diff --git a/src/exchange/taler-exchange-aggregator.c 
b/src/exchange/taler-exchange-aggregator.c
index f4573aa..d658398 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -733,6 +733,29 @@ run_aggregation (void *cls);
 
 
 /**
+ * Perform a database commit. If it fails, print a warning.
+ *
+ * @param session session to perform the commit for.
+ * @return status of commit
+ */
+static enum GNUNET_DB_QueryStatus
+commit_or_warn (struct TALER_EXCHANGEDB_Session *session)
+{
+  enum GNUNET_DB_QueryStatus qs;
+
+  qs = db_plugin->commit (db_plugin->cls,
+                          session);
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+    return qs;
+  GNUNET_log ((GNUNET_DB_STATUS_SOFT_ERROR == qs)
+              ? GNUNET_ERROR_TYPE_INFO
+              : GNUNET_ERROR_TYPE_ERROR,
+              "Failed to commit database transaction!\n");
+  return qs;
+}
+
+
+/**
  * Function to be called with the prepared transfer data
  * when closing a reserve.
  *
@@ -782,13 +805,7 @@ prepare_close_cb (void *cls,
   }
 
   /* finally commit */
-  if (GNUNET_OK !=
-      db_plugin->commit (db_plugin->cls,
-                        ctc->session))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               "Failed to commit database transaction!\n");
-  }
+  (void) commit_or_warn (ctc->session);
   GNUNET_free (ctc->type);
   GNUNET_free (ctc);
   ctc = NULL;
@@ -948,13 +965,7 @@ expired_reserve_cb (void *cls,
     return GNUNET_SYSERR;
   }
   /* Reserve balance was almost zero; just commit */
-  if (GNUNET_OK !=
-      db_plugin->commit (db_plugin->cls,
-                        session))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               "Failed to commit database transaction!\n");
-  }
+  (void) commit_or_warn (session);
   task = GNUNET_SCHEDULER_add_now (&run_reserve_closures,
                                   NULL);
   return GNUNET_SYSERR;
@@ -1191,13 +1202,7 @@ run_aggregation (void *cls)
                                           au->additional_rows[i]))
           ret = GNUNET_SYSERR;
     /* commit */
-    if (GNUNET_OK !=
-        db_plugin->commit (db_plugin->cls,
-                           session))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "Failed to commit database transaction!\n");
-    }
+    (void) commit_or_warn (session);
     GNUNET_free_non_null (au->additional_rows);
     if (NULL != au->wire)
       json_decref (au->wire);
@@ -1336,6 +1341,8 @@ prepare_cb (void *cls,
     au = NULL;
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Stored wire transfer out instructions\n");
   if (NULL != au->wire)
   {
     json_decref (au->wire);
@@ -1346,22 +1353,31 @@ prepare_cb (void *cls,
 
   /* Now we can finally commit the overall transaction, as we are
      again consistent if all of this passes. */
-  if (GNUNET_OK !=
-      db_plugin->commit (db_plugin->cls,
-                         session))
+  switch (commit_or_warn (session))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Failed to commit database transaction!\n");
+  case GNUNET_DB_STATUS_SOFT_ERROR:
     /* try again */
     task = GNUNET_SCHEDULER_add_now (&run_aggregation,
                                      NULL);
     return;
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    GNUNET_break (0);
+    global_ret = GNUNET_SYSERR;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Preparation complete, switching to transfer mode\n");
+    /* run alternative task: actually do wire transfer! */
+    task = GNUNET_SCHEDULER_add_now (&run_transfers,
+                                     NULL);
+    return;
+  default:
+    GNUNET_break (0);
+    global_ret = GNUNET_SYSERR;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Preparation complete, switching to transfer mode\n");
-  /* run alternative task: actually do wire transfer! */
-  task = GNUNET_SCHEDULER_add_now (&run_transfers,
-                                   NULL);
 }
 
 
@@ -1411,24 +1427,32 @@ wire_confirm_cb (void *cls,
   }
   GNUNET_free (wpd);
   wpd = NULL;
-  if (GNUNET_OK !=
-      db_plugin->commit (db_plugin->cls,
-                         session))
+  switch (commit_or_warn (session))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Failed to commit database transaction!\n");
+  case GNUNET_DB_STATUS_SOFT_ERROR:
     /* try again */
     task = GNUNET_SCHEDULER_add_now (&run_aggregation,
                                      NULL);
     return;
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    GNUNET_break (0);
+    global_ret = GNUNET_SYSERR;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Wire transfer complete\n");
+    /* continue with #run_transfers(), just to guard
+       against the unlikely case that there are more. */
+    task = GNUNET_SCHEDULER_add_now (&run_transfers,
+                                     NULL);
+    return;
+  default:
+    GNUNET_break (0);
+    global_ret = GNUNET_SYSERR;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Wire transfer complete\n");
-  /* continue with #run_transfers(), just to guard
-     against the unlikely case that there are more. */
-  task = GNUNET_SCHEDULER_add_now (&run_transfers,
-                                   NULL);
-
 }
 
 
diff --git a/src/exchange/taler-exchange-httpd_db.c 
b/src/exchange/taler-exchange-httpd_db.c
index 51e1ef5..71f82e9 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -46,7 +46,7 @@
 #define START_TRANSACTION(session,connection)                 \
 { /* start new scope, will be ended by COMMIT_TRANSACTION() */\
   unsigned int transaction_retries = 0;                       \
-  int transaction_commit_result;                              \
+  enum GNUNET_DB_QueryStatus transaction_commit_result;       \
 transaction_start_label: /* we will use goto for retries */   \
   if (GNUNET_OK !=                                            \
       TEH_plugin->start (TEH_plugin->cls,                     \
@@ -71,13 +71,13 @@ transaction_start_label: /* we will use goto for retries */ 
  \
   transaction_commit_result =                                              \
     TEH_plugin->commit (TEH_plugin->cls,                                   \
                         session);                                          \
-  if (GNUNET_SYSERR == transaction_commit_result)                          \
+  if (GNUNET_DB_STATUS_HARD_ERROR == transaction_commit_result)            \
   {                                                                        \
     TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
     return TEH_RESPONSE_reply_commit_error (connection, \
                                            TALER_EC_DB_COMMIT_FAILED_HARD); \
   }                                                       \
-  if (GNUNET_NO == transaction_commit_result)                              \
+  if (GNUNET_DB_STATUS_SOFT_ERROR == transaction_commit_result)            \
   {                                                                        \
     TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
     if (transaction_retries++ <= MAX_TRANSACTION_COMMIT_RETRIES)           \
diff --git a/src/exchange/taler-exchange-httpd_keystate.c 
b/src/exchange/taler-exchange-httpd_keystate.c
index 3f81b2e..6fc55a0 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -331,7 +331,9 @@ reload_keys_denom_iter (void *cls,
   struct GNUNET_TIME_Absolute expire_deposit;
   struct GNUNET_HashCode denom_key_hash;
   struct TALER_EXCHANGEDB_Session *session;
+  unsigned int thresh;
   int res;
+  enum GNUNET_DB_QueryStatus qs;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Loading denomination key `%s'\n",
@@ -361,8 +363,6 @@ reload_keys_denom_iter (void *cls,
 
   if (NULL != revocation_master_sig)
   {
-    unsigned int thresh = 0;
-
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Adding denomination key `%s' to revokation set\n",
                 alias);
@@ -373,11 +373,13 @@ reload_keys_denom_iter (void *cls,
     /* Try to insert DKI into DB until we succeed; note that if the DB
        failure is persistent, we need to die, as we cannot continue
        without the DKI being in the DB). */
-    res = GNUNET_SYSERR;
-    while (GNUNET_OK != res)
+    thresh = 0;
+    qs = GNUNET_DB_STATUS_SOFT_ERROR;
+    while (0 > qs)
     {
       thresh++;
-      if (thresh > 16)
+      if ( (thresh > 16) ||
+           (GNUNET_DB_STATUS_HARD_ERROR == qs) )
       {
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                     "Giving up, this is fatal. Committing suicide via 
SIGTERM.\n");
@@ -409,8 +411,8 @@ reload_keys_denom_iter (void *cls,
                               session);
         break; /* already in is also OK! */
       }
-      res = TEH_plugin->commit (TEH_plugin->cls,
-                                session);
+      qs = TEH_plugin->commit (TEH_plugin->cls,
+                               session);
     }
     GNUNET_assert (0 ==
                    json_array_append_new (ctx->payback_array,
@@ -440,12 +442,22 @@ reload_keys_denom_iter (void *cls,
   if (NULL == session)
     return GNUNET_SYSERR;
   /* Try to insert DKI into DB until we succeed; note that if the DB
-     failure is persistent, this code may loop forever (as there is no
-     sane alternative, we cannot continue without the DKI being in the
-     DB). */
-  res = GNUNET_SYSERR;
-  while (GNUNET_OK != res)
+     failure is persistent, we die, as we cannot continue without the
+     DKI being in the DB). */
+  qs = GNUNET_DB_STATUS_SOFT_ERROR;
+  thresh = 0;
+  while (0 > qs)
   {
+    thresh++;
+    if ( (thresh > 16) ||
+         (GNUNET_DB_STATUS_HARD_ERROR == qs) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Giving up, this is fatal. Committing suicide via 
SIGTERM.\n");
+      handle_signal (SIGTERM);
+      return GNUNET_SYSERR;
+    }
+
     res = TEH_plugin->start (TEH_plugin->cls,
                              session);
     if (GNUNET_OK != res)
@@ -485,8 +497,8 @@ reload_keys_denom_iter (void *cls,
                             session);
       continue;
     }
-    res = TEH_plugin->commit (TEH_plugin->cls,
-                              session);
+    qs = TEH_plugin->commit (TEH_plugin->cls,
+                             session);
     /* If commit succeeded, we're done, otherwise we retry; this
        time without logging, as theroetically commits can fail
        in a transactional DB due to concurrent activities that
diff --git a/src/exchange/test_taler_exchange_aggregator.c 
b/src/exchange/test_taler_exchange_aggregator.c
index 57cb9d3..6eaa093 100644
--- a/src/exchange/test_taler_exchange_aggregator.c
+++ b/src/exchange/test_taler_exchange_aggregator.c
@@ -450,7 +450,7 @@ do_deposit (struct Command *cmd)
         plugin->insert_deposit (plugin->cls,
                                 session,
                                 &deposit)) ||
-       (GNUNET_OK !=
+       (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
         plugin->commit (plugin->cls,
                         session)) )
     ret = GNUNET_SYSERR;
@@ -1148,7 +1148,7 @@ run (void *cls)
                                           session,
                                           &dpk,
                                           &issue)) ||
-       (GNUNET_OK !=
+       (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
         plugin->commit (plugin->cls,
                         session)) )
     {
diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c 
b/src/exchangedb/perf_taler_exchangedb_interpreter.c
index 5e4155c..0a8efbb 100644
--- a/src/exchangedb/perf_taler_exchangedb_interpreter.c
+++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c
@@ -1292,13 +1292,16 @@ interpret (struct 
PERF_TALER_EXCHANGEDB_interpreter_state *state)
         break;
 
       case PERF_TALER_EXCHANGEDB_CMD_START_TRANSACTION:
-        state->plugin->start (state->plugin->cls, state->session);
+        GNUNET_break (GNUNET_OK ==
+                      state->plugin->start (state->plugin->cls,
+                                            state->session));
         break;
 
       case PERF_TALER_EXCHANGEDB_CMD_COMMIT_TRANSACTION:
-        state->plugin->commit (state->plugin->cls, state->session);
+        GNUNET_break (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
+                      state->plugin->commit (state->plugin->cls,
+                                             state->session));
         break;
-
       case PERF_TALER_EXCHANGEDB_CMD_ABORT_TRANSACTION:
         state->plugin->rollback (state->plugin->cls,
                                  state->session);
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index e251722..2df4630 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -242,318 +242,298 @@ static int
 postgres_create_tables (void *cls)
 {
   struct PostgresClosure *pc = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    /* Denomination table for holding the publicly available information of
+       denominations keys.  The denominations are to be referred to using
+       foreign keys. */
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS denominations"
+                            "(denom_pub_hash BYTEA PRIMARY KEY CHECK 
(LENGTH(denom_pub_hash)=64)"
+                            ",denom_pub BYTEA NOT NULL"
+                            ",master_pub BYTEA NOT NULL CHECK 
(LENGTH(master_pub)=32)"
+                            ",master_sig BYTEA NOT NULL CHECK 
(LENGTH(master_sig)=64)"
+                            ",valid_from INT8 NOT NULL"
+                            ",expire_withdraw INT8 NOT NULL"
+                            ",expire_deposit INT8 NOT NULL"
+                            ",expire_legal INT8 NOT NULL"
+                            ",coin_val INT8 NOT NULL" /* value of this denom */
+                            ",coin_frac INT4 NOT NULL" /* fractional value of 
this denom */
+                            ",coin_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT 
NULL" /* assuming same currency for fees */
+                            ",fee_withdraw_val INT8 NOT NULL"
+                            ",fee_withdraw_frac INT4 NOT NULL"
+                            ",fee_withdraw_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                            ",fee_deposit_val INT8 NOT NULL"
+                            ",fee_deposit_frac INT4 NOT NULL"
+                            ",fee_deposit_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                            ",fee_refresh_val INT8 NOT NULL"
+                            ",fee_refresh_frac INT4 NOT NULL"
+                            ",fee_refresh_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                            ",fee_refund_val INT8 NOT NULL"
+                            ",fee_refund_frac INT4 NOT NULL"
+                            ",fee_refund_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                            ")"),
+    /* denomination_revocations table is for remembering which denomination 
keys have been revoked */
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
denomination_revocations"
+                            "(denom_revocations_serial_id BIGSERIAL"
+                            ",denom_pub_hash BYTEA PRIMARY KEY REFERENCES 
denominations (denom_pub_hash) ON DELETE CASCADE"
+                            ",master_sig BYTEA NOT NULL CHECK 
(LENGTH(master_sig)=64)"
+                            ");"),
+    /* reserves table is for summarization of a reserve.  It is updated when 
new
+       funds are added and existing funds are withdrawn.  The 'expiration_date'
+       can be used to eventually get rid of reserves that have not been used
+       for a very long time (either by refunding the owner or by greedily
+       grabbing the money, depending on the Exchange's terms of service) */
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS reserves"
+                            "(reserve_pub BYTEA PRIMARY KEY 
CHECK(LENGTH(reserve_pub)=32)"
+                            ",account_details TEXT NOT NULL "
+                            ",current_balance_val INT8 NOT NULL"
+                            ",current_balance_frac INT4 NOT NULL"
+                            ",current_balance_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                            ",expiration_date INT8 NOT NULL"
+                            ");"),
+    /* index on reserves table */
+    GNUNET_PQ_make_try_execute ("CREATE INDEX reserves_reserve_pub_index ON "
+                                "reserves (reserve_pub);"),
+    GNUNET_PQ_make_try_execute ("CREATE INDEX reserves_expiration_index"
+                                " ON reserves (expiration_date);"),
+    /* reserves_in table collects the transactions which transfer funds
+       into the reserve.  The rows of this table correspond to each
+       incoming transaction. */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS reserves_in"
+                           "(reserve_in_serial_id BIGSERIAL"
+                           ",reserve_pub BYTEA NOT NULL REFERENCES reserves 
(reserve_pub) ON DELETE CASCADE"
+                           ",wire_reference BYTEA NOT NULL"
+                           ",credit_val INT8 NOT NULL"
+                           ",credit_frac INT4 NOT NULL"
+                           ",credit_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT 
NULL"
+                           ",sender_account_details TEXT NOT NULL"
+                           ",execution_date INT8 NOT NULL"
+                           ",PRIMARY KEY (reserve_pub, wire_reference)"
+                           ");"),
+    /* Create indices on reserves_in */
+    GNUNET_PQ_make_try_execute ("CREATE INDEX reserves_in_execution_index"
+                                " ON reserves_in (execution_date);"),
+    /* This table contains the data for wire transfers the exchange has
+       executed to close a reserve. */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS reserves_close "
+                           "(close_uuid BIGSERIAL PRIMARY KEY"
+                           ",reserve_pub BYTEA NOT NULL REFERENCES reserves 
(reserve_pub) ON DELETE CASCADE"
+                           ",execution_date INT8 NOT NULL"
+                           ",wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32)"
+                           ",receiver_account TEXT NOT NULL"
+                           ",amount_val INT8 NOT NULL"
+                           ",amount_frac INT4 NOT NULL"
+                           ",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT 
NULL"
+                           ",closing_fee_val INT8 NOT NULL"
+                           ",closing_fee_frac INT4 NOT NULL"
+                           ",closing_fee_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                           ");"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX reserves_close_by_reserve "
+                               "ON reserves_close(reserve_pub)"),
+    /* Table with the withdraw operations that have been performed on a 
reserve.
+       The 'h_blind_ev' is the hash of the blinded coin. It serves as a primary
+       key, as (broken) clients that use a non-random coin and blinding factor
+       should fail to even withdraw, as otherwise the coins will fail to 
deposit
+       (as they really must be unique). */
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS reserves_out"
+                            "(reserve_out_serial_id BIGSERIAL"
+                            ",h_blind_ev BYTEA PRIMARY KEY"
+                            ",denom_pub_hash BYTEA NOT NULL REFERENCES 
denominations (denom_pub_hash) ON DELETE CASCADE"
+                            ",denom_sig BYTEA NOT NULL"
+                            ",reserve_pub BYTEA NOT NULL REFERENCES reserves 
(reserve_pub) ON DELETE CASCADE"
+                            ",reserve_sig BYTEA NOT NULL CHECK 
(LENGTH(reserve_sig)=64)"
+                            ",execution_date INT8 NOT NULL"
+                            ",amount_with_fee_val INT8 NOT NULL"
+                            ",amount_with_fee_frac INT4 NOT NULL"
+                            ",amount_with_fee_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                            ");"),
+    /* Index blindcoins(reserve_pub) for get_reserves_out statement */
+    GNUNET_PQ_make_try_execute ("CREATE INDEX reserves_out_reserve_pub_index 
ON"
+                                " reserves_out (reserve_pub)"),
+    GNUNET_PQ_make_try_execute ("CREATE INDEX reserves_out_execution_date ON "
+                                "reserves_out (execution_date)"),
+    /* Table with coins that have been (partially) spent, used to track
+       coin information only once. */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS known_coins "
+                           "(coin_pub BYTEA NOT NULL PRIMARY KEY CHECK 
(LENGTH(coin_pub)=32)"
+                           ",denom_pub_hash BYTEA NOT NULL REFERENCES 
denominations (denom_pub_hash) ON DELETE CASCADE"
+                           ",denom_sig BYTEA NOT NULL"
+                           ");"),
+    /**
+     * The DB will show negative values for some values of the following 
fields as
+     * we use them as 16 bit unsigned integers
+     *   @a num_newcoins
+     *   @a noreveal_index
+     * Do not do arithmetic in SQL on these fields.
+     * NOTE: maybe we should instead forbid values >= 2^15 categorically?
+     */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refresh_sessions "
+                           "(melt_serial_id BIGSERIAL"
+                           ",session_hash BYTEA PRIMARY KEY CHECK 
(LENGTH(session_hash)=64)"
+                           ",old_coin_pub BYTEA NOT NULL REFERENCES 
known_coins (coin_pub) ON DELETE CASCADE"
+                           ",old_coin_sig BYTEA NOT NULL 
CHECK(LENGTH(old_coin_sig)=64)"
+                           ",amount_with_fee_val INT8 NOT NULL"
+                           ",amount_with_fee_frac INT4 NOT NULL"
+                           ",amount_with_fee_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                           ",num_newcoins INT2 NOT NULL"
+                           ",noreveal_index INT2 NOT NULL"
+                           ");"),
+    /* Table with information about the desired denominations to be created
+       during a refresh operation; contains the denomination key for each
+       of the coins (for a given refresh session) */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refresh_order "
+                           "(session_hash BYTEA NOT NULL REFERENCES 
refresh_sessions (session_hash) ON DELETE CASCADE"
+                           ",newcoin_index INT2 NOT NULL "
+                           ",denom_pub_hash BYTEA NOT NULL REFERENCES 
denominations (denom_pub_hash) ON DELETE CASCADE"
+                           ",PRIMARY KEY (session_hash, newcoin_index)"
+                           ");"),
+    /* Table with the commitments for a refresh operation; includes
+       the session_hash for which this is the link information, the
+       oldcoin index and the cut-and-choose index (from 0 to 
#TALER_CNC_KAPPA-1),
+       as well as the actual link data (the transfer public key and the 
encrypted
+       link secret) */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS 
refresh_transfer_public_key "
+                           "(session_hash BYTEA NOT NULL PRIMARY KEY 
REFERENCES refresh_sessions (session_hash) ON DELETE CASCADE"
+                           ",transfer_pub BYTEA NOT NULL 
CHECK(LENGTH(transfer_pub)=32)"
+                           ");"),
+    /* Table with the commitments for the new coins that are to be created
+       during a melting session.  Includes the session, the cut-and-choose
+       index and the index of the new coin, and the envelope of the new
+       coin to be signed, as well as the encrypted information about the
+       private key and the blinding factor for the coin (for verification
+       in case this newcoin_index is chosen to be revealed) */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refresh_commit_coin "
+                           "(session_hash BYTEA NOT NULL REFERENCES 
refresh_sessions (session_hash) ON DELETE CASCADE"
+                           ",newcoin_index INT2 NOT NULL"
+                           ",coin_ev BYTEA NOT NULL"
+                           ",UNIQUE (session_hash, newcoin_index)"
+                           ");"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX 
refresh_commit_coin_session_hash_index "
+                               "ON refresh_commit_coin(session_hash, 
newcoin_index)"),
+    /* Table with the signatures over coins generated during a refresh
+       operation. Needed to answer /refresh/link queries later.  Stores
+       the coin signatures under the respective session hash and index. */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refresh_out "
+                           "(session_hash BYTEA NOT NULL REFERENCES 
refresh_sessions (session_hash) ON DELETE CASCADE"
+                           ",newcoin_index INT2 NOT NULL"
+                           ",ev_sig BYTEA NOT NULL"
+                           ",UNIQUE (session_hash, newcoin_index)"
+                           ");"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX refresh_out_session_hash_index "
+                               "ON refresh_out(session_hash, newcoin_index)"),
+    /* This table contains the wire transfers the exchange is supposed to
+       execute to transmit funds to the merchants (and manage refunds). */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS deposits "
+                           "(deposit_serial_id BIGSERIAL PRIMARY KEY"
+                           ",coin_pub BYTEA NOT NULL REFERENCES known_coins 
(coin_pub) ON DELETE CASCADE"
+                           ",amount_with_fee_val INT8 NOT NULL"
+                           ",amount_with_fee_frac INT4 NOT NULL"
+                           ",amount_with_fee_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                           ",timestamp INT8 NOT NULL"
+                           ",refund_deadline INT8 NOT NULL"
+                           ",wire_deadline INT8 NOT NULL"
+                           ",merchant_pub BYTEA NOT NULL CHECK 
(LENGTH(merchant_pub)=32)"
+                           ",h_contract_terms BYTEA NOT NULL CHECK 
(LENGTH(h_contract_terms)=64)"
+                           ",h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64)"
+                           ",coin_sig BYTEA NOT NULL CHECK 
(LENGTH(coin_sig)=64)"
+                           ",wire TEXT NOT NULL"
+                           ",tiny BOOLEAN NOT NULL DEFAULT false"
+                           ",done BOOLEAN NOT NULL DEFAULT false"
+                           ",UNIQUE (coin_pub, h_contract_terms, merchant_pub)"
+                           ");"),
+    /* Index for get_deposit statement on coin_pub, h_contract_terms and 
merchant_pub */
+    GNUNET_PQ_make_try_execute("CREATE INDEX deposits_coin_pub_index "
+                               "ON deposits(coin_pub, h_contract_terms, 
merchant_pub)"),
+    /* Table with information about coins that have been refunded. (Technically
+       one of the deposit operations that a coin was involved with is 
refunded.)*/
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refunds "
+                           "(refund_serial_id BIGSERIAL"
+                           ",coin_pub BYTEA NOT NULL REFERENCES known_coins 
(coin_pub) ON DELETE CASCADE"
+                           ",merchant_pub BYTEA NOT NULL 
CHECK(LENGTH(merchant_pub)=32)"
+                           ",merchant_sig BYTEA NOT NULL 
CHECK(LENGTH(merchant_sig)=64)"
+                           ",h_contract_terms BYTEA NOT NULL 
CHECK(LENGTH(h_contract_terms)=64)"
+                           ",rtransaction_id INT8 NOT NULL"
+                           ",amount_with_fee_val INT8 NOT NULL"
+                           ",amount_with_fee_frac INT4 NOT NULL"
+                           ",amount_with_fee_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+                           ",PRIMARY KEY (coin_pub, merchant_pub, 
h_contract_terms, rtransaction_id)" /* this combo must be unique, and we 
usually select by coin_pub */
+                           ");"),
+    /* This table contains the data for
+       wire transfers the exchange has executed. */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS wire_out "
+                           "(wireout_uuid BIGSERIAL PRIMARY KEY"
+                           ",execution_date INT8 NOT NULL"
+                           ",wtid_raw BYTEA UNIQUE NOT NULL CHECK 
(LENGTH(wtid_raw)=" TALER_WIRE_TRANSFER_IDENTIFIER_LEN_STR ")"
+                           ",wire_target TEXT NOT NULL"
+                           ",amount_val INT8 NOT NULL"
+                           ",amount_frac INT4 NOT NULL"
+                           ",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT 
NULL"
+                           ");"),
+    /* Table for the tracking API, mapping from wire transfer identifiers
+       to transactions and back */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS aggregation_tracking "
+                           "(aggregation_serial_id BIGSERIAL"
+                           ",deposit_serial_id INT8 PRIMARY KEY REFERENCES 
deposits (deposit_serial_id) ON DELETE CASCADE"
+                           ",wtid_raw BYTEA  CONSTRAINT wire_out_ref 
REFERENCES wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE"
+                           ");"),
+    /* Index for lookup_transactions statement on wtid */
+    GNUNET_PQ_make_try_execute("CREATE INDEX aggregation_tracking_wtid_index "
+                               "ON aggregation_tracking(wtid_raw)"),
+    /* Table for the wire fees. */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS wire_fee "
+                           "(wire_method VARCHAR NOT NULL"
+                           ",start_date INT8 NOT NULL"
+                           ",end_date INT8 NOT NULL"
+                           ",wire_fee_val INT8 NOT NULL"
+                           ",wire_fee_frac INT4 NOT NULL"
+                           ",wire_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") 
NOT NULL"
+                           ",master_sig BYTEA NOT NULL CHECK 
(LENGTH(master_sig)=64)"
+                           ",PRIMARY KEY (wire_method, start_date)" /* this 
combo must be unique */
+                           ");"),
+    /* Index for lookup_transactions statement on wtid */
+    GNUNET_PQ_make_try_execute("CREATE INDEX aggregation_tracking_wtid_index "
+                               "ON aggregation_tracking(wtid_raw);"),
+    /* Table for /payback information */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS payback "
+                           "(payback_uuid BIGSERIAL"
+                           ",reserve_pub BYTEA NOT NULL REFERENCES reserves 
(reserve_pub) ON DELETE CASCADE"
+                           ",coin_pub BYTEA NOT NULL REFERENCES known_coins 
(coin_pub) ON DELETE CASCADE"
+                           ",coin_sig BYTEA NOT NULL 
CHECK(LENGTH(coin_sig)=64)"
+                           ",coin_blind BYTEA NOT NULL 
CHECK(LENGTH(coin_blind)=32)"
+                           ",amount_val INT8 NOT NULL"
+                           ",amount_frac INT4 NOT NULL"
+                           ",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT 
NULL"
+                           ",timestamp INT8 NOT NULL"
+                           ",h_blind_ev BYTEA NOT NULL REFERENCES reserves_out 
(h_blind_ev) ON DELETE CASCADE"
+                           ");"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX payback_by_coin_index "
+                               "ON payback(coin_pub);"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX payback_by_reserve_index "
+                               "ON payback(reserve_pub);"),
+
+    /* This table contains the pre-commit data for
+       wire transfers the exchange is about to execute. */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS prewire "
+                           "(prewire_uuid BIGSERIAL PRIMARY KEY"
+                           ",type TEXT NOT NULL"
+                           ",finished BOOLEAN NOT NULL DEFAULT false"
+                           ",buf BYTEA NOT NULL"
+                           ");"),
+    /* Index for prepare_data_iterate statement */
+    GNUNET_PQ_make_try_execute("CREATE INDEX prepare_iteration_index "
+                               "ON prewire(type,finished);"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+
+  };
   PGconn *conn;
+  int ret;
 
   conn = GNUNET_PQ_connect (pc->connection_cfg_str);
   if (NULL == conn)
     return GNUNET_SYSERR;
-#define SQLEXEC(sql) SQLEXEC_(conn, sql);
-#define SQLEXEC_INDEX(sql) SQLEXEC_IGNORE_ERROR_(conn, sql);
-  /* Denomination table for holding the publicly available information of
-     denominations keys.  The denominations are to be referred to using
-     foreign keys. */
-  SQLEXEC ("CREATE TABLE IF NOT EXISTS denominations"
-           "(denom_pub_hash BYTEA PRIMARY KEY CHECK 
(LENGTH(denom_pub_hash)=64)"
-          ",denom_pub BYTEA NOT NULL"
-           ",master_pub BYTEA NOT NULL CHECK (LENGTH(master_pub)=32)"
-           ",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)"
-           ",valid_from INT8 NOT NULL"
-           ",expire_withdraw INT8 NOT NULL"
-           ",expire_deposit INT8 NOT NULL"
-           ",expire_legal INT8 NOT NULL"
-           ",coin_val INT8 NOT NULL" /* value of this denom */
-           ",coin_frac INT4 NOT NULL" /* fractional value of this denom */
-           ",coin_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" /* assuming 
same currency for fees */
-           ",fee_withdraw_val INT8 NOT NULL"
-           ",fee_withdraw_frac INT4 NOT NULL"
-           ",fee_withdraw_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-           ",fee_deposit_val INT8 NOT NULL"
-           ",fee_deposit_frac INT4 NOT NULL"
-           ",fee_deposit_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-           ",fee_refresh_val INT8 NOT NULL"
-           ",fee_refresh_frac INT4 NOT NULL"
-           ",fee_refresh_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-           ",fee_refund_val INT8 NOT NULL"
-           ",fee_refund_frac INT4 NOT NULL"
-           ",fee_refund_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-           ")");
-  /* denomination_revocations table is for remembering which denomination keys 
have been revoked */
-  SQLEXEC ("CREATE TABLE IF NOT EXISTS denomination_revocations"
-           "(denom_revocations_serial_id BIGSERIAL"
-          ",denom_pub_hash BYTEA PRIMARY KEY REFERENCES denominations 
(denom_pub_hash) ON DELETE CASCADE"
-           ",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)"
-           ")");
-
-  /* reserves table is for summarization of a reserve.  It is updated when new
-     funds are added and existing funds are withdrawn.  The 'expiration_date'
-     can be used to eventually get rid of reserves that have not been used
-     for a very long time (either by refunding the owner or by greedily
-     grabbing the money, depending on the Exchange's terms of service) */
-  SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves"
-           "(reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32)"
-          ",account_details TEXT NOT NULL "
-           ",current_balance_val INT8 NOT NULL"
-           ",current_balance_frac INT4 NOT NULL"
-           ",current_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-           ",expiration_date INT8 NOT NULL"
-           ")");
-  /* index on reserves table */
-  SQLEXEC_INDEX ("CREATE INDEX reserves_reserve_pub_index ON "
-                 "reserves (reserve_pub)");
-  SQLEXEC_INDEX ("CREATE INDEX reserves_expiration_index"
-                " ON reserves (expiration_date);");
-
-  /* reserves_in table collects the transactions which transfer funds
-     into the reserve.  The rows of this table correspond to each
-     incoming transaction. */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS reserves_in"
-          "(reserve_in_serial_id BIGSERIAL"
-         ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON 
DELETE CASCADE"
-          ",wire_reference BYTEA NOT NULL"
-          ",credit_val INT8 NOT NULL"
-          ",credit_frac INT4 NOT NULL"
-          ",credit_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ",sender_account_details TEXT NOT NULL"
-          ",execution_date INT8 NOT NULL"
-          ",PRIMARY KEY (reserve_pub, wire_reference)"
-          ");");
-  /* Create indices on reserves_in */
-  SQLEXEC_INDEX ("CREATE INDEX reserves_in_execution_index"
-                " ON reserves_in (execution_date);");
-
-  /* This table contains the data for wire transfers the exchange has
-     executed to close a reserve. */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS reserves_close "
-          "(close_uuid BIGSERIAL PRIMARY KEY"
-          ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON 
DELETE CASCADE"
-         ",execution_date INT8 NOT NULL"
-         ",wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32)"
-          ",receiver_account TEXT NOT NULL"
-          ",amount_val INT8 NOT NULL"
-          ",amount_frac INT4 NOT NULL"
-          ",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ",closing_fee_val INT8 NOT NULL"
-          ",closing_fee_frac INT4 NOT NULL"
-          ",closing_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ")");
-  SQLEXEC_INDEX("CREATE INDEX reserves_close_by_reserve "
-                "ON reserves_close(reserve_pub)");
-
-  /* Table with the withdraw operations that have been performed on a reserve.
-     The 'h_blind_ev' is the hash of the blinded coin. It serves as a primary
-     key, as (broken) clients that use a non-random coin and blinding factor
-     should fail to even withdraw, as otherwise the coins will fail to deposit
-     (as they really must be unique). */
-  SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves_out"
-           "(reserve_out_serial_id BIGSERIAL"
-          ",h_blind_ev BYTEA PRIMARY KEY"
-           ",denom_pub_hash BYTEA NOT NULL REFERENCES denominations 
(denom_pub_hash) ON DELETE CASCADE"
-           ",denom_sig BYTEA NOT NULL"
-           ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON 
DELETE CASCADE"
-           ",reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)"
-           ",execution_date INT8 NOT NULL"
-           ",amount_with_fee_val INT8 NOT NULL"
-           ",amount_with_fee_frac INT4 NOT NULL"
-           ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-           ");");
-  /* Index blindcoins(reserve_pub) for get_reserves_out statement */
-  SQLEXEC_INDEX ("CREATE INDEX reserves_out_reserve_pub_index ON"
-                 " reserves_out (reserve_pub)");
-  SQLEXEC_INDEX ("CREATE INDEX reserves_out_execution_date ON "
-                 "reserves_out (execution_date)");
-  /* Table with coins that have been (partially) spent, used to track
-     coin information only once. */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS known_coins "
-          "(coin_pub BYTEA NOT NULL PRIMARY KEY CHECK (LENGTH(coin_pub)=32)"
-          ",denom_pub_hash BYTEA NOT NULL REFERENCES denominations 
(denom_pub_hash) ON DELETE CASCADE"
-          ",denom_sig BYTEA NOT NULL"
-          ")");
-  /**
-   * The DB will show negative values for some values of the following fields 
as
-   * we use them as 16 bit unsigned integers
-   *   @a num_newcoins
-   *   @a noreveal_index
-   * Do not do arithmetic in SQL on these fields.
-   * NOTE: maybe we should instead forbid values >= 2^15 categorically?
-   */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_sessions "
-          "(melt_serial_id BIGSERIAL"
-         ",session_hash BYTEA PRIMARY KEY CHECK (LENGTH(session_hash)=64)"
-          ",old_coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON 
DELETE CASCADE"
-          ",old_coin_sig BYTEA NOT NULL CHECK(LENGTH(old_coin_sig)=64)"
-          ",amount_with_fee_val INT8 NOT NULL"
-          ",amount_with_fee_frac INT4 NOT NULL"
-          ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ",num_newcoins INT2 NOT NULL"
-          ",noreveal_index INT2 NOT NULL"
-          ")");
-
-  /* Table with information about the desired denominations to be created
-     during a refresh operation; contains the denomination key for each
-     of the coins (for a given refresh session) */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_order "
-          "(session_hash BYTEA NOT NULL REFERENCES refresh_sessions 
(session_hash) ON DELETE CASCADE"
-          ",newcoin_index INT2 NOT NULL "
-          ",denom_pub_hash BYTEA NOT NULL REFERENCES denominations 
(denom_pub_hash) ON DELETE CASCADE"
-          ",PRIMARY KEY (session_hash, newcoin_index)"
-          ")");
-
-  /* Table with the commitments for a refresh operation; includes
-     the session_hash for which this is the link information, the
-     oldcoin index and the cut-and-choose index (from 0 to #TALER_CNC_KAPPA-1),
-     as well as the actual link data (the transfer public key and the encrypted
-     link secret) */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_transfer_public_key "
-          "(session_hash BYTEA NOT NULL PRIMARY KEY REFERENCES 
refresh_sessions (session_hash) ON DELETE CASCADE"
-          ",transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32)"
-          ")");
-
-  /* Table with the commitments for the new coins that are to be created
-     during a melting session.  Includes the session, the cut-and-choose
-     index and the index of the new coin, and the envelope of the new
-     coin to be signed, as well as the encrypted information about the
-     private key and the blinding factor for the coin (for verification
-     in case this newcoin_index is chosen to be revealed) */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_coin "
-          "(session_hash BYTEA NOT NULL REFERENCES refresh_sessions 
(session_hash) ON DELETE CASCADE"
-          ",newcoin_index INT2 NOT NULL"
-          ",coin_ev BYTEA NOT NULL"
-          ",UNIQUE (session_hash, newcoin_index)"
-          ")");
-  SQLEXEC_INDEX("CREATE INDEX refresh_commit_coin_session_hash_index "
-                "ON refresh_commit_coin(session_hash, newcoin_index)");
-
-
-  /* Table with the signatures over coins generated during a refresh
-     operation. Needed to answer /refresh/link queries later.  Stores
-     the coin signatures under the respective session hash and index. */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_out "
-          "(session_hash BYTEA NOT NULL REFERENCES refresh_sessions 
(session_hash) ON DELETE CASCADE"
-          ",newcoin_index INT2 NOT NULL"
-          ",ev_sig BYTEA NOT NULL"
-          ",UNIQUE (session_hash, newcoin_index)"
-          ")");
-  SQLEXEC_INDEX("CREATE INDEX refresh_out_session_hash_index "
-                "ON refresh_out(session_hash, newcoin_index)");
-
-  /* This table contains the wire transfers the exchange is supposed to
-     execute to transmit funds to the merchants (and manage refunds). */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS deposits "
-          "(deposit_serial_id BIGSERIAL PRIMARY KEY"
-          ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON 
DELETE CASCADE"
-          ",amount_with_fee_val INT8 NOT NULL"
-          ",amount_with_fee_frac INT4 NOT NULL"
-          ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ",timestamp INT8 NOT NULL"
-          ",refund_deadline INT8 NOT NULL"
-          ",wire_deadline INT8 NOT NULL"
-          ",merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)"
-          ",h_contract_terms BYTEA NOT NULL CHECK 
(LENGTH(h_contract_terms)=64)"
-          ",h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64)"
-          ",coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)"
-          ",wire TEXT NOT NULL"
-          ",tiny BOOLEAN NOT NULL DEFAULT false"
-          ",done BOOLEAN NOT NULL DEFAULT false"
-          ",UNIQUE (coin_pub, h_contract_terms, merchant_pub)"
-          ")");
-  /* Index for get_deposit statement on coin_pub, h_contract_terms and 
merchant_pub */
-  SQLEXEC_INDEX("CREATE INDEX deposits_coin_pub_index "
-                "ON deposits(coin_pub, h_contract_terms, merchant_pub)");
-
-  /* Table with information about coins that have been refunded. (Technically
-     one of the deposit operations that a coin was involved with is 
refunded.)*/
-  SQLEXEC("CREATE TABLE IF NOT EXISTS refunds "
-          "(refund_serial_id BIGSERIAL"
-         ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE 
CASCADE"
-          ",merchant_pub BYTEA NOT NULL CHECK(LENGTH(merchant_pub)=32)"
-          ",merchant_sig BYTEA NOT NULL CHECK(LENGTH(merchant_sig)=64)"
-          ",h_contract_terms BYTEA NOT NULL CHECK(LENGTH(h_contract_terms)=64)"
-          ",rtransaction_id INT8 NOT NULL"
-          ",amount_with_fee_val INT8 NOT NULL"
-          ",amount_with_fee_frac INT4 NOT NULL"
-          ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ",PRIMARY KEY (coin_pub, merchant_pub, h_contract_terms, 
rtransaction_id)" /* this combo must be unique, and we usually select by 
coin_pub */
-          ") ");
-
-  /* This table contains the data for
-     wire transfers the exchange has executed. */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS wire_out "
-          "(wireout_uuid BIGSERIAL PRIMARY KEY"
-          ",execution_date INT8 NOT NULL"
-          ",wtid_raw BYTEA UNIQUE NOT NULL CHECK (LENGTH(wtid_raw)=" 
TALER_WIRE_TRANSFER_IDENTIFIER_LEN_STR ")"
-          ",wire_target TEXT NOT NULL"
-          ",amount_val INT8 NOT NULL"
-          ",amount_frac INT4 NOT NULL"
-          ",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ")");
-
-  /* Table for the tracking API, mapping from wire transfer identifiers
-     to transactions and back */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS aggregation_tracking "
-          "(aggregation_serial_id BIGSERIAL"
-          ",deposit_serial_id INT8 PRIMARY KEY REFERENCES deposits 
(deposit_serial_id) ON DELETE CASCADE"
-          ",wtid_raw BYTEA  CONSTRAINT wire_out_ref REFERENCES 
wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE"
-          ")");
-  /* Index for lookup_transactions statement on wtid */
-  SQLEXEC_INDEX("CREATE INDEX aggregation_tracking_wtid_index "
-                "ON aggregation_tracking(wtid_raw)");
-
-
-  /* Table for the wire fees. */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS wire_fee "
-          "(wire_method VARCHAR NOT NULL"
-          ",start_date INT8 NOT NULL"
-          ",end_date INT8 NOT NULL"
-          ",wire_fee_val INT8 NOT NULL"
-          ",wire_fee_frac INT4 NOT NULL"
-          ",wire_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ",master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)"
-          ",PRIMARY KEY (wire_method, start_date)" /* this combo must be 
unique */
-          ")");
-  /* Index for lookup_transactions statement on wtid */
-  SQLEXEC_INDEX("CREATE INDEX aggregation_tracking_wtid_index "
-                "ON aggregation_tracking(wtid_raw)");
-
-  /* Table for /payback information */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS payback "
-          "(payback_uuid BIGSERIAL"
-          ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON 
DELETE CASCADE"
-          ",coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON 
DELETE CASCADE"
-          ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
-          ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)"
-          ",amount_val INT8 NOT NULL"
-          ",amount_frac INT4 NOT NULL"
-          ",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-          ",timestamp INT8 NOT NULL"
-          ",h_blind_ev BYTEA NOT NULL REFERENCES reserves_out (h_blind_ev) ON 
DELETE CASCADE"
-          ")");
-  SQLEXEC_INDEX("CREATE INDEX payback_by_coin_index "
-                "ON payback(coin_pub)");
-  SQLEXEC_INDEX("CREATE INDEX payback_by_reserve_index "
-                "ON payback(reserve_pub)");
-
-  /* This table contains the pre-commit data for
-     wire transfers the exchange is about to execute. */
-  SQLEXEC("CREATE TABLE IF NOT EXISTS prewire "
-          "(prewire_uuid BIGSERIAL PRIMARY KEY"
-          ",type TEXT NOT NULL"
-          ",finished BOOLEAN NOT NULL DEFAULT false"
-          ",buf BYTEA NOT NULL"
-          ")");
-  /* Index for prepare_data_iterate statement */
-  SQLEXEC_INDEX("CREATE INDEX prepare_iteration_index "
-                "ON prewire(type,finished)");
-
-
-#undef SQLEXEC
-#undef SQLEXEC_INDEX
-
-  PQfinish (conn);
-  return GNUNET_OK;
-
- SQLEXEC_fail:
+  ret = GNUNET_PQ_exec_statements (conn,
+                                   es);
   PQfinish (conn);
-  return GNUNET_SYSERR;
+  return ret;
 }
 
 
@@ -566,1050 +546,1012 @@ postgres_create_tables (void *cls)
 static int
 postgres_prepare (PGconn *db_conn)
 {
-  PGresult *result;
-
-#define PREPARE(name, sql, ...)                                 \
-  do {                                                          \
-    result = PQprepare (db_conn, name, sql, __VA_ARGS__);       \
-    if (PGRES_COMMAND_OK != PQresultStatus (result))            \
-    {                                                           \
-      BREAK_DB_ERR (result, db_conn);                           \
-      PQclear (result); result = NULL;                          \
-      return GNUNET_SYSERR;                                     \
-    }                                                           \
-    PQclear (result); result = NULL;                            \
-  } while (0);
-
-  /* Used in #postgres_insert_denomination_info() */
-  PREPARE ("denomination_insert",
-           "INSERT INTO denominations "
-           "(denom_pub_hash"
-          ",denom_pub"
-           ",master_pub"
-           ",master_sig"
-           ",valid_from"
-           ",expire_withdraw"
-           ",expire_deposit"
-           ",expire_legal"
-           ",coin_val" /* value of this denom */
-           ",coin_frac" /* fractional value of this denom */
-           ",coin_curr" /* assuming same currency for fees */
-           ",fee_withdraw_val"
-           ",fee_withdraw_frac"
-           ",fee_withdraw_curr" /* must match coin_curr */
-           ",fee_deposit_val"
-           ",fee_deposit_frac"
-           ",fee_deposit_curr"  /* must match coin_curr */
-           ",fee_refresh_val"
-           ",fee_refresh_frac"
-           ",fee_refresh_curr" /* must match coin_curr */
-           ",fee_refund_val"
-           ",fee_refund_frac"
-           ",fee_refund_curr" /* must match coin_curr */
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
-           " $11, $12, $13, $14, $15, $16, $17, $18,"
-          " $19, $20, $21, $22, $23);",
-           23, NULL);
-
-  /* Used in #postgres_get_denomination_info() */
-  PREPARE ("denomination_get",
-           "SELECT"
-           " master_pub"
-           ",master_sig"
-           ",valid_from"
-           ",expire_withdraw"
-           ",expire_deposit"
-           ",expire_legal"
-           ",coin_val"  /* value of this denom */
-           ",coin_frac" /* fractional value of this denom */
-           ",coin_curr" /* assuming same currency for fees */
-           ",fee_withdraw_val"
-           ",fee_withdraw_frac"
-           ",fee_withdraw_curr" /* must match coin_curr */
-           ",fee_deposit_val"
-           ",fee_deposit_frac"
-           ",fee_deposit_curr"  /* must match coin_curr */
-           ",fee_refresh_val"
-           ",fee_refresh_frac"
-           ",fee_refresh_curr" /* must match coin_curr */
-           ",fee_refund_val"
-           ",fee_refund_frac"
-           ",fee_refund_curr" /* must match coin_curr */
-           " FROM denominations"
-           " WHERE denom_pub=$1;",
-           1, NULL);
-
-  /* Used in #postgres_insert_denomination_revocation() */
-  PREPARE ("denomination_revocation_insert",
-           "INSERT INTO denomination_revocations "
-           "(denom_pub_hash"
-           ",master_sig"
-           ") VALUES "
-           "($1, $2);",
-           2, NULL);
-
-  /* Used in #postgres_get_denomination_revocation() */
-  PREPARE ("denomination_revocation_get",
-           "SELECT"
-           " master_sig"
-          ",denom_revocations_serial_id"
-           " FROM denomination_revocations"
-           " WHERE denom_pub_hash=$1;",
-           1, NULL);
-
-
-  /* Used in #postgres_reserve_get() */
-  PREPARE ("reserve_get",
-           "SELECT"
-           " current_balance_val"
-           ",current_balance_frac"
-           ",current_balance_curr"
-           ",expiration_date"
-           " FROM reserves"
-           " WHERE reserve_pub=$1"
-           " LIMIT 1;",
-           1, NULL);
-
-  /* Used in #postgres_reserves_in_insert() when the reserve is new */
-  PREPARE ("reserve_create",
-           "INSERT INTO reserves "
-           "(reserve_pub"
-          ",account_details"
-           ",current_balance_val"
-           ",current_balance_frac"
-           ",current_balance_curr"
-           ",expiration_date"
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6);",
-           6, NULL);
-
-  /* Used in #postgres_insert_reserve_closed() */
-  PREPARE ("reserves_close_insert",
-          "INSERT INTO reserves_close "
-          "(reserve_pub"
-          ",execution_date"
-          ",wtid"
-          ",receiver_account"
-          ",amount_val"
-          ",amount_frac"
-          ",amount_curr"
-          ",closing_fee_val"
-          ",closing_fee_frac"
-          ",closing_fee_curr"
-          ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);",
-           10, NULL);
-
-  /* Used in #postgres_reserves_update() when the reserve is updated */
-  PREPARE ("reserve_update",
-           "UPDATE reserves"
-           " SET"
-           " expiration_date=$1 "
-           ",current_balance_val=$2 "
-           ",current_balance_frac=$3 "
-           "WHERE current_balance_curr=$4 AND reserve_pub=$5",
-           5, NULL);
-
-  /* Used in #postgres_reserves_in_insert() to store transaction details */
-  PREPARE ("reserves_in_add_transaction",
-           "INSERT INTO reserves_in "
-           "(reserve_pub"
-           ",wire_reference"
-           ",credit_val"
-           ",credit_frac"
-           ",credit_curr"
-           ",sender_account_details"
-           ",execution_date"
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7);",
-           7, NULL);
-
-
-  /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
-     transactions for reserves with serial id '\geq' the given parameter */
-  PREPARE ("reserves_in_get_latest_wire_reference",
-           "SELECT"
-           " wire_reference"
-           " FROM reserves_in"
-           " ORDER BY reserve_in_serial_id DESC LIMIT 1",
-           0, NULL);
-
-  /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
-     transactions for reserves with serial id '\geq' the given parameter */
-  PREPARE ("audit_reserves_in_get_transactions_incr",
-           "SELECT"
-           " reserve_pub"
-           ",wire_reference"
-           ",credit_val"
-           ",credit_frac"
-           ",credit_curr"
-           ",execution_date"
-           ",sender_account_details"
-           ",reserve_in_serial_id"
-           " FROM reserves_in"
-           " WHERE reserve_in_serial_id>=$1"
-           " ORDER BY reserve_in_serial_id",
-           1, NULL);
-
-  /* Used in #postgres_get_reserve_history() to obtain inbound transactions
-     for a reserve */
-  PREPARE ("reserves_in_get_transactions",
-           "SELECT"
-           " wire_reference"
-           ",credit_val"
-           ",credit_frac"
-           ",credit_curr"
-           ",execution_date"
-           ",sender_account_details"
-           " FROM reserves_in"
-           " WHERE reserve_pub=$1",
-           1, NULL);
-
-  /* Used in #postgres_insert_withdraw_info() to store
-     the signature of a blinded coin with the blinded coin's
-     details before returning it during /reserve/withdraw. We store
-     the coin's denomination information (public key, signature)
-     and the blinded message as well as the reserve that the coin
-     is being withdrawn from and the signature of the message
-     authorizing the withdrawal. */
-  PREPARE ("insert_withdraw_info",
-           "INSERT INTO reserves_out "
-           "(h_blind_ev"
-           ",denom_pub_hash"
-           ",denom_sig"
-           ",reserve_pub"
-           ",reserve_sig"
-           ",execution_date"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
-           9, NULL);
-
-  /* Used in #postgres_get_withdraw_info() to
-     locate the response for a /reserve/withdraw request
-     using the hash of the blinded message.  Used to
-     make sure /reserve/withdraw requests are idempotent. */
-  PREPARE ("get_withdraw_info",
-           "SELECT"
-           " denom.denom_pub"
-           ",denom_sig"
-           ",reserve_sig"
-           ",reserve_pub"
-           ",execution_date"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_withdraw_val"
-           ",denom.fee_withdraw_frac"
-           ",denom.fee_withdraw_curr"
-           " FROM reserves_out"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE h_blind_ev=$1",
-           1, NULL);
-
-  /* Used during #postgres_get_reserve_history() to
-     obtain all of the /reserve/withdraw operations that
-     have been performed on a given reserve. (i.e. to
-     demonstrate double-spending) */
-  PREPARE ("get_reserves_out",
-           "SELECT"
-           " h_blind_ev"
-           ",denom.denom_pub"
-           ",denom_sig"
-           ",reserve_sig"
-           ",execution_date"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_withdraw_val"
-           ",denom.fee_withdraw_frac"
-           ",denom.fee_withdraw_curr"
-           " FROM reserves_out"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE reserve_pub=$1;",
-           1, NULL);
-
-  /* Used in #postgres_select_reserves_out_above_serial_id() */
-  PREPARE ("audit_get_reserves_out_incr",
-           "SELECT"
-           " h_blind_ev"
-           ",denom.denom_pub"
-           ",denom_sig"
-           ",reserve_sig"
-           ",reserve_pub"
-           ",execution_date"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",reserve_out_serial_id"
-           " FROM reserves_out"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE reserve_out_serial_id>=$1"
-           " ORDER BY reserve_out_serial_id ASC",
-           1, NULL);
-
-  /* Used in #postgres_get_refresh_session() to fetch
-     high-level information about a refresh session */
-  PREPARE ("get_refresh_session",
-           "SELECT"
-           " old_coin_pub"
-           ",old_coin_sig"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_refresh_val "
-           ",denom.fee_refresh_frac "
-           ",denom.fee_refresh_curr "
-           ",num_newcoins"
-           ",noreveal_index"
-           " FROM refresh_sessions"
-           "    JOIN known_coins ON (refresh_sessions.old_coin_pub = 
known_coins.coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE session_hash=$1 ",
-           1, NULL);
-
-  /* Used in #postgres_select_refreshs_above_serial_id() to fetch
-     refresh session with id '\geq' the given parameter */
-  PREPARE ("audit_get_refresh_sessions_incr",
-           "SELECT"
-           " denom.denom_pub"
-           ",old_coin_pub"
-           ",old_coin_sig"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",num_newcoins"
-           ",noreveal_index"
-           ",melt_serial_id"
-           ",session_hash"
-           " FROM refresh_sessions"
-           "   JOIN known_coins kc ON (refresh_sessions.old_coin_pub = 
kc.coin_pub)"
-           "   JOIN denominations denom ON (kc.denom_pub_hash = 
denom.denom_pub_hash)"
-           " WHERE melt_serial_id>=$1"
-           " ORDER BY melt_serial_id ASC",
-           1, NULL);
-
-  /* Used in #postgres_create_refresh_session() to store
-     high-level information about a refresh session */
-  PREPARE ("insert_refresh_session",
-           "INSERT INTO refresh_sessions "
-           "(session_hash "
-           ",old_coin_pub "
-           ",old_coin_sig "
-           ",amount_with_fee_val "
-           ",amount_with_fee_frac "
-           ",amount_with_fee_curr "
-           ",num_newcoins "
-           ",noreveal_index "
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7, $8);",
-           8, NULL);
-
-  /* Used in #postgres_get_known_coin() to fetch
-     the denomination public key and signature for
-     a coin known to the exchange. */
-  PREPARE ("get_known_coin",
-           "SELECT"
-           " denom.denom_pub"
-           ",denom_sig"
-           " FROM known_coins"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE coin_pub=$1",
-           1, NULL);
-
-  /* Used in #postgres_insert_known_coin() to store
-     the denomination public key and signature for
-     a coin known to the exchange. */
-  PREPARE ("insert_known_coin",
-           "INSERT INTO known_coins "
-           "(coin_pub"
-           ",denom_pub_hash"
-           ",denom_sig"
-           ") VALUES "
-           "($1,$2,$3);",
-           3, NULL);
-
-  /* Store information about the desired denominations for a
-     refresh operation, used in #postgres_insert_refresh_order() */
-  PREPARE ("insert_refresh_order",
-           "INSERT INTO refresh_order "
-           "(newcoin_index "
-           ",session_hash "
-           ",denom_pub_hash "
-           ") VALUES "
-           "($1, $2, $3);",
-           3, NULL);
-
-  /* Obtain information about the desired denominations for a
-     refresh operation, used in #postgres_get_refresh_order() */
-  PREPARE ("get_refresh_order",
-           "SELECT denom_pub"
-           " FROM refresh_order"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE session_hash=$1 AND newcoin_index=$2",
-           2, NULL);
-
-  /* Query the 'refresh_sessions' by coin public key */
-  PREPARE ("get_refresh_session_by_coin",
-           "SELECT"
-           " session_hash"
-           ",old_coin_sig"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_refresh_val "
-           ",denom.fee_refresh_frac "
-           ",denom.fee_refresh_curr "
-           " FROM refresh_sessions"
-           "    JOIN known_coins ON (refresh_sessions.old_coin_pub = 
known_coins.coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE old_coin_pub=$1",
-           1, NULL);
-
-  /* Fetch refunds with rowid '\geq' the given parameter */
-  PREPARE ("audit_get_refunds_incr",
-           "SELECT"
-           " merchant_pub"
-           ",merchant_sig"
-           ",h_contract_terms"
-           ",rtransaction_id"
-           ",denom.denom_pub"
-           ",coin_pub"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",refund_serial_id"
-           " FROM refunds"
-           "   JOIN known_coins kc USING (coin_pub)"
-           "   JOIN denominations denom ON (kc.denom_pub_hash = 
denom.denom_pub_hash)"
-           " WHERE refund_serial_id>=$1"
-           " ORDER BY refund_serial_id ASC",
-           1, NULL);
-
-  /* Query the 'refunds' by coin public key */
-  PREPARE ("get_refunds_by_coin",
-           "SELECT"
-           " merchant_pub"
-           ",merchant_sig"
-           ",h_contract_terms"
-           ",rtransaction_id"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_refund_val "
-           ",denom.fee_refund_frac "
-           ",denom.fee_refund_curr "
-           " FROM refunds"
-           "    JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE coin_pub=$1",
-           1, NULL);
-
-  /* Used in #postgres_insert_transfer_public_key() to
-     store commitments */
-  PREPARE ("insert_transfer_public_key",
-           "INSERT INTO refresh_transfer_public_key "
-           "(session_hash"
-           ",transfer_pub"
-           ") VALUES "
-           "($1, $2);",
-           3, NULL);
-
-  /* Used in #postgres_get_refresh_transfer_public_key() to
-     retrieve original commitments during /refresh/reveal */
-  PREPARE ("get_refresh_transfer_public_key",
-           "SELECT"
-           " transfer_pub"
-           " FROM refresh_transfer_public_key"
-           " WHERE session_hash=$1",
-           1, NULL);
-
-  /* Used in #postgres_insert_refresh_commit_coins() to
-     store coin commitments. */
-  PREPARE ("insert_refresh_commit_coin",
-           "INSERT INTO refresh_commit_coin "
-           "(session_hash"
-           ",newcoin_index"
-           ",coin_ev"
-           ") VALUES "
-           "($1, $2, $3);",
-           3, NULL);
-
-  /* Used in #postgres_get_refresh_commit_coins() to
-     retrieve the original coin envelopes, to either be
-     verified or signed. */
-  PREPARE ("get_refresh_commit_coin",
-           "SELECT"
-           " coin_ev"
-           " FROM refresh_commit_coin"
-           " WHERE session_hash=$1 AND newcoin_index=$2",
-           2, NULL);
-
-  /* Store information about a /deposit the exchange is to execute.
-     Used in #postgres_insert_deposit(). */
-  PREPARE ("insert_deposit",
-           "INSERT INTO deposits "
-           "(coin_pub"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",timestamp"
-           ",refund_deadline"
-           ",wire_deadline"
-           ",merchant_pub"
-           ",h_contract_terms"
-           ",h_wire"
-           ",coin_sig"
-           ",wire"
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
-           " $11, $12);",
-           12, NULL);
-
-  /* Used in #postgres_insert_refund() to store refund information */
-  PREPARE ("insert_refund",
-           "INSERT INTO refunds "
-           "(coin_pub "
-           ",merchant_pub "
-           ",merchant_sig "
-           ",h_contract_terms "
-           ",rtransaction_id "
-           ",amount_with_fee_val "
-           ",amount_with_fee_frac "
-           ",amount_with_fee_curr "
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7, $8);",
-           8, NULL);
-
-  /* Fetch an existing deposit request, used to ensure idempotency
-     during /deposit processing. Used in #postgres_have_deposit(). */
-  PREPARE ("get_deposit",
-           "SELECT"
-           " amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",timestamp"
-           ",refund_deadline"
-           ",wire_deadline"
-           ",h_contract_terms"
-           ",h_wire"
-           " FROM deposits"
-           " WHERE ("
-           "  (coin_pub=$1) AND"
-           "  (h_contract_terms=$2) AND"
-           "  (merchant_pub=$3)"
-           " )",
-           3, NULL);
-
-  /* Fetch deposits with rowid '\geq' the given parameter */
-  PREPARE ("audit_get_deposits_incr",
-           "SELECT"
-           " amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",timestamp"
-          ",merchant_pub"
-           ",denom.denom_pub"
-          ",coin_pub"
-          ",coin_sig"
-           ",refund_deadline"
-           ",wire_deadline"
-           ",h_contract_terms"
-           ",wire"
-           ",done"
-           ",deposit_serial_id"
-           " FROM deposits"
-           "   JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE ("
-           "  (deposit_serial_id>=$1)"
-           " )"
-          " ORDER BY deposit_serial_id ASC",
-           1, NULL);
-
-  /* Fetch an existing deposit request.
-     Used in #postgres_wire_lookup_deposit_wtid(). */
-  PREPARE ("get_deposit_for_wtid",
-           "SELECT"
-           " amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_deposit_val"
-           ",denom.fee_deposit_frac"
-           ",denom.fee_deposit_curr"
-           ",wire_deadline"
-           " FROM deposits"
-           "    JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE ("
-           "  (coin_pub=$1) AND"
-           "  (merchant_pub=$2) AND"
-           "  (h_contract_terms=$3) AND"
-           "  (h_wire=$4)"
-           " )",
-           4, NULL);
-
-  /* Used in #postgres_get_ready_deposit() */
-  PREPARE ("deposits_get_ready",
-           "SELECT"
-           " deposit_serial_id"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_deposit_val"
-           ",denom.fee_deposit_frac"
-           ",denom.fee_deposit_curr"
-           ",wire_deadline"
-           ",h_contract_terms"
-           ",wire"
-           ",merchant_pub"
-           ",coin_pub"
-           " FROM deposits"
-           "    JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE"
-           " tiny=false AND"
-           " done=false AND"
-           " wire_deadline<=$1 AND"
-           " refund_deadline<$1"
-           " ORDER BY wire_deadline ASC"
-           " LIMIT 1",
-           1, NULL);
-
-  /* Used in #postgres_iterate_matching_deposits() */
-  PREPARE ("deposits_iterate_matching",
-           "SELECT"
-           " deposit_serial_id"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_deposit_val"
-           ",denom.fee_deposit_frac"
-           ",denom.fee_deposit_curr"
-           ",wire_deadline"
-           ",h_contract_terms"
-           ",coin_pub"
-           " FROM deposits"
-           "    JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE"
-           " merchant_pub=$1 AND"
-           " h_wire=$2 AND"
-           " done=false"
-           " ORDER BY wire_deadline ASC"
-           " LIMIT " TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT_STR,
-           2, NULL);
-
-  /* Used in #postgres_mark_deposit_tiny() */
-  PREPARE ("mark_deposit_tiny",
-           "UPDATE deposits"
-           " SET tiny=true"
-           " WHERE deposit_serial_id=$1",
-           1, NULL);
-
-  /* Used in #postgres_mark_deposit_done() */
-  PREPARE ("mark_deposit_done",
-           "UPDATE deposits"
-           " SET done=true"
-           " WHERE deposit_serial_id=$1",
-           1, NULL);
-
-  /* Used in #postgres_test_deposit_done() */
-  PREPARE ("test_deposit_done",
-           "SELECT done"
-           " FROM deposits"
-           " WHERE coin_pub=$1"
-           " AND merchant_pub=$2"
-           " AND h_contract_terms=$3"
-           " AND h_wire=$4",
-           5, NULL);
-
-  /* Used in #postgres_get_coin_transactions() to obtain information
-     about how a coin has been spend with /deposit requests. */
-  PREPARE ("get_deposit_with_coin_pub",
-           "SELECT"
-           " amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_deposit_val"
-           ",denom.fee_deposit_frac"
-           ",denom.fee_deposit_curr"
-           ",timestamp"
-           ",refund_deadline"
-           ",merchant_pub"
-           ",h_contract_terms"
-           ",h_wire"
-           ",wire"
-           ",coin_sig"
-           " FROM deposits"
-           "    JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           " WHERE coin_pub=$1",
-           1, NULL);
-
-  /* Used in #postgres_insert_refresh_out() to store the
-     generated signature(s) for future requests, i.e. /refresh/link */
-  PREPARE ("insert_refresh_out",
-           "INSERT INTO refresh_out "
-           "(session_hash"
-           ",newcoin_index"
-           ",ev_sig"
-           ") VALUES "
-           "($1, $2, $3)",
-           3, NULL);
-
-  /* Used in #postgres_get_refresh_out() to test if the
-     generated signature(s) already exists */
-  PREPARE ("get_refresh_out",
-           "SELECT ev_sig"
-           " FROM refresh_out"
-           " WHERE session_hash=$1"
-           " AND newcoin_index=$2",
-           2, NULL);
-
-  /* Used in #postgres_get_link_data_list().  We use the session_hash
-     to obtain the "noreveal_index" for that session, and then select the
-     corresponding signatures (ev_sig) and the denomination keys from
-     the respective tables (namely refresh_melts and refresh_order)
-     using the session_hash as the primary filter (on join) and the
-     'noreveal_index' to constrain the selection on the commitment.
-     We also want to get the triplet for each of the newcoins, so we
-     have another constraint to ensure we get each triplet with
-     matching "newcoin_index" values.  NOTE: This may return many
-     results, both for different sessions and for the different coins
-     being exchangeed in the refresh ops.  NOTE: There may be more
-     efficient ways to express the same query.  */
-  PREPARE ("get_link",
-           "SELECT "
-          " ev_sig"
-          ",denoms.denom_pub"
-           " FROM refresh_sessions"
-           "     JOIN refresh_order ro USING (session_hash)"
-           "     JOIN refresh_commit_coin rcc USING (session_hash)"
-           "     JOIN refresh_out rc USING (session_hash)"
-           "     JOIN denominations denoms ON (ro.denom_pub_hash = 
denoms.denom_pub_hash)"
-           " WHERE ro.session_hash=$1"
-           "  AND ro.newcoin_index=rcc.newcoin_index"
-           "  AND ro.newcoin_index=rc.newcoin_index",
-           1, NULL);
-
-  /* Used in #postgres_get_transfer().  Given the public key of a
-     melted coin, we obtain the corresponding encrypted link secret
-     and the transfer public key.  This is done by first finding
-     the session_hash(es) of all sessions the coin was melted into,
-     and then constraining the result to the selected "noreveal_index".
-     NOTE: This may (in theory) return multiple results, one per session
-     that the old coin was melted into. */
-  PREPARE ("get_transfer",
-           "SELECT transfer_pub,session_hash"
-           " FROM refresh_sessions rs"
-           "     JOIN refresh_transfer_public_key rcl USING (session_hash)"
-           " WHERE rs.old_coin_pub=$1",
-           1, NULL);
-
-  /* Used in #postgres_lookup_wire_transfer */
-  PREPARE ("lookup_transactions",
-           "SELECT"
-           " aggregation_serial_id"
-           ",deposits.h_contract_terms"
-           ",deposits.wire"
-           ",deposits.h_wire"
-           ",deposits.coin_pub"
-           ",deposits.merchant_pub"
-           ",wire_out.execution_date"
-           ",deposits.amount_with_fee_val"
-           ",deposits.amount_with_fee_frac"
-           ",deposits.amount_with_fee_curr"
-           ",denom.fee_deposit_val"
-           ",denom.fee_deposit_frac"
-           ",denom.fee_deposit_curr"
-           " FROM aggregation_tracking"
-           "    JOIN deposits USING (deposit_serial_id)"
-           "    JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           "    JOIN wire_out USING (wtid_raw)"
-           " WHERE wtid_raw=$1",
-           1, NULL);
-
-  /* Used in #postgres_wire_lookup_deposit_wtid */
-  PREPARE ("lookup_deposit_wtid",
-           "SELECT"
-           " aggregation_tracking.wtid_raw"
-           ",wire_out.execution_date"
-           ",amount_with_fee_val"
-           ",amount_with_fee_frac"
-           ",amount_with_fee_curr"
-           ",denom.fee_deposit_val"
-           ",denom.fee_deposit_frac"
-           ",denom.fee_deposit_curr"
-           " FROM deposits"
-           "    JOIN aggregation_tracking USING (deposit_serial_id)"
-           "    JOIN known_coins USING (coin_pub)"
-           "    JOIN denominations denom USING (denom_pub_hash)"
-           "    JOIN wire_out USING (wtid_raw)"
-           " WHERE coin_pub=$1"
-           "  AND h_contract_terms=$2"
-           "  AND h_wire=$3"
-           "  AND merchant_pub=$4",
-           4, NULL);
-
-  /* Used in #postgres_insert_aggregation_tracking */
-  PREPARE ("insert_aggregation_tracking",
-           "INSERT INTO aggregation_tracking "
-           "(deposit_serial_id"
-           ",wtid_raw"
-           ") VALUES "
-           "($1, $2)",
-           2, NULL);
-
-  /* Used in #postgres_get_wire_fee() */
-  PREPARE ("get_wire_fee",
-           "SELECT "
-           " start_date"
-           ",end_date"
-           ",wire_fee_val"
-           ",wire_fee_frac"
-           ",wire_fee_curr"
-           ",master_sig"
-           " FROM wire_fee"
-           " WHERE wire_method=$1"
-           " AND start_date <= $2"
-           " AND end_date > $2",
-           2, NULL);
-
-  /* Used in #postgres_insert_wire_fee */
-  PREPARE ("insert_wire_fee",
-           "INSERT INTO wire_fee "
-           "(wire_method"
-           ",start_date"
-           ",end_date"
-           ",wire_fee_val"
-           ",wire_fee_frac"
-           ",wire_fee_curr"
-           ",master_sig"
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7)",
-           7, NULL);
-
-  /* Used in #postgres_store_wire_transfer_out */
-  PREPARE ("insert_wire_out",
-           "INSERT INTO wire_out "
-           "(execution_date"
-           ",wtid_raw"
-           ",wire_target"
-           ",amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6)",
-           6, NULL);
-
-  /* Used in #postgres_wire_prepare_data_insert() to store
-     wire transfer information before actually committing it with the bank */
-  PREPARE ("wire_prepare_data_insert",
-           "INSERT INTO prewire "
-           "(type"
-           ",buf"
-           ") VALUES "
-           "($1, $2)",
-           2, NULL);
-
-  /* Used in #postgres_wire_prepare_data_mark_finished() */
-  PREPARE ("wire_prepare_data_mark_done",
-           "UPDATE prewire"
-           " SET finished=true"
-           " WHERE prewire_uuid=$1",
-           1, NULL);
-
-  /* Used in #postgres_wire_prepare_data_get() */
-  PREPARE ("wire_prepare_data_get",
-           "SELECT"
-           " prewire_uuid"
-           ",type"
-           ",buf"
-           " FROM prewire"
-           " WHERE finished=false"
-           " ORDER BY prewire_uuid ASC"
-           " LIMIT 1",
-           0, NULL);
-
-  /* Used in #postgres_gc() */
-  PREPARE ("gc_prewire",
-           "DELETE"
-           " FROM prewire"
-           " WHERE finished=true",
-           0, NULL);
-
-  /* Used in #postgres_select_wire_out_above_serial_id() */
-  PREPARE ("audit_get_wire_incr",
-           "SELECT"
-           " wireout_uuid"
-           ",execution_date"
-           ",wtid_raw"
-           ",wire_target"
-           ",amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           " FROM wire_out"
-           " WHERE wireout_uuid>=$1"
-           " ORDER BY wireout_uuid ASC",
-           1, NULL);
-
-  /* Used in #postgres_insert_payback_request() to store payback
-     information */
-  PREPARE ("payback_insert",
-           "INSERT INTO payback "
-           "(reserve_pub"
-           ",coin_pub"
-           ",coin_sig"
-           ",coin_blind"
-           ",amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           ",timestamp"
-           ",h_blind_ev"
-           ") VALUES "
-           "($1, $2, $3, $4, $5, $6, $7, $8, $9)",
-           9, NULL);
-
-  /* Used in #postgres_select_payback_above_serial_id() to obtain payback 
transactions */
-  PREPARE ("payback_get_incr",
-           "SELECT"
-           " payback_uuid"
-           ",timestamp"
-           ",reserve_pub"
-           ",coin_pub"
-           ",coin_sig"
-           ",coin_blind"
-           ",h_blind_ev"
-           ",denoms.denom_pub"
-           ",coins.denom_sig"
-           ",amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           " FROM payback"
-           "    JOIN known_coins coins USING (coin_pub)"
-           "    JOIN denominations denoms USING (denom_pub_hash)"
-           " WHERE payback_uuid>=$1"
-           " ORDER BY payback_uuid ASC",
-           1, NULL);
-
+  struct GNUNET_PQ_PreparedStatement ps[] = {
+    /* Used in #postgres_insert_denomination_info() */
+    GNUNET_PQ_make_prepare ("denomination_insert",
+                            "INSERT INTO denominations "
+                            "(denom_pub_hash"
+                            ",denom_pub"
+                            ",master_pub"
+                            ",master_sig"
+                            ",valid_from"
+                            ",expire_withdraw"
+                            ",expire_deposit"
+                            ",expire_legal"
+                            ",coin_val" /* value of this denom */
+                            ",coin_frac" /* fractional value of this denom */
+                            ",coin_curr" /* assuming same currency for fees */
+                            ",fee_withdraw_val"
+                            ",fee_withdraw_frac"
+                            ",fee_withdraw_curr" /* must match coin_curr */
+                            ",fee_deposit_val"
+                            ",fee_deposit_frac"
+                            ",fee_deposit_curr"  /* must match coin_curr */
+                            ",fee_refresh_val"
+                            ",fee_refresh_frac"
+                            ",fee_refresh_curr" /* must match coin_curr */
+                            ",fee_refund_val"
+                            ",fee_refund_frac"
+                            ",fee_refund_curr" /* must match coin_curr */
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
+                            " $11, $12, $13, $14, $15, $16, $17, $18,"
+                            " $19, $20, $21, $22, $23);",
+                            23),
+    /* Used in #postgres_get_denomination_info() */
+    GNUNET_PQ_make_prepare ("denomination_get",
+                            "SELECT"
+                            " master_pub"
+                            ",master_sig"
+                            ",valid_from"
+                            ",expire_withdraw"
+                            ",expire_deposit"
+                            ",expire_legal"
+                            ",coin_val"  /* value of this denom */
+                            ",coin_frac" /* fractional value of this denom */
+                            ",coin_curr" /* assuming same currency for fees */
+                            ",fee_withdraw_val"
+                            ",fee_withdraw_frac"
+                            ",fee_withdraw_curr" /* must match coin_curr */
+                            ",fee_deposit_val"
+                            ",fee_deposit_frac"
+                            ",fee_deposit_curr"  /* must match coin_curr */
+                            ",fee_refresh_val"
+                            ",fee_refresh_frac"
+                            ",fee_refresh_curr" /* must match coin_curr */
+                            ",fee_refund_val"
+                            ",fee_refund_frac"
+                            ",fee_refund_curr" /* must match coin_curr */
+                            " FROM denominations"
+                            " WHERE denom_pub=$1;",
+                            1),
+    /* Used in #postgres_insert_denomination_revocation() */
+    GNUNET_PQ_make_prepare ("denomination_revocation_insert",
+                            "INSERT INTO denomination_revocations "
+                            "(denom_pub_hash"
+                            ",master_sig"
+                            ") VALUES "
+                            "($1, $2);",
+                            2),
+    /* Used in #postgres_get_denomination_revocation() */
+    GNUNET_PQ_make_prepare ("denomination_revocation_get",
+                            "SELECT"
+                            " master_sig"
+                            ",denom_revocations_serial_id"
+                            " FROM denomination_revocations"
+                            " WHERE denom_pub_hash=$1;",
+                            1),
+    /* Used in #postgres_reserve_get() */
+    GNUNET_PQ_make_prepare ("reserve_get",
+                            "SELECT"
+                            " current_balance_val"
+                            ",current_balance_frac"
+                            ",current_balance_curr"
+                            ",expiration_date"
+                            " FROM reserves"
+                            " WHERE reserve_pub=$1"
+                            " LIMIT 1;",
+                            1),
+    /* Used in #postgres_reserves_in_insert() when the reserve is new */
+    GNUNET_PQ_make_prepare ("reserve_create",
+                            "INSERT INTO reserves "
+                            "(reserve_pub"
+                            ",account_details"
+                            ",current_balance_val"
+                            ",current_balance_frac"
+                            ",current_balance_curr"
+                            ",expiration_date"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6);",
+                            6),
+    /* Used in #postgres_insert_reserve_closed() */
+    GNUNET_PQ_make_prepare ("reserves_close_insert",
+                            "INSERT INTO reserves_close "
+                            "(reserve_pub"
+                            ",execution_date"
+                            ",wtid"
+                            ",receiver_account"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",closing_fee_val"
+                            ",closing_fee_frac"
+                            ",closing_fee_curr"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);",
+                            10),
+    /* Used in #postgres_reserves_update() when the reserve is updated */
+    GNUNET_PQ_make_prepare ("reserve_update",
+                            "UPDATE reserves"
+                            " SET"
+                            " expiration_date=$1 "
+                            ",current_balance_val=$2 "
+                            ",current_balance_frac=$3"
+                            " WHERE current_balance_curr=$4"
+                            " AND reserve_pub=$5;",
+                            5),
+    /* Used in #postgres_reserves_in_insert() to store transaction details */
+    GNUNET_PQ_make_prepare ("reserves_in_add_transaction",
+                            "INSERT INTO reserves_in "
+                            "(reserve_pub"
+                            ",wire_reference"
+                            ",credit_val"
+                            ",credit_frac"
+                            ",credit_curr"
+                            ",sender_account_details"
+                            ",execution_date"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7);",
+                            7),
+    /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
+       transactions for reserves with serial id '\geq' the given parameter */
+    GNUNET_PQ_make_prepare ("reserves_in_get_latest_wire_reference",
+                            "SELECT"
+                            " wire_reference"
+                            " FROM reserves_in"
+                            " ORDER BY reserve_in_serial_id DESC"
+                            " LIMIT 1;",
+                            0),
+    /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
+       transactions for reserves with serial id '\geq' the given parameter */
+    GNUNET_PQ_make_prepare ("audit_reserves_in_get_transactions_incr",
+                            "SELECT"
+                            " reserve_pub"
+                            ",wire_reference"
+                            ",credit_val"
+                            ",credit_frac"
+                            ",credit_curr"
+                            ",execution_date"
+                            ",sender_account_details"
+                            ",reserve_in_serial_id"
+                            " FROM reserves_in"
+                            " WHERE reserve_in_serial_id>=$1"
+                            " ORDER BY reserve_in_serial_id;",
+                            1),
+    /* Used in #postgres_get_reserve_history() to obtain inbound transactions
+       for a reserve */
+    GNUNET_PQ_make_prepare ("reserves_in_get_transactions",
+                            "SELECT"
+                            " wire_reference"
+                            ",credit_val"
+                            ",credit_frac"
+                            ",credit_curr"
+                            ",execution_date"
+                            ",sender_account_details"
+                            " FROM reserves_in"
+                            " WHERE reserve_pub=$1;",
+                            1),
+    /* Used in #postgres_insert_withdraw_info() to store
+       the signature of a blinded coin with the blinded coin's
+       details before returning it during /reserve/withdraw. We store
+       the coin's denomination information (public key, signature)
+       and the blinded message as well as the reserve that the coin
+       is being withdrawn from and the signature of the message
+       authorizing the withdrawal. */
+    GNUNET_PQ_make_prepare ("insert_withdraw_info",
+                            "INSERT INTO reserves_out "
+                            "(h_blind_ev"
+                            ",denom_pub_hash"
+                            ",denom_sig"
+                            ",reserve_pub"
+                            ",reserve_sig"
+                            ",execution_date"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
+                            9),
+    /* Used in #postgres_get_withdraw_info() to
+       locate the response for a /reserve/withdraw request
+       using the hash of the blinded message.  Used to
+       make sure /reserve/withdraw requests are idempotent. */
+    GNUNET_PQ_make_prepare ("get_withdraw_info",
+                            "SELECT"
+                            " denom.denom_pub"
+                            ",denom_sig"
+                            ",reserve_sig"
+                            ",reserve_pub"
+                            ",execution_date"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_withdraw_val"
+                            ",denom.fee_withdraw_frac"
+                            ",denom.fee_withdraw_curr"
+                            " FROM reserves_out"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            " WHERE h_blind_ev=$1;",
+                            1),
+    /* Used during #postgres_get_reserve_history() to
+       obtain all of the /reserve/withdraw operations that
+       have been performed on a given reserve. (i.e. to
+       demonstrate double-spending) */
+    GNUNET_PQ_make_prepare ("get_reserves_out",
+                            "SELECT"
+                            " h_blind_ev"
+                            ",denom.denom_pub"
+                            ",denom_sig"
+                            ",reserve_sig"
+                            ",execution_date"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_withdraw_val"
+                            ",denom.fee_withdraw_frac"
+                            ",denom.fee_withdraw_curr"
+                            " FROM reserves_out"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            " WHERE reserve_pub=$1;",
+                            1),
+    /* Used in #postgres_select_reserves_out_above_serial_id() */
+    GNUNET_PQ_make_prepare ("audit_get_reserves_out_incr",
+                            "SELECT"
+                            " h_blind_ev"
+                            ",denom.denom_pub"
+                            ",denom_sig"
+                            ",reserve_sig"
+                            ",reserve_pub"
+                            ",execution_date"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",reserve_out_serial_id"
+                            " FROM reserves_out"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            " WHERE reserve_out_serial_id>=$1"
+                            " ORDER BY reserve_out_serial_id ASC;",
+                            1),
+    /* Used in #postgres_get_refresh_session() to fetch
+       high-level information about a refresh session */
+    GNUNET_PQ_make_prepare ("get_refresh_session",
+                            "SELECT"
+                            " old_coin_pub"
+                            ",old_coin_sig"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_refresh_val "
+                            ",denom.fee_refresh_frac "
+                            ",denom.fee_refresh_curr "
+                            ",num_newcoins"
+                            ",noreveal_index"
+                            " FROM refresh_sessions"
+                            "    JOIN known_coins"
+                            "      ON (refresh_sessions.old_coin_pub = 
known_coins.coin_pub)"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            " WHERE session_hash=$1;",
+                            1),
+    /* Used in #postgres_select_refreshs_above_serial_id() to fetch
+       refresh session with id '\geq' the given parameter */
+    GNUNET_PQ_make_prepare ("audit_get_refresh_sessions_incr",
+                            "SELECT"
+                            " denom.denom_pub"
+                            ",old_coin_pub"
+                            ",old_coin_sig"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",num_newcoins"
+                            ",noreveal_index"
+                            ",melt_serial_id"
+                            ",session_hash"
+                            " FROM refresh_sessions"
+                            "   JOIN known_coins kc"
+                            "     ON (refresh_sessions.old_coin_pub = 
kc.coin_pub)"
+                            "   JOIN denominations denom"
+                            "     ON (kc.denom_pub_hash = 
denom.denom_pub_hash)"
+                            " WHERE melt_serial_id>=$1"
+                            " ORDER BY melt_serial_id ASC;",
+                            1),
+    /* Used in #postgres_create_refresh_session() to store
+       high-level information about a refresh session */
+    GNUNET_PQ_make_prepare ("insert_refresh_session",
+                            "INSERT INTO refresh_sessions "
+                            "(session_hash "
+                            ",old_coin_pub "
+                            ",old_coin_sig "
+                            ",amount_with_fee_val "
+                            ",amount_with_fee_frac "
+                            ",amount_with_fee_curr "
+                            ",num_newcoins "
+                            ",noreveal_index "
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8);",
+                            8),
+    /* Used in #postgres_get_known_coin() to fetch
+       the denomination public key and signature for
+       a coin known to the exchange. */
+    GNUNET_PQ_make_prepare ("get_known_coin",
+                            "SELECT"
+                            " denom.denom_pub"
+                            ",denom_sig"
+                            " FROM known_coins"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            " WHERE coin_pub=$1;",
+                            1),
+    /* Used in #postgres_insert_known_coin() to store
+       the denomination public key and signature for
+       a coin known to the exchange. */
+    GNUNET_PQ_make_prepare ("insert_known_coin",
+                            "INSERT INTO known_coins "
+                            "(coin_pub"
+                            ",denom_pub_hash"
+                            ",denom_sig"
+                            ") VALUES "
+                            "($1,$2,$3);",
+                            3),
+    /* Store information about the desired denominations for a
+       refresh operation, used in #postgres_insert_refresh_order() */
+    GNUNET_PQ_make_prepare ("insert_refresh_order",
+                            "INSERT INTO refresh_order "
+                            "(newcoin_index "
+                            ",session_hash "
+                            ",denom_pub_hash "
+                            ") VALUES "
+                            "($1, $2, $3);",
+                            3),
+    /* Obtain information about the desired denominations for a
+       refresh operation, used in #postgres_get_refresh_order() */
+    GNUNET_PQ_make_prepare ("get_refresh_order",
+                            "SELECT denom_pub"
+                            " FROM refresh_order"
+                            "    JOIN denominations denom "
+                            "      USING (denom_pub_hash)"
+                            " WHERE session_hash=$1"
+                            "   AND newcoin_index=$2;",
+                            2),
+    /* Query the 'refresh_sessions' by coin public key */
+    GNUNET_PQ_make_prepare ("get_refresh_session_by_coin",
+                            "SELECT"
+                            " session_hash"
+                            ",old_coin_sig"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_refresh_val "
+                            ",denom.fee_refresh_frac "
+                            ",denom.fee_refresh_curr "
+                            " FROM refresh_sessions"
+                            "    JOIN known_coins "
+                            "      ON (refresh_sessions.old_coin_pub = 
known_coins.coin_pub)"
+                            "    JOIN denominations denom USING 
(denom_pub_hash)"
+                            " WHERE old_coin_pub=$1;",
+                            1),
+    /* Fetch refunds with rowid '\geq' the given parameter */
+    GNUNET_PQ_make_prepare ("audit_get_refunds_incr",
+                            "SELECT"
+                            " merchant_pub"
+                            ",merchant_sig"
+                            ",h_contract_terms"
+                            ",rtransaction_id"
+                            ",denom.denom_pub"
+                            ",coin_pub"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",refund_serial_id"
+                            " FROM refunds"
+                            "   JOIN known_coins kc USING (coin_pub)"
+                            "   JOIN denominations denom ON (kc.denom_pub_hash 
= denom.denom_pub_hash)"
+                            " WHERE refund_serial_id>=$1"
+                            " ORDER BY refund_serial_id ASC;",
+                            1),
+    /* Query the 'refunds' by coin public key */
+    GNUNET_PQ_make_prepare ("get_refunds_by_coin",
+                            "SELECT"
+                            " merchant_pub"
+                            ",merchant_sig"
+                            ",h_contract_terms"
+                            ",rtransaction_id"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_refund_val "
+                            ",denom.fee_refund_frac "
+                            ",denom.fee_refund_curr "
+                            " FROM refunds"
+                            "    JOIN known_coins USING (coin_pub)"
+                            "    JOIN denominations denom USING 
(denom_pub_hash)"
+                            " WHERE coin_pub=$1;",
+                            1),
+    /* Used in #postgres_insert_transfer_public_key() to
+       store commitments */
+    GNUNET_PQ_make_prepare ("insert_transfer_public_key",
+                            "INSERT INTO refresh_transfer_public_key "
+                            "(session_hash"
+                            ",transfer_pub"
+                            ") VALUES "
+                            "($1, $2);",
+                            2),
+    /* Used in #postgres_get_refresh_transfer_public_key() to
+       retrieve original commitments during /refresh/reveal */
+    GNUNET_PQ_make_prepare ("get_refresh_transfer_public_key",
+                            "SELECT"
+                            " transfer_pub"
+                            " FROM refresh_transfer_public_key"
+                            " WHERE session_hash=$1;",
+                            1),
+    /* Used in #postgres_insert_refresh_commit_coins() to
+       store coin commitments. */
+    GNUNET_PQ_make_prepare ("insert_refresh_commit_coin",
+                            "INSERT INTO refresh_commit_coin "
+                            "(session_hash"
+                            ",newcoin_index"
+                            ",coin_ev"
+                            ") VALUES "
+                            "($1, $2, $3);",
+                            3),
+    /* Used in #postgres_get_refresh_commit_coins() to
+       retrieve the original coin envelopes, to either be
+       verified or signed. */
+    GNUNET_PQ_make_prepare ("get_refresh_commit_coin",
+                            "SELECT"
+                            " coin_ev"
+                            " FROM refresh_commit_coin"
+                            " WHERE session_hash=$1 AND newcoin_index=$2;",
+                            2),
+    /* Store information about a /deposit the exchange is to execute.
+       Used in #postgres_insert_deposit(). */
+    GNUNET_PQ_make_prepare ("insert_deposit",
+                            "INSERT INTO deposits "
+                            "(coin_pub"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",timestamp"
+                            ",refund_deadline"
+                            ",wire_deadline"
+                            ",merchant_pub"
+                            ",h_contract_terms"
+                            ",h_wire"
+                            ",coin_sig"
+                            ",wire"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
+                            " $11, $12);",
+                            12),
+    /* Used in #postgres_insert_refund() to store refund information */
+    GNUNET_PQ_make_prepare ("insert_refund",
+                            "INSERT INTO refunds "
+                            "(coin_pub "
+                            ",merchant_pub "
+                            ",merchant_sig "
+                            ",h_contract_terms "
+                            ",rtransaction_id "
+                            ",amount_with_fee_val "
+                            ",amount_with_fee_frac "
+                            ",amount_with_fee_curr "
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8);",
+                            8),
+    /* Fetch an existing deposit request, used to ensure idempotency
+       during /deposit processing. Used in #postgres_have_deposit(). */
+    GNUNET_PQ_make_prepare ("get_deposit",
+                            "SELECT"
+                            " amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",timestamp"
+                            ",refund_deadline"
+                            ",wire_deadline"
+                            ",h_contract_terms"
+                            ",h_wire"
+                            " FROM deposits"
+                            " WHERE ("
+                            "        (coin_pub=$1)"
+                            "    AND (h_contract_terms=$2)"
+                            "    AND (merchant_pub=$3)"
+                            " );",
+                            3),
+    /* Fetch deposits with rowid '\geq' the given parameter */
+    GNUNET_PQ_make_prepare ("audit_get_deposits_incr",
+                            "SELECT"
+                            " amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",timestamp"
+                            ",merchant_pub"
+                            ",denom.denom_pub"
+                            ",coin_pub"
+                            ",coin_sig"
+                            ",refund_deadline"
+                            ",wire_deadline"
+                            ",h_contract_terms"
+                            ",wire"
+                            ",done"
+                            ",deposit_serial_id"
+                            " FROM deposits"
+                            "    JOIN known_coins USING (coin_pub)"
+                            "    JOIN denominations denom USING 
(denom_pub_hash)"
+                            " WHERE ("
+                            "  (deposit_serial_id>=$1)"
+                            " )"
+                            " ORDER BY deposit_serial_id ASC;",
+                            1),
+    /* Fetch an existing deposit request.
+       Used in #postgres_wire_lookup_deposit_wtid(). */
+    GNUNET_PQ_make_prepare ("get_deposit_for_wtid",
+                            "SELECT"
+                            " amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_deposit_val"
+                            ",denom.fee_deposit_frac"
+                            ",denom.fee_deposit_curr"
+                            ",wire_deadline"
+                            " FROM deposits"
+                            "    JOIN known_coins USING (coin_pub)"
+                            "    JOIN denominations denom USING 
(denom_pub_hash)"
+                            " WHERE ("
+                            "      (coin_pub=$1)"
+                            "    AND (merchant_pub=$2)"
+                            "    AND (h_contract_terms=$3)"
+                            "    AND (h_wire=$4)"
+                            " );",
+                            4),
+    /* Used in #postgres_get_ready_deposit() */
+    GNUNET_PQ_make_prepare ("deposits_get_ready",
+                            "SELECT"
+                            " deposit_serial_id"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_deposit_val"
+                            ",denom.fee_deposit_frac"
+                            ",denom.fee_deposit_curr"
+                            ",wire_deadline"
+                            ",h_contract_terms"
+                            ",wire"
+                            ",merchant_pub"
+                            ",coin_pub"
+                            " FROM deposits"
+                            "    JOIN known_coins USING (coin_pub)"
+                            "    JOIN denominations denom USING 
(denom_pub_hash)"
+                            " WHERE tiny=false"
+                            "    AND done=false"
+                            "    AND wire_deadline<=$1"
+                            "    AND refund_deadline<$1"
+                            " ORDER BY wire_deadline ASC"
+                            " LIMIT 1;",
+                            1),
+    /* Used in #postgres_iterate_matching_deposits() */
+    GNUNET_PQ_make_prepare ("deposits_iterate_matching",
+                            "SELECT"
+                            " deposit_serial_id"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_deposit_val"
+                            ",denom.fee_deposit_frac"
+                            ",denom.fee_deposit_curr"
+                            ",wire_deadline"
+                            ",h_contract_terms"
+                            ",coin_pub"
+                            " FROM deposits"
+                            "    JOIN known_coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            " WHERE"
+                            " merchant_pub=$1 AND"
+                            " h_wire=$2 AND"
+                            " done=false"
+                            " ORDER BY wire_deadline ASC"
+                            " LIMIT " 
TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT_STR ";",
+                            2),
+    /* Used in #postgres_mark_deposit_tiny() */
+    GNUNET_PQ_make_prepare ("mark_deposit_tiny",
+                            "UPDATE deposits"
+                            " SET tiny=true"
+                            " WHERE deposit_serial_id=$1",
+                            1),
+    /* Used in #postgres_mark_deposit_done() */
+    GNUNET_PQ_make_prepare ("mark_deposit_done",
+                            "UPDATE deposits"
+                            " SET done=true"
+                            " WHERE deposit_serial_id=$1;",
+                            1),
+    /* Used in #postgres_test_deposit_done() */
+    GNUNET_PQ_make_prepare ("test_deposit_done",
+                            "SELECT done"
+                            " FROM deposits"
+                            " WHERE coin_pub=$1"
+                            "   AND merchant_pub=$2"
+                            "   AND h_contract_terms=$3"
+                            "   AND h_wire=$4;",
+                            5),
+    /* Used in #postgres_get_coin_transactions() to obtain information
+       about how a coin has been spend with /deposit requests. */
+    GNUNET_PQ_make_prepare ("get_deposit_with_coin_pub",
+                            "SELECT"
+                            " amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_deposit_val"
+                            ",denom.fee_deposit_frac"
+                            ",denom.fee_deposit_curr"
+                            ",timestamp"
+                            ",refund_deadline"
+                            ",merchant_pub"
+                            ",h_contract_terms"
+                            ",h_wire"
+                            ",wire"
+                            ",coin_sig"
+                            " FROM deposits"
+                            "    JOIN known_coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            " WHERE coin_pub=$1;",
+                            1),
+    /* Used in #postgres_insert_refresh_out() to store the
+       generated signature(s) for future requests, i.e. /refresh/link */
+    GNUNET_PQ_make_prepare ("insert_refresh_out",
+                            "INSERT INTO refresh_out "
+                            "(session_hash"
+                            ",newcoin_index"
+                            ",ev_sig"
+                            ") VALUES "
+                            "($1, $2, $3);",
+                            3),
+    /* Used in #postgres_get_refresh_out() to test if the
+       generated signature(s) already exists */
+    GNUNET_PQ_make_prepare ("get_refresh_out",
+                            "SELECT ev_sig"
+                            " FROM refresh_out"
+                            " WHERE session_hash=$1"
+                            " AND newcoin_index=$2;",
+                            2),
+    /* Used in #postgres_get_link_data_list().  We use the session_hash
+       to obtain the "noreveal_index" for that session, and then select the
+       corresponding signatures (ev_sig) and the denomination keys from
+       the respective tables (namely refresh_melts and refresh_order)
+       using the session_hash as the primary filter (on join) and the
+       'noreveal_index' to constrain the selection on the commitment.
+       We also want to get the triplet for each of the newcoins, so we
+       have another constraint to ensure we get each triplet with
+       matching "newcoin_index" values.  NOTE: This may return many
+       results, both for different sessions and for the different coins
+       being exchangeed in the refresh ops.  NOTE: There may be more
+       efficient ways to express the same query.  */
+    GNUNET_PQ_make_prepare ("get_link",
+                            "SELECT "
+                            " ev_sig"
+                            ",denoms.denom_pub"
+                            " FROM refresh_sessions"
+                            "     JOIN refresh_order ro"
+                            "       USING (session_hash)"
+                            "     JOIN refresh_commit_coin rcc"
+                            "       USING (session_hash)"
+                            "     JOIN refresh_out rc"
+                            "       USING (session_hash)"
+                            "     JOIN denominations denoms"
+                            "       ON (ro.denom_pub_hash = 
denoms.denom_pub_hash)"
+                            " WHERE ro.session_hash=$1"
+                            "  AND ro.newcoin_index=rcc.newcoin_index"
+                            "  AND ro.newcoin_index=rc.newcoin_index;",
+                            1),
+    /* Used in #postgres_get_transfer().  Given the public key of a
+       melted coin, we obtain the corresponding encrypted link secret
+       and the transfer public key.  This is done by first finding
+       the session_hash(es) of all sessions the coin was melted into,
+       and then constraining the result to the selected "noreveal_index".
+       NOTE: This may (in theory) return multiple results, one per session
+       that the old coin was melted into. */
+    GNUNET_PQ_make_prepare ("get_transfer",
+                            "SELECT transfer_pub,session_hash"
+                            " FROM refresh_sessions rs"
+                            "     JOIN refresh_transfer_public_key rcl"
+                            "       USING (session_hash)"
+                            " WHERE rs.old_coin_pub=$1;",
+                            1),
+    /* Used in #postgres_lookup_wire_transfer */
+    GNUNET_PQ_make_prepare ("lookup_transactions",
+                            "SELECT"
+                            " aggregation_serial_id"
+                            ",deposits.h_contract_terms"
+                            ",deposits.wire"
+                            ",deposits.h_wire"
+                            ",deposits.coin_pub"
+                            ",deposits.merchant_pub"
+                            ",wire_out.execution_date"
+                            ",deposits.amount_with_fee_val"
+                            ",deposits.amount_with_fee_frac"
+                            ",deposits.amount_with_fee_curr"
+                            ",denom.fee_deposit_val"
+                            ",denom.fee_deposit_frac"
+                            ",denom.fee_deposit_curr"
+                            " FROM aggregation_tracking"
+                            "    JOIN deposits"
+                            "      USING (deposit_serial_id)"
+                            "    JOIN known_coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            "    JOIN wire_out"
+                            "      USING (wtid_raw)"
+                            " WHERE wtid_raw=$1;",
+                            1),
+    /* Used in #postgres_wire_lookup_deposit_wtid */
+    GNUNET_PQ_make_prepare ("lookup_deposit_wtid",
+                            "SELECT"
+                            " aggregation_tracking.wtid_raw"
+                            ",wire_out.execution_date"
+                            ",amount_with_fee_val"
+                            ",amount_with_fee_frac"
+                            ",amount_with_fee_curr"
+                            ",denom.fee_deposit_val"
+                            ",denom.fee_deposit_frac"
+                            ",denom.fee_deposit_curr"
+                            " FROM deposits"
+                            "    JOIN aggregation_tracking"
+                            "      USING (deposit_serial_id)"
+                            "    JOIN known_coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denom"
+                            "      USING (denom_pub_hash)"
+                            "    JOIN wire_out"
+                            "      USING (wtid_raw)"
+                            " WHERE coin_pub=$1"
+                            "  AND h_contract_terms=$2"
+                            "  AND h_wire=$3"
+                            "  AND merchant_pub=$4;",
+                            4),
+    /* Used in #postgres_insert_aggregation_tracking */
+    GNUNET_PQ_make_prepare ("insert_aggregation_tracking",
+                            "INSERT INTO aggregation_tracking "
+                            "(deposit_serial_id"
+                            ",wtid_raw"
+                            ") VALUES "
+                            "($1, $2);",
+                            2),
+    /* Used in #postgres_get_wire_fee() */
+    GNUNET_PQ_make_prepare ("get_wire_fee",
+                            "SELECT "
+                            " start_date"
+                            ",end_date"
+                            ",wire_fee_val"
+                            ",wire_fee_frac"
+                            ",wire_fee_curr"
+                            ",master_sig"
+                            " FROM wire_fee"
+                            " WHERE wire_method=$1"
+                            "   AND start_date <= $2"
+                            "   AND end_date > $2;",
+                            2),
+    /* Used in #postgres_insert_wire_fee */
+    GNUNET_PQ_make_prepare ("insert_wire_fee",
+                            "INSERT INTO wire_fee "
+                            "(wire_method"
+                            ",start_date"
+                            ",end_date"
+                            ",wire_fee_val"
+                            ",wire_fee_frac"
+                            ",wire_fee_curr"
+                            ",master_sig"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7);",
+                            7),
+    /* Used in #postgres_store_wire_transfer_out */
+    GNUNET_PQ_make_prepare ("insert_wire_out",
+                            "INSERT INTO wire_out "
+                            "(execution_date"
+                            ",wtid_raw"
+                            ",wire_target"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6);",
+                            6),
+    /* Used in #postgres_wire_prepare_data_insert() to store
+       wire transfer information before actually committing it with the bank */
+    GNUNET_PQ_make_prepare ("wire_prepare_data_insert",
+                            "INSERT INTO prewire "
+                            "(type"
+                            ",buf"
+                            ") VALUES "
+                            "($1, $2);",
+                            2),
+    /* Used in #postgres_wire_prepare_data_mark_finished() */
+    GNUNET_PQ_make_prepare ("wire_prepare_data_mark_done",
+                            "UPDATE prewire"
+                            " SET finished=true"
+                            " WHERE prewire_uuid=$1;",
+                            1),
+    /* Used in #postgres_wire_prepare_data_get() */
+    GNUNET_PQ_make_prepare ("wire_prepare_data_get",
+                            "SELECT"
+                            " prewire_uuid"
+                            ",type"
+                            ",buf"
+                            " FROM prewire"
+                            " WHERE finished=false"
+                            " ORDER BY prewire_uuid ASC"
+                            " LIMIT 1;",
+                            0),
+    /* Used in #postgres_gc() */
+    GNUNET_PQ_make_prepare ("gc_prewire",
+                            "DELETE"
+                            " FROM prewire"
+                            " WHERE finished=true;",
+                            0),
+    /* Used in #postgres_select_wire_out_above_serial_id() */
+    GNUNET_PQ_make_prepare ("audit_get_wire_incr",
+                            "SELECT"
+                            " wireout_uuid"
+                            ",execution_date"
+                            ",wtid_raw"
+                            ",wire_target"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            " FROM wire_out"
+                            " WHERE wireout_uuid>=$1"
+                            " ORDER BY wireout_uuid ASC;",
+                            1),
+    /* Used in #postgres_insert_payback_request() to store payback
+       information */
+    GNUNET_PQ_make_prepare ("payback_insert",
+                            "INSERT INTO payback "
+                            "(reserve_pub"
+                            ",coin_pub"
+                            ",coin_sig"
+                            ",coin_blind"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",timestamp"
+                            ",h_blind_ev"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
+                            9),
+    /* Used in #postgres_select_payback_above_serial_id() to obtain payback 
transactions */
+    GNUNET_PQ_make_prepare ("payback_get_incr",
+                            "SELECT"
+                            " payback_uuid"
+                            ",timestamp"
+                            ",reserve_pub"
+                            ",coin_pub"
+                            ",coin_sig"
+                            ",coin_blind"
+                            ",h_blind_ev"
+                            ",denoms.denom_pub"
+                            ",coins.denom_sig"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            " FROM payback"
+                            "    JOIN known_coins coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denoms"
+                            "      USING (denom_pub_hash)"
+                            " WHERE payback_uuid>=$1"
+                            " ORDER BY payback_uuid ASC;",
+                            1),
     /* Used in #postgres_select_reserve_closed_above_serial_id() to
        obtain information about closed reserves */
-  PREPARE ("reserves_close_get_incr",
-           "SELECT"
-           " close_uuid"
-           ",reserve_pub"
-           ",execution_date"
-           ",wtid"
-           ",receiver_account"
-           ",amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           ",closing_fee_val"
-           ",closing_fee_frac"
-           ",closing_fee_curr"
-           " FROM reserves_close"
-           " WHERE close_uuid>=$1"
-           " ORDER BY close_uuid ASC",
-           1, NULL);
-
-  /* Used in #postgres_get_reserve_history() to obtain payback transactions
-     for a reserve */
-  PREPARE ("payback_by_reserve",
-           "SELECT"
-           " coin_pub"
-           ",coin_sig"
-           ",coin_blind"
-           ",amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           ",timestamp"
-           ",denoms.denom_pub"
-           ",coins.denom_sig"
-           " FROM payback"
-           "    JOIN known_coins coins USING (coin_pub)"
-           "    JOIN denominations denoms USING (denom_pub_hash)"
-           " WHERE payback.reserve_pub=$1",
-           1, NULL);
-
-  /* Used in #postgres_get_reserve_history() */
-  PREPARE ("close_by_reserve",
-           "SELECT"
-           " amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           ",closing_fee_val"
-           ",closing_fee_frac"
-           ",closing_fee_curr"
-          ",execution_date"
-          ",receiver_account"
-          ",wtid"
-           " FROM reserves_close"
-           " WHERE reserve_pub=$1;",
-           1, NULL);
-
-  /* Used in #postgres_get_expired_reserves() */
-  PREPARE ("get_expired_reserves",
-           "SELECT"
-          " expiration_date"
-          ",account_details"
-          ",reserve_pub"
-           ",current_balance_val"
-           ",current_balance_frac"
-           ",current_balance_curr"
-           " FROM reserves"
-           " WHERE expiration_date<=$1"
-          " AND (current_balance_val != 0 "
-          "      OR current_balance_frac != 0);",
-           1, NULL);
-
-  /* Used in #postgres_get_coin_transactions() to obtain payback transactions
-     for a coin */
-  PREPARE ("payback_by_coin",
-           "SELECT"
-           " payback.reserve_pub"
-           ",coin_sig"
-           ",coin_blind"
-           ",amount_val"
-           ",amount_frac"
-           ",amount_curr"
-           ",timestamp"
-           ",denoms.denom_pub"
-           ",coins.denom_sig"
-           " FROM payback"
-           "    JOIN known_coins coins USING (coin_pub)"
-           "    JOIN denominations denoms USING (denom_pub_hash)"
-           " WHERE payback.coin_pub=$1",
-           1, NULL);
-
-  /* Used in #postgres_get_reserve_by_h_blind() */
-  PREPARE ("reserve_by_h_blind",
-           "SELECT"
-           " reserve_pub"
-           " FROM reserves_out"
-           " WHERE h_blind_ev=$1"
-           " LIMIT 1;",
-           1, NULL);
-
-  PREPARE ("gc_denominations",
-           "DELETE"
-           " FROM denominations"
-           " WHERE expire_legal < $1",
-           1, NULL);
-  PREPARE ("gc_reserves",
-           "DELETE"
-           " FROM reserves"
-           " WHERE expiration_date < $1"
-           "   AND current_balance_val = 0"
-           "   AND current_balance_frac = 0",
-           1, NULL);
+    GNUNET_PQ_make_prepare ("reserves_close_get_incr",
+                            "SELECT"
+                            " close_uuid"
+                            ",reserve_pub"
+                            ",execution_date"
+                            ",wtid"
+                            ",receiver_account"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",closing_fee_val"
+                            ",closing_fee_frac"
+                            ",closing_fee_curr"
+                            " FROM reserves_close"
+                            " WHERE close_uuid>=$1"
+                            " ORDER BY close_uuid ASC;",
+                            1),
+    /* Used in #postgres_get_reserve_history() to obtain payback transactions
+       for a reserve */
+    GNUNET_PQ_make_prepare ("payback_by_reserve",
+                            "SELECT"
+                            " coin_pub"
+                            ",coin_sig"
+                            ",coin_blind"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",timestamp"
+                            ",denoms.denom_pub"
+                            ",coins.denom_sig"
+                            " FROM payback"
+                            "    JOIN known_coins coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denoms"
+                            "      USING (denom_pub_hash)"
+                            " WHERE payback.reserve_pub=$1;",
+                            1),
+    /* Used in #postgres_get_reserve_history() */
+    GNUNET_PQ_make_prepare ("close_by_reserve",
+                            "SELECT"
+                            " amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",closing_fee_val"
+                            ",closing_fee_frac"
+                            ",closing_fee_curr"
+                            ",execution_date"
+                            ",receiver_account"
+                            ",wtid"
+                            " FROM reserves_close"
+                            " WHERE reserve_pub=$1;",
+                            1),
+    /* Used in #postgres_get_expired_reserves() */
+    GNUNET_PQ_make_prepare ("get_expired_reserves",
+                            "SELECT"
+                            " expiration_date"
+                            ",account_details"
+                            ",reserve_pub"
+                            ",current_balance_val"
+                            ",current_balance_frac"
+                            ",current_balance_curr"
+                            " FROM reserves"
+                            " WHERE expiration_date<=$1"
+                            "   AND (current_balance_val != 0 "
+                            "        OR current_balance_frac != 0);",
+                            1),
+    /* Used in #postgres_get_coin_transactions() to obtain payback transactions
+       for a coin */
+    GNUNET_PQ_make_prepare ("payback_by_coin",
+                            "SELECT"
+                            " payback.reserve_pub"
+                            ",coin_sig"
+                            ",coin_blind"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",timestamp"
+                            ",denoms.denom_pub"
+                            ",coins.denom_sig"
+                            " FROM payback"
+                            "    JOIN known_coins coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denoms"
+                            "      USING (denom_pub_hash)"
+                            " WHERE payback.coin_pub=$1;",
+                            1),
+    /* Used in #postgres_get_reserve_by_h_blind() */
+    GNUNET_PQ_make_prepare ("reserve_by_h_blind",
+                            "SELECT"
+                            " reserve_pub"
+                            " FROM reserves_out"
+                            " WHERE h_blind_ev=$1"
+                            " LIMIT 1;",
+                            1),
+    /* used in #postgres_commit */
+    GNUNET_PQ_make_prepare ("do_commit",
+                            "COMMIT",
+                            0),
+    GNUNET_PQ_make_prepare ("gc_denominations",
+                            "DELETE"
+                            " FROM denominations"
+                            " WHERE expire_legal < $1;",
+                            1),
+    GNUNET_PQ_make_prepare ("gc_reserves",
+                            "DELETE"
+                            " FROM reserves"
+                            " WHERE expiration_date < $1"
+                            "   AND current_balance_val = 0"
+                            "   AND current_balance_frac = 0;",
+                            1),
+    GNUNET_PQ_PREPARED_STATEMENT_END
+  };
 
-  return GNUNET_OK;
-#undef PREPARE
+  return GNUNET_PQ_prepare_statements (db_conn,
+                                       ps);
 }
 
 
@@ -1775,32 +1717,19 @@ evaluate_pq_result (struct TALER_EXCHANGEDB_Session 
*session,
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
  * @param session the database connection
- * @return #GNUNET_SYSERR on hard error,
- *         #GNUNET_NO if commit failed but retry may work,
- *         #GNUNET_OK on success
+ * @return final transaction status
  */
-static int
+static enum GNUNET_DB_QueryStatus
 postgres_commit (void *cls,
                  struct TALER_EXCHANGEDB_Session *session)
 {
-  PGresult *result;
-  int ret;
-  int state;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_end
+  };
 
-  state = session->state;
-  if (GNUNET_OK != state)
-  {
-    postgres_rollback (cls,
-                       session);
-    return state;
-  }
-  result = PQexec (session->conn,
-                   "COMMIT");
-  ret = evaluate_pq_result (session,
-                            result);
-  GNUNET_break (GNUNET_SYSERR != ret);
-  PQclear (result);
-  return ret;
+  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+                                             "do_commit",
+                                             params);
 }
 
 
@@ -2287,8 +2216,9 @@ postgres_reserves_in_insert (void *cls,
                          &updated_reserve))
       goto rollback;
   }
-  if (GNUNET_OK != postgres_commit (cls,
-                                    session))
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
+      postgres_commit (cls,
+                       session))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Failed to commit transaction adding amount to reserve\n");
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 232b58c..98a095b 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -1337,7 +1337,7 @@ test_wire_out (struct TALER_EXCHANGEDB_Session *session,
                                            wire_out_account,
                                            &wire_out_amount));
   /* And now the commit should still succeed! */
-  FAILIF (GNUNET_OK !=
+  FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->commit (plugin->cls,
                           session));
 
@@ -1828,7 +1828,7 @@ run (void *cls)
           plugin->mark_deposit_done (plugin->cls,
                                      session,
                                      deposit_rowid));
-  FAILIF (GNUNET_OK !=
+  FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->commit (plugin->cls,
                           session));
   FAILIF (GNUNET_YES !=
@@ -1873,7 +1873,7 @@ run (void *cls)
                                                   session,
                                                   &dkp_pub_hash,
                                                   &master_sig));
-  FAILIF (GNUNET_OK !=
+  FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
           plugin->commit (plugin->cls,
                           session));
   FAILIF (GNUNET_OK !=
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 5539d52..810b66f 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -24,6 +24,7 @@
 
 #include <jansson.h>
 #include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_db_lib.h>
 #include "taler_exchangedb_lib.h"
 
 
@@ -1109,7 +1110,7 @@ struct TALER_EXCHANGEDB_Plugin
    * @return #GNUNET_OK on success, #GNUNET_NO if the transaction
    *         can be retried, #GNUNET_SYSERR on hard failures
    */
-  int
+  enum GNUNET_DB_QueryStatus
   (*commit) (void *cls,
              struct TALER_EXCHANGEDB_Session *session);
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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