diff options
Diffstat (limited to 'src/exchangedb')
| -rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 105 | ||||
| -rw-r--r-- | src/exchangedb/test_exchangedb.c | 12 | 
2 files changed, 34 insertions, 83 deletions
| diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 2a47f250..6758a308 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -1952,11 +1952,9 @@ reserves_update (void *cls,   * @param sender_account_details account information for the sender   * @param wire_reference unique reference identifying the wire transfer (binary blob)   * @param wire_reference_size number of bytes in @a wire_reference - * @return #GNUNET_OK upon success; #GNUNET_NO if the given - *         @a details are already known for this @a reserve_pub, - *         #GNUNET_SYSERR upon failures (DB error, incompatible currency) + * @return transaction status code   */ -static int +static enum GNUNET_DB_QueryStatus  postgres_reserves_in_insert (void *cls,                               struct TALER_EXCHANGEDB_Session *session,                               const struct TALER_ReservePublicKeyP *reserve_pub, @@ -1967,18 +1965,11 @@ postgres_reserves_in_insert (void *cls,                               size_t wire_reference_size)  {    struct PostgresClosure *pg = cls; -  PGresult *result;    enum GNUNET_DB_QueryStatus reserve_exists; +  enum GNUNET_DB_QueryStatus qs;    struct TALER_EXCHANGEDB_Reserve reserve;    struct GNUNET_TIME_Absolute expiry; -  if (GNUNET_OK != -      postgres_start (cls, -                      session)) -  { -    GNUNET_break (0); -    return GNUNET_SYSERR; -  }    reserve.pub = *reserve_pub;    reserve_exists = postgres_reserve_get (cls,                                           session, @@ -1986,7 +1977,7 @@ postgres_reserves_in_insert (void *cls,    if (0 > reserve_exists)    {      GNUNET_break (0); -    goto rollback; +    return reserve_exists;    }    if ( (0 == reserve.balance.value) &&         (0 == reserve.balance.fraction) ) @@ -2030,22 +2021,22 @@ postgres_reserves_in_insert (void *cls,      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,                  "Reserve does not exist; creating a new one\n"); -    result = GNUNET_PQ_exec_prepared (session->conn, -                                      "reserve_create", -                                      params); -    if (PGRES_COMMAND_OK != PQresultStatus(result)) +    qs = GNUNET_PQ_eval_prepared_non_select (session->conn, +					     "reserve_create", +					     params); +    if (0 > qs) +      return qs; +    if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)      { -      QUERY_ERR (result, session->conn); -      PQclear (result); -      goto rollback; +      /* Maybe DB did not detect serializiability error already, +	 but clearly there must be one. Still odd. */ +      GNUNET_break (0); +      return GNUNET_DB_STATUS_SOFT_ERROR;      } -    PQclear (result);    }    /* Create new incoming transaction, SQL "primary key" logic       is used to guard against duplicates.  If a duplicate is -     detected, we rollback (which really shouldn't undo -     anything) and return #GNUNET_NO to indicate that this failure -     is kind-of harmless (already executed). */ +     detected, we just "succeed" with no changes. */    {      struct GNUNET_PQ_QueryParam params[] = {        GNUNET_PQ_query_param_auto_from_type (&reserve.pub), @@ -2057,34 +2048,12 @@ postgres_reserves_in_insert (void *cls,        GNUNET_PQ_query_param_end      }; -    result = GNUNET_PQ_exec_prepared (session->conn, -                                      "reserves_in_add_transaction", -                                      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 */ -      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -                  "Uniqueness violation, deposit details already known\n"); -      PQclear (result); -      postgres_rollback (cls, -			 session); -      return GNUNET_NO; -    } -    QUERY_ERR (result, session->conn); -    PQclear (result); -    goto rollback; +    qs = GNUNET_PQ_eval_prepared_non_select (session->conn, +					     "reserves_in_add_transaction", +					     params); +    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) +      return qs;    } -  PQclear (result);    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == reserve_exists)    { @@ -2094,7 +2063,6 @@ postgres_reserves_in_insert (void *cls,         back for duplicate transactions; like this, we should virtually         never actually have to rollback anything. */      struct TALER_EXCHANGEDB_Reserve updated_reserve; -    enum GNUNET_DB_QueryStatus qs;      updated_reserve.pub = reserve.pub;      if (GNUNET_OK != @@ -2105,38 +2073,15 @@ postgres_reserves_in_insert (void *cls,        /* currency overflow or incompatible currency */        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,                    "Attempt to deposit incompatible amount into reserve\n"); -      goto rollback; +      return GNUNET_DB_STATUS_HARD_ERROR;      }      updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry,                                                         reserve.expiry); -    qs = reserves_update (cls, -			  session, -			  &updated_reserve); -    if (GNUNET_DB_STATUS_SOFT_ERROR == qs) -      goto rollback; /* FIXME: #5010 */ -    if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) -    { -      postgres_rollback (cls, -			 session); -      return GNUNET_SYSERR; -    } -  } -  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != -      postgres_commit (cls, -                       session)) -  { -    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, -                "Failed to commit transaction adding amount to reserve\n"); -    return GNUNET_SYSERR; +    return reserves_update (cls, +			    session, +			    &updated_reserve);    } -  return GNUNET_OK; - - rollback: -  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -              "Transaction failed, doing rollback\n"); -  postgres_rollback (cls, -                     session); -  return GNUNET_SYSERR; +  return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;  } diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index f7983924..701c20c7 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -162,7 +162,6 @@ check_reserve (struct TALER_EXCHANGEDB_Session *session,    struct TALER_EXCHANGEDB_Reserve reserve;    reserve.pub = *pub; -    FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=            plugin->reserve_get (plugin->cls,                                 session, @@ -1485,6 +1484,10 @@ run (void *cls)      goto drop;    } +  FAILIF (GNUNET_OK != +          plugin->start (plugin->cls, +                         session)); +    /* test DB is empty */    FAILIF (GNUNET_NO !=            plugin->select_payback_above_serial_id (plugin->cls, @@ -1520,7 +1523,7 @@ run (void *cls)                                                     session,                                                     &rr,                                                     &rr_size)); -  FAILIF (GNUNET_OK != +  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=            plugin->reserves_in_insert (plugin->cls,                                        session,                                        &reserve_pub, @@ -1543,7 +1546,7 @@ run (void *cls)                           value.value,                           value.fraction,                           value.currency)); -  FAILIF (GNUNET_OK != +  FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=            plugin->reserves_in_insert (plugin->cls,                                        session,                                        &reserve_pub, @@ -1810,6 +1813,9 @@ run (void *cls)                                       session,                                       &deposit_cb,                                       &deposit)); +  FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != +          plugin->commit (plugin->cls, +                          session));    FAILIF (GNUNET_OK !=            plugin->start (plugin->cls,                           session)); | 
