GNUnet 0.22.2
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 46 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}
static int status
The program status; 0 for success.
Definition: gnunet-nse.c:39
static int result
Global testing status.
static struct GNUNET_FS_DirectoryBuilder * db
@ 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:562
#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

References db, 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, result, and status.

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

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 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 135 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

References db, 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_clear_editor_hint(), namestore_postgres_store_records(), postgres_plugin_del(), postgres_plugin_put(), postgres_plugin_remove_key(), process_result(), and repl_proc().

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 165 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
Final status code.
Definition: gnunet-arm.c:93

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

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

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 199 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 {
231 "Statement %s returned more than one result, but there must be at most one when using %s\n",
232 statement_name,
233 __FUNCTION__);
234 GNUNET_break (0);
235 PQclear (result);
237 }
238 if (GNUNET_OK !=
240 rs,
241 0))
242 {
243 PQclear (result);
245 }
246 PQclear (result);
248}
@ 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:152
#define GNUNET_log(kind,...)
@ GNUNET_OK

References db, 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_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, GNUNET_PQ_eval_result(), GNUNET_PQ_exec_prepared(), GNUNET_PQ_extract_result(), and result.

Referenced by check_patch_applied(), GNUNET_PQ_get_oid_by_name(), namecache_postgres_lookup_block(), postgres_plugin_del(), and postgres_plugin_estimate_size().

Here is the call graph for this function:
Here is the caller graph for this function: