diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-05-15 17:24:27 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-05-15 17:24:27 +0200 |
commit | d080e59e272e307b9ebc267f2c4dd2941cd79436 (patch) | |
tree | fceb6637439e4786d643f9235028f960cc9ab0e5 | |
parent | 33f5242ac4105d8631d659447989cb718459b081 (diff) |
resolve #3717
-rw-r--r-- | src/include/taler_mintdb_plugin.h | 4 | ||||
-rw-r--r-- | src/mint-tools/taler-mint-reservemod.c | 40 | ||||
-rw-r--r-- | src/mintdb/plugin_mintdb_postgres.c | 23 |
3 files changed, 53 insertions, 14 deletions
diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index af641b186..1f4707b4d 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -685,7 +685,9 @@ struct TALER_MINTDB_Plugin /** * Insert a incoming transaction into reserves. New reserves are - * also created through this function. + * also created through this function. Note that this API call + * starts (and stops) its own transaction scope (so the application + * must not do so). * * @param cls the @e cls of this struct with the plugin-specific state * @param db the database connection handle diff --git a/src/mint-tools/taler-mint-reservemod.c b/src/mint-tools/taler-mint-reservemod.c index 8607c6dbf..645a2f32e 100644 --- a/src/mint-tools/taler-mint-reservemod.c +++ b/src/mint-tools/taler-mint-reservemod.c @@ -98,6 +98,9 @@ main (int argc, char *const *argv) { fprintf (stderr, "Mint directory not given\n"); + GNUNET_free_non_null (add_str); + GNUNET_free_non_null (details); + GNUNET_free_non_null (reserve_pub_str); return 1; } if ((NULL == reserve_pub_str) || @@ -109,6 +112,9 @@ main (int argc, char *const *argv) { fprintf (stderr, "Parsing reserve key invalid\n"); + GNUNET_free_non_null (add_str); + GNUNET_free_non_null (details); + GNUNET_free_non_null (reserve_pub_str); return 1; } if ( (NULL == add_str) || @@ -119,6 +125,9 @@ main (int argc, char *const *argv) fprintf (stderr, "Failed to parse currency amount `%s'\n", add_str); + GNUNET_free_non_null (add_str); + GNUNET_free_non_null (details); + GNUNET_free_non_null (reserve_pub_str); return 1; } @@ -126,7 +135,9 @@ main (int argc, char *const *argv) { fprintf (stderr, "No wiring details given (justification required)\n"); - return 1; + GNUNET_free_non_null (add_str); + GNUNET_free_non_null (reserve_pub_str); + return 1; } cfg = TALER_config_load (mint_directory); @@ -134,7 +145,10 @@ main (int argc, char *const *argv) { fprintf (stderr, "Failed to load mint configuration\n"); - return 1; + GNUNET_free_non_null (add_str); + GNUNET_free_non_null (details); + GNUNET_free_non_null (reserve_pub_str); + return 1; } ret = 1; if (NULL == @@ -154,24 +168,32 @@ main (int argc, char *const *argv) goto cleanup; } expiration = GNUNET_TIME_relative_to_absolute (RESERVE_EXPIRATION); - if (GNUNET_OK != - plugin->reserves_in_insert (plugin->cls, - session, - &reserve_pub, - &add_value, - details, - expiration)) + ret = plugin->reserves_in_insert (plugin->cls, + session, + &reserve_pub, + &add_value, + details, + expiration); + if (GNUNET_SYSERR == ret) { fprintf (stderr, "Failed to update reserve.\n"); goto cleanup; } + if (GNUNET_NO == ret) + { + fprintf (stderr, + "Record exists, reserve not updated.\n"); + } ret = 0; cleanup: if (NULL != plugin) TALER_MINTDB_plugin_unload (plugin); if (NULL != cfg) GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_free_non_null (add_str); + GNUNET_free_non_null (details); + GNUNET_free_non_null (reserve_pub_str); return ret; } diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index 45599f6e9..baf94ddab 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -986,7 +986,8 @@ postgres_reserves_update (void *cls, /** * Insert a incoming transaction into reserves. New reserves are also created - * through this function. + * through this function. Note that this API call starts (and stops) its + * own transaction scope (so the application must not do so). * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param session the database connection handle @@ -1025,9 +1026,8 @@ postgres_reserves_in_insert (void *cls, &reserve); if (GNUNET_SYSERR == reserve_exists) { - postgres_rollback (cls, - session); - return GNUNET_SYSERR; + GNUNET_break (0); + goto rollback; } if (GNUNET_NO == reserve_exists) { @@ -1084,6 +1084,21 @@ postgres_reserves_in_insert (void *cls, params); if (PGRES_COMMAND_OK != PQresultStatus(result)) { + const char *efield; + + efield = PQresultErrorField (result, + PG_DIAG_SQLSTATE); + if ( (PGRES_FATAL_ERROR == PQresultStatus(result)) && + (NULL != strstr ("23505", /* unique violation */ + efield)) ) + { + /* This means we had the same reserve/justification/details + before */ + PQclear (result); + postgres_rollback (cls, + session); + return GNUNET_NO; + } QUERY_ERR (result); goto rollback; } |