From 0c4579085a1b9f09b9e41efe69bf2deadfa22cd7 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Thu, 5 Mar 2015 18:16:32 +0100 Subject: [PATCH] db: Implement reserves_in_insert() --- src/mint/mint_db.c | 164 +++++++++++++++++++++++++++++++++++++++++++++ src/mint/mint_db.h | 17 +++++ 2 files changed, 181 insertions(+) diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c index 0bd888221..71e222008 100644 --- a/src/mint/mint_db.c +++ b/src/mint/mint_db.c @@ -297,6 +297,15 @@ TALER_MINT_DB_prepare (PGconn *db_conn) "WHERE reserve_pub=$1 " "LIMIT 1; ", 1, NULL); + PREPARE ("create_reserve", + "INSERT INTO reserves (" + " reserve_pub," + " current_balance_value," + " current_balance_fraction," + " balance_currency," + " expiration_date) VALUES (" + "$1, $2, $3, $4, $5);", + 5, NULL); PREPARE ("update_reserve", "UPDATE reserves " "SET" @@ -305,6 +314,14 @@ TALER_MINT_DB_prepare (PGconn *db_conn) ",expiration_date=$4 " "WHERE reserve_pub=$1 ", 4, NULL); + PREPARE ("create_reserves_in_transaction", + "INSERT INTO reserves_in (" + " reserve_pub," + " balance_value," + " balance_fraction," + " expiration_date) VALUES (" + " $1, $2, $3, $4);", + 4, NULL); PREPARE ("insert_collectable_blindcoins", "INSERT INTO collectable_blindcoins ( " " blind_ev, blind_ev_sig " @@ -732,8 +749,155 @@ TALER_MINT_DB_reserve_get (PGconn *db, } +/** + * Updates a reserve with the data from the given reserve structure. + * + * @param db the database connection + * @param reserve the reserve structure whose data will be used to update the + * corresponding record in the database. + * @return #GNUNET_OK upon successful update; #GNUNET_SYSERR upon any error + */ +int +reserves_update (PGconn *db, + struct Reserve *reserve) +{ + PGresult *result; + struct TALER_AmountNBO balance_nbo; + struct GNUNET_TIME_AbsoluteNBO expiry_nbo; + int ret; + + if ((NULL == reserve) || (NULL == reserve->pub)) + return GNUNET_SYSERR; + ret = GNUNET_OK; + struct TALER_DB_QueryParam params[] = { + TALER_DB_QUERY_PARAM_PTR (reserve->pub), + TALER_DB_QUERY_PARAM_PTR (&balance_nbo.value), + TALER_DB_QUERY_PARAM_PTR (&balance_nbo.fraction), + TALER_DB_QUERY_PARAM_PTR (&expiry_nbo), + TALER_DB_QUERY_PARAM_END + }; + balance_nbo = TALER_amount_hton (reserve->balance); + expiry_nbo = GNUNET_TIME_absolute_hton (reserve->expiry); + result = TALER_DB_exec_prepared (db, + "update_reserve", + params); + if (PGRES_COMMAND_OK != PQresultStatus(result)) + { + QUERY_ERR (result); + ret = GNUNET_SYSERR; + } + PQclear (result); + return ret; +} +/** + * Insert a incoming transaction into reserves. New reserves are also created + * through this function. + * + * @param db the database connection handle + * @param reserve the reserve structure. The public key of the reserve should + * be set here. Upon successful execution of this function, the + * balance and expiration of the reserve will be updated. + * @param balance the amount that has to be added to the reserve + * @param expiry the new expiration time for the reserve + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failures + */ +int +TALER_MINT_DB_reserves_in_insert (PGconn *db, + struct Reserve *reserve, + const struct TALER_Amount balance, + const struct GNUNET_TIME_Absolute expiry) +{ + struct TALER_AmountNBO balance_nbo; + struct GNUNET_TIME_AbsoluteNBO expiry_nbo; + PGresult *result; + int reserve_exists; + + if (NULL == reserve) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != TALER_MINT_DB_transaction (db)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + reserve_exists = TALER_MINT_DB_reserve_get (db, reserve); + if (GNUNET_SYSERR == reserve_exists) + { + TALER_MINT_DB_rollback (db); + return GNUNET_SYSERR; + } + balance_nbo = TALER_amount_hton (balance); + expiry_nbo = GNUNET_TIME_absolute_hton (expiry); + if (GNUNET_NO == reserve_exists) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Reserve does not exist; creating a new one\n"); + struct TALER_DB_QueryParam params[] = { + TALER_DB_QUERY_PARAM_PTR_SIZED (reserve->pub, sizeof (reserve->pub)), + TALER_DB_QUERY_PARAM_PTR (&balance_nbo.value), + TALER_DB_QUERY_PARAM_PTR (&balance_nbo.fraction), + TALER_DB_QUERY_PARAM_PTR_SIZED (balance_nbo.currency, + TALER_CURRENCY_LEN), + TALER_DB_QUERY_PARAM_PTR (&expiry_nbo), + TALER_DB_QUERY_PARAM_END + }; + result = TALER_DB_exec_prepared (db, + "create_reserve", + params); + if (PGRES_COMMAND_OK != PQresultStatus(result)) + { + QUERY_ERR (result); + goto rollback; + } + } + PQclear (result); result = NULL; + /* create new incoming transaction */ + struct TALER_DB_QueryParam params[] = { + TALER_DB_QUERY_PARAM_PTR (reserve->pub), + TALER_DB_QUERY_PARAM_PTR (&balance_nbo.value), + TALER_DB_QUERY_PARAM_PTR (&balance_nbo.fraction), + TALER_DB_QUERY_PARAM_PTR (&expiry_nbo), + TALER_DB_QUERY_PARAM_END + }; + result = TALER_DB_exec_prepared (db, + "create_reserves_in_transaction", + params); + if (PGRES_COMMAND_OK != result) + { + QUERY_ERR (result); + goto rollback; + } + PQclear (result); result = NULL; + if (GNUNET_NO == reserve_exists) + { + if (GNUNET_OK != TALER_MINT_DB_commit (db)) + return GNUNET_SYSERR; + reserve->balance = balance; + reserve->expiry = expiry; + return GNUNET_OK; + } + /* Update reserve */ + struct Reserve updated_reserve; + updated_reserve.pub = reserve->pub; + updated_reserve.balance = TALER_amount_add (reserve->balance, balance); + updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry, reserve->expiry); + if (GNUNET_OK != reserves_update (db, &updated_reserve)) + goto rollback; + if (GNUNET_OK != TALER_MINT_DB_commit (db)) + return GNUNET_SYSERR; + reserve->balance = updated_reserve.balance; + reserve->expiry = updated_reserve.expiry; + return GNUNET_OK; + + rollback: + PQclear (result); + TALER_MINT_DB_rollback (db); + return GNUNET_SYSERR; +} /** diff --git a/src/mint/mint_db.h b/src/mint/mint_db.h index b26c70b26..74f0c2d14 100644 --- a/src/mint/mint_db.h +++ b/src/mint/mint_db.h @@ -204,6 +204,23 @@ TALER_MINT_DB_reserve_get (PGconn *db, struct Reserve *reserve); +/** + * Insert a incoming transaction into reserves. New reserves are also created + * through this function. + * + * @param db the database connection handle + * @param reserve the reserve structure. The public key of the reserve should + * be set here. Upon successful execution of this function, the + * balance and expiration of the reserve will be updated. + * @param balance the amount that has to be added to the reserve + * @param expiry the new expiration time for the reserve + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failures + */ +int +TALER_MINT_DB_reserves_in_insert (PGconn *db, + struct Reserve *reserve, + const struct TALER_Amount balance, + const struct GNUNET_TIME_Absolute expiry); /* FIXME: need call to convert CollectableBlindcoin to JSON (#3527) */