Use Suffix Extensions in Makefiles (doc, src/{arm,dht,integration,statistics}) for...
[oweals/gnunet.git] / src / pq / pq_eval.c
index 9296dce2e478998b314dca99ab67fc41d751b3fa..0f28aec7eec3a02582edc0441606b59f48b1ad2e 100644 (file)
  * @param statement_name name of the statement that created @a result
  * @param result result to check
  * @return status code from the result, mapping PQ status
- *         codes to `enum GNUNET_PQ_QueryStatus`.  Never
+ *         codes to `enum GNUNET_DB_QueryStatus`.  Never
  *         returns positive values as this function does
  *         not look at the result set.
  * @deprecated (low level, let's see if we can do with just the high-level functions)
  */
-enum GNUNET_PQ_QueryStatus
+enum GNUNET_DB_QueryStatus
 GNUNET_PQ_eval_result (PGconn *connection,
                        const char *statement_name,
                        PGresult *result)
@@ -71,7 +71,7 @@ GNUNET_PQ_eval_result (PGconn *connection,
     {
       /* very unexpected... */
       GNUNET_break (0);
-      return GNUNET_PQ_STATUS_HARD_ERROR;
+      return GNUNET_DB_STATUS_HARD_ERROR;
     }
     if ( (0 == strcmp (sqlstate,
                        PQ_DIAG_SQLSTATE_DEADLOCK)) ||
@@ -91,7 +91,24 @@ GNUNET_PQ_eval_result (PGconn *connection,
                        PQresultErrorMessage (result),
                        PQresStatus (PQresultStatus (result)),
                        PQerrorMessage (connection));
-      return GNUNET_PQ_STATUS_SOFT_ERROR;
+      return GNUNET_DB_STATUS_SOFT_ERROR;
+    }
+    if (0 == strcmp (sqlstate,
+                     PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION))
+    {
+      /* Likely no need to retry, INSERT of "same" data. */
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+                       "pq",
+                       "Query `%s' failed with unique violation: %s/%s/%s/%s/%s\n",
+                       statement_name,
+                       PQresultErrorField (result,
+                                           PG_DIAG_MESSAGE_PRIMARY),
+                       PQresultErrorField (result,
+                                           PG_DIAG_MESSAGE_DETAIL),
+                       PQresultErrorMessage (result),
+                       PQresStatus (PQresultStatus (result)),
+                       PQerrorMessage (connection));
+      return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
     }
     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
                      "pq",
@@ -104,9 +121,9 @@ GNUNET_PQ_eval_result (PGconn *connection,
                      PQresultErrorMessage (result),
                      PQresStatus (PQresultStatus (result)),
                      PQerrorMessage (connection));
-    return GNUNET_PQ_STATUS_HARD_ERROR;
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
-  return GNUNET_PQ_STATUS_SUCCESS_NO_RESULTS;
+  return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
 }
 
 
@@ -119,17 +136,20 @@ GNUNET_PQ_eval_result (PGconn *connection,
  * @param statement_name name of the statement
  * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
  * @return status code from the result, mapping PQ status
- *         codes to `enum GNUNET_PQ_QueryStatus`.  If the
+ *         codes to `enum GNUNET_DB_QueryStatus`.  If the
  *         statement was a DELETE or UPDATE statement, the
- *         number of affected rows is returned.
+ *         number of affected rows is returned.; if the
+ *         statment was an INSERT statement, and no row
+ *         was added due to a UNIQUE violation, we return
+ *         zero; if INSERT was successful, we return one.
  */
-enum GNUNET_PQ_QueryStatus
+enum GNUNET_DB_QueryStatus
 GNUNET_PQ_eval_prepared_non_select (PGconn *connection,
                                     const char *statement_name,
                                     const struct GNUNET_PQ_QueryParam *params)
 {
   PGresult *result;
-  enum GNUNET_PQ_QueryStatus qs;
+  enum GNUNET_DB_QueryStatus qs;
 
   result = GNUNET_PQ_exec_prepared (connection,
                                     statement_name,
@@ -137,7 +157,7 @@ GNUNET_PQ_eval_prepared_non_select (PGconn *connection,
   qs = GNUNET_PQ_eval_result (connection,
                               statement_name,
                               result);
-  if (GNUNET_PQ_STATUS_SUCCESS_NO_RESULTS == qs)
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
   {
     const char *tuples;
 
@@ -164,9 +184,9 @@ GNUNET_PQ_eval_prepared_non_select (PGconn *connection,
  * @param rh function to call with the result set, NULL to ignore
  * @param rh_cls closure to pass to @a rh
  * @return status code from the result, mapping PQ status
- *         codes to `enum GNUNET_PQ_QueryStatus`.
+ *         codes to `enum GNUNET_DB_QueryStatus`.
  */
-enum GNUNET_PQ_QueryStatus
+enum GNUNET_DB_QueryStatus
 GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
                                       const char *statement_name,
                                       const struct GNUNET_PQ_QueryParam *params,
@@ -174,7 +194,7 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
                                       void *rh_cls)
 {
   PGresult *result;
-  enum GNUNET_PQ_QueryStatus qs;
+  enum GNUNET_DB_QueryStatus qs;
   unsigned int ret;
 
   result = GNUNET_PQ_exec_prepared (connection,
@@ -203,7 +223,7 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
  * which must return a single result in @a connection using the given
  * @a params.  Stores the result (if any) in @a rs, which the caller
  * must then clean up using #GNUNET_PQ_cleanup_result() if the return
- * value was #GNUNET_PQ_STATUS_SUCCESS_ONE_RESULT.  Returns the
+ * value was #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT.  Returns the
  * resulting session status.
  *
  * @param connection connection to execute the statement in
@@ -211,16 +231,16 @@ GNUNET_PQ_eval_prepared_multi_select (PGconn *connection,
  * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated)
  * @param[in,out] rs result specification to use for storing the result of the query
  * @return status code from the result, mapping PQ status
- *         codes to `enum GNUNET_PQ_QueryStatus`.
+ *         codes to `enum GNUNET_DB_QueryStatus`.
  */
-enum GNUNET_PQ_QueryStatus
+enum GNUNET_DB_QueryStatus
 GNUNET_PQ_eval_prepared_singleton_select (PGconn *connection,
                                           const char *statement_name,
                                           const struct GNUNET_PQ_QueryParam *params,
                                           struct GNUNET_PQ_ResultSpec *rs)
 {
   PGresult *result;
-  enum GNUNET_PQ_QueryStatus qs;
+  enum GNUNET_DB_QueryStatus qs;
 
   result = GNUNET_PQ_exec_prepared (connection,
                                     statement_name,
@@ -236,14 +256,14 @@ GNUNET_PQ_eval_prepared_singleton_select (PGconn *connection,
   if (0 == PQntuples (result))
   {
     PQclear (result);
-    return GNUNET_PQ_STATUS_SUCCESS_NO_RESULTS;
+    return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
   }
   if (1 != PQntuples (result))
   {
     /* more than one result, but there must be at most one */
     GNUNET_break (0);
     PQclear (result);
-    return GNUNET_PQ_STATUS_HARD_ERROR;
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
   if (GNUNET_OK !=
       GNUNET_PQ_extract_result (result,
@@ -251,10 +271,10 @@ GNUNET_PQ_eval_prepared_singleton_select (PGconn *connection,
                                 0))
   {
     PQclear (result);
-    return GNUNET_PQ_STATUS_HARD_ERROR;
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
   PQclear (result);
-  return GNUNET_PQ_STATUS_SUCCESS_ONE_RESULT;
+  return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
 }