diff options
author | Marcello Stanisci <marcello.stanisci@inria.fr> | 2015-08-06 15:50:52 +0200 |
---|---|---|
committer | Marcello Stanisci <marcello.stanisci@inria.fr> | 2015-08-06 15:50:52 +0200 |
commit | 21d71d7eae49f63d82ee91db62e3b2f7fb739abf (patch) | |
tree | 6f5e07244e3f86fffe2b22135ea2d06da3eee5c6 | |
parent | 8b32ffd60d2d6f34f35fd308183a4b09510c5e7b (diff) | |
download | merchant-21d71d7eae49f63d82ee91db62e3b2f7fb739abf.tar.gz merchant-21d71d7eae49f63d82ee91db62e3b2f7fb739abf.tar.bz2 merchant-21d71d7eae49f63d82ee91db62e3b2f7fb739abf.zip |
fixing insertion into "contracts" DB, prior to merge new merchant "melted"
sources back again into their proper directory"
-rw-r--r-- | src/backend/melted/merchant_db.c | 67 | ||||
-rw-r--r-- | src/backend/melted/merchant_db.h | 11 | ||||
-rw-r--r-- | src/backend/melted/taler-merchant-httpd.c | 34 |
3 files changed, 60 insertions, 52 deletions
diff --git a/src/backend/melted/merchant_db.c b/src/backend/melted/merchant_db.c index 6345f8a6..274de25a 100644 --- a/src/backend/melted/merchant_db.c +++ b/src/backend/melted/merchant_db.c @@ -87,16 +87,17 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp) (void) GNUNET_asprintf (&sql, "BEGIN TRANSACTION;" "CREATE %1$s TABLE IF NOT EXISTS contracts (" - "transaction_id SERIAL8 PRIMARY KEY," + "contract_id INT8 PRIMARY KEY," "amount INT8 NOT NULL," "amount_fraction INT4 NOT NULL," + "amount_currency VARCHAR(" TALER_CURRENCY_LEN_STR ") NOT NULL," "description TEXT NOT NULL," - "nounce BYTEA NOT NULL," + "nounce INT8 NOT NULL," "expiry INT8 NOT NULL," "product INT8 NOT NULL);" "CREATE %1$s TABLE IF NOT EXISTS checkouts (" "coin_pub BYTEA PRIMARY KEY," - "transaction_id INT8 REFERENCES contracts(transaction_id)," + "contract_id INT8 REFERENCES contracts(contract_id)," "amount INT4 NOT NULL," "amount_fraction INT4 NOT NULL," "coin_sig BYTEA NOT NULL);", @@ -118,11 +119,10 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp) (conn, "contract_create", "INSERT INTO contracts" - "(amount, amount_fraction, description," - "nounce, expiry, product) VALUES" - "($1, $2, $3, $4, $5, $6)" - "RETURNING transaction_id", - 6, NULL))); + "(contract_id, amount, amount_fraction, amount_currency," + "description, nounce, expiry, product) VALUES" + "($1, $2, $3, $4, $5, $6, $7, $8)", + 8, NULL))); EXITIF (PGRES_COMMAND_OK != (status = PQresultStatus(res))); PQclear (res); @@ -133,7 +133,7 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp) "product" ") FROM contracts " "WHERE (" - "transaction_id=$1" + "contract_id=$1" ")", 1, NULL))); EXITIF (PGRES_COMMAND_OK != (status = PQresultStatus(res))); @@ -144,7 +144,7 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp) "checkout_create", "INSERT INTO checkouts (" "coin_pub," - "transaction_id," + "contract_id," "amount," "amount_fraction," "coin_sig" @@ -162,8 +162,8 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp) "product" ") FROM contracts " "WHERE " - "transaction_id IN (" - "SELECT (transaction_id) FROM checkouts " + "contract_id IN (" + "SELECT (contract_id) FROM checkouts " "WHERE coin_pub=$1" ")", 1, NULL))); @@ -189,64 +189,67 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp) * @param conn the database connection * @param expiry the time when the contract will expire * @param amount the taler amount corresponding to the contract + * @param c_id contract's id * @param desc descripition of the contract * @param nounce a random 64-bit nounce * @param product description to identify a product - * @return -1 upon error; the serial id of the inserted contract upon success + * @return GNUNET_OK on success, GNUNET_SYSERR upon error */ -long long + +uint32_t MERCHANT_DB_contract_create (PGconn *conn, - struct GNUNET_TIME_Absolute expiry, - struct TALER_Amount *amount, + const struct GNUNET_TIME_Absolute *expiry, + const struct TALER_Amount *amount, + uint64_t c_id, const char *desc, uint64_t nounce, uint64_t product) { PGresult *res; + #if 0 uint64_t expiry_ms_nbo; uint64_t value_nbo; uint32_t fraction_nbo; uint64_t nounce_nbo; + #endif ExecStatusType status; - uint64_t id; + #if 0 + /* + NOTE: the conversion to nl(l) happens *inside* the query param helpers; since + the policy imposes this format for storing values. */ value_nbo = GNUNET_htonll (amount->value); fraction_nbo = GNUNET_htonll (amount->fraction); nounce_nbo = GNUNET_htonll (nounce); expiry_ms_nbo = GNUNET_htonll (expiry.abs_value_us); product = GNUNET_htonll (product); + #endif /* ported. To be tested/compiled */ struct TALER_PQ_QueryParam params[] = { - TALER_PQ_query_param_uint32 (&value_nbo), //FIXME uninitialized! - TALER_PQ_query_param_uint32 (&fraction_nbo), //FIXME uninitialized! + TALER_PQ_query_param_uint64 (&c_id), + TALER_PQ_query_param_amount (amount), /* a *string* is being put in the following statement, though the API talks about a *blob*. Will this be liked by the DB ? */ + // the following inserts a string as a blob. Will Taler provide a param-from-string helper? TALER_PQ_query_param_fixed_size (desc, strlen(desc)), - TALER_PQ_query_param_uint64 (&nounce_nbo), //FIXME uninitialized! - TALER_PQ_query_param_uint64 (&expiry_ms_nbo), //FIXME uninitialized! + TALER_PQ_query_param_uint64 (&nounce), + TALER_PQ_query_param_absolute_time (expiry), TALER_PQ_query_param_uint64 (&product), TALER_PQ_query_param_end }; - struct TALER_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_uint64 ("transaction_id", &id), - TALER_PQ_result_spec_end - }; - - + /* NOTE: the statement is prepared by MERCHANT_DB_initialize function */ res = TALER_PQ_exec_prepared (conn, "contract_create", params); status = PQresultStatus (res); - EXITIF (PGRES_TUPLES_OK != status); - EXITIF (1 != PQntuples (res)); - EXITIF (GNUNET_YES != TALER_PQ_extract_result (res, rs, 0)); + EXITIF (PGRES_COMMAND_OK != status); PQclear (res); - return GNUNET_ntohll ((uint64_t) id); + return GNUNET_OK; EXITIF_exit: PQclear (res); - return -1; + return GNUNET_SYSERR; } long long diff --git a/src/backend/melted/merchant_db.h b/src/backend/melted/merchant_db.h index bf334989..a723b229 100644 --- a/src/backend/melted/merchant_db.h +++ b/src/backend/melted/merchant_db.h @@ -64,15 +64,18 @@ MERCHANT_DB_initialize (PGconn *conn, int tmp); * @param conn the database connection * @param expiry the time when the contract will expire * @param amount the taler amount corresponding to the contract + * @param c_id this contract's identification number * @param desc descripition of the contract * @param nounce a random 64-bit nounce * @param product description to identify a product - * @return -1 upon error; the serial id of the inserted contract upon success + * @return GNUNET_OK on success, GNUNET_SYSERR upon error */ -long long + +uint32_t MERCHANT_DB_contract_create (PGconn *conn, - struct GNUNET_TIME_Absolute expiry, - struct TALER_Amount *amount, + const struct GNUNET_TIME_Absolute *expiry, + const struct TALER_Amount *amount, + uint64_t c_id, const char *desc, uint64_t nounce, uint64_t product); diff --git a/src/backend/melted/taler-merchant-httpd.c b/src/backend/melted/taler-merchant-httpd.c index ea3a22de..46379809 100644 --- a/src/backend/melted/taler-merchant-httpd.c +++ b/src/backend/melted/taler-merchant-httpd.c @@ -363,6 +363,7 @@ hash_wireformat (uint64_t nounce) * Make a binary blob representing a contract, store it into the DB, sign it * and return a pointer to it. * @param a 0-terminated string representing the description of this +* @param c_id contract id provided by the frontend * purchase (it should contain a human readable description of the good * in question) * @param product some product numerical id. Its indended use is to link the @@ -373,27 +374,26 @@ hash_wireformat (uint64_t nounce) */ struct Contract * -generate_and_store_contract (const char *a, uint64_t product, struct TALER_Amount *price) +generate_and_store_contract (const char *a, uint64_t c_id, uint64_t product, struct TALER_Amount *price) { struct Contract *contract; struct GNUNET_TIME_Absolute expiry; uint64_t nounce; - long long contract_id; uint64_t contract_id_nbo; expiry = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), GNUNET_TIME_UNIT_DAYS); ROUND_TO_SECS (expiry, abs_value_us); nounce = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); - contract_id = MERCHANT_DB_contract_create (db_conn, - expiry, - price, - a, - nounce, - product); - EXITIF (-1 == contract_id); - contract_id_nbo = GNUNET_htonll ((uint64_t) contract_id); + EXITIF (GNUNET_SYSERR == MERCHANT_DB_contract_create (db_conn, + &expiry, + price, + c_id, + a, + nounce, + product)); + contract_id_nbo = GNUNET_htonll ((uint64_t) c_id); contract = GNUNET_malloc (sizeof (struct Contract) + strlen (a) + 1); contract->purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_CONTRACT); contract->purpose.size = htonl (sizeof (struct Contract) @@ -472,6 +472,7 @@ url_handler (void *cls, unsigned int status; unsigned int no_destroy; json_int_t prod_id; + json_int_t contract_id; struct Contract *contract; struct MHD_Response *resp; struct TALER_Amount price; @@ -528,6 +529,7 @@ url_handler (void *cls, "desc" : string human-readable describing this deal, "product" : uint64-like integer referring to the product in some DB adminstered by the frontend, + "cid" : uint64-like integer, this contract's id "price" : a 'struct TALER_Amount' in the Taler compliant JSON format } */ @@ -552,9 +554,7 @@ url_handler (void *cls, printf ("desc is %s\n", desc_test); TALER_json_to_amount (json_price, &price); printf ("cur_test is %s\n", price.currency); - #endif json_error_t err; - #if 0 if (res = json_unpack_ex (root, &err, JSON_VALIDATE_ONLY, "{s:s, s:I, s:o}", "desc", //&desc, @@ -564,14 +564,16 @@ url_handler (void *cls, //json_price )) #else - if (res = json_unpack (root, "{s:s, s:I, s:o}", + if ((res = json_unpack (root, "{s:s, s:I, s:I, s:o}", "desc", &desc, "product", - &prod_id, + &prod_id, + "cid", + &contract_id, "price", &json_price - )) + ))) #endif @@ -590,7 +592,7 @@ url_handler (void *cls, else { /* Let's generate this contract! */ - if (NULL == (contract = generate_and_store_contract (desc, prod_id, &price))) + if (NULL == (contract = generate_and_store_contract (desc, contract_id, prod_id, &price))) { /* status equals 500, so the user will get a "Internal server error" */ //failure_resp (connection, status); |