diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index 755de66af..694ac8089 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -212,6 +212,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
pg_insert_denomination_info.h pg_insert_denomination_info.c \
pg_do_batch_withdraw_insert.h pg_do_batch_withdraw_insert.c \
pg_do_reserve_open.c pg_do_reserve_open.h \
+ pg_do_purse_delete.c pg_do_purse_delete.h \
pg_do_withdraw.h pg_do_withdraw.c \
pg_preflight.h pg_preflight.c \
pg_iterate_active_signkeys.h pg_iterate_active_signkeys.c \
diff --git a/src/exchangedb/pg_do_purse_delete.c b/src/exchangedb/pg_do_purse_delete.c
new file mode 100644
index 000000000..27b81cab9
--- /dev/null
+++ b/src/exchangedb/pg_do_purse_delete.c
@@ -0,0 +1,64 @@
+/*
+ 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
+ */
+/**
+ * @file exchangedb/pg_do_purse_delete.c
+ * @brief Implementation of the do_purse_delete 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_do_purse_delete.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_do_purse_delete (
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig,
+ bool *decided,
+ bool *found)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get ();
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (purse_pub),
+ GNUNET_PQ_query_param_auto_from_type (purse_sig),
+ GNUNET_PQ_query_param_timestamp (&now),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("decided",
+ decided),
+ GNUNET_PQ_result_spec_bool ("found",
+ found),
+ GNUNET_PQ_result_spec_end
+ };
+
+ PREPARE (pg,
+ "call_purse_delete",
+ "SELECT "
+ " out_decided AS decided"
+ ",out_found AS found"
+ " FROM exchange_do_purse_delete"
+ " ($1,$2,$3);");
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "call_purse_delete",
+ params,
+ rs);
+}
diff --git a/src/exchangedb/pg_do_purse_delete.h b/src/exchangedb/pg_do_purse_delete.h
new file mode 100644
index 000000000..01c7dd91b
--- /dev/null
+++ b/src/exchangedb/pg_do_purse_delete.h
@@ -0,0 +1,49 @@
+/*
+ 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
+ */
+/**
+ * @file exchangedb/pg_do_purse_delete.h
+ * @brief implementation of the do_purse_delete function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef PG_DO_PURSE_DELETE_H
+#define PG_DO_PURSE_DELETE_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+
+/**
+ * Function called to explicitly delete a purse.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub purse to delete
+ * @param purse_sig signature affirming the deletion
+ * @param[out] decided set to true if the purse was
+ * already decided and thus could not be deleted
+ * @param[out] found set to true if the purse was found
+ * (if false, purse could not be deleted)
+ * @return transaction status code
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_do_purse_delete (
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig,
+ bool *decided,
+ bool *found);
+
+#endif
diff --git a/src/exchangedb/pg_drop_tables.c b/src/exchangedb/pg_drop_tables.c
index 4693e1154..55857018b 100644
--- a/src/exchangedb/pg_drop_tables.c
+++ b/src/exchangedb/pg_drop_tables.c
@@ -43,7 +43,6 @@ TEH_PG_drop_tables (void *cls)
{
GNUNET_PQ_disconnect (pg->conn);
pg->conn = NULL;
- pg->init = false;
}
conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
"exchangedb-postgres",
diff --git a/src/exchangedb/pg_helper.h b/src/exchangedb/pg_helper.h
index 4b5859662..512f75056 100644
--- a/src/exchangedb/pg_helper.h
+++ b/src/exchangedb/pg_helper.h
@@ -88,12 +88,6 @@ struct PostgresClosure
*/
uint32_t def_purse_limit;
- /**
- * Did we initialize the prepared statements
- * for this session? (To be replaced with @e prep_gen.)
- */
- bool init;
-
};
diff --git a/src/exchangedb/pg_insert_refresh_reveal.c b/src/exchangedb/pg_insert_refresh_reveal.c
index 098a3aed8..bddca472b 100644
--- a/src/exchangedb/pg_insert_refresh_reveal.c
+++ b/src/exchangedb/pg_insert_refresh_reveal.c
@@ -43,6 +43,22 @@ TEH_PG_insert_refresh_reveal (
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
}
+ PREPARE (pg,
+ "insert_refresh_revealed_coin",
+ "INSERT INTO refresh_revealed_coins "
+ "(melt_serial_id "
+ ",freshcoin_index "
+ ",link_sig "
+ ",denominations_serial "
+ ",coin_ev"
+ ",ewv"
+ ",h_coin_ev"
+ ",ev_sig"
+ ") SELECT $1, $2, $3, "
+ " denominations_serial, $5, $6, $7, $8"
+ " FROM denominations"
+ " WHERE denom_pub_hash=$4"
+ " ON CONFLICT DO NOTHING;");
for (uint32_t i = 0; iconn,
"insert_refresh_transfer_keys",
params);
diff --git a/src/exchangedb/pg_preflight.c b/src/exchangedb/pg_preflight.c
index cc4de6f76..4533c9a97 100644
--- a/src/exchangedb/pg_preflight.c
+++ b/src/exchangedb/pg_preflight.c
@@ -30,12 +30,10 @@
* Connect to the database if the connection does not exist yet.
*
* @param pg the plugin-specific state
- * @param skip_prepare true if we should skip prepared statement setup
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
-TEH_PG_internal_setup (struct PostgresClosure *pg,
- bool skip_prepare);
+TEH_PG_internal_setup (struct PostgresClosure *pg);
enum GNUNET_GenericReturnValue
@@ -47,13 +45,9 @@ TEH_PG_preflight (void *cls)
GNUNET_PQ_EXECUTE_STATEMENT_END
};
- if (! pg->init)
- {
- if (GNUNET_OK !=
- TEH_PG_internal_setup (pg,
- false))
- return GNUNET_SYSERR;
- }
+ if (GNUNET_OK !=
+ TEH_PG_internal_setup (pg))
+ return GNUNET_SYSERR;
if (NULL == pg->transaction_name)
return GNUNET_OK; /* all good */
if (GNUNET_OK ==
diff --git a/src/exchangedb/pg_select_refunds_above_serial_id.c b/src/exchangedb/pg_select_refunds_above_serial_id.c
index a5f7d3df6..d8c87d7d4 100644
--- a/src/exchangedb/pg_select_refunds_above_serial_id.c
+++ b/src/exchangedb/pg_select_refunds_above_serial_id.c
@@ -178,7 +178,7 @@ TEH_PG_select_refunds_above_serial_id (
};
enum GNUNET_DB_QueryStatus qs;
- /* Fetch refunds with rowid '\geq' the given parameter */
+ /* Fetch refunds with rowid '\geq' the given parameter */
PREPARE (pg,
"audit_get_refunds_incr",
"SELECT"
@@ -200,6 +200,19 @@ TEH_PG_select_refunds_above_serial_id (
" ON (kc.denominations_serial=denom.denominations_serial)"
" WHERE ref.refund_serial_id>=$1"
" ORDER BY ref.refund_serial_id ASC;");
+ PREPARE (pg,
+ "test_refund_full",
+ "SELECT"
+ " CAST(SUM(CAST(ref.amount_with_fee_frac AS INT8)) AS INT8) AS s_f"
+ ",CAST(SUM(ref.amount_with_fee_val) AS INT8) AS s_v"
+ ",dep.amount_with_fee_val"
+ ",dep.amount_with_fee_frac"
+ " FROM refunds ref"
+ " JOIN deposits dep"
+ " ON (ref.coin_pub=dep.coin_pub AND ref.deposit_serial_id=dep.deposit_serial_id)"
+ " WHERE ref.refund_serial_id=$1"
+ " GROUP BY (dep.amount_with_fee_val, dep.amount_with_fee_frac);");
+
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
"audit_get_refunds_incr",
params,
diff --git a/src/exchangedb/pg_update_kyc_process_by_row.c b/src/exchangedb/pg_update_kyc_process_by_row.c
index b15472839..4ae44ce53 100644
--- a/src/exchangedb/pg_update_kyc_process_by_row.c
+++ b/src/exchangedb/pg_update_kyc_process_by_row.c
@@ -51,6 +51,16 @@ TEH_PG_update_kyc_process_by_row (
};
enum GNUNET_DB_QueryStatus qs;
+ PREPARE (pg,
+ "update_legitimization_process",
+ "UPDATE legitimization_processes"
+ " SET provider_user_id=$4"
+ " ,provider_legitimization_id=$5"
+ " ,expiration_time=GREATEST(expiration_time,$6)"
+ " WHERE"
+ " h_payto=$3"
+ " AND legitimization_process_serial_id=$1"
+ " AND provider_section=$2;");
qs = GNUNET_PQ_eval_prepared_non_select (
pg->conn,
"update_legitimization_process",
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 9e7242cc4..03c138f78 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -23,6 +23,9 @@
* @author Marcello Stanisci
*/
#include "platform.h"
+#include
+#include
+#include
#include "taler_error_codes.h"
#include "taler_dbevents.h"
#include "taler_pq_lib.h"
@@ -56,11 +59,6 @@
#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"
-#include
-#include
-#include
-
-/**NEW INCLUDES**/
#include "pg_insert_purse_request.h"
#include "pg_iterate_active_signkeys.h"
#include "pg_preflight.h"
@@ -94,6 +92,7 @@
#include "pg_begin_revolving_shard.h"
#include "pg_get_extension_manifest.h"
#include "pg_insert_history_request.h"
+#include "pg_do_purse_delete.h"
#include "pg_do_purse_merge.h"
#include "pg_start_read_committed.h"
#include "pg_start_read_only.h"
@@ -232,95 +231,14 @@
} while (0)
-/**
- * Initialize prepared statements for @a pg.
- *
- * @param[in,out] pg connection to initialize
- * @return #GNUNET_OK on success
- */
-enum GNUNET_GenericReturnValue
-prepare_statements (struct PostgresClosure *pg)
-{
- enum GNUNET_GenericReturnValue ret;
- struct GNUNET_PQ_PreparedStatement ps[] = {
- GNUNET_PQ_make_prepare (
- "get_kyc_h_payto",
- "SELECT"
- " wire_target_h_payto"
- " FROM wire_targets"
- " WHERE wire_target_h_payto=$1"
- " LIMIT 1;"),
- /* Used in #postgres_ensure_coin_known() */
- GNUNET_PQ_make_prepare (
- "get_known_coin_dh",
- "SELECT"
- " denominations.denom_pub_hash"
- " FROM known_coins"
- " JOIN denominations USING (denominations_serial)"
- " WHERE coin_pub=$1;"),
- /* Store information about the desired denominations for a
- refresh operation, used in #postgres_insert_refresh_reveal() */
- GNUNET_PQ_make_prepare (
- "insert_refresh_revealed_coin",
- "INSERT INTO refresh_revealed_coins "
- "(melt_serial_id "
- ",freshcoin_index "
- ",link_sig "
- ",denominations_serial "
- ",coin_ev"
- ",ewv"
- ",h_coin_ev"
- ",ev_sig"
- ") SELECT $1, $2, $3, "
- " denominations_serial, $5, $6, $7, $8"
- " FROM denominations"
- " WHERE denom_pub_hash=$4"
- " ON CONFLICT DO NOTHING;"),
- GNUNET_PQ_make_prepare (
- "test_refund_full",
- "SELECT"
- " CAST(SUM(CAST(ref.amount_with_fee_frac AS INT8)) AS INT8) AS s_f"
- ",CAST(SUM(ref.amount_with_fee_val) AS INT8) AS s_v"
- ",dep.amount_with_fee_val"
- ",dep.amount_with_fee_frac"
- " FROM refunds ref"
- " JOIN deposits dep"
- " ON (ref.coin_pub=dep.coin_pub AND ref.deposit_serial_id=dep.deposit_serial_id)"
- " WHERE ref.refund_serial_id=$1"
- " GROUP BY (dep.amount_with_fee_val, dep.amount_with_fee_frac);"),
- /* Used in #postgres_update_kyc_requirement_by_row() */
- GNUNET_PQ_make_prepare (
- "update_legitimization_process",
- "UPDATE legitimization_processes"
- " SET provider_user_id=$4"
- " ,provider_legitimization_id=$5"
- " ,expiration_time=GREATEST(expiration_time,$6)"
- " WHERE"
- " h_payto=$3"
- " AND legitimization_process_serial_id=$1"
- " AND provider_section=$2;"),
- GNUNET_PQ_PREPARED_STATEMENT_END
- };
-
- ret = GNUNET_PQ_prepare_statements (pg->conn,
- ps);
- if (GNUNET_OK != ret)
- return ret;
- pg->init = true;
- return GNUNET_OK;
-}
-
-
/**
* Connect to the database if the connection does not exist yet.
*
* @param pg the plugin-specific state
- * @param skip_prepare true if we should skip prepared statement setup
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
-TEH_PG_internal_setup (struct PostgresClosure *pg,
- bool skip_prepare)
+TEH_PG_internal_setup (struct PostgresClosure *pg)
{
if (NULL == pg->conn)
{
@@ -366,11 +284,7 @@ TEH_PG_internal_setup (struct PostgresClosure *pg,
}
if (NULL == pg->transaction_name)
GNUNET_PQ_reconnect_if_down (pg->conn);
- if (pg->init)
- return GNUNET_OK;
- if (skip_prepare)
- return GNUNET_OK;
- return prepare_statements (pg);
+ return GNUNET_OK;
}
@@ -472,8 +386,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
return NULL;
}
if (GNUNET_OK !=
- TEH_PG_internal_setup (pg,
- true))
+ TEH_PG_internal_setup (pg))
{
GNUNET_free (pg->exchange_url);
GNUNET_free (pg->currency);
@@ -483,7 +396,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
}
plugin = GNUNET_new (struct TALER_EXCHANGEDB_Plugin);
plugin->cls = pg;
- /* New style, sort alphabetically! */
plugin->do_reserve_open
= &TEH_PG_do_reserve_open;
plugin->drop_tables
@@ -542,7 +454,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &TEH_PG_select_reserve_closed_above_serial_id;
plugin->select_reserve_open_above_serial_id
= &TEH_PG_select_reserve_open_above_serial_id;
- /*need to sort*/
plugin->insert_purse_request
= &TEH_PG_insert_purse_request;
plugin->iterate_active_signkeys
@@ -555,7 +466,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &TEH_PG_insert_aggregation_tracking;
plugin->select_aggregation_amounts_for_kyc_check
= &TEH_PG_select_aggregation_amounts_for_kyc_check;
-
plugin->select_satisfied_kyc_processes
= &TEH_PG_select_satisfied_kyc_processes;
plugin->kyc_provider_account_lookup
@@ -610,6 +520,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &TEH_PG_insert_history_request;
plugin->do_purse_merge
= &TEH_PG_do_purse_merge;
+ plugin->do_purse_delete
+ = &TEH_PG_do_purse_delete;
plugin->start_read_committed
= &TEH_PG_start_read_committed;
plugin->start_read_only
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index d680cd731..5dcad4f71 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -5933,6 +5933,27 @@ struct TALER_EXCHANGEDB_Plugin
bool *conflict);
+ /**
+ * Function called to explicitly delete a purse.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub purse to delete
+ * @param purse_sig signature affirming the deletion
+ * @param[out] decided set to true if the purse was
+ * already decided and thus could not be deleted
+ * @param[out] found set to true if the purse was found
+ * (if false, purse could not be deleted)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_purse_delete)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig,
+ bool *dediced,
+ bool *found);
+
+
/**
* Set the current @a balance in the purse
* identified by @a purse_pub. Used by the auditor