GNUnet  0.10.x
Macros | Functions
pq_eval.c File Reference

functions to execute SQL statements with arguments and/or results (PostGres) More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_pq_lib.h"
Include dependency graph for pq_eval.c:

Go to the source code of this file.

Macros

#define PQ_DIAG_SQLSTATE_DEADLOCK   "40P01"
 Error code returned by Postgres for deadlock. More...
 
#define PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION   "23505"
 Error code returned by Postgres for uniqueness violation. More...
 
#define PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE   "40001"
 Error code returned by Postgres on serialization failure. More...
 

Functions

enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result (PGconn *connection, const char *statement_name, PGresult *result)
 Check the result's error code to see what happened. More...
 
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_non_select (PGconn *connection, const char *statement_name, const struct GNUNET_PQ_QueryParam *params)
 Execute a named prepared statement that is NOT a SELECT statement in connnection using the given params. More...
 
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_multi_select (PGconn *connection, const char *statement_name, const struct GNUNET_PQ_QueryParam *params, GNUNET_PQ_PostgresResultHandler rh, void *rh_cls)
 Execute a named prepared statement that is a SELECT statement which may return multiple results in connection using the given params. More...
 
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)
 Execute a named prepared statement that is a SELECT statement which must return a single result in connection using the given params. More...
 

Detailed Description

functions to execute SQL statements with arguments and/or results (PostGres)

Author
Christian Grothoff

Definition in file pq_eval.c.

Macro Definition Documentation

◆ PQ_DIAG_SQLSTATE_DEADLOCK

#define PQ_DIAG_SQLSTATE_DEADLOCK   "40P01"

Error code returned by Postgres for deadlock.

Definition at line 33 of file pq_eval.c.

Referenced by GNUNET_PQ_eval_result().

◆ PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION

#define PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION   "23505"

Error code returned by Postgres for uniqueness violation.

Definition at line 38 of file pq_eval.c.

Referenced by GNUNET_PQ_eval_result().

◆ PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE

#define PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE   "40001"

Error code returned by Postgres on serialization failure.

Definition at line 43 of file pq_eval.c.

Referenced by GNUNET_PQ_eval_result().

Function Documentation

◆ GNUNET_PQ_eval_result()

enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result ( PGconn *  connection,
const char *  statement_name,
PGresult *  result 
)

Check the result's error code to see what happened.

Also logs errors.

Parameters
connectionconnection to execute the statement in
statement_namename of the statement that created result
resultresult to check
Returns
status code from the result, mapping PQ status 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)

Definition at line 60 of file pq_eval.c.

References GNUNET_break, GNUNET_DB_STATUS_HARD_ERROR, GNUNET_DB_STATUS_SOFT_ERROR, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log_from, PQ_DIAG_SQLSTATE_DEADLOCK, PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE, and PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION.

Referenced by GNUNET_PQ_eval_prepared_multi_select(), GNUNET_PQ_eval_prepared_non_select(), and GNUNET_PQ_eval_prepared_singleton_select().

63 {
64  ExecStatusType est;
65 
66  est = PQresultStatus (result);
67  if ( (PGRES_COMMAND_OK != est) &&
68  (PGRES_TUPLES_OK != est) )
69  {
70  const char *sqlstate;
71 
72  sqlstate = PQresultErrorField (result,
73  PG_DIAG_SQLSTATE);
74  if (NULL == sqlstate)
75  {
76  /* very unexpected... */
77  GNUNET_break (0);
79  }
80  if ( (0 == strcmp (sqlstate,
82  (0 == strcmp (sqlstate,
84  {
85  /* These two can be retried and have a fair chance of working
86  the next time */
88  "pq",
89  "Query `%s' failed with result: %s/%s/%s/%s/%s\n",
90  statement_name,
91  PQresultErrorField (result,
92  PG_DIAG_MESSAGE_PRIMARY),
93  PQresultErrorField (result,
94  PG_DIAG_MESSAGE_DETAIL),
95  PQresultErrorMessage (result),
96  PQresStatus (PQresultStatus (result)),
97  PQerrorMessage (connection));
99  }
100  if (0 == strcmp (sqlstate,
102  {
103  /* Likely no need to retry, INSERT of "same" data. */
105  "pq",
106  "Query `%s' failed with unique violation: %s/%s/%s/%s/%s\n",
107  statement_name,
108  PQresultErrorField (result,
109  PG_DIAG_MESSAGE_PRIMARY),
110  PQresultErrorField (result,
111  PG_DIAG_MESSAGE_DETAIL),
112  PQresultErrorMessage (result),
113  PQresStatus (PQresultStatus (result)),
114  PQerrorMessage (connection));
116  }
118  "pq",
119  "Query `%s' failed with result: %s/%s/%s/%s/%s\n",
120  statement_name,
121  PQresultErrorField (result,
122  PG_DIAG_MESSAGE_PRIMARY),
123  PQresultErrorField (result,
124  PG_DIAG_MESSAGE_DETAIL),
125  PQresultErrorMessage (result),
126  PQresStatus (PQresultStatus (result)),
127  PQerrorMessage (connection));
129  }
131 }
#define PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE
Error code returned by Postgres on serialization failure.
Definition: pq_eval.c:43
A soft error occurred, retrying the transaction may succeed.
Definition: gnunet_db_lib.h:45
A hard error occurred, retrying will not help.
Definition: gnunet_db_lib.h:39
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define PQ_DIAG_SQLSTATE_DEADLOCK
Error code returned by Postgres for deadlock.
Definition: pq_eval.c:33
#define PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION
Error code returned by Postgres for uniqueness violation.
Definition: pq_eval.c:38
static int result
Global testing status.
#define GNUNET_log_from(kind, comp,...)
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:53
Here is the caller graph for this function:

◆ GNUNET_PQ_eval_prepared_non_select()

enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_non_select ( PGconn *  connection,
const char *  statement_name,
const struct GNUNET_PQ_QueryParam params 
)

Execute a named prepared statement that is NOT a SELECT statement in connnection using the given params.

Returns the resulting session state.

Parameters
connectionconnection to execute the statement in
statement_namename of the statement
paramsparameters to give to the statement (GNUNET_PQ_query_param_end-terminated)
Returns
status code from the result, mapping PQ status codes to enum GNUNET_DB_QueryStatus. If the statement was a DELETE or UPDATE statement, the 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.

Definition at line 151 of file pq_eval.c.

References GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_PQ_eval_result(), GNUNET_PQ_exec_prepared(), and result.

Referenced by delete_old_block(), namecache_postgres_cache_block(), namecache_postgres_expire_blocks(), namestore_postgres_store_records(), postgres_plugin_del(), postgres_plugin_put(), postgres_plugin_remove_key(), process_result(), and repl_proc().

154 {
155  PGresult *result;
156  enum GNUNET_DB_QueryStatus qs;
157 
158  result = GNUNET_PQ_exec_prepared (connection,
159  statement_name,
160  params);
161  qs = GNUNET_PQ_eval_result (connection,
162  statement_name,
163  result);
165  {
166  const char *tuples;
167 
168  /* What an awful API, this function really does return a string */
169  tuples = PQcmdTuples (result);
170  if (NULL != tuples)
171  qs = strtol (tuples, NULL, 10);
172  }
173  PQclear (result);
174  return qs;
175 }
static int result
Global testing status.
PGresult * GNUNET_PQ_exec_prepared(PGconn *db_conn, const char *name, const struct GNUNET_PQ_QueryParam *params)
Execute a prepared statement.
Definition: pq.c:41
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result(PGconn *connection, const char *statement_name, PGresult *result)
Check the result's error code to see what happened.
Definition: pq_eval.c:60
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:34
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_eval_prepared_multi_select()

enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_multi_select ( PGconn *  connection,
const char *  statement_name,
const struct GNUNET_PQ_QueryParam params,
GNUNET_PQ_PostgresResultHandler  rh,
void *  rh_cls 
)

Execute a named prepared statement that is a SELECT statement which may return multiple results in connection using the given params.

Call rh with the results. Returns the query status including the number of results given to rh (possibly zero). rh will not have been called if the return value is negative.

Parameters
connectionconnection to execute the statement in
statement_namename of the statement
paramsparameters to give to the statement (GNUNET_PQ_query_param_end-terminated)
rhfunction to call with the result set, NULL to ignore
rh_clsclosure to pass to rh
Returns
status code from the result, mapping PQ status codes to enum GNUNET_DB_QueryStatus.

Definition at line 194 of file pq_eval.c.

References GNUNET_PQ_eval_result(), GNUNET_PQ_exec_prepared(), result, and ret.

Referenced by namestore_postgres_iterate_records(), namestore_postgres_lookup_records(), namestore_postgres_zone_to_name(), postgres_plugin_get(), postgres_plugin_get_closest(), postgres_plugin_get_expiration(), postgres_plugin_get_key(), postgres_plugin_get_keys(), postgres_plugin_get_replication(), and postgres_plugin_get_zero_anonymity().

199 {
200  PGresult *result;
201  enum GNUNET_DB_QueryStatus qs;
202  unsigned int ret;
203 
204  result = GNUNET_PQ_exec_prepared (connection,
205  statement_name,
206  params);
207  qs = GNUNET_PQ_eval_result (connection,
208  statement_name,
209  result);
210  if (qs < 0)
211  {
212  PQclear (result);
213  return qs;
214  }
215  ret = PQntuples (result);
216  if (NULL != rh)
217  rh (rh_cls,
218  result,
219  ret);
220  PQclear (result);
221  return ret;
222 }
static int ret
Final status code.
Definition: gnunet-arm.c:89
static int result
Global testing status.
PGresult * GNUNET_PQ_exec_prepared(PGconn *db_conn, const char *name, const struct GNUNET_PQ_QueryParam *params)
Execute a prepared statement.
Definition: pq.c:41
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result(PGconn *connection, const char *statement_name, PGresult *result)
Check the result&#39;s error code to see what happened.
Definition: pq_eval.c:60
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_eval_prepared_singleton_select()

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 
)

Execute a named prepared statement that is a SELECT statement which must return a single result in connection using the given params.

Stores the result (if any) in rs, which the caller must then clean up using GNUNET_PQ_cleanup_result() if the return value was GNUNET_DB_STATUS_SUCCESS_ONE_RESULT. Returns the resulting session status.

Parameters
connectionconnection to execute the statement in
statement_namename of the statement
paramsparameters to give to the statement (GNUNET_PQ_query_param_end-terminated)
[in,out]rsresult specification to use for storing the result of the query
Returns
status code from the result, mapping PQ status codes to enum GNUNET_DB_QueryStatus.

Definition at line 241 of file pq_eval.c.

References GNUNET_break, GNUNET_DB_STATUS_HARD_ERROR, GNUNET_DB_STATUS_SUCCESS_NO_RESULTS, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT, GNUNET_OK, GNUNET_PQ_eval_result(), GNUNET_PQ_exec_prepared(), GNUNET_PQ_extract_result(), and result.

Referenced by namecache_postgres_lookup_block(), postgres_plugin_del(), postgres_plugin_estimate_size(), and postgres_plugin_get_random().

245 {
246  PGresult *result;
247  enum GNUNET_DB_QueryStatus qs;
248 
249  result = GNUNET_PQ_exec_prepared (connection,
250  statement_name,
251  params);
252  qs = GNUNET_PQ_eval_result (connection,
253  statement_name,
254  result);
255  if (qs < 0)
256  {
257  PQclear (result);
258  return qs;
259  }
260  if (0 == PQntuples (result))
261  {
262  PQclear (result);
264  }
265  if (1 != PQntuples (result))
266  {
267  /* more than one result, but there must be at most one */
268  GNUNET_break (0);
269  PQclear (result);
271  }
272  if (GNUNET_OK !=
273  GNUNET_PQ_extract_result (result,
274  rs,
275  0))
276  {
277  PQclear (result);
279  }
280  PQclear (result);
282 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
A hard error occurred, retrying will not help.
Definition: gnunet_db_lib.h:39
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static int result
Global testing status.
PGresult * GNUNET_PQ_exec_prepared(PGconn *db_conn, const char *name, const struct GNUNET_PQ_QueryParam *params)
Execute a prepared statement.
Definition: pq.c:41
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result(PGconn *connection, const char *statement_name, PGresult *result)
Check the result&#39;s error code to see what happened.
Definition: pq_eval.c:60
The transaction succeeded, and yielded one result.
Definition: gnunet_db_lib.h:58
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:34
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:53
int GNUNET_PQ_extract_result(PGresult *result, struct GNUNET_PQ_ResultSpec *rs, int row)
Extract results from a query result according to the given specification.
Definition: pq.c:144
Here is the call graph for this function:
Here is the caller graph for this function: