gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: clean up exchange DB logic a bit


From: gnunet
Subject: [taler-exchange] branch master updated: clean up exchange DB logic a bit, add missing function
Date: Wed, 02 Nov 2022 12:17:09 +0100

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 821c87cc clean up exchange DB logic a bit, add missing function
821c87cc is described below

commit 821c87ccbddbb7b0d0896f350de0a671f210ae40
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Nov 2 12:17:05 2022 +0100

    clean up exchange DB logic a bit, add missing function
---
 src/auditordb/Makefile.am                          |   12 +-
 src/{exchangedb => auditordb}/pg_template.c        |    2 +-
 src/{exchangedb => auditordb}/pg_template.h        |    4 +-
 src/auditordb/pg_template.sh                       |   21 +
 src/auditordb/plugin_auditordb_postgres.c          |   26 +
 src/exchangedb/Makefile.am                         |   14 +-
 .../pg_select_account_merges_above_serial_id.c     |  194 ++++
 ... => pg_select_account_merges_above_serial_id.h} |   25 +-
 ...pg_select_all_purse_decisions_above_serial_id.c |  137 +++
 ...g_select_all_purse_decisions_above_serial_id.h} |   26 +-
 src/exchangedb/pg_select_purse.c                   |   83 ++
 src/exchangedb/pg_select_purse.h                   |   54 ++
 .../pg_select_purse_deposits_above_serial_id.c     |  204 ++++
 ... => pg_select_purse_deposits_above_serial_id.h} |   26 +-
 .../pg_select_purse_merges_above_serial_id.c       |  192 ++++
 ....h => pg_select_purse_merges_above_serial_id.h} |   25 +-
 .../pg_select_purse_requests_above_serial_id.c     |  179 ++++
 ... => pg_select_purse_requests_above_serial_id.h} |   26 +-
 src/exchangedb/pg_template.c                       |    2 +-
 src/exchangedb/pg_template.h                       |    2 +-
 src/exchangedb/pg_template.sh                      |   15 +-
 src/exchangedb/plugin_exchangedb_postgres.c        | 1013 +++-----------------
 22 files changed, 1377 insertions(+), 905 deletions(-)

diff --git a/src/auditordb/Makefile.am b/src/auditordb/Makefile.am
index 7ca168d0..d00c4fb2 100644
--- a/src/auditordb/Makefile.am
+++ b/src/auditordb/Makefile.am
@@ -23,7 +23,9 @@ EXTRA_DIST = \
   auditordb-postgres.conf \
   test-auditor-db-postgres.conf \
   $(sql_DATA) \
-  9999.sql
+  9999.sql \
+  pg_template.h pg_template.c \
+  pg_template.sh
 
 plugindir = $(libdir)/taler
 
@@ -83,6 +85,14 @@ libtaler_plugin_auditordb_postgres_la_SOURCES = \
   pg_delete_exchange.h pg_delete_exchange.c \
   pg_insert_exchange_signkey.h pg_insert_exchange_signkey.c \
   pg_insert_deposit_confirmation.h pg_insert_deposit_confirmation.c \
+  pg_get_purse_info.h pg_get_purse_info.c \
+  pg_delete_purse_info.h pg_delete_purse_info.c \
+  pg_update_purse_info.h pg_update_purse_info.c \
+  pg_insert_purse_info.h pg_insert_purse_info.c \
+  pg_get_purse_summary.h pg_get_purse_summary.c \
+  pg_select_purse_expired.h pg_select_purse_expired.c \
+  pg_insert_purse_summary.h pg_insert_purse_summary.c \
+  pg_update_purse_summary.h pg_update_purse_summary.c \
   pg_get_deposit_confirmations.h pg_get_deposit_confirmations.c
 libtaler_plugin_auditordb_postgres_la_LIBADD = \
   $(LTLIBINTL)
diff --git a/src/exchangedb/pg_template.c b/src/auditordb/pg_template.c
similarity index 96%
copy from src/exchangedb/pg_template.c
copy to src/auditordb/pg_template.c
index 44878794..3e9cb642 100644
--- a/src/exchangedb/pg_template.c
+++ b/src/auditordb/pg_template.c
@@ -14,7 +14,7 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.c
+ * @file auditordb/pg_template.c
  * @brief Implementation of the template function for Postgres
  * @author Christian Grothoff
  */
diff --git a/src/exchangedb/pg_template.h b/src/auditordb/pg_template.h
similarity index 92%
copy from src/exchangedb/pg_template.h
copy to src/auditordb/pg_template.h
index fe4bdd04..acada605 100644
--- a/src/exchangedb/pg_template.h
+++ b/src/auditordb/pg_template.h
@@ -14,7 +14,7 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.h
+ * @file auditordb/pg_template.h
  * @brief implementation of the template function for Postgres
  * @author Christian Grothoff
  */
@@ -23,7 +23,7 @@
 
 #include "taler_util.h"
 #include "taler_json_lib.h"
-#include "taler_exchangedb_plugin.h"
+#include "taler_auditordb_plugin.h"
 
 
 #endif
diff --git a/src/auditordb/pg_template.sh b/src/auditordb/pg_template.sh
new file mode 100755
index 00000000..73bd7e98
--- /dev/null
+++ b/src/auditordb/pg_template.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+# This file is in the public domain.
+#
+# Instantiates pg_template for a particular function.
+
+for n in $*
+do
+    NCAPS=`echo $n | tr a-z A-Z`
+    if test ! -e pg_$n.c
+    then
+        cat pg_template.c | sed -e s/template/$n/g -e s/TEMPLATE/$NCAPS/g > 
pg_$n.c
+        cat pg_template.h | sed -e s/template/$n/g -e s/TEMPLATE/$NCAPS/g > 
pg_$n.h
+        echo "  plugin->$n\n    = &TEH_PG_$n;" >> tmpl.c
+        echo "#include \"pg_$n.h\"" >> tmpl.inc
+        echo "  pg_$n.h pg_$n.c \\" >> tmpl.am
+    fi
+done
+
+echo "Add lines from tmpl.am to Makefile.am"
+echo "Add lines from tmpl.inc to plugin_exchangedb_postgres.c at the beginning"
+echo "Add lines from tmpl.c to plugin_exchangedb_postgres.c at the end"
diff --git a/src/auditordb/plugin_auditordb_postgres.c 
b/src/auditordb/plugin_auditordb_postgres.c
index 2a6f200c..64c7b503 100644
--- a/src/auditordb/plugin_auditordb_postgres.c
+++ b/src/auditordb/plugin_auditordb_postgres.c
@@ -87,6 +87,14 @@
 #include "pg_get_wire_auditor_progress.h"
 #include "pg_insert_historic_reserve_revenue.h"
 #include "pg_helper.h"
+#include "pg_get_purse_info.h"
+#include "pg_delete_purse_info.h"
+#include "pg_update_purse_info.h"
+#include "pg_insert_purse_info.h"
+#include "pg_get_purse_summary.h"
+#include "pg_select_purse_expired.h"
+#include "pg_insert_purse_summary.h"
+#include "pg_update_purse_summary.h"
 
 #define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \
                                        __VA_ARGS__)
@@ -508,6 +516,24 @@ libtaler_plugin_auditordb_postgres_init (void *cls)
     = &TAH_PG_update_predicted_result;
   plugin->insert_predicted_result
     = &TAH_PG_insert_predicted_result;
+  plugin->get_purse_info
+    = &TEH_PG_get_purse_info;
+
+  plugin->delete_purse_info
+    = &TEH_PG_delete_purse_info;
+  plugin->update_purse_info
+    = &TEH_PG_update_purse_info;
+  plugin->insert_purse_info
+    = &TEH_PG_insert_purse_info;
+  plugin->get_purse_summary
+    = &TEH_PG_get_purse_summary;
+
+  plugin->select_purse_expired
+    = &TEH_PG_select_purse_expired;
+  plugin->insert_purse_summary
+    = &TEH_PG_insert_purse_summary;
+  plugin->update_purse_summary
+    = &TEH_PG_update_purse_summary;
 
   return plugin;
 }
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index 39bf4b7d..0dd83c4b 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -55,7 +55,9 @@ EXTRA_DIST = \
   bench-db-postgres.conf \
   test-exchange-db-postgres.conf \
   $(sqlinputs) \
-  $(sql_DATA)
+  $(sql_DATA) \
+  pg_template.h pg_template.c \
+  pg_template.sh
 
 plugindir = $(libdir)/taler
 
@@ -81,6 +83,12 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
   pg_lookup_serial_by_table.c pg_lookup_serial_by_table.h \
   pg_select_reserve_close_info.c pg_select_reserve_close_info.h \
   pg_select_reserve_closed_above_serial_id.c 
pg_select_reserve_closed_above_serial_id.h \
+  pg_select_purse.h pg_select_purse.c \
+  pg_select_purse_requests_above_serial_id.h 
pg_select_purse_requests_above_serial_id.c \
+  pg_select_purse_merges_above_serial_id.h 
pg_select_purse_merges_above_serial_id.c \
+  pg_select_purse_deposits_above_serial_id.h 
pg_select_purse_deposits_above_serial_id.c \
+  pg_select_account_merges_above_serial_id.h 
pg_select_account_merges_above_serial_id.c \
+  pg_select_all_purse_decisions_above_serial_id.h 
pg_select_all_purse_decisions_above_serial_id.c \
   pg_select_reserve_open_above_serial_id.c 
pg_select_reserve_open_above_serial_id.h
 libtaler_plugin_exchangedb_postgres_la_LIBADD = \
   $(LTLIBINTL)
@@ -146,7 +154,3 @@ bench_db_postgres_LDADD = \
 
 EXTRA_test_exchangedb_postgres_DEPENDENCIES = \
   libtaler_plugin_exchangedb_postgres.la
-
-EXTRA_DIST = \
-  pg_template.h pg_template.c \
-  pg_template.sh
diff --git a/src/exchangedb/pg_select_account_merges_above_serial_id.c 
b/src/exchangedb/pg_select_account_merges_above_serial_id.c
new file mode 100644
index 00000000..95c2f93a
--- /dev/null
+++ b/src/exchangedb/pg_select_account_merges_above_serial_id.c
@@ -0,0 +1,194 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file pg_select_account_merges_above_serial_id.c
+ * @brief Implementation of the select_account_merges_above_serial_id function 
for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_select_account_merges_above_serial_id.h"
+#include "pg_helper.h"
+
+
+/**
+ * Closure for #account_merge_serial_helper_cb().
+ */
+struct AccountMergeSerialContext
+{
+
+  /**
+   * Callback to call.
+   */
+  TALER_EXCHANGEDB_AccountMergeCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Plugin context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Status code, set to #GNUNET_SYSERR on hard errors.
+   */
+  enum GNUNET_GenericReturnValue status;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct AccountMergeSerialContext`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+account_merge_serial_helper_cb (void *cls,
+                                PGresult *result,
+                                unsigned int num_results)
+{
+  struct AccountMergeSerialContext *dsc = cls;
+  struct PostgresClosure *pg = dsc->pg;
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct TALER_PurseContractPublicKeyP purse_pub;
+    struct TALER_PrivateContractHashP h_contract_terms;
+    struct GNUNET_TIME_Timestamp purse_expiration;
+    struct TALER_Amount amount;
+    uint32_t min_age;
+    uint32_t flags32;
+    enum TALER_WalletAccountMergeFlags flags;
+    struct TALER_Amount purse_fee;
+    struct GNUNET_TIME_Timestamp merge_timestamp;
+    struct TALER_ReserveSignatureP reserve_sig;
+    uint64_t rowid;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                   &amount),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
+                                   &purse_fee),
+      GNUNET_PQ_result_spec_uint32 ("flags",
+                                    &flags32),
+      GNUNET_PQ_result_spec_uint32 ("age_limit",
+                                    &min_age),
+      GNUNET_PQ_result_spec_timestamp ("purse_expiration",
+                                       &purse_expiration),
+      GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
+                                       &merge_timestamp),
+      GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+                                            &h_contract_terms),
+      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
+                                            &purse_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
+                                            &reserve_sig),
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                            &reserve_pub),
+      GNUNET_PQ_result_spec_uint64 ("account_merge_request_serial_id",
+                                    &rowid),
+      GNUNET_PQ_result_spec_end
+    };
+    enum GNUNET_GenericReturnValue ret;
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      dsc->status = GNUNET_SYSERR;
+      return;
+    }
+    flags = (enum TALER_WalletAccountMergeFlags) flags32;
+    ret = dsc->cb (dsc->cb_cls,
+                   rowid,
+                   &reserve_pub,
+                   &purse_pub,
+                   &h_contract_terms,
+                   purse_expiration,
+                   &amount,
+                   min_age,
+                   flags,
+                   &purse_fee,
+                   merge_timestamp,
+                   &reserve_sig);
+    GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
+  }
+}
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_account_merges_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_AccountMergeCallback cb,
+  void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct AccountMergeSerialContext dsc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .pg = pg,
+    .status = GNUNET_OK
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  PREPARE (pg,
+           "audit_get_account_merge_incr",
+           "SELECT"
+           " am.account_merge_request_serial_id"
+           ",am.reserve_pub"
+           ",am.purse_pub"
+           ",pr.h_contract_terms"
+           ",pr.purse_expiration"
+           ",pr.amount_with_fee_val"
+           ",pr.amount_with_fee_frac"
+           ",pr.age_limit"
+           ",pr.flags"
+           ",pr.purse_fee_val"
+           ",pr.purse_fee_frac"
+           ",pm.merge_timestamp"
+           ",am.reserve_sig"
+           " FROM account_merges am"
+           " JOIN purse_requests pr USING (purse_pub)"
+           " JOIN purse_merges pm USING (purse_pub)"
+           " WHERE ("
+           "  (account_merge_request_serial_id>=$1)"
+           " )"
+           " ORDER BY account_merge_request_serial_id ASC;");
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             "audit_get_account_merge_incr",
+                                             params,
+                                             &account_merge_serial_helper_cb,
+                                             &dsc);
+  if (GNUNET_OK != dsc.status)
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  return qs;
+}
diff --git a/src/exchangedb/pg_template.h 
b/src/exchangedb/pg_select_account_merges_above_serial_id.h
similarity index 53%
copy from src/exchangedb/pg_template.h
copy to src/exchangedb/pg_select_account_merges_above_serial_id.h
index fe4bdd04..be3bd712 100644
--- a/src/exchangedb/pg_template.h
+++ b/src/exchangedb/pg_select_account_merges_above_serial_id.h
@@ -14,16 +14,33 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.h
- * @brief implementation of the template function for Postgres
+ * @file pg_select_account_merges_above_serial_id.h
+ * @brief implementation of the select_account_merges_above_serial_id function 
for Postgres
  * @author Christian Grothoff
  */
-#ifndef PG_TEMPLATE_H
-#define PG_TEMPLATE_H
+#ifndef PG_SELECT_ACCOUNT_MERGES_ABOVE_SERIAL_ID_H
+#define PG_SELECT_ACCOUNT_MERGES_ABOVE_SERIAL_ID_H
 
 #include "taler_util.h"
 #include "taler_json_lib.h"
 #include "taler_exchangedb_plugin.h"
 
 
+/**
+ * Select account merges above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_account_merges_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_AccountMergeCallback cb,
+  void *cb_cls);
+
 #endif
diff --git a/src/exchangedb/pg_select_all_purse_decisions_above_serial_id.c 
b/src/exchangedb/pg_select_all_purse_decisions_above_serial_id.c
new file mode 100644
index 00000000..4fd04328
--- /dev/null
+++ b/src/exchangedb/pg_select_all_purse_decisions_above_serial_id.c
@@ -0,0 +1,137 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file pg_select_all_purse_decisions_above_serial_id.c
+ * @brief Implementation of the select_all_purse_decisions_above_serial_id 
function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_select_all_purse_decisions_above_serial_id.h"
+#include "pg_helper.h"
+
+
+/**
+ * Closure for #all_purse_decision_serial_helper_cb().
+ */
+struct AllPurseDecisionSerialContext
+{
+
+  /**
+   * Callback to call.
+   */
+  TALER_EXCHANGEDB_AllPurseDecisionCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Plugin context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Status code, set to #GNUNET_SYSERR on hard errors.
+   */
+  enum GNUNET_GenericReturnValue status;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct PurseRefundSerialContext`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+all_purse_decision_serial_helper_cb (void *cls,
+                                     PGresult *result,
+                                     unsigned int num_results)
+{
+  struct AllPurseDecisionSerialContext *dsc = cls;
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    struct TALER_PurseContractPublicKeyP purse_pub;
+    bool refunded;
+    uint64_t rowid;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
+                                            &purse_pub),
+      GNUNET_PQ_result_spec_bool ("refunded",
+                                  &refunded),
+      GNUNET_PQ_result_spec_uint64 ("purse_decision_serial_id",
+                                    &rowid),
+      GNUNET_PQ_result_spec_end
+    };
+    enum GNUNET_GenericReturnValue ret;
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      dsc->status = GNUNET_SYSERR;
+      return;
+    }
+    ret = dsc->cb (dsc->cb_cls,
+                   rowid,
+                   &purse_pub,
+                   refunded);
+    GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
+  }
+}
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_all_purse_decisions_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_AllPurseDecisionCallback cb,
+  void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct AllPurseDecisionSerialContext dsc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .pg = pg,
+    .status = GNUNET_OK
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             
"audit_get_all_purse_decision_incr",
+                                             params,
+                                             &
+                                             
all_purse_decision_serial_helper_cb,
+                                             &dsc);
+  if (GNUNET_OK != dsc.status)
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  return qs;
+}
diff --git a/src/exchangedb/pg_template.h 
b/src/exchangedb/pg_select_all_purse_decisions_above_serial_id.h
similarity index 52%
copy from src/exchangedb/pg_template.h
copy to src/exchangedb/pg_select_all_purse_decisions_above_serial_id.h
index fe4bdd04..634be496 100644
--- a/src/exchangedb/pg_template.h
+++ b/src/exchangedb/pg_select_all_purse_decisions_above_serial_id.h
@@ -14,16 +14,34 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.h
- * @brief implementation of the template function for Postgres
+ * @file pg_select_all_purse_decisions_above_serial_id.h
+ * @brief implementation of the select_all_purse_decisions_above_serial_id 
function for Postgres
  * @author Christian Grothoff
  */
-#ifndef PG_TEMPLATE_H
-#define PG_TEMPLATE_H
+#ifndef PG_SELECT_ALL_PURSE_DECISIONS_ABOVE_SERIAL_ID_H
+#define PG_SELECT_ALL_PURSE_DECISIONS_ABOVE_SERIAL_ID_H
 
 #include "taler_util.h"
 #include "taler_json_lib.h"
 #include "taler_exchangedb_plugin.h"
 
 
+/**
+ * Select purse decisions above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_all_purse_decisions_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_AllPurseDecisionCallback cb,
+  void *cb_cls);
+
+
 #endif
diff --git a/src/exchangedb/pg_select_purse.c b/src/exchangedb/pg_select_purse.c
new file mode 100644
index 00000000..e2a36c33
--- /dev/null
+++ b/src/exchangedb/pg_select_purse.c
@@ -0,0 +1,83 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file pg_select_purse.c
+ * @brief Implementation of the select_purse function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_select_purse.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse (
+  void *cls,
+  const struct TALER_PurseContractPublicKeyP *purse_pub,
+  struct GNUNET_TIME_Timestamp *purse_creation,
+  struct GNUNET_TIME_Timestamp *purse_expiration,
+  struct TALER_Amount *amount,
+  struct TALER_Amount *deposited,
+  struct TALER_PrivateContractHashP *h_contract_terms,
+  struct GNUNET_TIME_Timestamp *merge_timestamp)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (purse_pub),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_timestamp ("purse_expiration",
+                                     purse_expiration),
+    GNUNET_PQ_result_spec_timestamp ("purse_creation",
+                                     purse_creation),
+    TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                 amount),
+    TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
+                                 deposited),
+    GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+                                          h_contract_terms),
+    GNUNET_PQ_result_spec_allow_null (
+      GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
+                                       merge_timestamp),
+      NULL),
+    GNUNET_PQ_result_spec_end
+  };
+
+  PREPARE (pg,
+           "select_purse",
+           "SELECT "
+           " merge_pub"
+           ",purse_creation"
+           ",purse_expiration"
+           ",h_contract_terms"
+           ",amount_with_fee_val"
+           ",amount_with_fee_frac"
+           ",balance_val"
+           ",balance_frac"
+           ",merge_timestamp"
+           " FROM purse_requests"
+           " LEFT JOIN purse_merges USING (purse_pub)"
+           " WHERE purse_pub=$1;");
+  *merge_timestamp = GNUNET_TIME_UNIT_FOREVER_TS;
+  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "select_purse",
+                                                   params,
+                                                   rs);
+}
diff --git a/src/exchangedb/pg_select_purse.h b/src/exchangedb/pg_select_purse.h
new file mode 100644
index 00000000..f522256d
--- /dev/null
+++ b/src/exchangedb/pg_select_purse.h
@@ -0,0 +1,54 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file pg_select_purse.h
+ * @brief implementation of the select_purse function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef PG_SELECT_PURSE_H
+#define PG_SELECT_PURSE_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+
+/**
+ * Function called to obtain information about a purse.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub public key of the new purse
+ * @param[out] purse_creation set to time when the purse was created
+ * @param[out] purse_expiration set to time when the purse will expire
+ * @param[out] amount set to target amount (with fees) to be put into the purse
+ * @param[out] deposited set to actual amount put into the purse so far
+ * @param[out] h_contract_terms set to hash of the contract for the purse
+ * @param[out] merge_timestamp set to time when the purse was merged, or NEVER 
if not
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse (
+  void *cls,
+  const struct TALER_PurseContractPublicKeyP *purse_pub,
+  struct GNUNET_TIME_Timestamp *purse_creation,
+  struct GNUNET_TIME_Timestamp *purse_expiration,
+  struct TALER_Amount *amount,
+  struct TALER_Amount *deposited,
+  struct TALER_PrivateContractHashP *h_contract_terms,
+  struct GNUNET_TIME_Timestamp *merge_timestamp);
+
+
+#endif
diff --git a/src/exchangedb/pg_select_purse_deposits_above_serial_id.c 
b/src/exchangedb/pg_select_purse_deposits_above_serial_id.c
new file mode 100644
index 00000000..72fdcd99
--- /dev/null
+++ b/src/exchangedb/pg_select_purse_deposits_above_serial_id.c
@@ -0,0 +1,204 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file pg_select_purse_deposits_above_serial_id.c
+ * @brief Implementation of the select_purse_deposits_above_serial_id function 
for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_select_purse_deposits_above_serial_id.h"
+#include "pg_helper.h"
+
+/**
+ * Closure for #purse_deposit_serial_helper_cb().
+ */
+struct PurseDepositSerialContext
+{
+
+  /**
+   * Callback to call.
+   */
+  TALER_EXCHANGEDB_PurseDepositCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Plugin context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Status code, set to #GNUNET_SYSERR on hard errors.
+   */
+  enum GNUNET_GenericReturnValue status;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct DepositSerialContext`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+purse_deposit_serial_helper_cb (void *cls,
+                                PGresult *result,
+                                unsigned int num_results)
+{
+  struct PurseDepositSerialContext *dsc = cls;
+  struct PostgresClosure *pg = dsc->pg;
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    struct TALER_EXCHANGEDB_PurseDeposit deposit = {
+      .exchange_base_url = NULL
+    };
+    struct TALER_DenominationPublicKey denom_pub;
+    uint64_t rowid;
+    uint32_t flags32;
+    struct TALER_ReservePublicKeyP reserve_pub;
+    bool not_merged = false;
+    struct TALER_Amount purse_balance;
+    struct TALER_Amount purse_total;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                   &deposit.amount),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
+                                   &purse_balance),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("total",
+                                   &purse_total),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee",
+                                   &deposit.deposit_fee),
+      GNUNET_PQ_result_spec_allow_null (
+        GNUNET_PQ_result_spec_string ("partner_base_url",
+                                      &deposit.exchange_base_url),
+        NULL),
+      GNUNET_PQ_result_spec_allow_null (
+        GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                              &reserve_pub),
+        &not_merged),
+      TALER_PQ_result_spec_denom_pub ("denom_pub",
+                                      &denom_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
+                                            &deposit.purse_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+                                            &deposit.coin_sig),
+      GNUNET_PQ_result_spec_uint32 ("flags",
+                                    &flags32),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                            &deposit.coin_pub),
+      GNUNET_PQ_result_spec_allow_null (
+        GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
+                                              &deposit.h_age_commitment),
+        &deposit.no_age_commitment),
+      GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
+                                    &rowid),
+      GNUNET_PQ_result_spec_end
+    };
+    enum GNUNET_GenericReturnValue ret;
+
+    memset (&deposit,
+            0,
+            sizeof (deposit));
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      dsc->status = GNUNET_SYSERR;
+      return;
+    }
+    ret = dsc->cb (dsc->cb_cls,
+                   rowid,
+                   &deposit,
+                   not_merged ? NULL : &reserve_pub,
+                   (enum TALER_WalletAccountMergeFlags) flags32,
+                   &purse_balance,
+                   &purse_total,
+                   &denom_pub);
+    GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
+  }
+}
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse_deposits_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_PurseDepositCallback cb,
+  void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct PurseDepositSerialContext dsc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .pg = pg,
+    .status = GNUNET_OK
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  PREPARE (pg,
+           "audit_get_purse_deposits_incr",
+           "SELECT"
+           " pd.amount_with_fee_val"
+           ",pd.amount_with_fee_frac"
+           ",pr.amount_with_fee_val AS total_val"
+           ",pr.amount_with_fee_frac AS total_frac"
+           ",pr.balance_val"
+           ",pr.balance_frac"
+           ",pr.flags"
+           ",pd.purse_pub"
+           ",pd.coin_sig"
+           ",partner_base_url"
+           ",denom.denom_pub"
+           ",pm.reserve_pub"
+           ",kc.coin_pub"
+           ",kc.age_commitment_hash"
+           ",pd.purse_deposit_serial_id"
+           " FROM purse_deposits pd"
+           " LEFT JOIN partners USING (partner_serial_id)"
+           " LEFT JOIN purse_merges pm USING (purse_pub)"
+           " JOIN purse_requests pr USING (purse_pub)"
+           " JOIN known_coins kc USING (coin_pub)"
+           " JOIN denominations denom USING (denominations_serial)"
+           " WHERE ("
+           "  (purse_deposit_serial_id>=$1)"
+           " )"
+           " ORDER BY purse_deposit_serial_id ASC;");
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             "audit_get_purse_deposits_incr",
+                                             params,
+                                             &purse_deposit_serial_helper_cb,
+                                             &dsc);
+  if (GNUNET_OK != dsc.status)
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  return qs;
+}
diff --git a/src/exchangedb/pg_template.h 
b/src/exchangedb/pg_select_purse_deposits_above_serial_id.h
similarity index 53%
copy from src/exchangedb/pg_template.h
copy to src/exchangedb/pg_select_purse_deposits_above_serial_id.h
index fe4bdd04..34d50b2a 100644
--- a/src/exchangedb/pg_template.h
+++ b/src/exchangedb/pg_select_purse_deposits_above_serial_id.h
@@ -14,16 +14,34 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.h
- * @brief implementation of the template function for Postgres
+ * @file pg_select_purse_deposits_above_serial_id.h
+ * @brief implementation of the select_purse_deposits_above_serial_id function 
for Postgres
  * @author Christian Grothoff
  */
-#ifndef PG_TEMPLATE_H
-#define PG_TEMPLATE_H
+#ifndef PG_SELECT_PURSE_DEPOSITS_ABOVE_SERIAL_ID_H
+#define PG_SELECT_PURSE_DEPOSITS_ABOVE_SERIAL_ID_H
 
 #include "taler_util.h"
 #include "taler_json_lib.h"
 #include "taler_exchangedb_plugin.h"
 
 
+/**
+ * Select deposits above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse_deposits_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_PurseDepositCallback cb,
+  void *cb_cls);
+
+
 #endif
diff --git a/src/exchangedb/pg_select_purse_merges_above_serial_id.c 
b/src/exchangedb/pg_select_purse_merges_above_serial_id.c
new file mode 100644
index 00000000..748a92b7
--- /dev/null
+++ b/src/exchangedb/pg_select_purse_merges_above_serial_id.c
@@ -0,0 +1,192 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file pg_select_purse_merges_above_serial_id.c
+ * @brief Implementation of the select_purse_merges_above_serial_id function 
for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_select_purse_merges_above_serial_id.h"
+#include "pg_helper.h"
+
+
+/**
+ * Closure for #purse_deposit_serial_helper_cb().
+ */
+struct PurseMergeSerialContext
+{
+
+  /**
+   * Callback to call.
+   */
+  TALER_EXCHANGEDB_PurseMergeCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Plugin context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Status code, set to #GNUNET_SYSERR on hard errors.
+   */
+  enum GNUNET_GenericReturnValue status;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct PurseMergeSerialContext`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+purse_merges_serial_helper_cb (void *cls,
+                               PGresult *result,
+                               unsigned int num_results)
+{
+  struct PurseMergeSerialContext *dsc = cls;
+  struct PostgresClosure *pg = dsc->pg;
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    uint64_t rowid;
+    char *partner_base_url = NULL;
+    struct TALER_Amount amount;
+    struct TALER_Amount balance;
+    uint32_t flags32;
+    enum TALER_WalletAccountMergeFlags flags;
+    struct TALER_PurseMergePublicKeyP merge_pub;
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct TALER_PurseMergeSignatureP merge_sig;
+    struct TALER_PurseContractPublicKeyP purse_pub;
+    struct GNUNET_TIME_Timestamp merge_timestamp;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                   &amount),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
+                                   &balance),
+      GNUNET_PQ_result_spec_allow_null (
+        GNUNET_PQ_result_spec_string ("partner_base_url",
+                                      &partner_base_url),
+        NULL),
+      GNUNET_PQ_result_spec_uint32 ("flags",
+                                    &flags32),
+      GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
+                                       &merge_timestamp),
+      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
+                                            &purse_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                            &reserve_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("merge_sig",
+                                            &merge_sig),
+      GNUNET_PQ_result_spec_auto_from_type ("merge_pub",
+                                            &merge_pub),
+      GNUNET_PQ_result_spec_uint64 ("purse_merge_request_serial_id",
+                                    &rowid),
+      GNUNET_PQ_result_spec_end
+    };
+    enum GNUNET_GenericReturnValue ret;
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      dsc->status = GNUNET_SYSERR;
+      return;
+    }
+    flags = (enum TALER_WalletAccountMergeFlags) flags32;
+    ret = dsc->cb (dsc->cb_cls,
+                   rowid,
+                   partner_base_url,
+                   &amount,
+                   &balance,
+                   flags,
+                   &merge_pub,
+                   &reserve_pub,
+                   &merge_sig,
+                   &purse_pub,
+                   merge_timestamp);
+    GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
+  }
+}
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse_merges_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_PurseMergeCallback cb,
+  void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct PurseMergeSerialContext dsc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .pg = pg,
+    .status = GNUNET_OK
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  PREPARE (pg,
+           "audit_get_purse_merge_incr",
+           "SELECT"
+           " pm.purse_merge_request_serial_id"
+           ",partner_base_url"
+           ",pr.amount_with_fee_val"
+           ",pr.amount_with_fee_frac"
+           ",pr.balance_val"
+           ",pr.balance_frac"
+           ",pr.flags"
+           ",pr.merge_pub"
+           ",pm.reserve_pub"
+           ",pm.merge_sig"
+           ",pm.purse_pub"
+           ",pm.merge_timestamp"
+           " FROM purse_merges pm"
+           " JOIN purse_requests pr USING (purse_pub)"
+           " LEFT JOIN partners USING (partner_serial_id)"
+           " WHERE ("
+           "  (purse_merge_request_serial_id>=$1)"
+           " )"
+           " ORDER BY purse_merge_request_serial_id ASC;");
+
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             "audit_get_purse_merge_incr",
+                                             params,
+                                             &purse_merges_serial_helper_cb,
+                                             &dsc);
+  if (GNUNET_OK != dsc.status)
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  return qs;
+}
diff --git a/src/exchangedb/pg_template.h 
b/src/exchangedb/pg_select_purse_merges_above_serial_id.h
similarity index 53%
copy from src/exchangedb/pg_template.h
copy to src/exchangedb/pg_select_purse_merges_above_serial_id.h
index fe4bdd04..d63db55d 100644
--- a/src/exchangedb/pg_template.h
+++ b/src/exchangedb/pg_select_purse_merges_above_serial_id.h
@@ -14,16 +14,33 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.h
- * @brief implementation of the template function for Postgres
+ * @file pg_select_purse_merges_above_serial_id.h
+ * @brief implementation of the select_purse_merges_above_serial_id function 
for Postgres
  * @author Christian Grothoff
  */
-#ifndef PG_TEMPLATE_H
-#define PG_TEMPLATE_H
+#ifndef PG_SELECT_PURSE_MERGES_ABOVE_SERIAL_ID_H
+#define PG_SELECT_PURSE_MERGES_ABOVE_SERIAL_ID_H
 
 #include "taler_util.h"
 #include "taler_json_lib.h"
 #include "taler_exchangedb_plugin.h"
 
 
+/**
+ * Select purse merges deposits above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse_merges_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_PurseMergeCallback cb,
+  void *cb_cls);
+
 #endif
diff --git a/src/exchangedb/pg_select_purse_requests_above_serial_id.c 
b/src/exchangedb/pg_select_purse_requests_above_serial_id.c
new file mode 100644
index 00000000..51f5de82
--- /dev/null
+++ b/src/exchangedb/pg_select_purse_requests_above_serial_id.c
@@ -0,0 +1,179 @@
+/*
+   This file is part of TALER
+   Copyright (C) 2022 Taler Systems SA
+
+   TALER is free software; you can redistribute it and/or modify it under the
+   terms of the GNU General Public License as published by the Free Software
+   Foundation; either version 3, or (at your option) any later version.
+
+   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along with
+   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file pg_select_purse_requests_above_serial_id.c
+ * @brief Implementation of the select_purse_requests_above_serial_id function 
for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_error_codes.h"
+#include "taler_dbevents.h"
+#include "taler_pq_lib.h"
+#include "pg_select_purse_requests_above_serial_id.h"
+#include "pg_helper.h"
+
+
+/**
+ * Closure for #purse_deposit_serial_helper_cb().
+ */
+struct PurseRequestsSerialContext
+{
+
+  /**
+   * Callback to call.
+   */
+  TALER_EXCHANGEDB_PurseRequestCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Plugin context.
+   */
+  struct PostgresClosure *pg;
+
+  /**
+   * Status code, set to #GNUNET_SYSERR on hard errors.
+   */
+  enum GNUNET_GenericReturnValue status;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct PurseRequestsSerialContext`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+purse_requests_serial_helper_cb (void *cls,
+                                 PGresult *result,
+                                 unsigned int num_results)
+{
+  struct PurseRequestsSerialContext *dsc = cls;
+  struct PostgresClosure *pg = dsc->pg;
+
+  for (unsigned int i = 0; i<num_results; i++)
+  {
+    uint64_t rowid;
+    struct TALER_Amount target_amount;
+    uint32_t age_limit;
+    struct TALER_PurseMergePublicKeyP merge_pub;
+    struct TALER_PurseContractPublicKeyP purse_pub;
+    struct TALER_PrivateContractHashP h_contract_terms;
+    struct TALER_PurseContractSignatureP purse_sig;
+    struct GNUNET_TIME_Timestamp purse_creation;
+    struct GNUNET_TIME_Timestamp purse_expiration;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                   &target_amount),
+      GNUNET_PQ_result_spec_uint32 ("age_limit",
+                                    &age_limit),
+      GNUNET_PQ_result_spec_timestamp ("purse_creation",
+                                       &purse_creation),
+      GNUNET_PQ_result_spec_timestamp ("purse_expiration",
+                                       &purse_expiration),
+      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
+                                            &purse_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+                                            &h_contract_terms),
+      GNUNET_PQ_result_spec_auto_from_type ("purse_sig",
+                                            &purse_sig),
+      GNUNET_PQ_result_spec_auto_from_type ("merge_pub",
+                                            &merge_pub),
+      GNUNET_PQ_result_spec_uint64 ("purse_requests_request_serial_id",
+                                    &rowid),
+      GNUNET_PQ_result_spec_end
+    };
+    enum GNUNET_GenericReturnValue ret;
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      dsc->status = GNUNET_SYSERR;
+      return;
+    }
+    ret = dsc->cb (dsc->cb_cls,
+                   rowid,
+                   &purse_pub,
+                   &merge_pub,
+                   purse_creation,
+                   purse_expiration,
+                   &h_contract_terms,
+                   age_limit,
+                   &target_amount,
+                   &purse_sig);
+    GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
+  }
+}
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse_requests_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_PurseRequestCallback cb,
+  void *cb_cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct PurseRequestsSerialContext dsc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .pg = pg,
+    .status = GNUNET_OK
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  PREPARE (pg,
+           "audit_get_purse_requests_incr",
+           "SELECT"
+           " purse_requests_serial_id"
+           ",purse_pub"
+           ",amount_with_fee_val"
+           ",amount_with_fee_frac"
+           ",age_limit"
+           ",h_contract_terms"
+           ",purse_creation"
+           ",purse_expiration"
+           ",merge_pub"
+           ",purse_sig"
+           " FROM purse_requests"
+           " WHERE ("
+           "  (purse_requests_serial_id>=$1)"
+           " )"
+           " ORDER BY purse_requests_serial_id ASC;");
+  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                             "audit_get_purse_requests_incr",
+                                             params,
+                                             &purse_requests_serial_helper_cb,
+                                             &dsc);
+  if (GNUNET_OK != dsc.status)
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  return qs;
+}
diff --git a/src/exchangedb/pg_template.h 
b/src/exchangedb/pg_select_purse_requests_above_serial_id.h
similarity index 53%
copy from src/exchangedb/pg_template.h
copy to src/exchangedb/pg_select_purse_requests_above_serial_id.h
index fe4bdd04..25323e3d 100644
--- a/src/exchangedb/pg_template.h
+++ b/src/exchangedb/pg_select_purse_requests_above_serial_id.h
@@ -14,16 +14,34 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.h
- * @brief implementation of the template function for Postgres
+ * @file pg_select_purse_requests_above_serial_id.h
+ * @brief implementation of the select_purse_requests_above_serial_id function 
for Postgres
  * @author Christian Grothoff
  */
-#ifndef PG_TEMPLATE_H
-#define PG_TEMPLATE_H
+#ifndef PG_SELECT_PURSE_REQUESTS_ABOVE_SERIAL_ID_H
+#define PG_SELECT_PURSE_REQUESTS_ABOVE_SERIAL_ID_H
 
 #include "taler_util.h"
 #include "taler_json_lib.h"
 #include "taler_exchangedb_plugin.h"
 
 
+/**
+ * Select purse requestss deposits above @a serial_id in monotonically 
increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_purse_requests_above_serial_id (
+  void *cls,
+  uint64_t serial_id,
+  TALER_EXCHANGEDB_PurseRequestCallback cb,
+  void *cb_cls);
+
+
 #endif
diff --git a/src/exchangedb/pg_template.c b/src/exchangedb/pg_template.c
index 44878794..095d8961 100644
--- a/src/exchangedb/pg_template.c
+++ b/src/exchangedb/pg_template.c
@@ -14,7 +14,7 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.c
+ * @file exchangedb/pg_template.c
  * @brief Implementation of the template function for Postgres
  * @author Christian Grothoff
  */
diff --git a/src/exchangedb/pg_template.h b/src/exchangedb/pg_template.h
index fe4bdd04..88bb930d 100644
--- a/src/exchangedb/pg_template.h
+++ b/src/exchangedb/pg_template.h
@@ -14,7 +14,7 @@
    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 /**
- * @file pg_template.h
+ * @file exchangedb/pg_template.h
  * @brief implementation of the template function for Postgres
  * @author Christian Grothoff
  */
diff --git a/src/exchangedb/pg_template.sh b/src/exchangedb/pg_template.sh
index 5aa8f8d4..73bd7e98 100755
--- a/src/exchangedb/pg_template.sh
+++ b/src/exchangedb/pg_template.sh
@@ -6,7 +6,16 @@
 for n in $*
 do
     NCAPS=`echo $n | tr a-z A-Z`
-    cat pg_template.c | sed -e s/template/$n/g -e s/TEMPLATE/$NCAPS/g > pg_$n.c
-    cat pg_template.h | sed -e s/template/$n/g -e s/TEMPLATE/$NCAPS/g > pg_$n.h
-    echo "\#include \"pg_$n.h\"" >> hdr.h
+    if test ! -e pg_$n.c
+    then
+        cat pg_template.c | sed -e s/template/$n/g -e s/TEMPLATE/$NCAPS/g > 
pg_$n.c
+        cat pg_template.h | sed -e s/template/$n/g -e s/TEMPLATE/$NCAPS/g > 
pg_$n.h
+        echo "  plugin->$n\n    = &TEH_PG_$n;" >> tmpl.c
+        echo "#include \"pg_$n.h\"" >> tmpl.inc
+        echo "  pg_$n.h pg_$n.c \\" >> tmpl.am
+    fi
 done
+
+echo "Add lines from tmpl.am to Makefile.am"
+echo "Add lines from tmpl.inc to plugin_exchangedb_postgres.c at the beginning"
+echo "Add lines from tmpl.c to plugin_exchangedb_postgres.c at the end"
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 9f14cc28..b6715af8 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -43,6 +43,12 @@
 #include "pg_iterate_reserve_close_info.h"
 #include "pg_lookup_records_by_table.h"
 #include "pg_lookup_serial_by_table.h"
+#include "pg_select_account_merges_above_serial_id.h"
+#include "pg_select_all_purse_decisions_above_serial_id.h"
+#include "pg_select_purse.h"
+#include "pg_select_purse_deposits_above_serial_id.h"
+#include "pg_select_purse_merges_above_serial_id.h"
+#include "pg_select_purse_requests_above_serial_id.h"
 #include "pg_select_reserve_close_info.h"
 #include "pg_select_reserve_closed_above_serial_id.h"
 #include "pg_select_reserve_open_above_serial_id.h"
@@ -1202,82 +1208,6 @@ prepare_statements (struct PostgresClosure *pg)
       "  (deposit_serial_id>=$1)"
       " )"
       " ORDER BY deposit_serial_id ASC;"),
-    /* Fetch purse deposits with rowid '\geq' the given parameter */
-    GNUNET_PQ_make_prepare (
-      "audit_get_purse_deposits_incr",
-      "SELECT"
-      " pd.amount_with_fee_val"
-      ",pd.amount_with_fee_frac"
-      ",pr.amount_with_fee_val AS total_val"
-      ",pr.amount_with_fee_frac AS total_frac"
-      ",pr.balance_val"
-      ",pr.balance_frac"
-      ",pr.flags"
-      ",pd.purse_pub"
-      ",pd.coin_sig"
-      ",partner_base_url"
-      ",denom.denom_pub"
-      ",pm.reserve_pub"
-      ",kc.coin_pub"
-      ",kc.age_commitment_hash"
-      ",pd.purse_deposit_serial_id"
-      " FROM purse_deposits pd"
-      " LEFT JOIN partners USING (partner_serial_id)"
-      " LEFT JOIN purse_merges pm USING (purse_pub)"
-      " JOIN purse_requests pr USING (purse_pub)"
-      " JOIN known_coins kc USING (coin_pub)"
-      " JOIN denominations denom USING (denominations_serial)"
-      " WHERE ("
-      "  (purse_deposit_serial_id>=$1)"
-      " )"
-      " ORDER BY purse_deposit_serial_id ASC;"),
-
-    GNUNET_PQ_make_prepare (
-      "audit_get_account_merge_incr",
-      "SELECT"
-      " am.account_merge_request_serial_id"
-      ",am.reserve_pub"
-      ",am.purse_pub"
-      ",pr.h_contract_terms"
-      ",pr.purse_expiration"
-      ",pr.amount_with_fee_val"
-      ",pr.amount_with_fee_frac"
-      ",pr.age_limit"
-      ",pr.flags"
-      ",pr.purse_fee_val"
-      ",pr.purse_fee_frac"
-      ",pm.merge_timestamp"
-      ",am.reserve_sig"
-      " FROM account_merges am"
-      " JOIN purse_requests pr USING (purse_pub)"
-      " JOIN purse_merges pm USING (purse_pub)"
-      " WHERE ("
-      "  (account_merge_request_serial_id>=$1)"
-      " )"
-      " ORDER BY account_merge_request_serial_id ASC;"),
-
-    GNUNET_PQ_make_prepare (
-      "audit_get_purse_merge_incr",
-      "SELECT"
-      " pm.purse_merge_request_serial_id"
-      ",partner_base_url"
-      ",pr.amount_with_fee_val"
-      ",pr.amount_with_fee_frac"
-      ",pr.balance_val"
-      ",pr.balance_frac"
-      ",pr.flags"
-      ",pr.merge_pub"
-      ",pm.reserve_pub"
-      ",pm.merge_sig"
-      ",pm.purse_pub"
-      ",pm.merge_timestamp"
-      " FROM purse_merges pm"
-      " JOIN purse_requests pr USING (purse_pub)"
-      " LEFT JOIN partners USING (partner_serial_id)"
-      " WHERE ("
-      "  (purse_merge_request_serial_id>=$1)"
-      " )"
-      " ORDER BY purse_merge_request_serial_id ASC;"),
 
     GNUNET_PQ_make_prepare (
       "audit_get_history_requests_incr",
@@ -2234,22 +2164,6 @@ prepare_statements (struct PostgresClosure *pg)
       "  ) VALUES "
       "  ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)"
       "  ON CONFLICT DO NOTHING;"),
-    /* Used in #postgres_select_purse */
-    GNUNET_PQ_make_prepare (
-      "select_purse",
-      "SELECT "
-      " merge_pub"
-      ",purse_creation"
-      ",purse_expiration"
-      ",h_contract_terms"
-      ",amount_with_fee_val"
-      ",amount_with_fee_frac"
-      ",balance_val"
-      ",balance_frac"
-      ",merge_timestamp"
-      " FROM purse_requests"
-      " LEFT JOIN purse_merges USING (purse_pub)"
-      " WHERE purse_pub=$1;"),
     /* Used in #postgres_get_purse_request */
     GNUNET_PQ_make_prepare (
       "get_purse_request",
@@ -7232,13 +7146,13 @@ postgres_select_deposits_above_serial_id (
 /**
  * Closure for #purse_deposit_serial_helper_cb().
  */
-struct PurseDepositSerialContext
+struct HistoryRequestSerialContext
 {
 
   /**
    * Callback to call.
    */
-  TALER_EXCHANGEDB_PurseDepositCallback cb;
+  TALER_EXCHANGEDB_HistoryRequestCallback cb;
 
   /**
    * Closure for @e cb.
@@ -7261,70 +7175,40 @@ struct PurseDepositSerialContext
  * Helper function to be called with the results of a SELECT statement
  * that has returned @a num_results results.
  *
- * @param cls closure of type `struct DepositSerialContext`
+ * @param cls closure of type `struct HistoryRequestSerialContext`
  * @param result the postgres result
  * @param num_results the number of results in @a result
  */
 static void
-purse_deposit_serial_helper_cb (void *cls,
-                                PGresult *result,
-                                unsigned int num_results)
+history_request_serial_helper_cb (void *cls,
+                                  PGresult *result,
+                                  unsigned int num_results)
 {
-  struct PurseDepositSerialContext *dsc = cls;
+  struct HistoryRequestSerialContext *dsc = cls;
   struct PostgresClosure *pg = dsc->pg;
 
   for (unsigned int i = 0; i<num_results; i++)
   {
-    struct TALER_EXCHANGEDB_PurseDeposit deposit = {
-      .exchange_base_url = NULL
-    };
-    struct TALER_DenominationPublicKey denom_pub;
     uint64_t rowid;
-    uint32_t flags32;
+    struct TALER_Amount history_fee;
+    struct GNUNET_TIME_Timestamp ts;
     struct TALER_ReservePublicKeyP reserve_pub;
-    bool not_merged = false;
-    struct TALER_Amount purse_balance;
-    struct TALER_Amount purse_total;
+    struct TALER_ReserveSignatureP reserve_sig;
     struct GNUNET_PQ_ResultSpec rs[] = {
-      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                   &deposit.amount),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
-                                   &purse_balance),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("total",
-                                   &purse_total),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee",
-                                   &deposit.deposit_fee),
-      GNUNET_PQ_result_spec_allow_null (
-        GNUNET_PQ_result_spec_string ("partner_base_url",
-                                      &deposit.exchange_base_url),
-        NULL),
-      GNUNET_PQ_result_spec_allow_null (
-        GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
-                                              &reserve_pub),
-        &not_merged),
-      TALER_PQ_result_spec_denom_pub ("denom_pub",
-                                      &denom_pub),
-      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
-                                            &deposit.purse_pub),
-      GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
-                                            &deposit.coin_sig),
-      GNUNET_PQ_result_spec_uint32 ("flags",
-                                    &flags32),
-      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
-                                            &deposit.coin_pub),
-      GNUNET_PQ_result_spec_allow_null (
-        GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
-                                              &deposit.h_age_commitment),
-        &deposit.no_age_commitment),
-      GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
+      TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
+                                   &history_fee),
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                            &reserve_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
+                                            &reserve_sig),
+      GNUNET_PQ_result_spec_uint64 ("history_request_serial_id",
                                     &rowid),
+      GNUNET_PQ_result_spec_timestamp ("request_timestamp",
+                                       &ts),
       GNUNET_PQ_result_spec_end
     };
     enum GNUNET_GenericReturnValue ret;
 
-    memset (&deposit,
-            0,
-            sizeof (deposit));
     if (GNUNET_OK !=
         GNUNET_PQ_extract_result (result,
                                   rs,
@@ -7336,12 +7220,10 @@ purse_deposit_serial_helper_cb (void *cls,
     }
     ret = dsc->cb (dsc->cb_cls,
                    rowid,
-                   &deposit,
-                   not_merged ? NULL : &reserve_pub,
-                   (enum TALER_WalletAccountMergeFlags) flags32,
-                   &purse_balance,
-                   &purse_total,
-                   &denom_pub);
+                   &history_fee,
+                   ts,
+                   &reserve_pub,
+                   &reserve_sig);
     GNUNET_PQ_cleanup_result (rs);
     if (GNUNET_OK != ret)
       break;
@@ -7350,7 +7232,7 @@ purse_deposit_serial_helper_cb (void *cls,
 
 
 /**
- * Select deposits above @a serial_id in monotonically increasing
+ * Select history requests above @a serial_id in monotonically increasing
  * order.
  *
  * @param cls closure
@@ -7360,10 +7242,10 @@ purse_deposit_serial_helper_cb (void *cls,
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
-postgres_select_purse_deposits_above_serial_id (
+postgres_select_history_requests_above_serial_id (
   void *cls,
   uint64_t serial_id,
-  TALER_EXCHANGEDB_PurseDepositCallback cb,
+  TALER_EXCHANGEDB_HistoryRequestCallback cb,
   void *cb_cls)
 {
   struct PostgresClosure *pg = cls;
@@ -7371,7 +7253,7 @@ postgres_select_purse_deposits_above_serial_id (
     GNUNET_PQ_query_param_uint64 (&serial_id),
     GNUNET_PQ_query_param_end
   };
-  struct PurseDepositSerialContext dsc = {
+  struct HistoryRequestSerialContext dsc = {
     .cb = cb,
     .cb_cls = cb_cls,
     .pg = pg,
@@ -7380,9 +7262,9 @@ postgres_select_purse_deposits_above_serial_id (
   enum GNUNET_DB_QueryStatus qs;
 
   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "audit_get_purse_deposits_incr",
+                                             "audit_get_history_requests_incr",
                                              params,
-                                             &purse_deposit_serial_helper_cb,
+                                             &history_request_serial_helper_cb,
                                              &dsc);
   if (GNUNET_OK != dsc.status)
     return GNUNET_DB_STATUS_HARD_ERROR;
@@ -7391,15 +7273,15 @@ postgres_select_purse_deposits_above_serial_id (
 
 
 /**
- * Closure for #account_merge_serial_helper_cb().
+ * Closure for #purse_decision_serial_helper_cb().
  */
-struct AccountMergeSerialContext
+struct PurseDecisionSerialContext
 {
 
   /**
    * Callback to call.
    */
-  TALER_EXCHANGEDB_AccountMergeCallback cb;
+  TALER_EXCHANGEDB_PurseDecisionCallback cb;
 
   /**
    * Closure for @e cb.
@@ -7422,54 +7304,35 @@ struct AccountMergeSerialContext
  * Helper function to be called with the results of a SELECT statement
  * that has returned @a num_results results.
  *
- * @param cls closure of type `struct AccountMergeSerialContext`
+ * @param cls closure of type `struct PurseRefundSerialContext`
  * @param result the postgres result
  * @param num_results the number of results in @a result
  */
 static void
-account_merge_serial_helper_cb (void *cls,
-                                PGresult *result,
-                                unsigned int num_results)
+purse_decision_serial_helper_cb (void *cls,
+                                 PGresult *result,
+                                 unsigned int num_results)
 {
-  struct AccountMergeSerialContext *dsc = cls;
+  struct PurseDecisionSerialContext *dsc = cls;
   struct PostgresClosure *pg = dsc->pg;
 
   for (unsigned int i = 0; i<num_results; i++)
   {
-    struct TALER_ReservePublicKeyP reserve_pub;
     struct TALER_PurseContractPublicKeyP purse_pub;
-    struct TALER_PrivateContractHashP h_contract_terms;
-    struct GNUNET_TIME_Timestamp purse_expiration;
-    struct TALER_Amount amount;
-    uint32_t min_age;
-    uint32_t flags32;
-    enum TALER_WalletAccountMergeFlags flags;
-    struct TALER_Amount purse_fee;
-    struct GNUNET_TIME_Timestamp merge_timestamp;
-    struct TALER_ReserveSignatureP reserve_sig;
+    struct TALER_ReservePublicKeyP reserve_pub;
+    bool no_reserve = true;
     uint64_t rowid;
+    struct TALER_Amount val;
     struct GNUNET_PQ_ResultSpec rs[] = {
-      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                   &amount),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
-                                   &purse_fee),
-      GNUNET_PQ_result_spec_uint32 ("flags",
-                                    &flags32),
-      GNUNET_PQ_result_spec_uint32 ("age_limit",
-                                    &min_age),
-      GNUNET_PQ_result_spec_timestamp ("purse_expiration",
-                                       &purse_expiration),
-      GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
-                                       &merge_timestamp),
-      GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
-                                            &h_contract_terms),
       GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
                                             &purse_pub),
-      GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
-                                            &reserve_sig),
-      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
-                                            &reserve_pub),
-      GNUNET_PQ_result_spec_uint64 ("account_merge_request_serial_id",
+      GNUNET_PQ_result_spec_allow_null (
+        GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                              &reserve_pub),
+        &no_reserve),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                   &val),
+      GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
                                     &rowid),
       GNUNET_PQ_result_spec_end
     };
@@ -7484,19 +7347,11 @@ account_merge_serial_helper_cb (void *cls,
       dsc->status = GNUNET_SYSERR;
       return;
     }
-    flags = (enum TALER_WalletAccountMergeFlags) flags32;
     ret = dsc->cb (dsc->cb_cls,
                    rowid,
-                   &reserve_pub,
                    &purse_pub,
-                   &h_contract_terms,
-                   purse_expiration,
-                   &amount,
-                   min_age,
-                   flags,
-                   &purse_fee,
-                   merge_timestamp,
-                   &reserve_sig);
+                   no_reserve ? NULL : &reserve_pub,
+                   &val);
     GNUNET_PQ_cleanup_result (rs);
     if (GNUNET_OK != ret)
       break;
@@ -7505,28 +7360,31 @@ account_merge_serial_helper_cb (void *cls,
 
 
 /**
- * Select account merges above @a serial_id in monotonically increasing
+ * Select purse decisions above @a serial_id in monotonically increasing
  * order.
  *
  * @param cls closure
  * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param refunded which refund status to select for
  * @param cb function to call on each result
  * @param cb_cls closure for @a cb
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
-postgres_select_account_merges_above_serial_id (
+postgres_select_purse_decisions_above_serial_id (
   void *cls,
   uint64_t serial_id,
-  TALER_EXCHANGEDB_AccountMergeCallback cb,
+  bool refunded,
+  TALER_EXCHANGEDB_PurseDecisionCallback cb,
   void *cb_cls)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_bool (refunded),
     GNUNET_PQ_query_param_end
   };
-  struct AccountMergeSerialContext dsc = {
+  struct PurseDecisionSerialContext dsc = {
     .cb = cb,
     .cb_cls = cb_cls,
     .pg = pg,
@@ -7535,9 +7393,9 @@ postgres_select_account_merges_above_serial_id (
   enum GNUNET_DB_QueryStatus qs;
 
   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "audit_get_account_merge_incr",
+                                             "audit_get_purse_decisions_incr",
                                              params,
-                                             &account_merge_serial_helper_cb,
+                                             &purse_decision_serial_helper_cb,
                                              &dsc);
   if (GNUNET_OK != dsc.status)
     return GNUNET_DB_STATUS_HARD_ERROR;
@@ -7546,15 +7404,15 @@ postgres_select_account_merges_above_serial_id (
 
 
 /**
- * Closure for #purse_deposit_serial_helper_cb().
+ * Closure for #purse_refund_coin_helper_cb().
  */
-struct PurseMergeSerialContext
+struct PurseRefundCoinContext
 {
 
   /**
    * Callback to call.
    */
-  TALER_EXCHANGEDB_PurseMergeCallback cb;
+  TALER_EXCHANGEDB_PurseRefundCoinCallback cb;
 
   /**
    * Closure for @e cb.
@@ -7577,53 +7435,32 @@ struct PurseMergeSerialContext
  * Helper function to be called with the results of a SELECT statement
  * that has returned @a num_results results.
  *
- * @param cls closure of type `struct PurseMergeSerialContext`
+ * @param cls closure of type `struct PurseRefundCoinContext`
  * @param result the postgres result
  * @param num_results the number of results in @a result
  */
 static void
-purse_merges_serial_helper_cb (void *cls,
-                               PGresult *result,
-                               unsigned int num_results)
+purse_refund_coin_helper_cb (void *cls,
+                             PGresult *result,
+                             unsigned int num_results)
 {
-  struct PurseMergeSerialContext *dsc = cls;
+  struct PurseRefundCoinContext *dsc = cls;
   struct PostgresClosure *pg = dsc->pg;
 
   for (unsigned int i = 0; i<num_results; i++)
   {
+    struct TALER_Amount amount_with_fee;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_DenominationPublicKey denom_pub;
     uint64_t rowid;
-    char *partner_base_url = NULL;
-    struct TALER_Amount amount;
-    struct TALER_Amount balance;
-    uint32_t flags32;
-    enum TALER_WalletAccountMergeFlags flags;
-    struct TALER_PurseMergePublicKeyP merge_pub;
-    struct TALER_ReservePublicKeyP reserve_pub;
-    struct TALER_PurseMergeSignatureP merge_sig;
-    struct TALER_PurseContractPublicKeyP purse_pub;
-    struct GNUNET_TIME_Timestamp merge_timestamp;
     struct GNUNET_PQ_ResultSpec rs[] = {
+      TALER_PQ_result_spec_denom_pub ("denom_pub",
+                                      &denom_pub),
       TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                   &amount),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
-                                   &balance),
-      GNUNET_PQ_result_spec_allow_null (
-        GNUNET_PQ_result_spec_string ("partner_base_url",
-                                      &partner_base_url),
-        NULL),
-      GNUNET_PQ_result_spec_uint32 ("flags",
-                                    &flags32),
-      GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
-                                       &merge_timestamp),
-      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
-                                            &purse_pub),
-      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
-                                            &reserve_pub),
-      GNUNET_PQ_result_spec_auto_from_type ("merge_sig",
-                                            &merge_sig),
-      GNUNET_PQ_result_spec_auto_from_type ("merge_pub",
-                                            &merge_pub),
-      GNUNET_PQ_result_spec_uint64 ("purse_merge_request_serial_id",
+                                   &amount_with_fee),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                            &coin_pub),
+      GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
                                     &rowid),
       GNUNET_PQ_result_spec_end
     };
@@ -7638,18 +7475,11 @@ purse_merges_serial_helper_cb (void *cls,
       dsc->status = GNUNET_SYSERR;
       return;
     }
-    flags = (enum TALER_WalletAccountMergeFlags) flags32;
     ret = dsc->cb (dsc->cb_cls,
                    rowid,
-                   partner_base_url,
-                   &amount,
-                   &balance,
-                   flags,
-                   &merge_pub,
-                   &reserve_pub,
-                   &merge_sig,
-                   &purse_pub,
-                   merge_timestamp);
+                   &amount_with_fee,
+                   &coin_pub,
+                   &denom_pub);
     GNUNET_PQ_cleanup_result (rs);
     if (GNUNET_OK != ret)
       break;
@@ -7658,28 +7488,27 @@ purse_merges_serial_helper_cb (void *cls,
 
 
 /**
- * Select purse merges deposits above @a serial_id in monotonically increasing
- * order.
+ * Select coin affected by purse refund.
  *
  * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param purse_pub purse that was refunded
  * @param cb function to call on each result
  * @param cb_cls closure for @a cb
  * @return transaction status code
  */
 static enum GNUNET_DB_QueryStatus
-postgres_select_purse_merges_above_serial_id (
+postgres_select_purse_deposits_by_purse (
   void *cls,
-  uint64_t serial_id,
-  TALER_EXCHANGEDB_PurseMergeCallback cb,
+  const struct TALER_PurseContractPublicKeyP *purse_pub,
+  TALER_EXCHANGEDB_PurseRefundCoinCallback cb,
   void *cb_cls)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_auto_from_type (purse_pub),
     GNUNET_PQ_query_param_end
   };
-  struct PurseMergeSerialContext dsc = {
+  struct PurseRefundCoinContext dsc = {
     .cb = cb,
     .cb_cls = cb_cls,
     .pg = pg,
@@ -7688,9 +7517,9 @@ postgres_select_purse_merges_above_serial_id (
   enum GNUNET_DB_QueryStatus qs;
 
   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "audit_get_purse_merge_incr",
+                                             
"audit_get_purse_deposits_by_purse",
                                              params,
-                                             &purse_merges_serial_helper_cb,
+                                             &purse_refund_coin_helper_cb,
                                              &dsc);
   if (GNUNET_OK != dsc.status)
     return GNUNET_DB_STATUS_HARD_ERROR;
@@ -7699,15 +7528,15 @@ postgres_select_purse_merges_above_serial_id (
 
 
 /**
- * Closure for #purse_deposit_serial_helper_cb().
+ * Closure for #refreshs_serial_helper_cb().
  */
-struct HistoryRequestSerialContext
+struct RefreshsSerialContext
 {
 
   /**
    * Callback to call.
    */
-  TALER_EXCHANGEDB_HistoryRequestCallback cb;
+  TALER_EXCHANGEDB_RefreshesCallback cb;
 
   /**
    * Closure for @e cb.
@@ -7730,36 +7559,48 @@ struct HistoryRequestSerialContext
  * Helper function to be called with the results of a SELECT statement
  * that has returned @a num_results results.
  *
- * @param cls closure of type `struct HistoryRequestSerialContext`
+ * @param cls closure of type `struct RefreshsSerialContext`
  * @param result the postgres result
  * @param num_results the number of results in @a result
  */
 static void
-history_request_serial_helper_cb (void *cls,
-                                  PGresult *result,
-                                  unsigned int num_results)
+refreshs_serial_helper_cb (void *cls,
+                           PGresult *result,
+                           unsigned int num_results)
 {
-  struct HistoryRequestSerialContext *dsc = cls;
-  struct PostgresClosure *pg = dsc->pg;
+  struct RefreshsSerialContext *rsc = cls;
+  struct PostgresClosure *pg = rsc->pg;
 
   for (unsigned int i = 0; i<num_results; i++)
   {
+    struct TALER_DenominationPublicKey denom_pub;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_CoinSpendSignatureP coin_sig;
+    struct TALER_AgeCommitmentHash h_age_commitment;
+    bool ac_isnull;
+    struct TALER_Amount amount_with_fee;
+    uint32_t noreveal_index;
     uint64_t rowid;
-    struct TALER_Amount history_fee;
-    struct GNUNET_TIME_Timestamp ts;
-    struct TALER_ReservePublicKeyP reserve_pub;
-    struct TALER_ReserveSignatureP reserve_sig;
+    struct TALER_RefreshCommitmentP rc;
     struct GNUNET_PQ_ResultSpec rs[] = {
-      TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
-                                   &history_fee),
-      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
-                                            &reserve_pub),
-      GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
-                                            &reserve_sig),
-      GNUNET_PQ_result_spec_uint64 ("history_request_serial_id",
+      TALER_PQ_result_spec_denom_pub ("denom_pub",
+                                      &denom_pub),
+      GNUNET_PQ_result_spec_allow_null (
+        GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
+                                              &h_age_commitment),
+        &ac_isnull),
+      GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+                                            &coin_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
+                                            &coin_sig),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+                                   &amount_with_fee),
+      GNUNET_PQ_result_spec_uint32 ("noreveal_index",
+                                    &noreveal_index),
+      GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
                                     &rowid),
-      GNUNET_PQ_result_spec_timestamp ("request_timestamp",
-                                       &ts),
+      GNUNET_PQ_result_spec_auto_from_type ("rc",
+                                            &rc),
       GNUNET_PQ_result_spec_end
     };
     enum GNUNET_GenericReturnValue ret;
@@ -7770,528 +7611,11 @@ history_request_serial_helper_cb (void *cls,
                                   i))
     {
       GNUNET_break (0);
-      dsc->status = GNUNET_SYSERR;
+      rsc->status = GNUNET_SYSERR;
       return;
     }
-    ret = dsc->cb (dsc->cb_cls,
-                   rowid,
-                   &history_fee,
-                   ts,
-                   &reserve_pub,
-                   &reserve_sig);
-    GNUNET_PQ_cleanup_result (rs);
-    if (GNUNET_OK != ret)
-      break;
-  }
-}
-
-
-/**
- * Select history requests above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_history_requests_above_serial_id (
-  void *cls,
-  uint64_t serial_id,
-  TALER_EXCHANGEDB_HistoryRequestCallback cb,
-  void *cb_cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_uint64 (&serial_id),
-    GNUNET_PQ_query_param_end
-  };
-  struct HistoryRequestSerialContext dsc = {
-    .cb = cb,
-    .cb_cls = cb_cls,
-    .pg = pg,
-    .status = GNUNET_OK
-  };
-  enum GNUNET_DB_QueryStatus qs;
-
-  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "audit_get_history_requests_incr",
-                                             params,
-                                             &history_request_serial_helper_cb,
-                                             &dsc);
-  if (GNUNET_OK != dsc.status)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return qs;
-}
-
-
-/**
- * Closure for #purse_decision_serial_helper_cb().
- */
-struct PurseDecisionSerialContext
-{
-
-  /**
-   * Callback to call.
-   */
-  TALER_EXCHANGEDB_PurseDecisionCallback cb;
-
-  /**
-   * Closure for @e cb.
-   */
-  void *cb_cls;
-
-  /**
-   * Plugin context.
-   */
-  struct PostgresClosure *pg;
-
-  /**
-   * Status code, set to #GNUNET_SYSERR on hard errors.
-   */
-  enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct PurseRefundSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-purse_decision_serial_helper_cb (void *cls,
-                                 PGresult *result,
-                                 unsigned int num_results)
-{
-  struct PurseDecisionSerialContext *dsc = cls;
-  struct PostgresClosure *pg = dsc->pg;
-
-  for (unsigned int i = 0; i<num_results; i++)
-  {
-    struct TALER_PurseContractPublicKeyP purse_pub;
-    struct TALER_ReservePublicKeyP reserve_pub;
-    bool no_reserve = true;
-    uint64_t rowid;
-    struct TALER_Amount val;
-    struct GNUNET_PQ_ResultSpec rs[] = {
-      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
-                                            &purse_pub),
-      GNUNET_PQ_result_spec_allow_null (
-        GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
-                                              &reserve_pub),
-        &no_reserve),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                   &val),
-      GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
-                                    &rowid),
-      GNUNET_PQ_result_spec_end
-    };
-    enum GNUNET_GenericReturnValue ret;
-
-    if (GNUNET_OK !=
-        GNUNET_PQ_extract_result (result,
-                                  rs,
-                                  i))
-    {
-      GNUNET_break (0);
-      dsc->status = GNUNET_SYSERR;
-      return;
-    }
-    ret = dsc->cb (dsc->cb_cls,
-                   rowid,
-                   &purse_pub,
-                   no_reserve ? NULL : &reserve_pub,
-                   &val);
-    GNUNET_PQ_cleanup_result (rs);
-    if (GNUNET_OK != ret)
-      break;
-  }
-}
-
-
-/**
- * Select purse decisions above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param refunded which refund status to select for
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_decisions_above_serial_id (
-  void *cls,
-  uint64_t serial_id,
-  bool refunded,
-  TALER_EXCHANGEDB_PurseDecisionCallback cb,
-  void *cb_cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_uint64 (&serial_id),
-    GNUNET_PQ_query_param_bool (refunded),
-    GNUNET_PQ_query_param_end
-  };
-  struct PurseDecisionSerialContext dsc = {
-    .cb = cb,
-    .cb_cls = cb_cls,
-    .pg = pg,
-    .status = GNUNET_OK
-  };
-  enum GNUNET_DB_QueryStatus qs;
-
-  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "audit_get_purse_decisions_incr",
-                                             params,
-                                             &purse_decision_serial_helper_cb,
-                                             &dsc);
-  if (GNUNET_OK != dsc.status)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return qs;
-}
-
-
-/**
- * Closure for #all_purse_decision_serial_helper_cb().
- */
-struct AllPurseDecisionSerialContext
-{
-
-  /**
-   * Callback to call.
-   */
-  TALER_EXCHANGEDB_AllPurseDecisionCallback cb;
-
-  /**
-   * Closure for @e cb.
-   */
-  void *cb_cls;
-
-  /**
-   * Plugin context.
-   */
-  struct PostgresClosure *pg;
-
-  /**
-   * Status code, set to #GNUNET_SYSERR on hard errors.
-   */
-  enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct PurseRefundSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-all_purse_decision_serial_helper_cb (void *cls,
-                                     PGresult *result,
-                                     unsigned int num_results)
-{
-  struct AllPurseDecisionSerialContext *dsc = cls;
-
-  for (unsigned int i = 0; i<num_results; i++)
-  {
-    struct TALER_PurseContractPublicKeyP purse_pub;
-    bool refunded;
-    uint64_t rowid;
-    struct GNUNET_PQ_ResultSpec rs[] = {
-      GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
-                                            &purse_pub),
-      GNUNET_PQ_result_spec_bool ("refunded",
-                                  &refunded),
-      GNUNET_PQ_result_spec_uint64 ("purse_decision_serial_id",
-                                    &rowid),
-      GNUNET_PQ_result_spec_end
-    };
-    enum GNUNET_GenericReturnValue ret;
-
-    if (GNUNET_OK !=
-        GNUNET_PQ_extract_result (result,
-                                  rs,
-                                  i))
-    {
-      GNUNET_break (0);
-      dsc->status = GNUNET_SYSERR;
-      return;
-    }
-    ret = dsc->cb (dsc->cb_cls,
-                   rowid,
-                   &purse_pub,
-                   refunded);
-    GNUNET_PQ_cleanup_result (rs);
-    if (GNUNET_OK != ret)
-      break;
-  }
-}
-
-
-/**
- * Select purse decisions above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_all_purse_decisions_above_serial_id (
-  void *cls,
-  uint64_t serial_id,
-  TALER_EXCHANGEDB_AllPurseDecisionCallback cb,
-  void *cb_cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_uint64 (&serial_id),
-    GNUNET_PQ_query_param_end
-  };
-  struct AllPurseDecisionSerialContext dsc = {
-    .cb = cb,
-    .cb_cls = cb_cls,
-    .pg = pg,
-    .status = GNUNET_OK
-  };
-  enum GNUNET_DB_QueryStatus qs;
-
-  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             
"audit_get_all_purse_decision_incr",
-                                             params,
-                                             &
-                                             
all_purse_decision_serial_helper_cb,
-                                             &dsc);
-  if (GNUNET_OK != dsc.status)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return qs;
-}
-
-
-/**
- * Closure for #purse_refund_coin_helper_cb().
- */
-struct PurseRefundCoinContext
-{
-
-  /**
-   * Callback to call.
-   */
-  TALER_EXCHANGEDB_PurseRefundCoinCallback cb;
-
-  /**
-   * Closure for @e cb.
-   */
-  void *cb_cls;
-
-  /**
-   * Plugin context.
-   */
-  struct PostgresClosure *pg;
-
-  /**
-   * Status code, set to #GNUNET_SYSERR on hard errors.
-   */
-  enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct PurseRefundCoinContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-purse_refund_coin_helper_cb (void *cls,
-                             PGresult *result,
-                             unsigned int num_results)
-{
-  struct PurseRefundCoinContext *dsc = cls;
-  struct PostgresClosure *pg = dsc->pg;
-
-  for (unsigned int i = 0; i<num_results; i++)
-  {
-    struct TALER_Amount amount_with_fee;
-    struct TALER_CoinSpendPublicKeyP coin_pub;
-    struct TALER_DenominationPublicKey denom_pub;
-    uint64_t rowid;
-    struct GNUNET_PQ_ResultSpec rs[] = {
-      TALER_PQ_result_spec_denom_pub ("denom_pub",
-                                      &denom_pub),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                   &amount_with_fee),
-      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
-                                            &coin_pub),
-      GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
-                                    &rowid),
-      GNUNET_PQ_result_spec_end
-    };
-    enum GNUNET_GenericReturnValue ret;
-
-    if (GNUNET_OK !=
-        GNUNET_PQ_extract_result (result,
-                                  rs,
-                                  i))
-    {
-      GNUNET_break (0);
-      dsc->status = GNUNET_SYSERR;
-      return;
-    }
-    ret = dsc->cb (dsc->cb_cls,
-                   rowid,
-                   &amount_with_fee,
-                   &coin_pub,
-                   &denom_pub);
-    GNUNET_PQ_cleanup_result (rs);
-    if (GNUNET_OK != ret)
-      break;
-  }
-}
-
-
-/**
- * Select coin affected by purse refund.
- *
- * @param cls closure
- * @param purse_pub purse that was refunded
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_deposits_by_purse (
-  void *cls,
-  const struct TALER_PurseContractPublicKeyP *purse_pub,
-  TALER_EXCHANGEDB_PurseRefundCoinCallback cb,
-  void *cb_cls)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_auto_from_type (purse_pub),
-    GNUNET_PQ_query_param_end
-  };
-  struct PurseRefundCoinContext dsc = {
-    .cb = cb,
-    .cb_cls = cb_cls,
-    .pg = pg,
-    .status = GNUNET_OK
-  };
-  enum GNUNET_DB_QueryStatus qs;
-
-  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             
"audit_get_purse_deposits_by_purse",
-                                             params,
-                                             &purse_refund_coin_helper_cb,
-                                             &dsc);
-  if (GNUNET_OK != dsc.status)
-    return GNUNET_DB_STATUS_HARD_ERROR;
-  return qs;
-}
-
-
-/**
- * Closure for #refreshs_serial_helper_cb().
- */
-struct RefreshsSerialContext
-{
-
-  /**
-   * Callback to call.
-   */
-  TALER_EXCHANGEDB_RefreshesCallback cb;
-
-  /**
-   * Closure for @e cb.
-   */
-  void *cb_cls;
-
-  /**
-   * Plugin context.
-   */
-  struct PostgresClosure *pg;
-
-  /**
-   * Status code, set to #GNUNET_SYSERR on hard errors.
-   */
-  enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct RefreshsSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-refreshs_serial_helper_cb (void *cls,
-                           PGresult *result,
-                           unsigned int num_results)
-{
-  struct RefreshsSerialContext *rsc = cls;
-  struct PostgresClosure *pg = rsc->pg;
-
-  for (unsigned int i = 0; i<num_results; i++)
-  {
-    struct TALER_DenominationPublicKey denom_pub;
-    struct TALER_CoinSpendPublicKeyP coin_pub;
-    struct TALER_CoinSpendSignatureP coin_sig;
-    struct TALER_AgeCommitmentHash h_age_commitment;
-    bool ac_isnull;
-    struct TALER_Amount amount_with_fee;
-    uint32_t noreveal_index;
-    uint64_t rowid;
-    struct TALER_RefreshCommitmentP rc;
-    struct GNUNET_PQ_ResultSpec rs[] = {
-      TALER_PQ_result_spec_denom_pub ("denom_pub",
-                                      &denom_pub),
-      GNUNET_PQ_result_spec_allow_null (
-        GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
-                                              &h_age_commitment),
-        &ac_isnull),
-      GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
-                                            &coin_pub),
-      GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
-                                            &coin_sig),
-      TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                   &amount_with_fee),
-      GNUNET_PQ_result_spec_uint32 ("noreveal_index",
-                                    &noreveal_index),
-      GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
-                                    &rowid),
-      GNUNET_PQ_result_spec_auto_from_type ("rc",
-                                            &rc),
-      GNUNET_PQ_result_spec_end
-    };
-    enum GNUNET_GenericReturnValue ret;
-
-    if (GNUNET_OK !=
-        GNUNET_PQ_extract_result (result,
-                                  rs,
-                                  i))
-    {
-      GNUNET_break (0);
-      rsc->status = GNUNET_SYSERR;
-      return;
-    }
-
-    ret = rsc->cb (rsc->cb_cls,
+
+    ret = rsc->cb (rsc->cb_cls,
                    rowid,
                    &denom_pub,
                    ac_isnull ? NULL : &h_age_commitment,
@@ -11594,61 +10918,6 @@ postgres_expire_purse (
 }
 
 
-/**
- * Function called to obtain information about a purse.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub public key of the new purse
- * @param[out] purse_creation set to time when the purse was created
- * @param[out] purse_expiration set to time when the purse will expire
- * @param[out] amount set to target amount (with fees) to be put into the purse
- * @param[out] deposited set to actual amount put into the purse so far
- * @param[out] h_contract_terms set to hash of the contract for the purse
- * @param[out] merge_timestamp set to time when the purse was merged, or NEVER 
if not
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse (
-  void *cls,
-  const struct TALER_PurseContractPublicKeyP *purse_pub,
-  struct GNUNET_TIME_Timestamp *purse_creation,
-  struct GNUNET_TIME_Timestamp *purse_expiration,
-  struct TALER_Amount *amount,
-  struct TALER_Amount *deposited,
-  struct TALER_PrivateContractHashP *h_contract_terms,
-  struct GNUNET_TIME_Timestamp *merge_timestamp)
-{
-  struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_auto_from_type (purse_pub),
-    GNUNET_PQ_query_param_end
-  };
-  struct GNUNET_PQ_ResultSpec rs[] = {
-    GNUNET_PQ_result_spec_timestamp ("purse_expiration",
-                                     purse_expiration),
-    GNUNET_PQ_result_spec_timestamp ("purse_creation",
-                                     purse_creation),
-    TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
-                                 amount),
-    TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
-                                 deposited),
-    GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
-                                          h_contract_terms),
-    GNUNET_PQ_result_spec_allow_null (
-      GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
-                                       merge_timestamp),
-      NULL),
-    GNUNET_PQ_result_spec_end
-  };
-
-  *merge_timestamp = GNUNET_TIME_UNIT_FOREVER_TS;
-  return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                   "select_purse",
-                                                   params,
-                                                   rs);
-}
-
-
 /**
  * Function called to return meta data about a purse by the
  * merge capability key.
@@ -13093,18 +12362,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
   plugin->gc = &postgres_gc;
   plugin->select_deposits_above_serial_id
     = &postgres_select_deposits_above_serial_id;
-  plugin->select_purse_deposits_above_serial_id
-    = &postgres_select_purse_deposits_above_serial_id;
-  plugin->select_account_merges_above_serial_id
-    = &postgres_select_account_merges_above_serial_id;
-  plugin->select_purse_merges_above_serial_id
-    = &postgres_select_purse_merges_above_serial_id;
   plugin->select_history_requests_above_serial_id
     = &postgres_select_history_requests_above_serial_id;
   plugin->select_purse_decisions_above_serial_id
     = &postgres_select_purse_decisions_above_serial_id;
-  plugin->select_all_purse_decisions_above_serial_id
-    = &postgres_select_all_purse_decisions_above_serial_id;
   plugin->select_purse_deposits_by_purse
     = &postgres_select_purse_deposits_by_purse;
   plugin->select_refreshes_above_serial_id
@@ -13203,8 +12464,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     = &postgres_get_purse_request;
   plugin->expire_purse
     = &postgres_expire_purse;
-  plugin->select_purse
-    = &postgres_select_purse;
   plugin->select_purse_by_merge_pub
     = &postgres_select_purse_by_merge_pub;
   plugin->do_purse_deposit
@@ -13280,6 +12539,18 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     = &TEH_PG_lookup_records_by_table;
   plugin->lookup_serial_by_table
     = &TEH_PG_lookup_serial_by_table;
+  plugin->select_account_merges_above_serial_id
+    = &TEH_PG_select_account_merges_above_serial_id;
+  plugin->select_all_purse_decisions_above_serial_id
+    = &TEH_PG_select_all_purse_decisions_above_serial_id;
+  plugin->select_purse
+    = &TEH_PG_select_purse;
+  plugin->select_purse_deposits_above_serial_id
+    = &TEH_PG_select_purse_deposits_above_serial_id;
+  plugin->select_purse_merges_above_serial_id
+    = &TEH_PG_select_purse_merges_above_serial_id;
+  plugin->select_purse_requests_above_serial_id
+    = &TEH_PG_select_purse_requests_above_serial_id;
   plugin->select_reserve_close_info
     = &TEH_PG_select_reserve_close_info;
   plugin->select_reserve_closed_above_serial_id

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



reply via email to

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