extend PQ library to support Absolute time values

This commit is contained in:
Christian Grothoff 2015-05-07 13:59:56 +02:00
parent e2fb24f0a9
commit 17055134a3
3 changed files with 108 additions and 45 deletions

View File

@ -69,7 +69,13 @@ enum TALER_PQ_QueryFormat
* We have an RSA signature. * We have an RSA signature.
* Data points to a `struct GNUNET_CRYPTO_rsa_Signature`, size is not used. * 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 } #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. * Different formats of results that can be extracted.
*/ */
@ -206,7 +222,13 @@ enum TALER_PQ_ResultFormat
* We expect an RSA signature. * We expect an RSA signature.
* Data points to a `struct GNUNET_CRYPTO_rsa_Signature **`, size is not used. * 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 name name of the field in the table
* @param amount a `struct TALER_AmountNBO` where to store the result * @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. * Currency amount expected.
@ -295,7 +317,7 @@ struct TALER_PQ_ResultSpec
* @param name name of the field in the table * @param name name of the field in the table
* @param amount a `struct TALER_Amount` where to store the result * @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. * 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 } #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 }
/** /**

View File

@ -723,8 +723,8 @@ postgres_get_session (void *cls,
GNUNET_break (0); GNUNET_break (0);
return NULL; return NULL;
} }
if ((GNUNET_YES == temporary) if ( (GNUNET_YES == temporary) &&
&& (GNUNET_SYSERR == set_temporary_schema(db_conn))) (GNUNET_SYSERR == set_temporary_schema(db_conn)) )
{ {
GNUNET_break (0); GNUNET_break (0);
return NULL; return NULL;
@ -741,7 +741,7 @@ postgres_get_session (void *cls,
session)) session))
{ {
GNUNET_break (0); GNUNET_break (0);
// FIXME: close db_conn! PQfinish (db_conn);
GNUNET_free (session); GNUNET_free (session);
return NULL; return NULL;
} }
@ -822,7 +822,6 @@ postgres_commit (void *cls,
PQclear (result); PQclear (result);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
PQclear (result); PQclear (result);
return GNUNET_OK; return GNUNET_OK;
} }
@ -841,12 +840,10 @@ postgres_insert_denomination (void *cls,
struct TALER_MINTDB_Session *session, struct TALER_MINTDB_Session *session,
const struct TALER_MINTDB_DenominationKeyIssueInformation *dki) const struct TALER_MINTDB_DenominationKeyIssueInformation *dki)
{ {
const struct TALER_DenominationKeyValidityPS *issue = &dki->issue;
PGresult *result; PGresult *result;
const struct TALER_DenominationKeyValidityPS *issue;
int ret; int ret;
ret = GNUNET_SYSERR;
issue = &dki->issue;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (dki->denom_pub.rsa_public_key), TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (dki->denom_pub.rsa_public_key),
TALER_PQ_QUERY_PARAM_PTR (&issue->start.abs_value_us__), TALER_PQ_QUERY_PARAM_PTR (&issue->start.abs_value_us__),
@ -863,10 +860,13 @@ postgres_insert_denomination (void *cls,
params); params);
if (PGRES_COMMAND_OK != PQresultStatus (result)) if (PGRES_COMMAND_OK != PQresultStatus (result))
{ {
ret = GNUNET_SYSERR;
BREAK_DB_ERR (result); BREAK_DB_ERR (result);
} }
else else
{
ret = GNUNET_OK; ret = GNUNET_OK;
}
PQclear (result); PQclear (result);
return ret; return ret;
} }
@ -888,11 +888,15 @@ postgres_reserve_get (void *cls,
struct TALER_MINTDB_Reserve *reserve) struct TALER_MINTDB_Reserve *reserve)
{ {
PGresult *result; PGresult *result;
uint64_t expiration_date_nbo;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(&reserve->pub), TALER_PQ_QUERY_PARAM_PTR(&reserve->pub),
TALER_PQ_QUERY_PARAM_END 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, result = TALER_PQ_exec_prepared (session->conn,
"get_reserve", "get_reserve",
@ -908,18 +912,10 @@ postgres_reserve_get (void *cls,
PQclear (result); PQclear (result);
return GNUNET_NO; 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 != EXITIF (GNUNET_OK !=
TALER_PQ_extract_amount (result, 0, TALER_PQ_extract_result (result,
"current_balance_val", rs,
"current_balance_frac", 0));
"current_balance_curr",
&reserve->balance));
reserve->expiry.abs_value_us = GNUNET_ntohll (expiration_date_nbo);
PQclear (result); PQclear (result);
return GNUNET_OK; return GNUNET_OK;
@ -944,22 +940,16 @@ postgres_reserves_update (void *cls,
struct TALER_MINTDB_Reserve *reserve) struct TALER_MINTDB_Reserve *reserve)
{ {
PGresult *result; PGresult *result;
struct TALER_AmountNBO balance_nbo;
struct GNUNET_TIME_AbsoluteNBO expiry_nbo;
int ret; int ret;
if (NULL == reserve) if (NULL == reserve)
return GNUNET_SYSERR; return GNUNET_SYSERR;
ret = GNUNET_OK;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (&expiry_nbo), TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (reserve->expiry),
TALER_PQ_QUERY_PARAM_AMOUNT_NBO (balance_nbo), TALER_PQ_QUERY_PARAM_AMOUNT (reserve->balance),
TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), TALER_PQ_QUERY_PARAM_PTR (&reserve->pub),
TALER_PQ_QUERY_PARAM_END 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, result = TALER_PQ_exec_prepared (session->conn,
"update_reserve", "update_reserve",
params); params);
@ -968,6 +958,10 @@ postgres_reserves_update (void *cls,
QUERY_ERR (result); QUERY_ERR (result);
ret = GNUNET_SYSERR; ret = GNUNET_SYSERR;
} }
else
{
ret = GNUNET_OK;
}
PQclear (result); PQclear (result);
return ret; return ret;
} }
@ -993,8 +987,6 @@ postgres_reserves_in_insert (void *cls,
const struct TALER_Amount *balance, const struct TALER_Amount *balance,
const struct GNUNET_TIME_Absolute expiry) const struct GNUNET_TIME_Absolute expiry)
{ {
struct TALER_AmountNBO balance_nbo;
struct GNUNET_TIME_AbsoluteNBO expiry_nbo;
PGresult *result; PGresult *result;
int reserve_exists; int reserve_exists;
@ -1019,17 +1011,14 @@ postgres_reserves_in_insert (void *cls,
session); session);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
TALER_amount_hton (&balance_nbo,
balance);
expiry_nbo = GNUNET_TIME_absolute_hton (expiry);
if (GNUNET_NO == reserve_exists) if (GNUNET_NO == reserve_exists)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Reserve does not exist; creating a new one\n"); "Reserve does not exist; creating a new one\n");
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), TALER_PQ_QUERY_PARAM_PTR (&reserve->pub),
TALER_PQ_QUERY_PARAM_AMOUNT_NBO (balance_nbo), TALER_PQ_QUERY_PARAM_AMOUNT (balance),
TALER_PQ_QUERY_PARAM_PTR (&expiry_nbo), TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (expiry),
TALER_PQ_QUERY_PARAM_END TALER_PQ_QUERY_PARAM_END
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
@ -1047,8 +1036,8 @@ postgres_reserves_in_insert (void *cls,
/* create new incoming transaction */ /* create new incoming transaction */
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), TALER_PQ_QUERY_PARAM_PTR (&reserve->pub),
TALER_PQ_QUERY_PARAM_AMOUNT_NBO (balance_nbo), TALER_PQ_QUERY_PARAM_AMOUNT (balance),
TALER_PQ_QUERY_PARAM_PTR (&expiry_nbo), TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (expiry),
TALER_PQ_QUERY_PARAM_END TALER_PQ_QUERY_PARAM_END
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
@ -1081,7 +1070,8 @@ postgres_reserves_in_insert (void *cls,
{ {
return GNUNET_SYSERR; 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, if (GNUNET_OK != postgres_reserves_update (cls,
session, session,
&updated_reserve)) &updated_reserve))
@ -1460,19 +1450,16 @@ postgres_insert_deposit (void *cls,
{ {
char *json_wire_enc; char *json_wire_enc;
PGresult *result; PGresult *result;
struct TALER_AmountNBO amount_nbo;
int ret; int ret;
ret = GNUNET_SYSERR; ret = GNUNET_SYSERR;
json_wire_enc = json_dumps (deposit->wire, JSON_COMPACT); json_wire_enc = json_dumps (deposit->wire, JSON_COMPACT);
TALER_amount_hton (&amount_nbo,
&deposit->amount_with_fee);
struct TALER_PQ_QueryParam params[]= { struct TALER_PQ_QueryParam params[]= {
TALER_PQ_QUERY_PARAM_PTR (&deposit->coin.coin_pub), 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_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_RSA_SIGNATURE (deposit->coin.denom_sig.rsa_signature),
TALER_PQ_QUERY_PARAM_PTR (&deposit->transaction_id), 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->merchant_pub),
TALER_PQ_QUERY_PARAM_PTR (&deposit->h_contract), TALER_PQ_QUERY_PARAM_PTR (&deposit->h_contract),
TALER_PQ_QUERY_PARAM_PTR (&deposit->h_wire), TALER_PQ_QUERY_PARAM_PTR (&deposit->h_wire),

View File

@ -169,6 +169,20 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
off++; off++;
} }
break; 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: default:
/* format not supported */ /* format not supported */
GNUNET_assert (0); GNUNET_assert (0);
@ -480,6 +494,39 @@ TALER_PQ_extract_result (PGresult *result,
} }
break; 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: default:
GNUNET_assert (0); GNUNET_assert (0);
break; break;