From 5540747ca2e5f37f2df504d689b850d1078fcdc5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 30 Nov 2017 17:17:37 +0100 Subject: patch to address #5183: always round time before giving it to DB, tolerate DB answering without rounded time --- src/auditordb/plugin_auditordb_postgres.c | 46 +++--- src/auditordb/test_auditordb.c | 3 +- src/exchange/taler-exchange-aggregator.c | 5 +- src/exchange/test_taler_exchange_aggregator.c | 2 + src/exchangedb/perf_taler_exchangedb_init.c | 15 +- src/exchangedb/perf_taler_exchangedb_interpreter.c | 5 +- src/exchangedb/plugin_exchangedb_postgres.c | 113 ++++++++------- src/exchangedb/test_exchangedb.c | 68 ++++++--- src/include/taler_pq_lib.h | 56 ++++++++ src/pq/pq_query_helper.c | 123 ++++++++++++++++ src/pq/pq_result_helper.c | 160 +++++++++++++++++++++ 11 files changed, 493 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index b699a76f5..2f881ae29 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -1014,7 +1014,7 @@ postgres_gc (void *cls) struct PostgresClosure *pc = cls; struct GNUNET_TIME_Absolute now; struct GNUNET_PQ_QueryParam params_time[] = { - GNUNET_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; PGconn *conn; @@ -1063,10 +1063,10 @@ postgres_insert_denomination_info (void *cls, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&issue->denom_hash), GNUNET_PQ_query_param_auto_from_type (&issue->master), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->start), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->expire_withdraw), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->expire_deposit), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->expire_legal), + TALER_PQ_query_param_absolute_time_nbo (&issue->start), + TALER_PQ_query_param_absolute_time_nbo (&issue->expire_withdraw), + TALER_PQ_query_param_absolute_time_nbo (&issue->expire_deposit), + TALER_PQ_query_param_absolute_time_nbo (&issue->expire_legal), TALER_PQ_query_param_amount_nbo (&issue->value), TALER_PQ_query_param_amount_nbo (&issue->fee_withdraw), TALER_PQ_query_param_amount_nbo (&issue->fee_deposit), @@ -1145,10 +1145,10 @@ denomination_info_cb (void *cls, }; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &issue.denom_hash), - GNUNET_PQ_result_spec_absolute_time_nbo ("valid_from", &issue.start), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_withdraw", &issue.expire_withdraw), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_deposit", &issue.expire_deposit), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_legal", &issue.expire_legal), + TALER_PQ_result_spec_absolute_time_nbo ("valid_from", &issue.start), + TALER_PQ_result_spec_absolute_time_nbo ("expire_withdraw", &issue.expire_withdraw), + TALER_PQ_result_spec_absolute_time_nbo ("expire_deposit", &issue.expire_deposit), + TALER_PQ_result_spec_absolute_time_nbo ("expire_legal", &issue.expire_legal), TALER_PQ_result_spec_amount_nbo ("coin", &issue.value), TALER_PQ_result_spec_amount_nbo ("fee_withdraw", &issue.fee_withdraw), TALER_PQ_result_spec_amount_nbo ("fee_deposit", &issue.fee_deposit), @@ -1358,7 +1358,7 @@ postgres_insert_wire_auditor_progress (void *cls, GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id), GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id), - GNUNET_PQ_query_param_absolute_time (&pp->last_timestamp), + TALER_PQ_query_param_absolute_time (&pp->last_timestamp), GNUNET_PQ_query_param_fixed_size (in_wire_off, wire_off_size), GNUNET_PQ_query_param_fixed_size (out_wire_off, @@ -1394,7 +1394,7 @@ postgres_update_wire_auditor_progress (void *cls, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id), GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id), - GNUNET_PQ_query_param_absolute_time (&pp->last_timestamp), + TALER_PQ_query_param_absolute_time (&pp->last_timestamp), GNUNET_PQ_query_param_fixed_size (in_wire_off, wire_off_size), GNUNET_PQ_query_param_fixed_size (out_wire_off, @@ -1438,7 +1438,7 @@ postgres_get_wire_auditor_progress (void *cls, &pp->last_reserve_in_serial_id), GNUNET_PQ_result_spec_uint64 ("last_wire_wire_out_serial_id", &pp->last_wire_out_serial_id), - GNUNET_PQ_result_spec_absolute_time ("last_timestamp", + TALER_PQ_result_spec_absolute_time ("last_timestamp", &pp->last_timestamp), GNUNET_PQ_result_spec_variable_size ("wire_in_off", in_wire_off, @@ -1491,7 +1491,7 @@ postgres_insert_reserve_info (void *cls, GNUNET_PQ_query_param_auto_from_type (master_pub), TALER_PQ_query_param_amount (reserve_balance), TALER_PQ_query_param_amount (withdraw_fee_balance), - GNUNET_PQ_query_param_absolute_time (&expiration_date), + TALER_PQ_query_param_absolute_time (&expiration_date), GNUNET_PQ_query_param_end }; @@ -1531,7 +1531,7 @@ postgres_update_reserve_info (void *cls, struct GNUNET_PQ_QueryParam params[] = { TALER_PQ_query_param_amount (reserve_balance), TALER_PQ_query_param_amount (withdraw_fee_balance), - GNUNET_PQ_query_param_absolute_time (&expiration_date), + TALER_PQ_query_param_absolute_time (&expiration_date), GNUNET_PQ_query_param_auto_from_type (reserve_pub), GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_end @@ -1606,7 +1606,7 @@ postgres_get_reserve_info (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_amount ("reserve_balance", reserve_balance), TALER_PQ_result_spec_amount ("withdraw_fee_balance", withdraw_fee_balance), - GNUNET_PQ_result_spec_absolute_time ("expiration_date", expiration_date), + TALER_PQ_result_spec_absolute_time ("expiration_date", expiration_date), GNUNET_PQ_result_spec_uint64 ("auditor_reserves_rowid", rowid), GNUNET_PQ_result_spec_end }; @@ -2066,7 +2066,7 @@ postgres_insert_historic_denom_revenue (void *cls, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), - GNUNET_PQ_query_param_absolute_time (&revenue_timestamp), + TALER_PQ_query_param_absolute_time (&revenue_timestamp), TALER_PQ_query_param_amount (revenue_balance), GNUNET_PQ_query_param_end }; @@ -2122,7 +2122,7 @@ historic_denom_revenue_cb (void *cls, struct TALER_Amount revenue_balance; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &denom_pub_hash), - GNUNET_PQ_result_spec_absolute_time ("revenue_timestamp", &revenue_timestamp), + TALER_PQ_result_spec_absolute_time ("revenue_timestamp", &revenue_timestamp), TALER_PQ_result_spec_amount ("revenue_balance", &revenue_balance), GNUNET_PQ_result_spec_end }; @@ -2213,7 +2213,7 @@ postgres_insert_historic_losses (void *cls, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), - GNUNET_PQ_query_param_absolute_time (&loss_timestamp), + TALER_PQ_query_param_absolute_time (&loss_timestamp), TALER_PQ_query_param_amount (loss_balance), GNUNET_PQ_query_param_end }; @@ -2269,7 +2269,7 @@ losses_cb (void *cls, struct TALER_Amount loss_balance; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &denom_pub_hash), - GNUNET_PQ_result_spec_absolute_time ("loss_timestamp", &loss_timestamp), + TALER_PQ_result_spec_absolute_time ("loss_timestamp", &loss_timestamp), TALER_PQ_result_spec_amount ("loss_balance", &loss_balance), GNUNET_PQ_result_spec_end }; @@ -2354,8 +2354,8 @@ postgres_insert_historic_reserve_revenue (void *cls, { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (master_pub), - GNUNET_PQ_query_param_absolute_time (&start_time), - GNUNET_PQ_query_param_absolute_time (&end_time), + TALER_PQ_query_param_absolute_time (&start_time), + TALER_PQ_query_param_absolute_time (&end_time), TALER_PQ_query_param_amount (reserve_profits), GNUNET_PQ_query_param_end }; @@ -2410,8 +2410,8 @@ historic_reserve_revenue_cb (void *cls, struct GNUNET_TIME_Absolute end_date; struct TALER_Amount reserve_profits; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_absolute_time ("start_date", &start_date), - GNUNET_PQ_result_spec_absolute_time ("end_date", &end_date), + TALER_PQ_result_spec_absolute_time ("start_date", &start_date), + TALER_PQ_result_spec_absolute_time ("end_date", &end_date), TALER_PQ_result_spec_amount ("reserve_profits", &reserve_profits), GNUNET_PQ_result_spec_end }; diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c index 04c6d23b0..a5e8ba71d 100644 --- a/src/auditordb/test_auditordb.c +++ b/src/auditordb/test_auditordb.c @@ -164,6 +164,7 @@ run (void *cls) struct GNUNET_TIME_Absolute now, past, future, date; now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); past = GNUNET_TIME_absolute_subtract (now, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)); @@ -357,7 +358,7 @@ run (void *cls) (0 != memcmp (&withdraw_fee_balance2, &withdraw_fee_balance, sizeof (withdraw_fee_balance))) ) ); - + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: insert_denomination_balance\n"); diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 84aef1a89..788e817fd 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -1102,6 +1102,7 @@ run_reserve_closures (void *cls) enum GNUNET_DB_QueryStatus qs; const struct GNUNET_SCHEDULER_TaskContext *tc; struct ExpiredReserveContext erc; + struct GNUNET_TIME_Absolute now; task = NULL; reserves_idle = GNUNET_NO; @@ -1130,9 +1131,11 @@ run_reserve_closures (void *cls) } erc.session = session; erc.async_cont = GNUNET_NO; + now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); qs = db_plugin->get_expired_reserves (db_plugin->cls, session, - GNUNET_TIME_absolute_get (), + now, &expired_reserve_cb, &erc); switch (qs) diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index 0b56b4854..178b5aa32 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -440,7 +440,9 @@ do_deposit (struct Command *cmd) TALER_JSON_hash (deposit.receiver_wire_account, &deposit.h_wire)); deposit.timestamp = GNUNET_TIME_absolute_get (); + GNUNET_TIME_round_abs (&deposit.timestamp); deposit.wire_deadline = GNUNET_TIME_relative_to_absolute (cmd->details.deposit.wire_deadline); + GNUNET_TIME_round_abs (&deposit.wire_deadline); /* finally, actually perform the DB operation */ if ( (GNUNET_OK != diff --git a/src/exchangedb/perf_taler_exchangedb_init.c b/src/exchangedb/perf_taler_exchangedb_init.c index 412853980..4efec3911 100644 --- a/src/exchangedb/perf_taler_exchangedb_init.c +++ b/src/exchangedb/perf_taler_exchangedb_init.c @@ -59,15 +59,18 @@ PERF_TALER_EXCHANGEDB_denomination_init () {/* properties */ struct TALER_Amount amount; + struct GNUNET_TIME_Absolute now; properties.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY); properties.purpose.size = htonl (sizeof (struct TALER_DenominationKeyValidityPS)); GNUNET_CRYPTO_eddsa_key_get_public (master_prvt, &properties.master.eddsa_pub); - properties.start = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get()); - properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); - properties.expire_deposit = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); - properties.expire_legal = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_()); + now = GNUNET_TIME_absolute_get(); + (void) GNUNET_TIME_round_abs (&now); + properties.start = GNUNET_TIME_absolute_hton (now); + properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); + properties.expire_deposit = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); + properties.expire_legal = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.1", &amount)); TALER_amount_hton (&properties.value, &amount); @@ -164,7 +167,7 @@ PERF_TALER_EXCHANGEDB_reserve_init () &reserve->reserve.pub.eddsa_pub); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1000", &reserve->reserve.balance)); - reserve->reserve.expiry = GNUNET_TIME_absolute_get_forever_ (); + reserve->reserve.expiry = GNUNET_TIME_UNIT_FOREVER_ABS; return reserve; } @@ -256,7 +259,9 @@ PERF_TALER_EXCHANGEDB_deposit_init (const struct PERF_TALER_EXCHANGEDB_Coin *coi GNUNET_free (eddsa_prv); } timestamp = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (×tamp); refund_deadline = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&refund_deadline); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.1", &amount_with_fee)); diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c b/src/exchangedb/perf_taler_exchangedb_interpreter.c index eca519527..b9bf9c32e 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.c +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c @@ -1244,6 +1244,7 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) struct PERF_TALER_EXCHANGEDB_Reserve *reserve; json_t *sndr; uint32_t uid; + struct GNUNET_TIME_Absolute now; reserve_index = state->cmd[state->i].details.insert_reserve.index_reserve; reserve = state->cmd[reserve_index].exposed.data.reserve; @@ -1254,11 +1255,13 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) uid = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); GNUNET_assert (NULL != sndr); + now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); ret = state->plugin->reserves_in_insert (state->plugin->cls, state->session, &reserve->reserve.pub, &reserve->reserve.balance, - GNUNET_TIME_absolute_get (), + now, sndr, &uid, sizeof (uid)); diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index b6e862ab9..3db1d4c44 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -1612,10 +1612,10 @@ postgres_insert_denomination_info (void *cls, GNUNET_PQ_query_param_rsa_public_key (denom_pub->rsa_public_key), GNUNET_PQ_query_param_auto_from_type (&issue->properties.master), GNUNET_PQ_query_param_auto_from_type (&issue->signature), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.start), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_withdraw), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_deposit), - GNUNET_PQ_query_param_absolute_time_nbo (&issue->properties.expire_legal), + TALER_PQ_query_param_absolute_time_nbo (&issue->properties.start), + TALER_PQ_query_param_absolute_time_nbo (&issue->properties.expire_withdraw), + TALER_PQ_query_param_absolute_time_nbo (&issue->properties.expire_deposit), + TALER_PQ_query_param_absolute_time_nbo (&issue->properties.expire_legal), TALER_PQ_query_param_amount_nbo (&issue->properties.value), TALER_PQ_query_param_amount_nbo (&issue->properties.fee_withdraw), TALER_PQ_query_param_amount_nbo (&issue->properties.fee_deposit), @@ -1670,13 +1670,13 @@ postgres_get_denomination_info (void *cls, &issue->properties.master), GNUNET_PQ_result_spec_auto_from_type ("master_sig", &issue->signature), - GNUNET_PQ_result_spec_absolute_time_nbo ("valid_from", + TALER_PQ_result_spec_absolute_time_nbo ("valid_from", &issue->properties.start), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_withdraw", + TALER_PQ_result_spec_absolute_time_nbo ("expire_withdraw", &issue->properties.expire_withdraw), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_deposit", + TALER_PQ_result_spec_absolute_time_nbo ("expire_deposit", &issue->properties.expire_deposit), - GNUNET_PQ_result_spec_absolute_time_nbo ("expire_legal", + TALER_PQ_result_spec_absolute_time_nbo ("expire_legal", &issue->properties.expire_legal), TALER_PQ_result_spec_amount_nbo ("coin", &issue->properties.value), @@ -1728,7 +1728,7 @@ postgres_reserve_get (void *cls, }; struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_amount("current_balance", &reserve->balance), - GNUNET_PQ_result_spec_absolute_time("expiration_date", &reserve->expiry), + TALER_PQ_result_spec_absolute_time("expiration_date", &reserve->expiry), GNUNET_PQ_result_spec_end }; @@ -1754,7 +1754,7 @@ reserves_update (void *cls, const struct TALER_EXCHANGEDB_Reserve *reserve) { struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_absolute_time (&reserve->expiry), + TALER_PQ_query_param_absolute_time (&reserve->expiry), TALER_PQ_query_param_amount (&reserve->balance), GNUNET_PQ_query_param_auto_from_type (&reserve->pub), GNUNET_PQ_query_param_end @@ -1842,7 +1842,7 @@ postgres_reserves_in_insert (void *cls, GNUNET_PQ_query_param_auto_from_type (reserve_pub), TALER_PQ_query_param_json (sender_account_details), TALER_PQ_query_param_amount (balance), - GNUNET_PQ_query_param_absolute_time (&expiry), + TALER_PQ_query_param_absolute_time (&expiry), GNUNET_PQ_query_param_end }; @@ -1871,7 +1871,7 @@ postgres_reserves_in_insert (void *cls, wire_reference_size), TALER_PQ_query_param_amount (balance), TALER_PQ_query_param_json (sender_account_details), - GNUNET_PQ_query_param_absolute_time (&execution_time), + TALER_PQ_query_param_absolute_time (&execution_time), GNUNET_PQ_query_param_end }; @@ -2016,13 +2016,14 @@ postgres_insert_withdraw_info (void *cls, GNUNET_PQ_query_param_rsa_signature (collectable->sig.rsa_signature), GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub), GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig), - GNUNET_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_absolute_time (&now), TALER_PQ_query_param_amount (&collectable->amount_with_fee), GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus qs; now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); GNUNET_CRYPTO_rsa_public_key_hash (collectable->denom_pub.rsa_public_key, &denom_pub_hash); qs = GNUNET_PQ_eval_prepared_non_select (session->conn, @@ -2160,7 +2161,7 @@ add_bank_to_exchange (void *cls, &bt->wire_reference_size), TALER_PQ_result_spec_amount ("credit", &bt->amount), - GNUNET_PQ_result_spec_absolute_time ("execution_date", + TALER_PQ_result_spec_absolute_time ("execution_date", &bt->execution_date), TALER_PQ_result_spec_json ("sender_account_details", &bt->sender_account_details), @@ -2272,7 +2273,7 @@ add_payback (void *cls, &payback->coin_blind), GNUNET_PQ_result_spec_auto_from_type ("coin_sig", &payback->coin_sig), - GNUNET_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("timestamp", &payback->timestamp), GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", &payback->coin.denom_pub.rsa_public_key), @@ -2327,7 +2328,7 @@ add_exchange_to_bank (void *cls, &closing->amount), TALER_PQ_result_spec_amount ("closing_fee", &closing->closing_fee), - GNUNET_PQ_result_spec_absolute_time ("execution_date", + TALER_PQ_result_spec_absolute_time ("execution_date", &closing->execution_date), TALER_PQ_result_spec_json ("receiver_account", &closing->receiver_account_details), @@ -2462,11 +2463,11 @@ postgres_have_deposit (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_amount ("amount_with_fee", &deposit2.amount_with_fee), - GNUNET_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("timestamp", &deposit2.timestamp), - GNUNET_PQ_result_spec_absolute_time ("refund_deadline", + TALER_PQ_result_spec_absolute_time ("refund_deadline", &deposit2.refund_deadline), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", + TALER_PQ_result_spec_absolute_time ("wire_deadline", &deposit2.wire_deadline), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", &deposit2.h_contract_terms), @@ -2623,7 +2624,7 @@ postgres_get_ready_deposit (void *cls, { struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; struct TALER_Amount amount_with_fee; @@ -2641,7 +2642,7 @@ postgres_get_ready_deposit (void *cls, &amount_with_fee), TALER_PQ_result_spec_amount ("fee_deposit", &deposit_fee), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", + TALER_PQ_result_spec_absolute_time ("wire_deadline", &wire_deadline), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", &h_contract_terms), @@ -2655,6 +2656,7 @@ postgres_get_ready_deposit (void *cls, }; enum GNUNET_DB_QueryStatus qs; + (void) GNUNET_TIME_round_abs (&now); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Finding ready deposits by deadline %s (%llu)\n", GNUNET_STRINGS_absolute_time_to_string (now), @@ -2755,7 +2757,7 @@ match_deposit_cb (void *cls, &amount_with_fee), TALER_PQ_result_spec_amount ("fee_deposit", &deposit_fee), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", + TALER_PQ_result_spec_absolute_time ("wire_deadline", &wire_deadline), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", &h_contract_terms), @@ -2972,9 +2974,9 @@ postgres_insert_deposit (void *cls, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub), TALER_PQ_query_param_amount (&deposit->amount_with_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), + TALER_PQ_query_param_absolute_time (&deposit->timestamp), + TALER_PQ_query_param_absolute_time (&deposit->refund_deadline), + TALER_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_terms), GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire), @@ -3606,11 +3608,11 @@ add_coin_deposit (void *cls, &deposit->amount_with_fee), TALER_PQ_result_spec_amount ("fee_deposit", &deposit->deposit_fee), - GNUNET_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("timestamp", &deposit->timestamp), - GNUNET_PQ_result_spec_absolute_time ("refund_deadline", + TALER_PQ_result_spec_absolute_time ("refund_deadline", &deposit->refund_deadline), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", + TALER_PQ_result_spec_absolute_time ("wire_deadline", &deposit->wire_deadline), GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", &deposit->merchant_pub), @@ -3828,7 +3830,7 @@ add_coin_payback (void *cls, &payback->coin_blind), GNUNET_PQ_result_spec_auto_from_type ("coin_sig", &payback->coin_sig), - GNUNET_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("timestamp", &payback->timestamp), GNUNET_PQ_result_spec_rsa_public_key ("denom_pub", &payback->coin.denom_pub.rsa_public_key), @@ -3995,7 +3997,7 @@ handle_wt_result (void *cls, GNUNET_PQ_result_spec_auto_from_type ("h_wire", &h_wire), GNUNET_PQ_result_spec_auto_from_type ("coin_pub", &coin_pub), GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", &merchant_pub), - GNUNET_PQ_result_spec_absolute_time ("execution_date", &exec_time), + TALER_PQ_result_spec_absolute_time ("execution_date", &exec_time), TALER_PQ_result_spec_amount ("amount_with_fee", &amount_with_fee), TALER_PQ_result_spec_amount ("fee_deposit", &deposit_fee), GNUNET_PQ_result_spec_end @@ -4118,7 +4120,7 @@ postgres_wire_lookup_deposit_wtid (void *cls, struct TALER_Amount deposit_fee; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("wtid_raw", &wtid), - GNUNET_PQ_result_spec_absolute_time ("execution_date", &exec_time), + TALER_PQ_result_spec_absolute_time ("execution_date", &exec_time), TALER_PQ_result_spec_amount ("amount_with_fee", &amount_with_fee), TALER_PQ_result_spec_amount ("fee_deposit", &deposit_fee), GNUNET_PQ_result_spec_end @@ -4161,7 +4163,7 @@ postgres_wire_lookup_deposit_wtid (void *cls, struct GNUNET_PQ_ResultSpec rs2[] = { TALER_PQ_result_spec_amount ("amount_with_fee", &amount_with_fee), TALER_PQ_result_spec_amount ("fee_deposit", &deposit_fee), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", &exec_time), + TALER_PQ_result_spec_absolute_time ("wire_deadline", &exec_time), GNUNET_PQ_result_spec_end }; @@ -4238,12 +4240,12 @@ postgres_get_wire_fee (void *cls, { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (type), - GNUNET_PQ_query_param_absolute_time (&date), + TALER_PQ_query_param_absolute_time (&date), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_absolute_time ("start_date", start_date), - GNUNET_PQ_result_spec_absolute_time ("end_date", end_date), + TALER_PQ_result_spec_absolute_time ("start_date", start_date), + TALER_PQ_result_spec_absolute_time ("end_date", end_date), TALER_PQ_result_spec_amount ("wire_fee", wire_fee), GNUNET_PQ_result_spec_auto_from_type ("master_sig", master_sig), GNUNET_PQ_result_spec_end @@ -4279,8 +4281,8 @@ postgres_insert_wire_fee (void *cls, { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (type), - GNUNET_PQ_query_param_absolute_time (&start_date), - GNUNET_PQ_query_param_absolute_time (&end_date), + TALER_PQ_query_param_absolute_time (&start_date), + TALER_PQ_query_param_absolute_time (&end_date), TALER_PQ_query_param_amount (wire_fee), GNUNET_PQ_query_param_auto_from_type (master_sig), GNUNET_PQ_query_param_end @@ -4378,7 +4380,7 @@ reserve_expired_cb (void *cls, struct TALER_ReservePublicKeyP reserve_pub; struct TALER_Amount remaining_balance; struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_absolute_time ("expiration_date", + TALER_PQ_result_spec_absolute_time ("expiration_date", &exp_date), TALER_PQ_result_spec_json ("account_details", &account_details), @@ -4430,7 +4432,7 @@ postgres_get_expired_reserves (void *cls, void *rec_cls) { struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; struct ExpiredReserveContext ectx; @@ -4476,7 +4478,7 @@ postgres_insert_reserve_closed (void *cls, struct TALER_EXCHANGEDB_Reserve reserve; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (reserve_pub), - GNUNET_PQ_query_param_absolute_time (&execution_date), + TALER_PQ_query_param_absolute_time (&execution_date), GNUNET_PQ_query_param_auto_from_type (wtid), TALER_PQ_query_param_json (receiver_account), TALER_PQ_query_param_amount (amount_with_fee), @@ -4695,7 +4697,7 @@ postgres_store_wire_transfer_out (void *cls, const struct TALER_Amount *amount) { struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_absolute_time (&date), + TALER_PQ_query_param_absolute_time (&date), GNUNET_PQ_query_param_auto_from_type (wtid), TALER_PQ_query_param_json (wire_account), TALER_PQ_query_param_amount (amount), @@ -4726,17 +4728,18 @@ postgres_gc (void *cls) GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam params_time[] = { - GNUNET_PQ_query_param_absolute_time (&now), + TALER_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam params_ancient_time[] = { - GNUNET_PQ_query_param_absolute_time (&long_ago), + TALER_PQ_query_param_absolute_time (&long_ago), GNUNET_PQ_query_param_end }; PGconn *conn; int ret; now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); /* Keep wire fees for 10 years, that should always be enough _and_ they are tiny so it does not matter to make this tight */ @@ -4822,7 +4825,7 @@ deposit_serial_helper_cb (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_amount ("amount_with_fee", &deposit.amount_with_fee), - GNUNET_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("timestamp", &deposit.timestamp), GNUNET_PQ_result_spec_auto_from_type ("merchant_pub", &deposit.merchant_pub), @@ -4832,9 +4835,9 @@ deposit_serial_helper_cb (void *cls, &deposit.coin.coin_pub), GNUNET_PQ_result_spec_auto_from_type ("coin_sig", &deposit.csig), - GNUNET_PQ_result_spec_absolute_time ("refund_deadline", + TALER_PQ_result_spec_absolute_time ("refund_deadline", &deposit.refund_deadline), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", + TALER_PQ_result_spec_absolute_time ("wire_deadline", &deposit.wire_deadline), GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", &deposit.h_contract_terms), @@ -5231,7 +5234,7 @@ reserves_in_serial_helper_cb (void *cls, &wire_reference_size), TALER_PQ_result_spec_amount ("credit", &credit), - GNUNET_PQ_result_spec_absolute_time("execution_date", + TALER_PQ_result_spec_absolute_time("execution_date", &execution_date), TALER_PQ_result_spec_json ("sender_account_details", &sender_account_details), @@ -5364,7 +5367,7 @@ reserves_out_serial_helper_cb (void *cls, &reserve_pub), GNUNET_PQ_result_spec_auto_from_type ("reserve_sig", &reserve_sig), - GNUNET_PQ_result_spec_absolute_time ("execution_date", + TALER_PQ_result_spec_absolute_time ("execution_date", &execution_date), TALER_PQ_result_spec_amount ("amount_with_fee", &amount_with_fee), @@ -5487,7 +5490,7 @@ wire_out_serial_helper_cb (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint64 ("wireout_uuid", &rowid), - GNUNET_PQ_result_spec_absolute_time ("execution_date", + TALER_PQ_result_spec_absolute_time ("execution_date", &date), GNUNET_PQ_result_spec_auto_from_type ("wtid_raw", &wtid), @@ -5612,7 +5615,7 @@ payback_serial_helper_cb (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_uint64 ("payback_uuid", &rowid), - GNUNET_PQ_result_spec_absolute_time ("timestamp", + TALER_PQ_result_spec_absolute_time ("timestamp", ×tamp), GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", &reserve_pub), @@ -5750,7 +5753,7 @@ reserve_closed_serial_helper_cb (void *cls, &rowid), GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", &reserve_pub), - GNUNET_PQ_result_spec_absolute_time ("execution_date", + TALER_PQ_result_spec_absolute_time ("execution_date", &execution_date), GNUNET_PQ_result_spec_auto_from_type ("wtid", &wtid), @@ -5864,7 +5867,7 @@ postgres_insert_payback_request (void *cls, GNUNET_PQ_query_param_auto_from_type (coin_sig), GNUNET_PQ_query_param_auto_from_type (coin_blind), TALER_PQ_query_param_amount (amount), - GNUNET_PQ_query_param_absolute_time (×tamp), + TALER_PQ_query_param_absolute_time (×tamp), GNUNET_PQ_query_param_auto_from_type (h_blind_ev), GNUNET_PQ_query_param_end }; @@ -6069,7 +6072,7 @@ missing_wire_cb (void *cls, &amount), TALER_PQ_result_spec_json ("wire", &wire), - GNUNET_PQ_result_spec_absolute_time ("wire_deadline", + TALER_PQ_result_spec_absolute_time ("wire_deadline", &deadline), GNUNET_PQ_result_spec_uint32 ("tiny", &tiny), @@ -6122,8 +6125,8 @@ postgres_select_deposits_missing_wire (void *cls, void *cb_cls) { struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_absolute_time (&start_date), - GNUNET_PQ_query_param_absolute_time (&end_date), + TALER_PQ_query_param_absolute_time (&start_date), + TALER_PQ_query_param_absolute_time (&end_date), GNUNET_PQ_query_param_end }; struct MissingWireContext mwc = { diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 33dc74cd6..5891a08a0 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -490,6 +490,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session) struct TALER_DenominationPublicKey *ret_denom_pubs; int ret; enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Absolute now; ret = GNUNET_SYSERR; RND_BLK (&refresh_session); @@ -500,9 +501,11 @@ test_melting (struct TALER_EXCHANGEDB_Session *session) /* create and test a refresh session */ refresh_session.noreveal_index = MELT_NOREVEAL_INDEX; /* create a denomination (value: 1; fraction: 100) */ + now = GNUNET_TIME_absolute_get (); + GNUNET_TIME_round_abs (&now); dkp = create_denom_key_pair (512, session, - GNUNET_TIME_absolute_get (), + now, &value, &fee_withdraw, &fee_deposit, @@ -589,10 +592,13 @@ test_melting (struct TALER_EXCHANGEDB_Session *session) { struct TALER_EXCHANGEDB_RefreshRevealedCoin *ccoin; struct GNUNET_HashCode hc; + struct GNUNET_TIME_Absolute now; + now = GNUNET_TIME_absolute_get (); + GNUNET_TIME_round_abs (&now); new_dkp[cnt] = create_denom_key_pair (1024, session, - GNUNET_TIME_absolute_get (), + now, &value, &fee_withdraw, &fee_deposit, @@ -1009,6 +1015,7 @@ test_gc (struct TALER_EXCHANGEDB_Session *session) struct TALER_EXCHANGEDB_DenominationKeyInformationP issue2; now = GNUNET_TIME_absolute_get (); + GNUNET_TIME_round_abs (&now); past = GNUNET_TIME_absolute_subtract (now, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)); @@ -1062,7 +1069,9 @@ test_wire_fees (struct TALER_EXCHANGEDB_Session *session) struct TALER_MasterSignatureP ms; start_date = GNUNET_TIME_absolute_get (); + GNUNET_TIME_round_abs (&start_date); end_date = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); + GNUNET_TIME_round_abs (&end_date); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":1.424242", &wire_fee)); @@ -1351,16 +1360,32 @@ wire_missing_cb (void *cls, memset (&h_wire, 0, sizeof (h_wire)); - if ( (GNUNET_NO != tiny) || - (GNUNET_NO != done) || - (0 != TALER_amount_cmp (amount, - &deposit->amount_with_fee)) || - (0 != memcmp (coin_pub, - &deposit->coin.coin_pub, - sizeof (struct TALER_CoinSpendPublicKeyP))) || - (0 != memcmp (&h_wire, - &deposit->h_wire, - sizeof (struct GNUNET_HashCode))) ) + if (GNUNET_NO != tiny) + { + GNUNET_break (0); + result = 66; + } + if (GNUNET_NO != done) + { + GNUNET_break (0); + result = 66; + } + if (0 != TALER_amount_cmp (amount, + &deposit->amount_with_fee)) + { + GNUNET_break (0); + result = 66; + } + if (0 != memcmp (coin_pub, + &deposit->coin.coin_pub, + sizeof (struct TALER_CoinSpendPublicKeyP))) + { + GNUNET_break (0); + result = 66; + } + if (0 != memcmp (&h_wire, + &deposit->h_wire, + sizeof (struct GNUNET_HashCode))) { GNUNET_break (0); result = 66; @@ -1412,6 +1437,7 @@ run (void *cls) void *rr; size_t rr_size; enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Absolute now; dkp = NULL; rh = NULL; @@ -1479,12 +1505,14 @@ run (void *cls) session, &rr, &rr_size)); + now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->reserves_in_insert (plugin->cls, session, &reserve_pub, &value, - GNUNET_TIME_absolute_get (), + now, sndr, "TEST", 4)); @@ -1502,12 +1530,14 @@ run (void *cls) value.value, value.fraction, value.currency)); + now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->reserves_in_insert (plugin->cls, session, &reserve_pub, &value, - GNUNET_TIME_absolute_get (), + now, sndr, "TEST2", 5)); @@ -1533,9 +1563,11 @@ run (void *cls) value.fraction * 2, value.currency)); result = 5; + now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); dkp = create_denom_key_pair (1024, session, - GNUNET_TIME_absolute_get (), + now, &value, &fee_withdraw, &fee_deposit, @@ -1625,11 +1657,13 @@ run (void *cls) GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":0.000010", &fee_closing)); + now = GNUNET_TIME_absolute_get (); + (void) GNUNET_TIME_round_abs (&now); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->insert_reserve_closed (plugin->cls, session, &reserve_pub, - GNUNET_TIME_absolute_get (), + now, sndr, &wire_out_wtid, &amount_with_fee, @@ -1787,7 +1821,7 @@ run (void *cls) &deposit.merchant_pub, &deposit_cb, &deposit, 2)); - + sleep (2); /* giv deposit time to be ready */ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->get_ready_deposit (plugin->cls, session, diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index 1fda8e585..4ac0a6df2 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -64,6 +64,32 @@ struct GNUNET_PQ_QueryParam TALER_PQ_query_param_json (const json_t *x); +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_PQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); + + +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_PQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x); + + /** * Currency amount expected. * @@ -100,6 +126,36 @@ TALER_PQ_result_spec_json (const char *name, json_t **jp); +/** + * Rounded absolute time expected. + * In contrast to #GNUNET_PQ_query_param_absolute_time_nbo(), + * this function ensures that the result is rounded and can + * be converted to JSON. + * + * @param name name of the field in the table + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_absolute_time (const char *name, + struct GNUNET_TIME_Absolute *at); + + +/** + * Rounded absolute time expected. + * In contrast to #GNUNET_PQ_result_spec_absolute_time_nbo(), + * this function ensures that the result is rounded and can + * be converted to JSON. + * + * @param name name of the field in the table + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_absolute_time_nbo (const char *name, + struct GNUNET_TIME_AbsoluteNBO *at); + + #endif /* TALER_PQ_LIB_H_ */ /* end of include/taler_pq_lib.h */ diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index d6418a18b..6386749c9 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -205,4 +205,127 @@ TALER_PQ_query_param_json (const json_t *x) } +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument + * @param data_len number of bytes in @a data (if applicable) + * @param[out] param_values SQL data to set + * @param[out] param_lengths SQL length data to set + * @param[out] param_formats SQL format data to set + * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays + * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() + * @param scratch_length number of entries left in @a scratch + * @return -1 on error, number of offsets used in @a scratch otherwise + */ +static int +qconv_round_time (void *cls, + const void *data, + size_t data_len, + void *param_values[], + int param_lengths[], + int param_formats[], + unsigned int param_length, + void *scratch[], + unsigned int scratch_length) +{ + const struct GNUNET_TIME_Absolute *at = data; + struct GNUNET_TIME_Absolute tmp; + struct GNUNET_TIME_AbsoluteNBO *buf; + + GNUNET_break (NULL == cls); + if (1 != param_length) + return -1; + tmp = *at; + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&tmp)); + buf = GNUNET_new (struct GNUNET_TIME_AbsoluteNBO); + *buf = GNUNET_TIME_absolute_hton (tmp); + scratch[0] = buf; + param_values[0] = (void *) buf; + param_lengths[0] = sizeof (struct GNUNET_TIME_AbsoluteNBO); + param_formats[0] = 1; + return 1; +} + + +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_PQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + * @return array entry for the query parameters to use + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) +{ + struct GNUNET_PQ_QueryParam res = + { &qconv_round_time, NULL, x, sizeof (*x), 1 }; + return res; +} + + +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument + * @param data_len number of bytes in @a data (if applicable) + * @param[out] param_values SQL data to set + * @param[out] param_lengths SQL length data to set + * @param[out] param_formats SQL format data to set + * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays + * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() + * @param scratch_length number of entries left in @a scratch + * @return -1 on error, number of offsets used in @a scratch otherwise + */ +static int +qconv_round_time_abs (void *cls, + const void *data, + size_t data_len, + void *param_values[], + int param_lengths[], + int param_formats[], + unsigned int param_length, + void *scratch[], + unsigned int scratch_length) +{ + const struct GNUNET_TIME_AbsoluteNBO *at = data; + struct GNUNET_TIME_Absolute tmp; + + GNUNET_break (NULL == cls); + if (1 != param_length) + return -1; + tmp = GNUNET_TIME_absolute_ntoh (*at); + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&tmp)); + param_values[0] = (void *) at; + param_lengths[0] = sizeof (struct GNUNET_TIME_AbsoluteNBO); + param_formats[0] = 1; + return 0; +} + + +/** + * Generate query parameter for an absolute time value. + * In contrast to + * #GNUNET_PQ_query_param_absolute_time(), this function + * will abort (!) if the time given is not rounded! + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_absolute_time_nbo(const struct GNUNET_TIME_AbsoluteNBO *x) +{ + struct GNUNET_PQ_QueryParam res = + { &qconv_round_time_abs, NULL, x, sizeof (*x), 1 }; + return res; +} + + /* end of pq/pq_query_helper.c */ diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index d0ff78d1c..c1395b7c8 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -370,4 +370,164 @@ TALER_PQ_result_spec_json (const char *name, return res; } + + +/** + * Extract data from a Postgres database @a result at row @a row. + * + * @param cls closure + * @param result where to extract data from + * @param int row to extract data from + * @param fname name (or prefix) of the fields to extract from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_round_time (void *cls, + PGresult *result, + int row, + const char *fname, + size_t *dst_size, + void *dst) +{ + struct GNUNET_TIME_Absolute *udst = dst; + const struct GNUNET_TIME_AbsoluteNBO *res; + struct GNUNET_TIME_Absolute tmp; + int fnum; + + fnum = PQfnumber (result, + fname); + if (fnum < 0) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (PQgetisnull (result, + row, + fnum)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_assert (NULL != dst); + if (sizeof (struct GNUNET_TIME_Absolute) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + res = (struct GNUNET_TIME_AbsoluteNBO *) PQgetvalue (result, + row, + fnum); + tmp = GNUNET_TIME_absolute_ntoh (*res); + GNUNET_break (GNUNET_OK == + GNUNET_TIME_round_abs (&tmp)); + *udst = tmp; + return GNUNET_OK; +} + + +/** + * Rounded absolute time expected. + * In contrast to #GNUNET_PQ_query_param_absolute_time_nbo(), + * this function ensures that the result is rounded and can + * be converted to JSON. + * + * @param name name of the field in the table + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_absolute_time (const char *name, + struct GNUNET_TIME_Absolute *at) +{ + struct GNUNET_PQ_ResultSpec res = + { &extract_round_time, NULL, NULL, + (void *) at, sizeof (struct GNUNET_TIME_Absolute), + name, NULL }; + return res; +} + + +/** + * Extract data from a Postgres database @a result at row @a row. + * + * @param cls closure + * @param result where to extract data from + * @param int row to extract data from + * @param fname name (or prefix) of the fields to extract from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_round_time_nbo (void *cls, + PGresult *result, + int row, + const char *fname, + size_t *dst_size, + void *dst) +{ + struct GNUNET_TIME_AbsoluteNBO *udst = dst; + const struct GNUNET_TIME_AbsoluteNBO *res; + struct GNUNET_TIME_Absolute tmp; + int fnum; + + fnum = PQfnumber (result, + fname); + if (fnum < 0) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (PQgetisnull (result, + row, + fnum)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_assert (NULL != dst); + if (sizeof (struct GNUNET_TIME_AbsoluteNBO) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + res = (struct GNUNET_TIME_AbsoluteNBO *) PQgetvalue (result, + row, + fnum); + tmp = GNUNET_TIME_absolute_ntoh (*res); + GNUNET_break (GNUNET_OK == + GNUNET_TIME_round_abs (&tmp)); + *udst = GNUNET_TIME_absolute_hton (tmp); + return GNUNET_OK; +} + + +/** + * Rounded absolute time in network byte order expected. + * In contrast to #GNUNET_PQ_query_param_absolute_time_nbo(), + * this function ensures that the result is rounded and can + * be converted to JSON. + * + * @param name name of the field in the table + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_absolute_time_nbo (const char *name, + struct GNUNET_TIME_AbsoluteNBO *at) +{ + struct GNUNET_PQ_ResultSpec res = + { &extract_round_time_nbo, NULL, NULL, + (void *) at, sizeof (struct GNUNET_TIME_AbsoluteNBO), + name, NULL }; + return res; +} + + /* end of pq_result_helper.c */ -- cgit v1.2.3