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

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

#include "platform.h"
#include "pq.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 (struct GNUNET_PQ_Context *db, 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 (struct GNUNET_PQ_Context *db, 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 (struct GNUNET_PQ_Context *db, 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 (struct GNUNET_PQ_Context *db, 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 32 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 37 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 42 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 ( struct GNUNET_PQ_Context db,
const char *  statement_name,
PGresult *  result 
)

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

Also logs errors.

Parameters
dbdatabase to execute the statement with
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 59 of file pq_eval.c.

References GNUNET_PQ_Context::conn, 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, GNUNET_PQ_reconnect(), PQ_DIAG_SQLSTATE_DEADLOCK, PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE, PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION, and status.

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

62 {
63  ExecStatusType est;
64 
65  if (NULL == result)
67  est = PQresultStatus (result);
68  if ((PGRES_COMMAND_OK != est) &&
69  (PGRES_TUPLES_OK != est))
70  {
71  const char *sqlstate;
72  ConnStatusType status;
73 
74  if (CONNECTION_OK != (status = PQstatus (db->conn)))
75  {
77  "pq",
78  "Database connection failed during query `%s': %d (reconnecting)\n",
79  statement_name,
80  status);
83  }
84 
85  sqlstate = PQresultErrorField (result,
86  PG_DIAG_SQLSTATE);
87  if (NULL == sqlstate)
88  {
89  /* very unexpected... */
90  GNUNET_break (0);
92  }
93  if ((0 == strcmp (sqlstate,
95  (0 == strcmp (sqlstate,
97  {
98  /* These two can be retried and have a fair chance of working
99  the next time */
101  "pq",
102  "Query `%s' failed with result: %s/%s/%s/%s/%s\n",
103  statement_name,
104  PQresultErrorField (result,
105  PG_DIAG_MESSAGE_PRIMARY),
106  PQresultErrorField (result,
107  PG_DIAG_MESSAGE_DETAIL),
108  PQresultErrorMessage (result),
109  PQresStatus (PQresultStatus (result)),
110  PQerrorMessage (db->conn));
112  }
113  if (0 == strcmp (sqlstate,
115  {
116  /* Likely no need to retry, INSERT of "same" data. */
118  "pq",
119  "Query `%s' failed with unique violation: %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 (db->conn));
129  }
131  "pq",
132  "Query `%s' failed with result: %s/%s/%s/%s/%s\n",
133  statement_name,
134  PQresultErrorField (result,
135  PG_DIAG_MESSAGE_PRIMARY),
136  PQresultErrorField (result,
137  PG_DIAG_MESSAGE_DETAIL),
138  PQresultErrorMessage (result),
139  PQresStatus (PQresultStatus (result)),
140  PQerrorMessage (db->conn));
142  }
144 }
#define PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE
Error code returned by Postgres on serialization failure.
Definition: pq_eval.c:42
void GNUNET_PQ_reconnect(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition: pq_connect.c:150
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...
PGconn * conn
Actual connection.
Definition: pq.h:39
#define PQ_DIAG_SQLSTATE_DEADLOCK
Error code returned by Postgres for deadlock.
Definition: pq_eval.c:32
#define PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION
Error code returned by Postgres for uniqueness violation.
Definition: pq_eval.c:37
uint16_t status
See PRISM_STATUS_*-constants.
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 call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_PQ_eval_prepared_non_select()

enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_prepared_non_select ( struct GNUNET_PQ_Context db,
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
dbdatabase to execute the statement with
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 164 of file pq_eval.c.

References GNUNET_DB_STATUS_SOFT_ERROR, 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().

167 {
168  PGresult *result;
169  enum GNUNET_DB_QueryStatus qs;
170 
171  result = GNUNET_PQ_exec_prepared (db,
172  statement_name,
173  params);
174  if (NULL == result)
176  qs = GNUNET_PQ_eval_result (db,
177  statement_name,
178  result);
180  {
181  const char *tuples;
182 
183  /* What an awful API, this function really does return a string */
184  tuples = PQcmdTuples (result);
185  if (NULL != tuples)
186  qs = strtol (tuples, NULL, 10);
187  }
188  PQclear (result);
189  return qs;
190 }
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result(struct GNUNET_PQ_Context *db, const char *statement_name, PGresult *result)
Check the result's error code to see what happened.
Definition: pq_eval.c:59
PGresult * GNUNET_PQ_exec_prepared(struct GNUNET_PQ_Context *db, const char *name, const struct GNUNET_PQ_QueryParam *params)
Execute a prepared statement.
Definition: pq.c:39
A soft error occurred, retrying the transaction may succeed.
Definition: gnunet_db_lib.h:45
static int result
Global testing status.
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 ( struct GNUNET_PQ_Context db,
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
dbdatabase to execute the statement with
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 209 of file pq_eval.c.

References GNUNET_DB_STATUS_SOFT_ERROR, 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().

214 {
215  PGresult *result;
216  enum GNUNET_DB_QueryStatus qs;
217  unsigned int ret;
218 
219  result = GNUNET_PQ_exec_prepared (db,
220  statement_name,
221  params);
222  if (NULL == result)
224  qs = GNUNET_PQ_eval_result (db,
225  statement_name,
226  result);
227  if (qs < 0)
228  {
229  PQclear (result);
230  return qs;
231  }
232  ret = PQntuples (result);
233  if (NULL != rh)
234  rh (rh_cls,
235  result,
236  ret);
237  PQclear (result);
238  return ret;
239 }
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result(struct GNUNET_PQ_Context *db, const char *statement_name, PGresult *result)
Check the result&#39;s error code to see what happened.
Definition: pq_eval.c:59
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
PGresult * GNUNET_PQ_exec_prepared(struct GNUNET_PQ_Context *db, const char *name, const struct GNUNET_PQ_QueryParam *params)
Execute a prepared statement.
Definition: pq.c:39
A soft error occurred, retrying the transaction may succeed.
Definition: gnunet_db_lib.h:45
static int result
Global testing status.
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 ( struct GNUNET_PQ_Context db,
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
dbdatabase to execute the statement with
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 258 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_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().

263 {
264  PGresult *result;
265  enum GNUNET_DB_QueryStatus qs;
266 
267  result = GNUNET_PQ_exec_prepared (db,
268  statement_name,
269  params);
270  if (NULL == result)
272  qs = GNUNET_PQ_eval_result (db,
273  statement_name,
274  result);
275  if (qs < 0)
276  {
277  PQclear (result);
278  return qs;
279  }
280  if (0 == PQntuples (result))
281  {
282  PQclear (result);
284  }
285  if (1 != PQntuples (result))
286  {
287  /* more than one result, but there must be at most one */
288  GNUNET_break (0);
289  PQclear (result);
291  }
292  if (GNUNET_OK !=
293  GNUNET_PQ_extract_result (result,
294  rs,
295  0))
296  {
297  PQclear (result);
299  }
300  PQclear (result);
302 }
enum GNUNET_DB_QueryStatus GNUNET_PQ_eval_result(struct GNUNET_PQ_Context *db, const char *statement_name, PGresult *result)
Check the result&#39;s error code to see what happened.
Definition: pq_eval.c:59
PGresult * GNUNET_PQ_exec_prepared(struct GNUNET_PQ_Context *db, const char *name, const struct GNUNET_PQ_QueryParam *params)
Execute a prepared statement.
Definition: pq.c:39
A soft error occurred, retrying the transaction may succeed.
Definition: gnunet_db_lib.h:45
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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.
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:151
Here is the call graph for this function:
Here is the caller graph for this function: