From eedfc0485010a2afb1cb4a2d202eb0ceb8bc5cb8 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 11 Jun 2015 14:46:03 +0200 Subject: [PATCH] implement #3830 --- src/mintdb/plugin_mintdb_postgres.c | 148 ++++++++++++++++++---------- 1 file changed, 94 insertions(+), 54 deletions(-) diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index e89e7acc0..870bfb756 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -2095,36 +2095,62 @@ postgres_insert_refresh_order (void *cls, uint16_t num_newcoins, const struct TALER_DenominationPublicKey *denom_pubs) { - // FIXME: check logic: was written for just one COIN! (#3830) - PGresult *result; + unsigned int i; + for (i=0;i<(unsigned int) num_newcoins;i++) { - struct TALER_PQ_QueryParam params[] = { - TALER_PQ_query_param_uint16 (&num_newcoins), - TALER_PQ_query_param_auto_from_type (session_hash), - TALER_PQ_query_param_rsa_public_key (denom_pubs->rsa_public_key), - TALER_PQ_query_param_end - }; - result = TALER_PQ_exec_prepared (session->conn, - "insert_refresh_order", - params); - } - if (PGRES_COMMAND_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); + uint16_t newcoin_off = (uint16_t) i; + PGresult *result; + + { + struct TALER_PQ_QueryParam params[] = { + TALER_PQ_query_param_uint16 (&newcoin_off), + TALER_PQ_query_param_auto_from_type (session_hash), + TALER_PQ_query_param_rsa_public_key (denom_pubs->rsa_public_key), + TALER_PQ_query_param_end + }; + result = TALER_PQ_exec_prepared (session->conn, + "insert_refresh_order", + params); + } + if (PGRES_COMMAND_OK != PQresultStatus (result)) + { + BREAK_DB_ERR (result); + PQclear (result); + return GNUNET_SYSERR; + } + if (0 != strcmp ("1", PQcmdTuples (result))) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } PQclear (result); - return GNUNET_SYSERR; } - if (0 != strcmp ("1", PQcmdTuples (result))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - PQclear (result); return GNUNET_OK; } +/** + * We allocated some @a denom_pubs information, but now need + * to abort. Free allocated memory. + * + * @param denom_pubs data to free (but not the array itself) + * @param denom_pubs_len length of @a denom_pubs array + */ +static void +free_dpk_result (struct TALER_DenominationPublicKey *denom_pubs, + unsigned int denom_pubs_len) +{ + unsigned int i; + + for (i=0;iconn, - "get_refresh_order", params); + for (i=0;i<(unsigned int) num_newcoins;i++) + { + uint16_t newcoin_off = (uint16_t) i; + PGresult *result; - if (PGRES_TUPLES_OK != PQresultStatus (result)) - { - BREAK_DB_ERR (result); - PQclear (result); - return GNUNET_SYSERR; - } + { + struct TALER_PQ_QueryParam params[] = { + TALER_PQ_query_param_auto_from_type (session_hash), + TALER_PQ_query_param_uint16 (&newcoin_off), + TALER_PQ_query_param_end + }; - if (0 == PQntuples (result)) - { - PQclear (result); - /* FIXME: may want to distinguish between different error cases! */ - return GNUNET_SYSERR; + result = TALER_PQ_exec_prepared (session->conn, + "get_refresh_order", + params); + } + if (PGRES_TUPLES_OK != PQresultStatus (result)) + { + BREAK_DB_ERR (result); + PQclear (result); + free_dpk_result (denom_pubs, i); + return GNUNET_SYSERR; + } + if (0 == PQntuples (result)) + { + PQclear (result); + /* FIXME: may want to distinguish between different error cases! */ + free_dpk_result (denom_pubs, i); + return GNUNET_SYSERR; + } + GNUNET_assert (1 == PQntuples (result)); + { + struct TALER_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_rsa_public_key ("denom_pub", + &denom_pubs[i].rsa_public_key), + TALER_PQ_result_spec_end + }; + if (GNUNET_OK != + TALER_PQ_extract_result (result, rs, 0)) + { + PQclear (result); + GNUNET_break (0); + free_dpk_result (denom_pubs, i); + return GNUNET_SYSERR; + } + PQclear (result); + } } - GNUNET_assert (1 == PQntuples (result)); - struct TALER_PQ_ResultSpec rs[] = { - TALER_PQ_result_spec_rsa_public_key ("denom_pub", &denom_pubs->rsa_public_key), - TALER_PQ_result_spec_end - }; - if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) - { - PQclear (result); - GNUNET_break (0); - return GNUNET_SYSERR; - } - PQclear (result); return GNUNET_OK; } - /** * Store information about the commitment of the * given coin for the given refresh session in the database.