From 17055134a3df2c9d84aec69b1da1cb3c273a55fb Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 7 May 2015 13:59:56 +0200 Subject: extend PQ library to support Absolute time values --- src/include/taler_pq_lib.h | 37 +++++++++++++++++--- src/mintdb/plugin_mintdb_postgres.c | 69 +++++++++++++++---------------------- src/pq/db_pq.c | 47 +++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index ba9de3079..b826ae26a 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -69,7 +69,13 @@ enum TALER_PQ_QueryFormat * We have an RSA signature. * Data points to a `struct GNUNET_CRYPTO_rsa_Signature`, size is not used. */ - TALER_PQ_QF_RSA_SIGNATURE + TALER_PQ_QF_RSA_SIGNATURE, + + /** + * We have an absolute time. + * Data points to a `struct GNUNET_TIME_Absolute`, size is only used to check. + */ + TALER_PQ_QF_TIME_ABSOLUTE }; @@ -163,6 +169,16 @@ struct TALER_PQ_QueryParam #define TALER_PQ_QUERY_PARAM_RSA_SIGNATURE(x) { TALER_PQ_QF_RSA_SIGNATURE, (x), 0 } +/** + * Generate query parameter for an absolute time value. + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass, must be + * a variable of type `struct GNUNET_TIME_Absolute`. + */ +#define TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME(x) { TALER_PQ_QF_TIME_ABSOLUTE, &(x), sizeof (x) } + + /** * Different formats of results that can be extracted. */ @@ -206,7 +222,13 @@ enum TALER_PQ_ResultFormat * We expect an RSA signature. * Data points to a `struct GNUNET_CRYPTO_rsa_Signature **`, size is not used. */ - TALER_PQ_RF_RSA_SIGNATURE + TALER_PQ_RF_RSA_SIGNATURE, + + /** + * We expect an absolute time. + * Data points to a `struct GNUNET_TIME_Absolute`, size is only used for checking. + */ + TALER_PQ_RF_TIME_ABSOLUTE }; @@ -287,7 +309,7 @@ struct TALER_PQ_ResultSpec * @param name name of the field in the table * @param amount a `struct TALER_AmountNBO` where to store the result */ -#define TALER_PQ_RESULT_SPEC_AMOUNT_NBO(name, amount) {TALER_PQ_RF_AMOUNT_NBO, (void *) (&dst), sizeof (amount), (name), NULL } +#define TALER_PQ_RESULT_SPEC_AMOUNT_NBO(name, amount) {TALER_PQ_RF_AMOUNT_NBO, (void *) (&amount), sizeof (amount), (name), NULL } /** * Currency amount expected. @@ -295,7 +317,7 @@ struct TALER_PQ_ResultSpec * @param name name of the field in the table * @param amount a `struct TALER_Amount` where to store the result */ -#define TALER_PQ_RESULT_SPEC_AMOUNT(name, amount) {TALER_PQ_RF_AMOUNT, (void *) (&dst), sizeof (amount), (name), NULL } +#define TALER_PQ_RESULT_SPEC_AMOUNT(name, amount) {TALER_PQ_RF_AMOUNT, (void *) (&amount), sizeof (amount), (name), NULL } /** * RSA public key expected. @@ -315,6 +337,13 @@ struct TALER_PQ_ResultSpec */ #define TALER_PQ_RESULT_SPEC_RSA_SIGNATURE(name, sig) {TALER_PQ_RF_RSA_SIGNATURE, (void *) &(sig), 0, (name), NULL } +/** + * Absolute time expected. + * + * @param name name of the field in the table + * @param at a `struct GNUNET_TIME_Absolute` where to store the result + */ +#define TALER_PQ_RESULT_SPEC_ABSOLUTE_TIME(name,at) {TALER_PQ_RF_TIME_ABSOLUTE, (void *) (&at), sizeof (at), (name), NULL } /** diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index 3f22ce999..2f61211a5 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -723,8 +723,8 @@ postgres_get_session (void *cls, GNUNET_break (0); return NULL; } - if ((GNUNET_YES == temporary) - && (GNUNET_SYSERR == set_temporary_schema(db_conn))) + if ( (GNUNET_YES == temporary) && + (GNUNET_SYSERR == set_temporary_schema(db_conn)) ) { GNUNET_break (0); return NULL; @@ -741,7 +741,7 @@ postgres_get_session (void *cls, session)) { GNUNET_break (0); - // FIXME: close db_conn! + PQfinish (db_conn); GNUNET_free (session); return NULL; } @@ -822,7 +822,6 @@ postgres_commit (void *cls, PQclear (result); return GNUNET_SYSERR; } - PQclear (result); return GNUNET_OK; } @@ -841,12 +840,10 @@ postgres_insert_denomination (void *cls, struct TALER_MINTDB_Session *session, const struct TALER_MINTDB_DenominationKeyIssueInformation *dki) { + const struct TALER_DenominationKeyValidityPS *issue = &dki->issue; PGresult *result; - const struct TALER_DenominationKeyValidityPS *issue; int ret; - ret = GNUNET_SYSERR; - issue = &dki->issue; struct TALER_PQ_QueryParam params[] = { TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (dki->denom_pub.rsa_public_key), TALER_PQ_QUERY_PARAM_PTR (&issue->start.abs_value_us__), @@ -863,10 +860,13 @@ postgres_insert_denomination (void *cls, params); if (PGRES_COMMAND_OK != PQresultStatus (result)) { + ret = GNUNET_SYSERR; BREAK_DB_ERR (result); } else + { ret = GNUNET_OK; + } PQclear (result); return ret; } @@ -888,11 +888,15 @@ postgres_reserve_get (void *cls, struct TALER_MINTDB_Reserve *reserve) { PGresult *result; - uint64_t expiration_date_nbo; struct TALER_PQ_QueryParam params[] = { TALER_PQ_QUERY_PARAM_PTR(&reserve->pub), TALER_PQ_QUERY_PARAM_END }; + struct TALER_PQ_ResultSpec rs[] = { + TALER_PQ_RESULT_SPEC_AMOUNT("current_balance", reserve->balance), + TALER_PQ_RESULT_SPEC_ABSOLUTE_TIME("expiration_date", reserve->expiry), + TALER_PQ_RESULT_SPEC_END + }; result = TALER_PQ_exec_prepared (session->conn, "get_reserve", @@ -908,18 +912,10 @@ postgres_reserve_get (void *cls, PQclear (result); return GNUNET_NO; } - struct TALER_PQ_ResultSpec rs[] = { - TALER_PQ_RESULT_SPEC("expiration_date", &expiration_date_nbo), - TALER_PQ_RESULT_SPEC_END - }; - EXITIF (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)); EXITIF (GNUNET_OK != - TALER_PQ_extract_amount (result, 0, - "current_balance_val", - "current_balance_frac", - "current_balance_curr", - &reserve->balance)); - reserve->expiry.abs_value_us = GNUNET_ntohll (expiration_date_nbo); + TALER_PQ_extract_result (result, + rs, + 0)); PQclear (result); return GNUNET_OK; @@ -944,22 +940,16 @@ postgres_reserves_update (void *cls, struct TALER_MINTDB_Reserve *reserve) { PGresult *result; - struct TALER_AmountNBO balance_nbo; - struct GNUNET_TIME_AbsoluteNBO expiry_nbo; int ret; if (NULL == reserve) return GNUNET_SYSERR; - ret = GNUNET_OK; struct TALER_PQ_QueryParam params[] = { - TALER_PQ_QUERY_PARAM_PTR (&expiry_nbo), - TALER_PQ_QUERY_PARAM_AMOUNT_NBO (balance_nbo), + TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (reserve->expiry), + TALER_PQ_QUERY_PARAM_AMOUNT (reserve->balance), TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), TALER_PQ_QUERY_PARAM_END }; - TALER_amount_hton (&balance_nbo, - &reserve->balance); - expiry_nbo = GNUNET_TIME_absolute_hton (reserve->expiry); result = TALER_PQ_exec_prepared (session->conn, "update_reserve", params); @@ -968,6 +958,10 @@ postgres_reserves_update (void *cls, QUERY_ERR (result); ret = GNUNET_SYSERR; } + else + { + ret = GNUNET_OK; + } PQclear (result); return ret; } @@ -993,8 +987,6 @@ postgres_reserves_in_insert (void *cls, 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; @@ -1019,17 +1011,14 @@ postgres_reserves_in_insert (void *cls, session); return GNUNET_SYSERR; } - TALER_amount_hton (&balance_nbo, - 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_PQ_QueryParam params[] = { TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), - TALER_PQ_QUERY_PARAM_AMOUNT_NBO (balance_nbo), - TALER_PQ_QUERY_PARAM_PTR (&expiry_nbo), + TALER_PQ_QUERY_PARAM_AMOUNT (balance), + TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (expiry), TALER_PQ_QUERY_PARAM_END }; result = TALER_PQ_exec_prepared (session->conn, @@ -1047,8 +1036,8 @@ postgres_reserves_in_insert (void *cls, /* create new incoming transaction */ struct TALER_PQ_QueryParam params[] = { TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), - TALER_PQ_QUERY_PARAM_AMOUNT_NBO (balance_nbo), - TALER_PQ_QUERY_PARAM_PTR (&expiry_nbo), + TALER_PQ_QUERY_PARAM_AMOUNT (balance), + TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (expiry), TALER_PQ_QUERY_PARAM_END }; result = TALER_PQ_exec_prepared (session->conn, @@ -1081,7 +1070,8 @@ postgres_reserves_in_insert (void *cls, { return GNUNET_SYSERR; } - updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry, reserve->expiry); + updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry, + reserve->expiry); if (GNUNET_OK != postgres_reserves_update (cls, session, &updated_reserve)) @@ -1460,19 +1450,16 @@ postgres_insert_deposit (void *cls, { char *json_wire_enc; PGresult *result; - struct TALER_AmountNBO amount_nbo; int ret; ret = GNUNET_SYSERR; json_wire_enc = json_dumps (deposit->wire, JSON_COMPACT); - TALER_amount_hton (&amount_nbo, - &deposit->amount_with_fee); struct TALER_PQ_QueryParam params[]= { TALER_PQ_QUERY_PARAM_PTR (&deposit->coin.coin_pub), TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (deposit->coin.denom_pub.rsa_public_key), TALER_PQ_QUERY_PARAM_RSA_SIGNATURE (deposit->coin.denom_sig.rsa_signature), TALER_PQ_QUERY_PARAM_PTR (&deposit->transaction_id), - TALER_PQ_QUERY_PARAM_AMOUNT_NBO (amount_nbo), + TALER_PQ_QUERY_PARAM_AMOUNT (deposit->amount_with_fee), TALER_PQ_QUERY_PARAM_PTR (&deposit->merchant_pub), TALER_PQ_QUERY_PARAM_PTR (&deposit->h_contract), TALER_PQ_QUERY_PARAM_PTR (&deposit->h_wire), diff --git a/src/pq/db_pq.c b/src/pq/db_pq.c index 130a07ca3..1decd3bbe 100644 --- a/src/pq/db_pq.c +++ b/src/pq/db_pq.c @@ -169,6 +169,20 @@ TALER_PQ_exec_prepared (PGconn *db_conn, off++; } break; + case TALER_PQ_QF_TIME_ABSOLUTE: + { + const struct GNUNET_TIME_Absolute *at_hbo = x->data; + struct GNUNET_TIME_AbsoluteNBO *at_nbo; + + at_nbo = GNUNET_new (struct GNUNET_TIME_AbsoluteNBO); + scratch[soff++] = at_nbo; + *at_nbo = GNUNET_TIME_absolute_hton (*at_hbo); + param_values[off] = (void *) at_nbo; + param_lengths[off] = sizeof (struct GNUNET_TIME_AbsoluteNBO); + param_formats[off] = 1; + off++; + } + break; default: /* format not supported */ GNUNET_assert (0); @@ -480,6 +494,39 @@ TALER_PQ_extract_result (PGresult *result, } break; } + case TALER_PQ_RF_TIME_ABSOLUTE: + { + struct GNUNET_TIME_Absolute *dst = spec->dst; + const struct GNUNET_TIME_AbsoluteNBO *res; + int fnum; + + fnum = PQfnumber (result, + spec->fname); + if (fnum < 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Field `%s' does not exist in result\n", + spec->fname); + return GNUNET_SYSERR; + } + if (PQgetisnull (result, + row, + fnum)) + { + had_null = GNUNET_YES; + continue; + } + GNUNET_assert (NULL != dst); + GNUNET_assert (sizeof (struct GNUNET_TIME_AbsoluteNBO) == + spec->dst_size); + res = (const struct GNUNET_TIME_AbsoluteNBO *) + PQgetvalue (result, + row, + fnum); + *dst = GNUNET_TIME_absolute_ntoh (*res); + break; + } + default: GNUNET_assert (0); break; -- cgit v1.2.3