aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb/plugin_exchangedb_postgres.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-05-06 12:55:44 +0200
committerChristian Grothoff <christian@grothoff.org>2016-05-06 12:55:44 +0200
commita4d99f229a0a9c1e0c94c7e4ee5bfd8986b796a3 (patch)
tree8b8b144099bb8752e9f58f9671ebd31b2b9741b0 /src/exchangedb/plugin_exchangedb_postgres.c
parent0c959e75d109fc914ab8891518f7963ade74cff8 (diff)
implement logic to store refund data into postgres database
Diffstat (limited to 'src/exchangedb/plugin_exchangedb_postgres.c')
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c171
1 files changed, 144 insertions, 27 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index b189b7a17..4dee4b54c 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -366,6 +366,25 @@ postgres_create_tables (void *cls)
",PRIMARY KEY (session_hash, oldcoin_index)" /* a coin can be used only
once in a refresh session */
") ");
+ /* Table with information about coins that have been refunded. (Technically
+ one of the deposit operations that a coin was involved with is refunded.)*/
+ SQLEXEC("CREATE TABLE IF NOT EXISTS refunds "
+ "(coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)"
+ ",merchant_pub BYTEA NOT NULL CHECK(LENGTH(merchant_pub)=32)"
+ ",merchant_sig BYTEA NOT NULL CHECK(LENGTH(merchant_pub)=64)"
+ ",h_contract BYTEA NOT NULL CHECK(LENGTH(merchant_pub)=64)"
+ ",transaction_id INT8 NOT NULL"
+ ",rtransaction_id INT8 NOT NULL"
+ ",amount_with_fee_val INT8 NOT NULL"
+ ",amount_with_fee_frac INT4 NOT NULL"
+ ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+ ",refund_fee_val INT8 NOT NULL"
+ ",refund_fee_frac INT4 NOT NULL"
+ ",refund_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
+ ",PRIMARY KEY (coin_pub, merchant_pub, transaction_id, rtransaction_id)" /* this combo must be unique, and we usually select by coin_pub */
+ ") ");
+
+
/* Table with information about the desired denominations to be created
during a refresh operation; contains the denomination key for each
of the coins (for a given refresh session) */
@@ -892,6 +911,26 @@ postgres_prepare (PGconn *db_conn)
" $11, $12, $13, $14, $15, $16, $17, $18);",
18, NULL);
+ /* Used in #postgres_insert_refund() to store refund information */
+ PREPARE ("insert_refund",
+ "INSERT INTO refunds "
+ "(coin_pub "
+ ",merchant_pub "
+ ",merchant_sig "
+ ",h_contract "
+ ",transaction_id "
+ ",rtransaction_id "
+ ",amount_with_fee_val "
+ ",amount_with_fee_frac "
+ ",amount_with_fee_curr "
+ ",refund_fee_val "
+ ",refund_fee_frac "
+ ",refund_fee_curr "
+ ") VALUES "
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
+ " $11, $12);",
+ 12, NULL);
+
/* Fetch an existing deposit request, used to ensure idempotency
during /deposit processing. Used in #postgres_have_deposit(). */
PREPARE ("get_deposit",
@@ -995,6 +1034,17 @@ postgres_prepare (PGconn *db_conn)
" WHERE serial_id=$1",
1, NULL);
+ /* Used in #postgres_test_deposit_done() */
+ PREPARE ("test_deposit_done",
+ "SELECT done"
+ " FROM deposits"
+ " WHERE coin_pub=$1"
+ " AND transaction_id=$2"
+ " AND merchant_pub=$3"
+ " AND h_contract=$4"
+ " AND h_wire=$5",
+ 5, NULL);
+
/* Used in #postgres_get_coin_transactions() to obtain information
about how a coin has been spend with /deposit requests. */
PREPARE ("get_deposit_with_coin_pub",
@@ -2191,8 +2241,50 @@ postgres_test_deposit_done (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Deposit *deposit)
{
- GNUNET_break (0); // not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
+ GNUNET_PQ_query_param_uint64 (&deposit->transaction_id),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "test_deposit_done",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ if (0 == PQntuples (result))
+ {
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ {
+ /* NOTE: maybe wrong type for a 'boolean' */
+ uint32_t done;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint32 ("done",
+ &done),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return (done ? GNUNET_YES : GNUNET_NO);
+ }
}
@@ -2449,29 +2541,26 @@ postgres_insert_deposit (void *cls,
{
PGresult *result;
int ret;
-
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
- GNUNET_PQ_query_param_rsa_public_key (deposit->coin.denom_pub.rsa_public_key),
- GNUNET_PQ_query_param_rsa_signature (deposit->coin.denom_sig.rsa_signature),
- GNUNET_PQ_query_param_uint64 (&deposit->transaction_id),
- TALER_PQ_query_param_amount (&deposit->amount_with_fee),
- TALER_PQ_query_param_amount (&deposit->deposit_fee),
- GNUNET_PQ_query_param_absolute_time (&deposit->timestamp),
- GNUNET_PQ_query_param_absolute_time (&deposit->refund_deadline),
- GNUNET_PQ_query_param_absolute_time (&deposit->wire_deadline),
- GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract),
- GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire),
- GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
- TALER_PQ_query_param_json (deposit->wire),
- GNUNET_PQ_query_param_end
- };
- result = GNUNET_PQ_exec_prepared (session->conn,
- "insert_deposit",
- params);
- }
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
+ GNUNET_PQ_query_param_rsa_public_key (deposit->coin.denom_pub.rsa_public_key),
+ GNUNET_PQ_query_param_rsa_signature (deposit->coin.denom_sig.rsa_signature),
+ GNUNET_PQ_query_param_uint64 (&deposit->transaction_id),
+ TALER_PQ_query_param_amount (&deposit->amount_with_fee),
+ TALER_PQ_query_param_amount (&deposit->deposit_fee),
+ GNUNET_PQ_query_param_absolute_time (&deposit->timestamp),
+ GNUNET_PQ_query_param_absolute_time (&deposit->refund_deadline),
+ GNUNET_PQ_query_param_absolute_time (&deposit->wire_deadline),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
+ TALER_PQ_query_param_json (deposit->wire),
+ GNUNET_PQ_query_param_end
+ };
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "insert_deposit",
+ params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
BREAK_DB_ERR (result);
@@ -2499,8 +2588,36 @@ postgres_insert_refund (void *cls,
struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Refund *refund)
{
- GNUNET_break (0); // not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&refund->coin.coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&refund->merchant_pub),
+ GNUNET_PQ_query_param_auto_from_type (&refund->merchant_sig),
+ GNUNET_PQ_query_param_auto_from_type (&refund->h_contract),
+ GNUNET_PQ_query_param_uint64 (&refund->transaction_id),
+ GNUNET_PQ_query_param_uint64 (&refund->rtransaction_id),
+ TALER_PQ_query_param_amount (&refund->refund_amount),
+ TALER_PQ_query_param_amount (&refund->refund_fee),
+ GNUNET_PQ_query_param_end
+ };
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (&refund->refund_amount,
+ &refund->refund_fee));
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "insert_refund",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}