summaryrefslogtreecommitdiff
path: root/src/backenddb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-04-26 14:01:59 +0200
committerChristian Grothoff <christian@grothoff.org>2020-04-26 14:01:59 +0200
commitf799df31e066a23a0df8f4d062470526710741dd (patch)
treea593608f323bc970154dbeaff22c49a44556e4d7 /src/backenddb
parentfa640a10c6b9bf2e9ec688bb5ab59b9e8a4d599a (diff)
downloadmerchant-f799df31e066a23a0df8f4d062470526710741dd.tar.gz
merchant-f799df31e066a23a0df8f4d062470526710741dd.tar.bz2
merchant-f799df31e066a23a0df8f4d062470526710741dd.zip
implement logic to complete POSTed /orders using inventory data
Diffstat (limited to 'src/backenddb')
-rw-r--r--src/backenddb/merchant-0001.sql6
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c104
2 files changed, 104 insertions, 6 deletions
diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index 7c586432..b92cd6f5 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -167,12 +167,12 @@ CREATE TABLE IF NOT EXISTS merchant_inventory_locks
,total_locked BIGINT NOT NULL
,expiration TIMESTAMP NOT NULL
);
-CREATE INDEX IF NOT EXISTS merchant_inventory_locks_by_product_and_lock
- ON merchant_inventory_locks
- (product_serial, lock_uuid);
CREATE INDEX IF NOT EXISTS merchant_inventory_locks_by_expiration
ON merchant_inventory_locks
(expiration);
+CREATE INDEX IF NOT EXISTS merchant_inventory_locks_by_uuid
+ ON merchant_inventory_locks
+ (lock_uuid);
COMMENT ON TABLE merchant_inventory_locks
IS 'locks on inventory helt by shopping carts; note that locks MAY not be honored if merchants increase total_lost for inventory';
COMMENT ON COLUMN merchant_inventory_locks.total_locked
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 4ad8463c..280b9f5b 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -1151,6 +1151,68 @@ postgres_insert_order (void *cls,
}
+/**
+ * Release an inventory lock by UUID. Releases ALL stocks locked under
+ * the given UUID.
+ *
+ * @param cls closure
+ * @param uuid the UUID to release locks for
+ * @return transaction status,
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS means there are no locks under @a uuid
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT indicates success
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_unlock_inventory (void *cls,
+ const struct GNUNET_Uuid *uuid)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (uuid),
+ GNUNET_PQ_query_param_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "unlock_inventory",
+ params);
+}
+
+
+/**
+ * Lock inventory stock to a particular order.
+ *
+ * @param cls closure
+ * @param instance_id identifies the instance responsible for the order
+ * @param order_id alphanumeric string that uniquely identifies the order
+ * @param product_id uniquely identifies the product to be locked
+ * @param quantity how many units should be locked to the @a order_id
+ * @return transaction status,
+ * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS means there are insufficient stocks
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT indicates success
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_insert_order_lock (void *cls,
+ const char *instance_id,
+ const char *order_id,
+ const char *product_id,
+ uint32_t quantity)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (instance_id),
+ GNUNET_PQ_query_param_string (order_id),
+ GNUNET_PQ_query_param_string (product_id),
+ GNUNET_PQ_query_param_uint32 (&quantity),
+ GNUNET_PQ_query_param_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_order_lock",
+ params);
+}
+
+
/* ********************* OLD API ************************** */
/**
@@ -4163,7 +4225,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" FROM merchant_inventory"
" JOIN ps USING (product_serial)"
" WHERE "
- " total_stock - total_sold - total_lost > "
+ " total_stock - total_sold - total_lost - $4 >= "
" (SELECT SUM(total_locked)"
" FROM merchant_inventory_locks"
" WHERE product_serial=ps.product_serial) + "
@@ -4204,6 +4266,41 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" FROM merchant_instances"
" WHERE merchant_id=$1",
4),
+ GNUNET_PQ_make_prepare ("unlock_inventory",
+ "DELETE"
+ " FROM merchant_inventory_locks"
+ " WHERE lock_uuid=$1",
+ 1),
+ GNUNET_PQ_make_prepare ("insert_order_lock",
+ "WITH tmp AS"
+ " (SELECT "
+ " product_serial"
+ " ,merchant_serial"
+ " ,total_stock"
+ " ,total_sold"
+ " ,total_lost"
+ " FROM merchant_inventory"
+ " WHERE product_id=$3"
+ " AND merchant_serial="
+ " (SELECT merchant_serial"
+ " FROM merchant_instances"
+ " WHERE merchant_id=$1))"
+ " INSERT INTO merchant_order_locks"
+ " (product_serial"
+ " ,total_locked"
+ " ,order_serial)"
+ " SELECT tmp.product_serial, $4, order_serial"
+ " FROM merchant_orders"
+ " JOIN tmp USING(merchant_serial)"
+ " WHERE order_id=$2 AND"
+ " tmp.total_stock - tmp.total_sold - tmp.total_lost - $4 >= "
+ " (SELECT SUM(total_locked)"
+ " FROM merchant_inventory_locks"
+ " WHERE product_serial=tmp.product_serial) + "
+ " (SELECT SUM(total_locked)"
+ " FROM merchant_order_locks"
+ " WHERE product_serial=tmp.product_serial)",
+ 4),
/* OLD API: */
#if 0
GNUNET_PQ_make_prepare ("insert_deposit",
@@ -4698,7 +4795,9 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->lock_product = &postgres_lock_product;
plugin->delete_order = &postgres_delete_order;
plugin->lookup_order = &postgres_lookup_order;
-
+ plugin->insert_order = &postgres_insert_order;
+ plugin->unlock_inventory = &postgres_unlock_inventory;
+ plugin->insert_order_lock = &postgres_insert_order_lock;
/* old API: */
plugin->store_deposit = &postgres_store_deposit;
plugin->store_coin_to_transfer = &postgres_store_coin_to_transfer;
@@ -4711,7 +4810,6 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->find_deposits_by_wtid = &postgres_find_deposits_by_wtid;
plugin->find_proof_by_wtid = &postgres_find_proof_by_wtid;
plugin->insert_contract_terms = &postgres_insert_contract_terms;
- plugin->insert_order = &postgres_insert_order;
plugin->find_contract_terms = &postgres_find_contract_terms;
plugin->find_contract_terms_history = &postgres_find_contract_terms_history;
plugin->find_contract_terms_by_date = &postgres_find_contract_terms_by_date;