From b712481beaeb1dcc2e2a7195d0607a3c0f073665 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Mon, 15 May 2023 13:02:54 -0600 Subject: Factor out 9 new functions (shit job) --- src/backenddb/Makefile.am | 9 + src/backenddb/pg_insert_deposit.c | 114 +++ src/backenddb/pg_insert_deposit.h | 61 ++ src/backenddb/pg_insert_exchange_signkey.c | 66 ++ src/backenddb/pg_insert_exchange_signkey.h | 48 ++ src/backenddb/pg_lookup_deposits.c | 173 +++++ src/backenddb/pg_lookup_deposits.h | 46 ++ src/backenddb/pg_lookup_order_status.c | 73 ++ src/backenddb/pg_lookup_order_status.h | 45 ++ src/backenddb/pg_lookup_order_status_by_serial.c | 77 ++ src/backenddb/pg_lookup_order_status_by_serial.h | 48 ++ src/backenddb/pg_lookup_payment_status.c | 98 +++ src/backenddb/pg_lookup_payment_status.h | 45 ++ src/backenddb/pg_lookup_refunds.c | 150 ++++ src/backenddb/pg_lookup_refunds.h | 45 ++ src/backenddb/pg_mark_contract_paid.c | 112 +++ src/backenddb/pg_mark_contract_paid.h | 45 ++ src/backenddb/pg_refund_coin.c | 77 ++ src/backenddb/pg_refund_coin.h | 51 ++ src/backenddb/plugin_merchantdb_postgres.c | 863 +---------------------- 20 files changed, 1410 insertions(+), 836 deletions(-) create mode 100644 src/backenddb/pg_insert_deposit.c create mode 100644 src/backenddb/pg_insert_deposit.h create mode 100644 src/backenddb/pg_insert_exchange_signkey.c create mode 100644 src/backenddb/pg_insert_exchange_signkey.h create mode 100644 src/backenddb/pg_lookup_deposits.c create mode 100644 src/backenddb/pg_lookup_deposits.h create mode 100644 src/backenddb/pg_lookup_order_status.c create mode 100644 src/backenddb/pg_lookup_order_status.h create mode 100644 src/backenddb/pg_lookup_order_status_by_serial.c create mode 100644 src/backenddb/pg_lookup_order_status_by_serial.h create mode 100644 src/backenddb/pg_lookup_payment_status.c create mode 100644 src/backenddb/pg_lookup_payment_status.h create mode 100644 src/backenddb/pg_lookup_refunds.c create mode 100644 src/backenddb/pg_lookup_refunds.h create mode 100644 src/backenddb/pg_mark_contract_paid.c create mode 100644 src/backenddb/pg_mark_contract_paid.h create mode 100644 src/backenddb/pg_refund_coin.c create mode 100644 src/backenddb/pg_refund_coin.h diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am index 1b400bce..745e33eb 100644 --- a/src/backenddb/Makefile.am +++ b/src/backenddb/Makefile.am @@ -94,6 +94,15 @@ libtaler_plugin_merchantdb_postgres_la_SOURCES = \ pg_insert_contract_terms.h pg_insert_contract_terms.c \ pg_update_contract_terms.h pg_update_contract_terms.c \ pg_delete_contract_terms.h pg_delete_contract_terms.c \ + pg_lookup_deposits.h pg_lookup_deposits.c \ + pg_insert_exchange_signkey.h pg_insert_exchange_signkey.c \ + pg_insert_deposit.h pg_insert_deposit.c \ + pg_lookup_refunds.h pg_lookup_refunds.c \ + pg_mark_contract_paid.h pg_mark_contract_paid.c \ + pg_refund_coin.h pg_refund_coin.c \ + pg_lookup_order_status.h pg_lookup_order_status.c \ + pg_lookup_order_status_by_serial.h pg_lookup_order_status_by_serial.c \ + pg_lookup_payment_status.h pg_lookup_payment_status.c \ plugin_merchantdb_postgres.c pg_helper.h libtaler_plugin_merchantdb_postgres_la_LIBADD = \ $(LTLIBINTL) diff --git a/src/backenddb/pg_insert_deposit.c b/src/backenddb/pg_insert_deposit.c new file mode 100644 index 00000000..f7f20d47 --- /dev/null +++ b/src/backenddb/pg_insert_deposit.c @@ -0,0 +1,114 @@ +/* + 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 backenddb/pg_insert_deposit.c + * @brief Implementation of the insert_deposit function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_insert_deposit.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_insert_deposit ( + void *cls, + const char *instance_id, + struct GNUNET_TIME_Timestamp deposit_timestamp, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const char *exchange_url, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *deposit_fee, + const struct TALER_Amount *refund_fee, + const struct TALER_Amount *wire_fee, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_ExchangeSignatureP *exchange_sig, + const struct TALER_ExchangePublicKeyP *exchange_pub) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_timestamp (&deposit_timestamp), /* $3 */ + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_string (exchange_url), + TALER_PQ_query_param_amount (amount_with_fee), /* $6/$7 */ + TALER_PQ_query_param_amount (deposit_fee), /* $8, $9 */ + TALER_PQ_query_param_amount (refund_fee), /* $10, $11 */ + TALER_PQ_query_param_amount (wire_fee), /* $12, $13 */ + GNUNET_PQ_query_param_auto_from_type (h_wire), /* $14 */ + GNUNET_PQ_query_param_auto_from_type (exchange_sig), /* $15 */ + GNUNET_PQ_query_param_auto_from_type (exchange_pub), /* $16 */ + GNUNET_PQ_query_param_end + }; + + /* no preflight check here, run in transaction by caller! */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Storing deposit for instance `%s' h_contract_terms `%s', coin_pub: `%s', amount_with_fee: %s\n", + instance_id, + GNUNET_h2s (&h_contract_terms->hash), + TALER_B2S (coin_pub), + TALER_amount2s (amount_with_fee)); + check_connection (pg); + PREPARE (pg, + "insert_deposit", + "WITH md AS" + " (SELECT account_serial, merchant_serial" + " FROM merchant_accounts" + " WHERE h_wire=$14" + " AND merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1))" + ", ed AS" + " (SELECT signkey_serial" + " FROM merchant_exchange_signing_keys" + " WHERE exchange_pub=$16" + " ORDER BY start_date DESC" + " LIMIT 1)" + "INSERT INTO merchant_deposits" + "(order_serial" + ",deposit_timestamp" + ",coin_pub" + ",exchange_url" + ",amount_with_fee_val" + ",amount_with_fee_frac" + ",deposit_fee_val" + ",deposit_fee_frac" + ",refund_fee_val" + ",refund_fee_frac" + ",wire_fee_val" + ",wire_fee_frac" + ",exchange_sig" + ",signkey_serial" + ",account_serial)" + " SELECT " + " order_serial" + " ,$3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $15" + " ,ed.signkey_serial" + " ,md.account_serial" + " FROM merchant_contract_terms" + " JOIN md USING (merchant_serial)" + " FULL OUTER JOIN ed ON TRUE" + " WHERE h_contract_terms=$2"); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "insert_deposit", + params); + +} diff --git a/src/backenddb/pg_insert_deposit.h b/src/backenddb/pg_insert_deposit.h new file mode 100644 index 00000000..49d783aa --- /dev/null +++ b/src/backenddb/pg_insert_deposit.h @@ -0,0 +1,61 @@ +/* + 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 backenddb/pg_insert_deposit.h + * @brief implementation of the insert_deposit function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_INSERT_DEPOSIT_H +#define PG_INSERT_DEPOSIT_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Insert payment confirmation from the exchange into the database. + * + * @param cls closure + * @param instance_id instance to lookup deposits for + * @param deposit_timestamp time when the exchange generated the deposit confirmation + * @param h_contract_terms proposal data's hashcode + * @param coin_pub public key of the coin + * @param exchange_url URL of the exchange that issued @a coin_pub + * @param amount_with_fee amount the exchange will deposit for this coin + * @param deposit_fee fee the exchange will charge for this coin + * @param wire_fee wire fee the exchange charges + * @param refund_fee fee the exchange charges to refund this coin + * @param h_wire hash of the wire details of the target account of the merchant + * @param exchange_sig signature from exchange that coin was accepted + * @param exchange_pub signgin key that was used for @a exchange_sig + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TMH_PG_insert_deposit (void *cls, + const char *instance_id, + struct GNUNET_TIME_Timestamp deposit_timestamp, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const char *exchange_url, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *deposit_fee, + const struct TALER_Amount *refund_fee, + const struct TALER_Amount *wire_fee, + const struct TALER_MerchantWireHashP *h_wire, + const struct TALER_ExchangeSignatureP *exchange_sig, + const struct TALER_ExchangePublicKeyP *exchange_pub); + +#endif diff --git a/src/backenddb/pg_insert_exchange_signkey.c b/src/backenddb/pg_insert_exchange_signkey.c new file mode 100644 index 00000000..81d27d60 --- /dev/null +++ b/src/backenddb/pg_insert_exchange_signkey.c @@ -0,0 +1,66 @@ +/* + 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 backenddb/pg_insert_exchange_signkey.c + * @brief Implementation of the insert_exchange_signkey function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_insert_exchange_signkey.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_insert_exchange_signkey ( + void *cls, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp expire_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_MasterSignatureP *master_sig) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (master_pub), + GNUNET_PQ_query_param_auto_from_type (exchange_pub), + GNUNET_PQ_query_param_timestamp (&start_date), + GNUNET_PQ_query_param_timestamp (&expire_date), + GNUNET_PQ_query_param_timestamp (&end_date), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_end + }; + + check_connection (pg); + postgres_preflight (pg); + PREPARE (pg, + "insert_exchange_signkey", + "INSERT INTO merchant_exchange_signing_keys" + "(master_pub" + ",exchange_pub" + ",start_date" + ",expire_date" + ",end_date" + ",master_sig)" + "VALUES" + "($1, $2, $3, $4, $5, $6)"); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "insert_exchange_signkey", + params); + +} diff --git a/src/backenddb/pg_insert_exchange_signkey.h b/src/backenddb/pg_insert_exchange_signkey.h new file mode 100644 index 00000000..78f84846 --- /dev/null +++ b/src/backenddb/pg_insert_exchange_signkey.h @@ -0,0 +1,48 @@ +/* + 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 backenddb/pg_insert_exchange_signkey.h + * @brief implementation of the insert_exchange_signkey function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_INSERT_EXCHANGE_SIGNKEY_H +#define PG_INSERT_EXCHANGE_SIGNKEY_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Insert an exchange signing key into our database. + * + * @param cls closure + * @param master_pub exchange master public key used for @a master_sig + * @param exchange_pub exchange signing key to insert + * @param start_date when does the signing key become valid + * @param expire_date when does the signing key stop being used + * @param end_date when does the signing key become void as proof + * @param master_sig signature of @a master_pub over the @a exchange_pub and the dates + */ +enum GNUNET_DB_QueryStatus +TMH_PG_insert_exchange_signkey (void *cls, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_ExchangePublicKeyP *exchange_pub, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp expire_date, + struct GNUNET_TIME_Timestamp end_date, + const struct TALER_MasterSignatureP *master_sig); + +#endif diff --git a/src/backenddb/pg_lookup_deposits.c b/src/backenddb/pg_lookup_deposits.c new file mode 100644 index 00000000..27647dda --- /dev/null +++ b/src/backenddb/pg_lookup_deposits.c @@ -0,0 +1,173 @@ +/* + 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 backenddb/pg_lookup_deposits.c + * @brief Implementation of the lookup_deposits function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_lookup_deposits.h" +#include "pg_helper.h" + +/** + * Closure for #lookup_deposits_cb(). + */ +struct LookupDepositsContext +{ + /** + * Function to call with results. + */ + TALER_MERCHANTDB_DepositsCallback cb; + + /** + * Closure for @e cls. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Transaction status (set). + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param[in,out] cls of type `struct LookupDepositsContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lookup_deposits_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct LookupDepositsContext *ldc = cls; + struct PostgresClosure *pg = ldc->pg; + + for (unsigned int i = 0; iqs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + ldc->cb (ldc->cb_cls, + exchange_url, + &coin_pub, + &amount_with_fee, + &deposit_fee, + &refund_fee, + &wire_fee); + GNUNET_PQ_cleanup_result (rs); + } + ldc->qs = num_results; +} + + +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_deposits ( + void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + TALER_MERCHANTDB_DepositsCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_end + }; + struct LookupDepositsContext ldc = { + .cb = cb, + .cb_cls = cb_cls, + .pg = pg + }; + enum GNUNET_DB_QueryStatus qs; + + /* no preflight check here, run in its own transaction by the caller! */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Finding deposits for h_contract_terms '%s'\n", + GNUNET_h2s (&h_contract_terms->hash)); + check_connection (pg); + PREPARE (pg, + "lookup_deposits", + "SELECT" + " exchange_url" + ",coin_pub" + ",amount_with_fee_val" + ",amount_with_fee_frac" + ",deposit_fee_val" + ",deposit_fee_frac" + ",refund_fee_val" + ",refund_fee_frac" + ",wire_fee_val" + ",wire_fee_frac" + " FROM merchant_deposits" + " WHERE order_serial=" + " (SELECT order_serial" + " FROM merchant_contract_terms" + " WHERE h_contract_terms=$2" + " AND merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1))"); + qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, + "lookup_deposits", + params, + &lookup_deposits_cb, + &ldc); + if (qs <= 0) + return qs; + return ldc.qs; +} diff --git a/src/backenddb/pg_lookup_deposits.h b/src/backenddb/pg_lookup_deposits.h new file mode 100644 index 00000000..891a1093 --- /dev/null +++ b/src/backenddb/pg_lookup_deposits.h @@ -0,0 +1,46 @@ +/* + 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 backenddb/pg_lookup_deposits.h + * @brief implementation of the lookup_deposits function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_LOOKUP_DEPOSITS_H +#define PG_LOOKUP_DEPOSITS_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Lookup information about coins that were successfully deposited for a + * given contract. + * + * @param cls closure + * @param instance_id instance to lookup deposits for + * @param h_contract_terms proposal data's hashcode + * @param cb function to call with payment data + * @param cb_cls closure for @a cb + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_deposits (void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + TALER_MERCHANTDB_DepositsCallback cb, + void *cb_cls); + +#endif diff --git a/src/backenddb/pg_lookup_order_status.c b/src/backenddb/pg_lookup_order_status.c new file mode 100644 index 00000000..be6f0a15 --- /dev/null +++ b/src/backenddb/pg_lookup_order_status.c @@ -0,0 +1,73 @@ +/* + 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 backenddb/pg_lookup_order_status.c + * @brief Implementation of the lookup_order_status function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_lookup_order_status.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_order_status ( + void *cls, + const char *instance_id, + const char *order_id, + struct TALER_PrivateContractHashP *h_contract_terms, + bool *paid) +{ + struct PostgresClosure *pg = cls; + uint8_t paid8; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (order_id), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("paid", + &paid8), + GNUNET_PQ_result_spec_end + }; + + check_connection (pg); + PREPARE (pg, + "lookup_order_status", + "SELECT" + " h_contract_terms" + ",paid" + " FROM merchant_contract_terms" + " WHERE merchant_serial=" + " (SELECT merchant_serial " + " FROM merchant_instances" + " WHERE merchant_id=$1)" + " AND order_id=$2"); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "lookup_order_status", + params, + rs); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + *paid = (0 != paid8); + else + *paid = false; /* just to be safe(r) */ + return qs; +} diff --git a/src/backenddb/pg_lookup_order_status.h b/src/backenddb/pg_lookup_order_status.h new file mode 100644 index 00000000..acf8fe31 --- /dev/null +++ b/src/backenddb/pg_lookup_order_status.h @@ -0,0 +1,45 @@ +/* + 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 backenddb/pg_lookup_order_status.h + * @brief implementation of the lookup_order_status function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_LOOKUP_ORDER_STATUS_H +#define PG_LOOKUP_ORDER_STATUS_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Retrieve contract terms given its @a order_id + * + * @param cls closure + * @param instance_id instance's identifier + * @param order_id order to lookup contract for + * @param[out] h_contract_terms set to the hash of the contract. + * @param[out] paid set to the payment status of the contract + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_order_status (void *cls, + const char *instance_id, + const char *order_id, + struct TALER_PrivateContractHashP *h_contract_terms, + bool *paid); + +#endif diff --git a/src/backenddb/pg_lookup_order_status_by_serial.c b/src/backenddb/pg_lookup_order_status_by_serial.c new file mode 100644 index 00000000..b6a4ebb0 --- /dev/null +++ b/src/backenddb/pg_lookup_order_status_by_serial.c @@ -0,0 +1,77 @@ +/* + 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 backenddb/pg_lookup_order_status_by_serial.c + * @brief Implementation of the lookup_order_status_by_serial function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_lookup_order_status_by_serial.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_order_status_by_serial (void *cls, + const char *instance_id, + uint64_t order_serial, + char **order_id, + struct TALER_PrivateContractHashP * + h_contract_terms, + bool *paid) +{ + struct PostgresClosure *pg = cls; + uint8_t paid8; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_uint64 (&order_serial), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", + h_contract_terms), + GNUNET_PQ_result_spec_auto_from_type ("paid", + &paid8), + GNUNET_PQ_result_spec_string ("order_id", + order_id), + GNUNET_PQ_result_spec_end + }; + + check_connection (pg); + PREPARE (pg, + "lookup_order_status_by_serial", + "SELECT" + " h_contract_terms" + ",order_id" + ",paid" + " FROM merchant_contract_terms" + " WHERE merchant_serial=" + " (SELECT merchant_serial " + " FROM merchant_instances" + " WHERE merchant_id=$1)" + " AND order_serial=$2"); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "lookup_order_status_by_serial", + params, + rs); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + *paid = (0 != paid8); + else + *paid = false; /* just to be safe(r) */ + return qs; +} diff --git a/src/backenddb/pg_lookup_order_status_by_serial.h b/src/backenddb/pg_lookup_order_status_by_serial.h new file mode 100644 index 00000000..eb60e97f --- /dev/null +++ b/src/backenddb/pg_lookup_order_status_by_serial.h @@ -0,0 +1,48 @@ +/* + 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 backenddb/pg_lookup_order_status_by_serial.h + * @brief implementation of the lookup_order_status_by_serial function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_LOOKUP_ORDER_STATUS_BY_SERIAL_H +#define PG_LOOKUP_ORDER_STATUS_BY_SERIAL_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Retrieve contract terms given its @a order_serial + * + * @param cls closure + * @param instance_id instance's identifier + * @param order_serial serial ID of the order to look up + * @param[out] order_id set to ID of the order + * @param[out] h_contract_terms set to the hash of the contract. + * @param[out] paid set to the payment status of the contract + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_order_status_by_serial (void *cls, + const char *instance_id, + uint64_t order_serial, + char **order_id, + struct TALER_PrivateContractHashP * + h_contract_terms, + bool *paid); + +#endif diff --git a/src/backenddb/pg_lookup_payment_status.c b/src/backenddb/pg_lookup_payment_status.c new file mode 100644 index 00000000..fc4e5d94 --- /dev/null +++ b/src/backenddb/pg_lookup_payment_status.c @@ -0,0 +1,98 @@ +/* + 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 backenddb/pg_lookup_payment_status.c + * @brief Implementation of the lookup_payment_status function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_lookup_payment_status.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_payment_status (void *cls, + uint64_t order_serial, + const char *session_id, + bool *paid, + bool *wired) +{ + struct PostgresClosure *pg = cls; + uint8_t paid8; + uint8_t wired8; + enum GNUNET_DB_QueryStatus qs; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_auto_from_type ("paid", + &paid8), + GNUNET_PQ_result_spec_auto_from_type ("wired", + &wired8), + GNUNET_PQ_result_spec_end + }; + check_connection (pg); + if (NULL == session_id) + { + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&order_serial), + GNUNET_PQ_query_param_end + }; + + PREPARE (pg, + "lookup_payment_status", + "SELECT" + " wired" + ",paid" + " FROM merchant_contract_terms" + " WHERE order_serial=$1"); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "lookup_payment_status", + params, + rs); + } + else + { + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&order_serial), + GNUNET_PQ_query_param_string (session_id), + GNUNET_PQ_query_param_end + }; + + PREPARE (pg, + "lookup_payment_status_session_id", + "SELECT" + " wired" + ",paid" + " FROM merchant_contract_terms" + " WHERE order_serial=$1" + " AND session_id=$2"); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "lookup_payment_status_session_id", + params, + rs); + } + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + { + *paid = (0 != paid8); + *wired = (0 != wired8); + } + else + { + *paid = false; /* just to be safe(r) */ + *wired = false; /* just to be safe(r) */ + } + return qs; +} diff --git a/src/backenddb/pg_lookup_payment_status.h b/src/backenddb/pg_lookup_payment_status.h new file mode 100644 index 00000000..a46ee31e --- /dev/null +++ b/src/backenddb/pg_lookup_payment_status.h @@ -0,0 +1,45 @@ +/* + 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 backenddb/pg_lookup_payment_status.h + * @brief implementation of the lookup_payment_status function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_LOOKUP_PAYMENT_STATUS_H +#define PG_LOOKUP_PAYMENT_STATUS_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Retrieve payment and wire status for a given @a order_serial and session ID. + * + * @param cls closure + * @param order_serial identifies the order + * @param session_id session for which to check the payment status, NULL for any + * @param[out] paid set to the payment status of the contract + * @param[out] wired set to the wire transfer status of the exchange payment + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_payment_status (void *cls, + uint64_t order_serial, + const char *session_id, + bool *paid, + bool *wired); + +#endif diff --git a/src/backenddb/pg_lookup_refunds.c b/src/backenddb/pg_lookup_refunds.c new file mode 100644 index 00000000..bc943162 --- /dev/null +++ b/src/backenddb/pg_lookup_refunds.c @@ -0,0 +1,150 @@ +/* + 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 backenddb/pg_lookup_refunds.c + * @brief Implementation of the lookup_refunds function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_lookup_refunds.h" +#include "pg_helper.h" + +/** + * Closure for #lookup_refunds_cb(). + */ +struct LookupRefundsContext +{ + /** + * Function to call for each refund. + */ + TALER_MERCHANTDB_RefundCallback rc; + + /** + * Closure for @e rc. + */ + void *rc_cls; + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Transaction result. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls of type `struct LookupRefundsContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +lookup_refunds_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct LookupRefundsContext *lrc = cls; + struct PostgresClosure *pg = lrc->pg; + + for (unsigned int i = 0; iqs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + lrc->rc (lrc->rc_cls, + &coin_pub, + &refund_amount); + GNUNET_PQ_cleanup_result (rs); /* technically useless here */ + } + lrc->qs = num_results; +} + + +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_refunds ( + void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + TALER_MERCHANTDB_RefundCallback rc, + void *rc_cls) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_end + }; + struct LookupRefundsContext lrc = { + .rc = rc, + .rc_cls = rc_cls, + .pg = pg + }; + enum GNUNET_DB_QueryStatus qs; + + /* no preflight check here, run in transaction by caller! */ + TALER_LOG_DEBUG ("Looking for refund of h_contract_terms %s at `%s'\n", + GNUNET_h2s (&h_contract_terms->hash), + instance_id); + check_connection (pg); + PREPARE (pg, + "lookup_refunds", + "SELECT" + " coin_pub" + ",refund_amount_val" + ",refund_amount_frac" + " FROM merchant_refunds" + " WHERE order_serial=" + " (SELECT order_serial" + " FROM merchant_contract_terms" + " WHERE h_contract_terms=$2" + " AND merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1))"); + qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, + "lookup_refunds", + params, + &lookup_refunds_cb, + &lrc); + if (0 >= qs) + return qs; + return lrc.qs; +} diff --git a/src/backenddb/pg_lookup_refunds.h b/src/backenddb/pg_lookup_refunds.h new file mode 100644 index 00000000..dcd0d203 --- /dev/null +++ b/src/backenddb/pg_lookup_refunds.h @@ -0,0 +1,45 @@ +/* + 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 backenddb/pg_lookup_refunds.h + * @brief implementation of the lookup_refunds function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_LOOKUP_REFUNDS_H +#define PG_LOOKUP_REFUNDS_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Obtain refunds associated with a contract. + * + * @param cls closure, typically a connection to the db + * @param instance_id instance to lookup refunds for + * @param h_contract_terms hash code of the contract + * @param rc function to call for each coin on which there is a refund + * @param rc_cls closure for @a rc + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_refunds (void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + TALER_MERCHANTDB_RefundCallback rc, + void *rc_cls); + +#endif diff --git a/src/backenddb/pg_mark_contract_paid.c b/src/backenddb/pg_mark_contract_paid.c new file mode 100644 index 00000000..1119dd76 --- /dev/null +++ b/src/backenddb/pg_mark_contract_paid.c @@ -0,0 +1,112 @@ +/* + 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 backenddb/pg_mark_contract_paid.c + * @brief Implementation of the mark_contract_paid function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_mark_contract_paid.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_mark_contract_paid ( + void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + const char *session_id) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_string (session_id), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_QueryParam uparams[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + /* Session ID must always be given by the caller. */ + GNUNET_assert (NULL != session_id); + + /* no preflight check here, run in transaction by caller! */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Marking h_contract_terms '%s' of %s as paid for session `%s'\n", + GNUNET_h2s (&h_contract_terms->hash), + instance_id, + session_id); + PREPARE (pg, + "mark_contract_paid", + "UPDATE merchant_contract_terms SET" + " paid=TRUE" + ",session_id=$3" + " WHERE h_contract_terms=$2" + " AND merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1)"); + qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, + "mark_contract_paid", + params); + if (qs <= 0) + return qs; + PREPARE (pg, + "mark_inventory_sold", + "UPDATE merchant_inventory SET" + " total_sold=total_sold + order_locks.total_locked" + " FROM (SELECT total_locked,product_serial" + " FROM merchant_order_locks" + " WHERE order_serial=" + " (SELECT order_serial" + " FROM merchant_contract_terms" + " WHERE h_contract_terms=$2" + " AND merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1))" + " ) AS order_locks" + " WHERE merchant_inventory.product_serial" + " =order_locks.product_serial"); + qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, + "mark_inventory_sold", + uparams); + if (qs < 0) + return qs; /* 0: no inventory management, that's OK! */ + /* ON DELETE CASCADE deletes from merchant_order_locks */ + PREPARE (pg, + "delete_completed_order", + "WITH md AS" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1) " + "DELETE" + " FROM merchant_orders" + " WHERE order_serial=" + " (SELECT order_serial" + " FROM merchant_contract_terms" + " JOIN md USING (merchant_serial)" + " WHERE h_contract_terms=$2)"); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "delete_completed_order", + uparams); +} diff --git a/src/backenddb/pg_mark_contract_paid.h b/src/backenddb/pg_mark_contract_paid.h new file mode 100644 index 00000000..20c87bd2 --- /dev/null +++ b/src/backenddb/pg_mark_contract_paid.h @@ -0,0 +1,45 @@ +/* + 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 backenddb/pg_mark_contract_paid.h + * @brief implementation of the mark_contract_paid function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_MARK_CONTRACT_PAID_H +#define PG_MARK_CONTRACT_PAID_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Mark contract as paid and store the current @a session_id + * for which the contract was paid. Deletes the underlying order + * and marks the locked stocks of the order as sold. + * + * @param cls closure + * @param instance_id instance to mark contract as paid for + * @param h_contract_terms hash of the contract that is now paid + * @param session_id the session that paid the contract + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TMH_PG_mark_contract_paid (void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + const char *session_id); + +#endif diff --git a/src/backenddb/pg_refund_coin.c b/src/backenddb/pg_refund_coin.c new file mode 100644 index 00000000..3b124612 --- /dev/null +++ b/src/backenddb/pg_refund_coin.c @@ -0,0 +1,77 @@ +/* + 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 backenddb/pg_refund_coin.c + * @brief Implementation of the refund_coin function for Postgres + * @author Iván Ávalos + */ +#include "platform.h" +#include +#include +#include +#include "pg_refund_coin.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_refund_coin (void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp refund_timestamp, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const char *reason) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_auto_from_type (h_contract_terms), + GNUNET_PQ_query_param_timestamp (&refund_timestamp), + GNUNET_PQ_query_param_auto_from_type (coin_pub), + GNUNET_PQ_query_param_string (reason), + GNUNET_PQ_query_param_end + }; + PREPARE (pg, + "refund_coin", + "INSERT INTO merchant_refunds" + "(order_serial" + ",rtransaction_id" + ",refund_timestamp" + ",coin_pub" + ",reason" + ",refund_amount_val" + ",refund_amount_frac" + ") " + "SELECT " + " order_serial" + ",0" /* rtransaction_id always 0 for /abort */ + ",$3" + ",coin_pub" + ",$5" + ",amount_with_fee_val" + ",amount_with_fee_frac" + " FROM merchant_deposits" + " WHERE coin_pub=$4" + " AND order_serial=" + " (SELECT order_serial" + " FROM merchant_contract_terms" + " WHERE h_contract_terms=$2" + " AND merchant_serial=" + " (SELECT merchant_serial" + " FROM merchant_instances" + " WHERE merchant_id=$1))"); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "refund_coin", + params); +} diff --git a/src/backenddb/pg_refund_coin.h b/src/backenddb/pg_refund_coin.h new file mode 100644 index 00000000..6b5c5d30 --- /dev/null +++ b/src/backenddb/pg_refund_coin.h @@ -0,0 +1,51 @@ +/* + 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 backenddb/pg_refund_coin.h + * @brief implementation of the refund_coin function for Postgres + * @author Iván Ávalos + */ +#ifndef PG_REFUND_COIN_H +#define PG_REFUND_COIN_H + +#include +#include +#include "taler_merchantdb_plugin.h" + +/** + * Function called during aborts to refund a coin. Marks the + * respective coin as refunded. + * + * @param cls closure + * @param instance_id instance to refund payment for + * @param h_contract_terms hash of the contract to refund coin for + * @param refund_timestamp timestamp of the refund + * @param coin_pub public key of the coin to refund (fully) + * @param reason text justifying the refund + * @return transaction status + * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a coin_pub is unknown to us; + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the request is valid, + * regardless of whether it actually increased the refund + */ +enum GNUNET_DB_QueryStatus +TMH_PG_refund_coin (void *cls, + const char *instance_id, + const struct TALER_PrivateContractHashP *h_contract_terms, + struct GNUNET_TIME_Timestamp refund_timestamp, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const char *reason); + +#endif diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index 757a303c..3dbdae48 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -72,6 +72,15 @@ #include "pg_insert_contract_terms.h" #include "pg_update_contract_terms.h" #include "pg_delete_contract_terms.h" +#include "pg_lookup_deposits.h" +#include "pg_insert_exchange_signkey.h" +#include "pg_insert_deposit.h" +#include "pg_lookup_refunds.h" +#include "pg_mark_contract_paid.h" +#include "pg_refund_coin.h" +#include "pg_lookup_order_status.h" +#include "pg_lookup_order_status_by_serial.h" +#include "pg_lookup_payment_status.h" #include "pg_set_transfer_status_to_confirmed.h" @@ -349,633 +358,6 @@ postgres_commit (void *cls) } -/** - * Closure for #lookup_deposits_cb(). - */ -struct LookupDepositsContext -{ - /** - * Function to call with results. - */ - TALER_MERCHANTDB_DepositsCallback cb; - - /** - * Closure for @e cls. - */ - void *cb_cls; - - /** - * Plugin context. - */ - struct PostgresClosure *pg; - - /** - * Transaction status (set). - */ - enum GNUNET_DB_QueryStatus qs; -}; - - -/** - * Function to be called with the results of a SELECT statement - * that has returned @a num_results results. - * - * @param[in,out] cls of type `struct LookupDepositsContext *` - * @param result the postgres result - * @param num_results the number of results in @a result - */ -static void -lookup_deposits_cb (void *cls, - PGresult *result, - unsigned int num_results) -{ - struct LookupDepositsContext *ldc = cls; - struct PostgresClosure *pg = ldc->pg; - - for (unsigned int i = 0; iqs = GNUNET_DB_STATUS_HARD_ERROR; - return; - } - ldc->cb (ldc->cb_cls, - exchange_url, - &coin_pub, - &amount_with_fee, - &deposit_fee, - &refund_fee, - &wire_fee); - GNUNET_PQ_cleanup_result (rs); - } - ldc->qs = num_results; -} - - -/** - * Lookup information about coins that were successfully deposited for a - * given contract. - * - * @param cls closure - * @param instance_id instance to lookup deposits for - * @param h_contract_terms proposal data's hashcode - * @param cb function to call with payment data - * @param cb_cls closure for @a cb - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_lookup_deposits ( - void *cls, - const char *instance_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - TALER_MERCHANTDB_DepositsCallback cb, - void *cb_cls) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (h_contract_terms), - GNUNET_PQ_query_param_end - }; - struct LookupDepositsContext ldc = { - .cb = cb, - .cb_cls = cb_cls, - .pg = pg - }; - enum GNUNET_DB_QueryStatus qs; - - /* no preflight check here, run in its own transaction by the caller! */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Finding deposits for h_contract_terms '%s'\n", - GNUNET_h2s (&h_contract_terms->hash)); - check_connection (pg); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - "lookup_deposits", - params, - &lookup_deposits_cb, - &ldc); - if (qs <= 0) - return qs; - return ldc.qs; -} - - -/** - * Insert an exchange signing key into our database. - * - * @param cls closure - * @param master_pub exchange master public key used for @a master_sig - * @param exchange_pub exchange signing key to insert - * @param start_date when does the signing key become valid - * @param expire_date when does the signing key stop being used - * @param end_date when does the signing key become void as proof - * @param master_sig signature of @a master_pub over the @a exchange_pub and the dates - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_exchange_signkey ( - void *cls, - const struct TALER_MasterPublicKeyP *master_pub, - const struct TALER_ExchangePublicKeyP *exchange_pub, - struct GNUNET_TIME_Timestamp start_date, - struct GNUNET_TIME_Timestamp expire_date, - struct GNUNET_TIME_Timestamp end_date, - const struct TALER_MasterSignatureP *master_sig) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (master_pub), - GNUNET_PQ_query_param_auto_from_type (exchange_pub), - GNUNET_PQ_query_param_timestamp (&start_date), - GNUNET_PQ_query_param_timestamp (&expire_date), - GNUNET_PQ_query_param_timestamp (&end_date), - GNUNET_PQ_query_param_auto_from_type (master_sig), - GNUNET_PQ_query_param_end - }; - - check_connection (pg); - postgres_preflight (pg); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_exchange_signkey", - params); - -} - - -/** - * Insert payment confirmation from the exchange into the database. - * - * @param cls closure - * @param instance_id instance to lookup deposits for - * @param deposit_timestamp time when the exchange generated the deposit confirmation - * @param h_contract_terms proposal data's hashcode - * @param coin_pub public key of the coin - * @param exchange_url URL of the exchange that issued @a coin_pub - * @param amount_with_fee amount the exchange will deposit for this coin - * @param deposit_fee fee the exchange will charge for this coin - * @param wire_fee wire fee the exchange charges - * @param refund_fee fee the exchange charges to refund this coin - * @param h_wire hash of the wire details of the target account of the merchant - * @param exchange_sig signature from exchange that coin was accepted - * @param exchange_pub signgin key that was used for @a exchange_sig - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_deposit ( - void *cls, - const char *instance_id, - struct GNUNET_TIME_Timestamp deposit_timestamp, - const struct TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const char *exchange_url, - const struct TALER_Amount *amount_with_fee, - const struct TALER_Amount *deposit_fee, - const struct TALER_Amount *refund_fee, - const struct TALER_Amount *wire_fee, - const struct TALER_MerchantWireHashP *h_wire, - const struct TALER_ExchangeSignatureP *exchange_sig, - const struct TALER_ExchangePublicKeyP *exchange_pub) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (h_contract_terms), - GNUNET_PQ_query_param_timestamp (&deposit_timestamp), /* $3 */ - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_string (exchange_url), - TALER_PQ_query_param_amount (amount_with_fee), /* $6/$7 */ - TALER_PQ_query_param_amount (deposit_fee), /* $8, $9 */ - TALER_PQ_query_param_amount (refund_fee), /* $10, $11 */ - TALER_PQ_query_param_amount (wire_fee), /* $12, $13 */ - GNUNET_PQ_query_param_auto_from_type (h_wire), /* $14 */ - GNUNET_PQ_query_param_auto_from_type (exchange_sig), /* $15 */ - GNUNET_PQ_query_param_auto_from_type (exchange_pub), /* $16 */ - GNUNET_PQ_query_param_end - }; - - /* no preflight check here, run in transaction by caller! */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Storing deposit for instance `%s' h_contract_terms `%s', coin_pub: `%s', amount_with_fee: %s\n", - instance_id, - GNUNET_h2s (&h_contract_terms->hash), - TALER_B2S (coin_pub), - TALER_amount2s (amount_with_fee)); - check_connection (pg); - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "insert_deposit", - params); - -} - - -/** - * Closure for #lookup_refunds_cb(). - */ -struct LookupRefundsContext -{ - /** - * Function to call for each refund. - */ - TALER_MERCHANTDB_RefundCallback rc; - - /** - * Closure for @e rc. - */ - void *rc_cls; - - /** - * Plugin context. - */ - struct PostgresClosure *pg; - - /** - * Transaction result. - */ - enum GNUNET_DB_QueryStatus qs; -}; - - -/** - * Function to be called with the results of a SELECT statement - * that has returned @a num_results results. - * - * @param cls of type `struct LookupRefundsContext *` - * @param result the postgres result - * @param num_results the number of results in @a result - */ -static void -lookup_refunds_cb (void *cls, - PGresult *result, - unsigned int num_results) -{ - struct LookupRefundsContext *lrc = cls; - struct PostgresClosure *pg = lrc->pg; - - for (unsigned int i = 0; iqs = GNUNET_DB_STATUS_HARD_ERROR; - return; - } - lrc->rc (lrc->rc_cls, - &coin_pub, - &refund_amount); - GNUNET_PQ_cleanup_result (rs); /* technically useless here */ - } - lrc->qs = num_results; -} - - -/** - * Obtain refunds associated with a contract. - * - * @param cls closure, typically a connection to the db - * @param instance_id instance to lookup refunds for - * @param h_contract_terms hash code of the contract - * @param rc function to call for each coin on which there is a refund - * @param rc_cls closure for @a rc - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_lookup_refunds ( - void *cls, - const char *instance_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - TALER_MERCHANTDB_RefundCallback rc, - void *rc_cls) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (h_contract_terms), - GNUNET_PQ_query_param_end - }; - struct LookupRefundsContext lrc = { - .rc = rc, - .rc_cls = rc_cls, - .pg = pg - }; - enum GNUNET_DB_QueryStatus qs; - - /* no preflight check here, run in transaction by caller! */ - TALER_LOG_DEBUG ("Looking for refund of h_contract_terms %s at `%s'\n", - GNUNET_h2s (&h_contract_terms->hash), - instance_id); - check_connection (pg); - qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - "lookup_refunds", - params, - &lookup_refunds_cb, - &lrc); - if (0 >= qs) - return qs; - return lrc.qs; -} - - -/** - * Mark contract as paid and store the current @a session_id - * for which the contract was paid. Deletes the underlying order - * and marks the locked stocks of the order as sold. - * - * @param cls closure - * @param instance_id instance to mark contract as paid for - * @param h_contract_terms hash of the contract that is now paid - * @param session_id the session that paid the contract - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_mark_contract_paid ( - void *cls, - const char *instance_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - const char *session_id) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (h_contract_terms), - GNUNET_PQ_query_param_string (session_id), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_QueryParam uparams[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (h_contract_terms), - GNUNET_PQ_query_param_end - }; - enum GNUNET_DB_QueryStatus qs; - - /* Session ID must always be given by the caller. */ - GNUNET_assert (NULL != session_id); - - /* no preflight check here, run in transaction by caller! */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Marking h_contract_terms '%s' of %s as paid for session `%s'\n", - GNUNET_h2s (&h_contract_terms->hash), - instance_id, - session_id); - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "mark_contract_paid", - params); - if (qs <= 0) - return qs; - qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, - "mark_inventory_sold", - uparams); - if (qs < 0) - return qs; /* 0: no inventory management, that's OK! */ - /* ON DELETE CASCADE deletes from merchant_order_locks */ - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "delete_completed_order", - uparams); -} - - -/** - * Function called during aborts to refund a coin. Marks the - * respective coin as refunded. - * - * @param cls closure - * @param instance_id instance to refund payment for - * @param h_contract_terms hash of the contract to refund coin for - * @param refund_timestamp timestamp of the refund - * @param coin_pub public key of the coin to refund (fully) - * @param reason text justifying the refund - * @return transaction status - * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a coin_pub is unknown to us; - * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the request is valid, - * regardless of whether it actually increased the refund - */ -static enum GNUNET_DB_QueryStatus -postgres_refund_coin (void *cls, - const char *instance_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - struct GNUNET_TIME_Timestamp refund_timestamp, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const char *reason) -{ - struct PostgresClosure *pg = cls; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (h_contract_terms), - GNUNET_PQ_query_param_timestamp (&refund_timestamp), - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_string (reason), - GNUNET_PQ_query_param_end - }; - - return GNUNET_PQ_eval_prepared_non_select (pg->conn, - "refund_coin", - params); -} - - -/** - * Retrieve contract terms given its @a order_id - * - * @param cls closure - * @param instance_id instance's identifier - * @param order_id order to lookup contract for - * @param[out] h_contract_terms set to the hash of the contract. - * @param[out] paid set to the payment status of the contract - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_lookup_order_status ( - void *cls, - const char *instance_id, - const char *order_id, - struct TALER_PrivateContractHashP *h_contract_terms, - bool *paid) -{ - struct PostgresClosure *pg = cls; - uint8_t paid8; - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_string (order_id), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", - h_contract_terms), - GNUNET_PQ_result_spec_auto_from_type ("paid", - &paid8), - GNUNET_PQ_result_spec_end - }; - - check_connection (pg); - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_order_status", - params, - rs); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) - *paid = (0 != paid8); - else - *paid = false; /* just to be safe(r) */ - return qs; -} - - -/** - * Retrieve contract terms given its @a order_serial - * - * @param cls closure - * @param instance_id instance's identifier - * @param order_serial serial ID of the order to look up - * @param[out] order_id set to ID of the order - * @param[out] h_contract_terms set to the hash of the contract. - * @param[out] paid set to the payment status of the contract - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_lookup_order_status_by_serial (void *cls, - const char *instance_id, - uint64_t order_serial, - char **order_id, - struct TALER_PrivateContractHashP * - h_contract_terms, - bool *paid) -{ - struct PostgresClosure *pg = cls; - uint8_t paid8; - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_uint64 (&order_serial), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", - h_contract_terms), - GNUNET_PQ_result_spec_auto_from_type ("paid", - &paid8), - GNUNET_PQ_result_spec_string ("order_id", - order_id), - GNUNET_PQ_result_spec_end - }; - - check_connection (pg); - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_order_status_by_serial", - params, - rs); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) - *paid = (0 != paid8); - else - *paid = false; /* just to be safe(r) */ - return qs; -} - - -/** - * Retrieve payment and wire status for a given @a order_serial and session ID. - * - * @param cls closure - * @param order_serial identifies the order - * @param session_id session for which to check the payment status, NULL for any - * @param[out] paid set to the payment status of the contract - * @param[out] wired set to the wire transfer status of the exchange payment - * @return transaction status - */ -static enum GNUNET_DB_QueryStatus -postgres_lookup_payment_status (void *cls, - uint64_t order_serial, - const char *session_id, - bool *paid, - bool *wired) -{ - struct PostgresClosure *pg = cls; - uint8_t paid8; - uint8_t wired8; - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("paid", - &paid8), - GNUNET_PQ_result_spec_auto_from_type ("wired", - &wired8), - GNUNET_PQ_result_spec_end - }; - check_connection (pg); - if (NULL == session_id) - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&order_serial), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_payment_status", - params, - rs); - } - else - { - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_uint64 (&order_serial), - GNUNET_PQ_query_param_string (session_id), - GNUNET_PQ_query_param_end - }; - - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "lookup_payment_status_session_id", - params, - rs); - } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) - { - *paid = (0 != paid8); - *wired = (0 != wired8); - } - else - { - *paid = false; /* just to be safe(r) */ - *wired = false; /* just to be safe(r) */ - } - return qs; -} - - /** * Closure for lookup_deposits_by_order_cb(). */ @@ -5428,205 +4810,6 @@ postgres_connect (void *cls) struct GNUNET_PQ_PreparedStatement ps[] = { GNUNET_PQ_make_prepare ("end_transaction", "COMMIT"), - /* for postgres_lookup_deposits() */ - GNUNET_PQ_make_prepare ("lookup_deposits", - "SELECT" - " exchange_url" - ",coin_pub" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",deposit_fee_val" - ",deposit_fee_frac" - ",refund_fee_val" - ",refund_fee_frac" - ",wire_fee_val" - ",wire_fee_frac" - " FROM merchant_deposits" - " WHERE order_serial=" - " (SELECT order_serial" - " FROM merchant_contract_terms" - " WHERE h_contract_terms=$2" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1))"), - /* for postgres_insert_exchange_signkey() */ - GNUNET_PQ_make_prepare ("insert_exchange_signkey", - "INSERT INTO merchant_exchange_signing_keys" - "(master_pub" - ",exchange_pub" - ",start_date" - ",expire_date" - ",end_date" - ",master_sig)" - "VALUES" - "($1, $2, $3, $4, $5, $6)"), - /* for postgres_insert_deposit() */ - GNUNET_PQ_make_prepare ("insert_deposit", - "WITH md AS" - " (SELECT account_serial, merchant_serial" - " FROM merchant_accounts" - " WHERE h_wire=$14" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1))" - ", ed AS" - " (SELECT signkey_serial" - " FROM merchant_exchange_signing_keys" - " WHERE exchange_pub=$16" - " ORDER BY start_date DESC" - " LIMIT 1)" - "INSERT INTO merchant_deposits" - "(order_serial" - ",deposit_timestamp" - ",coin_pub" - ",exchange_url" - ",amount_with_fee_val" - ",amount_with_fee_frac" - ",deposit_fee_val" - ",deposit_fee_frac" - ",refund_fee_val" - ",refund_fee_frac" - ",wire_fee_val" - ",wire_fee_frac" - ",exchange_sig" - ",signkey_serial" - ",account_serial)" - " SELECT " - " order_serial" - " ,$3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $15" - " ,ed.signkey_serial" - " ,md.account_serial" - " FROM merchant_contract_terms" - " JOIN md USING (merchant_serial)" - " FULL OUTER JOIN ed ON TRUE" - " WHERE h_contract_terms=$2"), - /* for postgres_lookup_refunds() */ - GNUNET_PQ_make_prepare ("lookup_refunds", - "SELECT" - " coin_pub" - ",refund_amount_val" - ",refund_amount_frac" - " FROM merchant_refunds" - " WHERE order_serial=" - " (SELECT order_serial" - " FROM merchant_contract_terms" - " WHERE h_contract_terms=$2" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1))"), - /* for postgres_mark_contract_paid() */ - GNUNET_PQ_make_prepare ("mark_contract_paid", - "UPDATE merchant_contract_terms SET" - " paid=TRUE" - ",session_id=$3" - " WHERE h_contract_terms=$2" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1)"), - /* for postgres_mark_contract_paid() */ - GNUNET_PQ_make_prepare ("mark_inventory_sold", - "UPDATE merchant_inventory SET" - " total_sold=total_sold + order_locks.total_locked" - " FROM (SELECT total_locked,product_serial" - " FROM merchant_order_locks" - " WHERE order_serial=" - " (SELECT order_serial" - " FROM merchant_contract_terms" - " WHERE h_contract_terms=$2" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1))" - " ) AS order_locks" - " WHERE merchant_inventory.product_serial" - " =order_locks.product_serial"), - /* for postgres_mark_contract_paid() */ - GNUNET_PQ_make_prepare ("delete_completed_order", - "WITH md AS" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1) " - "DELETE" - " FROM merchant_orders" - " WHERE order_serial=" - " (SELECT order_serial" - " FROM merchant_contract_terms" - " JOIN md USING (merchant_serial)" - " WHERE h_contract_terms=$2)"), - /* for postgres_refund_coin() */ - GNUNET_PQ_make_prepare ("refund_coin", - "INSERT INTO merchant_refunds" - "(order_serial" - ",rtransaction_id" - ",refund_timestamp" - ",coin_pub" - ",reason" - ",refund_amount_val" - ",refund_amount_frac" - ") " - "SELECT " - " order_serial" - ",0" /* rtransaction_id always 0 for /abort */ - ",$3" - ",coin_pub" - ",$5" - ",amount_with_fee_val" - ",amount_with_fee_frac" - " FROM merchant_deposits" - " WHERE coin_pub=$4" - " AND order_serial=" - " (SELECT order_serial" - " FROM merchant_contract_terms" - " WHERE h_contract_terms=$2" - " AND merchant_serial=" - " (SELECT merchant_serial" - " FROM merchant_instances" - " WHERE merchant_id=$1))"), - - /* for postgres_lookup_order_status() */ - GNUNET_PQ_make_prepare ("lookup_order_status", - "SELECT" - " h_contract_terms" - ",paid" - " FROM merchant_contract_terms" - " WHERE merchant_serial=" - " (SELECT merchant_serial " - " FROM merchant_instances" - " WHERE merchant_id=$1)" - " AND order_id=$2"), - - /* for postgres_lookup_order_status_by_serial() */ - GNUNET_PQ_make_prepare ("lookup_order_status_by_serial", - "SELECT" - " h_contract_terms" - ",order_id" - ",paid" - " FROM merchant_contract_terms" - " WHERE merchant_serial=" - " (SELECT merchant_serial " - " FROM merchant_instances" - " WHERE merchant_id=$1)" - " AND order_serial=$2"), - - /* for postgres_lookup_payment_status() */ - GNUNET_PQ_make_prepare ("lookup_payment_status", - "SELECT" - " wired" - ",paid" - " FROM merchant_contract_terms" - " WHERE order_serial=$1"), - /* for postgres_lookup_payment_status() */ - GNUNET_PQ_make_prepare ("lookup_payment_status_session_id", - "SELECT" - " wired" - ",paid" - " FROM merchant_contract_terms" - " WHERE order_serial=$1" - " AND session_id=$2"), /* for postgres_lookup_deposits_by_order() */ GNUNET_PQ_make_prepare ("lookup_deposits_by_order", "SELECT" @@ -6700,16 +5883,24 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) = &TMH_PG_update_contract_terms; plugin->delete_contract_terms = &TMH_PG_delete_contract_terms; - plugin->lookup_deposits = &postgres_lookup_deposits; - plugin->insert_exchange_signkey = &postgres_insert_exchange_signkey; - plugin->insert_deposit = &postgres_insert_deposit; - plugin->lookup_refunds = &postgres_lookup_refunds; - plugin->mark_contract_paid = &postgres_mark_contract_paid; - plugin->refund_coin = &postgres_refund_coin; - plugin->lookup_order_status = &postgres_lookup_order_status; - plugin->lookup_order_status_by_serial = - &postgres_lookup_order_status_by_serial; - plugin->lookup_payment_status = &postgres_lookup_payment_status; + plugin->lookup_deposits + = &TMH_PG_lookup_deposits; + plugin->insert_exchange_signkey + = &TMH_PG_insert_exchange_signkey; + plugin->insert_deposit + = &TMH_PG_insert_deposit; + plugin->lookup_refunds + = &TMH_PG_lookup_refunds; + plugin->mark_contract_paid + = &TMH_PG_mark_contract_paid; + plugin->refund_coin + = &TMH_PG_refund_coin; + plugin->lookup_order_status + = &TMH_PG_lookup_order_status; + plugin->lookup_order_status_by_serial + = &TMH_PG_lookup_order_status_by_serial; + plugin->lookup_payment_status + = &TMH_PG_lookup_payment_status; plugin->lookup_deposits_by_order = &postgres_lookup_deposits_by_order; plugin->lookup_transfer_details_by_order = &postgres_lookup_transfer_details_by_order; -- cgit v1.2.3