GNUnet  0.20.0
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 connection 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.

◆ 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.

◆ 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.

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 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 1 of file pq_eval.c.

49 {
50  ExecStatusType est;
51 
52  if (NULL == result)
54  est = PQresultStatus (result);
55  if ((PGRES_COMMAND_OK != est) &&
56  (PGRES_TUPLES_OK != est))
57  {
58  const char *sqlstate;
59  ConnStatusType status;
60 
61  if (CONNECTION_OK != (status = PQstatus (db->conn)))
62  {
64  "pq",
65  "Database connection failed during query `%s': %d (reconnecting)\n",
66  statement_name,
67  status);
70  }
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 (db->conn));
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 (db->conn));
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 (db->conn));
129  }
131 }
uint16_t status
See PRISM_STATUS_*-constants.
static int result
Global testing status.
static struct GNUNET_FS_DirectoryBuilder * db
Definition: gnunet-search.c:97
@ GNUNET_DB_STATUS_HARD_ERROR
A hard error occurred, retrying will not help.
Definition: gnunet_db_lib.h:41
@ GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
The transaction succeeded, but yielded zero results.
Definition: gnunet_db_lib.h:55
@ GNUNET_DB_STATUS_SOFT_ERROR
A soft error occurred, retrying the transaction may succeed.
Definition: gnunet_db_lib.h:47
void GNUNET_PQ_reconnect(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition: pq_connect.c:427
#define GNUNET_log_from(kind, comp,...)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define PQ_DIAG_SQLSTATE_DEADLOCK
Error code returned by Postgres for deadlock.
Definition: pq_eval.c:32
#define PQ_DIAG_SQLSTATE_SERIALIZATION_FAILURE
Error code returned by Postgres on serialization failure.
Definition: pq_eval.c:42
#define PQ_DIAG_SQLSTATE_UNIQUE_VIOLATION
Error code returned by Postgres for uniqueness violation.
Definition: pq_eval.c:37

◆ 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 connection 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 statement 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 1 of file pq_eval.c.

138 {
139  PGresult *result;
140  enum GNUNET_DB_QueryStatus qs;
141 
143  statement_name,
144  params);
145  if (NULL == result)
148  statement_name,
149  result);
151  {
152  const char *tuples;
153 
154  /* What an awful API, this function really does return a string */
155  tuples = PQcmdTuples (result);
156  if (NULL != tuples)
157  qs = strtol (tuples, NULL, 10);
158  }
159  PQclear (result);
160  return qs;
161 }
GNUNET_DB_QueryStatus
Status code returned from functions running database commands.
Definition: gnunet_db_lib.h:37
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:33
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:46

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

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 1 of file pq_eval.c.

170 {
171  PGresult *result;
172  enum GNUNET_DB_QueryStatus qs;
173  unsigned int ret;
174 
176  statement_name,
177  params);
178  if (NULL == result)
181  statement_name,
182  result);
183  if (qs < 0)
184  {
185  PQclear (result);
186  return qs;
187  }
188  ret = PQntuples (result);
189  if (NULL != rh)
190  rh (rh_cls,
191  result,
192  ret);
193  PQclear (result);
194  return ret;
195 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81

Referenced by postgres_plugin_del(), 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().

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 1 of file pq_eval.c.

204 {
205  PGresult *result;
206  enum GNUNET_DB_QueryStatus qs;
207  int ntuples;
208 
210  statement_name,
211  params);
212  if (NULL == result)
215  statement_name,
216  result);
217  if (qs < 0)
218  {
219  PQclear (result);
220  return qs;
221  }
222  ntuples = PQntuples (result);
223  if (0 == ntuples)
224  {
225  PQclear (result);
227  }
228  if (1 != ntuples)
229  {
230  /* more than one result, but there must be at most one */
231  GNUNET_break (0);
232  PQclear (result);
234  }
235  if (GNUNET_OK !=
237  rs,
238  0))
239  {
240  PQclear (result);
242  }
243  PQclear (result);
245 }
@ GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
The transaction succeeded, and yielded one result.
Definition: gnunet_db_lib.h:60
enum GNUNET_GenericReturnValue 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:149
@ GNUNET_OK

Referenced by postgres_plugin_estimate_size().

Here is the caller graph for this function: