summaryrefslogtreecommitdiff
path: root/src/backenddb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-06-25 17:27:49 +0200
committerChristian Grothoff <christian@grothoff.org>2020-06-25 17:27:49 +0200
commit057ac0fa95c29421b3868f43696023af3ec4cdd6 (patch)
tree961e58368be2fa9e2959266f0a6c6d4598c42ff3 /src/backenddb
parent2bc6e492ee9aaa6ed1fa5001b585db4cad76e92e (diff)
downloadmerchant-057ac0fa95c29421b3868f43696023af3ec4cdd6.tar.gz
merchant-057ac0fa95c29421b3868f43696023af3ec4cdd6.tar.bz2
merchant-057ac0fa95c29421b3868f43696023af3ec4cdd6.zip
logic to update 'wired' status of an order
Diffstat (limited to 'src/backenddb')
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c85
1 files changed, 83 insertions, 2 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index ba08d934..efb58918 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -215,6 +215,41 @@ postgres_start (void *cls,
/**
+ * Start a transaction in 'read committed' mode.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param name unique name identifying the transaction (for debugging),
+ * must point to a constant
+ * @return #GNUNET_OK on success
+ */
+static int
+postgres_start_read_committed (void *cls,
+ const char *name)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_ExecuteStatement es[] = {
+ GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL READ COMMITTED"),
+ GNUNET_PQ_EXECUTE_STATEMENT_END
+ };
+
+ check_connection (pg);
+ postgres_preflight (pg);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Starting merchant DB transaction (READ COMMITTED)\n");
+ if (GNUNET_OK !=
+ GNUNET_PQ_exec_statements (pg->conn,
+ es))
+ {
+ TALER_LOG_ERROR ("Failed to start transaction\n");
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ pg->transaction_name = name;
+ return GNUNET_OK;
+}
+
+
+/**
* Roll back the current transaction of a database connection.
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
@@ -3226,8 +3261,8 @@ RETRY:
if (MAX_RETRIES < ++retries)
return GNUNET_DB_STATUS_SOFT_ERROR;
if (GNUNET_OK !=
- postgres_start (pg,
- "insert transfer details"))
+ postgres_start_read_committed (pg,
+ "insert transfer details"))
{
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
@@ -3320,6 +3355,30 @@ RETRY:
return qs;
}
}
+ /* Update merchant_contract_terms 'wired' status: for all coins
+ that were wired, set the respective order's "wired" status to
+ true, *if* all other deposited coins associated with that order
+ have also been wired (this time or earlier) */
+ for (unsigned int i = 0; i<td->details_length; i++)
+ {
+ const struct TALER_TrackTransferDetails *d = &td->details[i];
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&d->coin_pub),
+ GNUNET_PQ_query_param_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "update_wired_by_coin_pub",
+ params);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return qs;
+ }
+ }
qs = postgres_commit (pg);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
@@ -7425,6 +7484,27 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" WHERE coin_pub=$7"
" AND h_contract_terms=$8",
8),
+ /* for postgres_insert_transfer_details() */
+ GNUNET_PQ_make_prepare ("update_wired_by_coin_pub",
+ "WITH os AS" /* select orders affected by the coin */
+ "(SELECT order_serial"
+ " FROM merchant_deposits"
+ " WHERE coin_pub=$1)"
+ "UPDATE merchant_contract_terms "
+ " SET wired=TRUE "
+ " WHERE order_serial IN "
+ " (SELECT order_serial FROM merchant_deposits" /* only orders for which NO un-wired coin exists*/
+ " WHERE NOT EXISTS "
+ " (SELECT order_serial FROM merchant_deposits" /* orders for which ANY un-wired coin exists */
+ " JOIN os USING (order_serial)" /* filter early */
+ " WHERE deposit_serial NOT IN"
+ " (SELECT deposit_serial " /* all coins associated with order that WERE wired */
+ " FROM merchant_deposits "
+ " JOIN os USING (order_serial)" /* filter early */
+ " JOIN merchant_deposit_to_transfer USING (deposit_serial)"
+ " JOIN merchant_transfers USING (credit_serial)"
+ " WHERE confirmed=TRUE)))",
+ 1),
/* for postgres_lookup_wire_fee() */
GNUNET_PQ_make_prepare ("lookup_wire_fee",
"SELECT"
@@ -8206,6 +8286,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->drop_tables = &postgres_drop_tables;
plugin->preflight = &postgres_preflight;
plugin->start = &postgres_start;
+ plugin->start_read_committed = &postgres_start_read_committed;
plugin->rollback = &postgres_rollback;
plugin->commit = &postgres_commit;
plugin->lookup_instances = &postgres_lookup_instances;