GNUnet 0.21.1
pq.c File Reference

helper functions for libpq (PostGres) interactions More...

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

Go to the source code of this file.

Functions

PGresult * GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db, const char *name, const struct GNUNET_PQ_QueryParam *params)
 Execute a prepared statement. More...
 
void GNUNET_PQ_cleanup_query_params_closures (const struct GNUNET_PQ_QueryParam *params)
 Must be called to cleanup memory from closures after the query parameters have been used as much as needed. More...
 
void GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs)
 Free all memory that was allocated in rs during GNUNET_PQ_extract_result(). More...
 
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. More...
 

Detailed Description

helper functions for libpq (PostGres) interactions

Author
Sree Harsha Totakura sreeh.nosp@m.arsh.nosp@m.a@tot.nosp@m.akur.nosp@m.a.in
Florian Dold
Christian Grothoff

Definition in file pq.c.

Function Documentation

◆ GNUNET_PQ_exec_prepared()

PGresult * GNUNET_PQ_exec_prepared ( struct GNUNET_PQ_Context db,
const char *  name,
const struct GNUNET_PQ_QueryParam params 
)

Execute a prepared statement.

Parameters
dbdatabase context
namename of the prepared statement
paramsparameters to the statement
Returns
postgres result
Deprecated:
(should become an internal API)

Definition at line 33 of file pq.c.

36{
37 unsigned int len;
38
40 "Running prepared statement `%s' on %p\n",
41 name,
42 db);
43 /* count the number of parameters */
44 len = 0;
45 for (unsigned int i = 0; 0 != params[i].num_params; i++)
46 len += params[i].num_params;
47
48 /* new scope to allow stack allocation without alloca */
49 {
50 /* Scratch buffer for temporary storage */
51 void *scratch[GNUNET_NZL (len)];
52 /* Parameter array we are building for the query */
53 void *param_values[GNUNET_NZL (len)];
54 int param_lengths[GNUNET_NZL (len)];
55 int param_formats[GNUNET_NZL (len)];
56 unsigned int off;
57 /* How many entries in the scratch buffer are in use? */
58 unsigned int soff;
59 PGresult *res;
60 int ret;
61 ConnStatusType status;
62
63 off = 0;
64 soff = 0;
65 for (unsigned int i = 0; 0 != params[i].num_params; i++)
66 {
67 const struct GNUNET_PQ_QueryParam *x = &params[i];
68
69 ret = x->conv (x->conv_cls,
70 x->data,
71 x->size,
72 &param_values[off],
73 &param_lengths[off],
74 &param_formats[off],
75 x->num_params,
76 &scratch[soff],
77 len - soff);
78 if (ret < 0)
79 {
80 for (off = 0; off < soff; off++)
81 GNUNET_free (scratch[off]);
82 return NULL;
83 }
84 soff += ret;
85 off += x->num_params;
86 }
87 GNUNET_assert (off == len);
89 "pq",
90 "Executing prepared SQL statement `%s'\n",
91 name);
92 res = PQexecPrepared (db->conn,
93 name,
94 len,
95 (const char **) param_values,
96 param_lengths,
97 param_formats,
98 1);
100 "pq",
101 "Execution of prepared SQL statement `%s' finished (%s)\n",
102 name,
103 PQresStatus (PQresultStatus (res)));
104 if ( (PGRES_COMMAND_OK != PQresultStatus (res)) &&
105 (CONNECTION_OK != (status = PQstatus (db->conn))) )
106 {
108 "pq",
109 "Database disconnected on SQL statement `%s' (reconnecting)\n",
110 name);
112 res = NULL;
113 }
114
115 for (off = 0; off < soff; off++)
116 GNUNET_free (scratch[off]);
117 return res;
118 }
119}
static int ret
Final status code.
Definition: gnunet-arm.c:94
static char * name
Name (label) of the records to list.
static char * res
Currently read line or NULL on EOF.
static int status
The program status; 0 for success.
Definition: gnunet-nse.c:39
static struct GNUNET_FS_DirectoryBuilder * db
Definition: gnunet-search.c:97
void GNUNET_PQ_reconnect(struct GNUNET_PQ_Context *db)
Reinitialize the database db.
Definition: pq_connect.c:427
#define GNUNET_log(kind,...)
#define GNUNET_log_from(kind, comp,...)
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:83
void * conv_cls
Closure for conv.
Definition: gnunet_pq_lib.h:95
const void * data
Data or NULL.
GNUNET_PQ_QueryConverter conv
Function for how to handle this type of entry.
Definition: gnunet_pq_lib.h:87
unsigned int num_params
Number of parameters eaten by this operation.
size_t size
Size of data.

References GNUNET_PQ_QueryParam::conv, GNUNET_PQ_QueryParam::conv_cls, GNUNET_PQ_QueryParam::data, db, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_log_from, GNUNET_NZL, GNUNET_PQ_reconnect(), name, GNUNET_PQ_QueryParam::num_params, res, ret, GNUNET_PQ_QueryParam::size, 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_cleanup_query_params_closures()

void GNUNET_PQ_cleanup_query_params_closures ( const struct GNUNET_PQ_QueryParam params)

Must be called to cleanup memory from closures after the query parameters have been used as much as needed.

Parameters
paramsArray of GNUNET_PQ_QueryParam which must terminate with a GNUNET_PQ_query_param_end

Definition at line 123 of file pq.c.

125{
126 for (unsigned int i = 0; 0 != params[i].num_params; i++)
127 {
128 const struct GNUNET_PQ_QueryParam *x = &params[i];
129
130 if ((NULL != x->conv_cls) &&
131 (NULL != x->conv_cls_cleanup))
133 }
134
135}
GNUNET_PQ_QueryConverter_Cleanup conv_cls_cleanup
Function to cleanup the closure conv_cls, may be NULL.

References GNUNET_PQ_QueryParam::conv_cls, GNUNET_PQ_QueryParam::conv_cls_cleanup, and GNUNET_PQ_QueryParam::num_params.

◆ GNUNET_PQ_cleanup_result()

void GNUNET_PQ_cleanup_result ( struct GNUNET_PQ_ResultSpec rs)

Free all memory that was allocated in rs during GNUNET_PQ_extract_result().

Parameters
rsreult specification to clean up

Definition at line 139 of file pq.c.

140{
141 for (unsigned int i = 0; NULL != rs[i].conv; i++)
142 if (NULL != rs[i].cleaner)
143 rs[i].cleaner (rs[i].cls,
144 rs[i].dst);
145}
GNUNET_PQ_ResultConverter conv
What is the format of the result?
GNUNET_PQ_ResultCleanup cleaner
Function to clean up result data, NULL if cleanup is not necessary.

References GNUNET_PQ_ResultSpec::cleaner, and GNUNET_PQ_ResultSpec::conv.

Referenced by extract_result_cb(), GNUNET_PQ_run_sql(), handle_results(), namecache_postgres_lookup_block(), parse_result_call_iterator(), postgres_plugin_del(), process_keys(), and process_result().

Here is the caller graph for this function:

◆ GNUNET_PQ_extract_result()

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.

Parameters
resultresult to process
[in,out]rsresult specification to extract for
rowrow from the result to extract
Returns
GNUNET_YES if all results could be extracted GNUNET_SYSERR if a result was invalid (non-existing field)

Definition at line 149 of file pq.c.

152{
153 unsigned int i;
154
155 if (NULL == result)
156 return GNUNET_SYSERR;
157 for (i = 0; NULL != rs[i].conv; i++)
158 {
159 struct GNUNET_PQ_ResultSpec *spec;
161
162 spec = &rs[i];
163 ret = spec->conv (spec->cls,
164 result,
165 row,
166 spec->fname,
167 &spec->dst_size,
168 spec->dst);
169 switch (ret)
170 {
171 case GNUNET_OK:
172 /* canonical case, continue below */
173 if (NULL != spec->is_null)
174 *spec->is_null = false;
175 break;
176 case GNUNET_NO:
177 if (spec->is_nullable)
178 {
179 if (NULL != spec->is_null)
180 *spec->is_null = true;
181 continue;
182 }
184 "NULL field encountered for `%s' where non-NULL was required\n",
185 spec->fname);
186 goto cleanup;
187 case GNUNET_SYSERR:
189 "Failed to extract field `%s'\n",
190 spec->fname);
191 GNUNET_break (0);
192 goto cleanup;
193 }
194 if (NULL != spec->result_size)
195 *spec->result_size = spec->dst_size;
196 }
197 return GNUNET_OK;
198cleanup:
199 for (unsigned int j = 0; j < i; j++)
200 if (NULL != rs[j].cleaner)
201 rs[j].cleaner (rs[j].cls,
202 rs[j].dst);
203 return GNUNET_SYSERR;
204}
static void cleanup(void *cls)
Disconnect and shutdown.
Definition: gnunet-did.c:131
static int result
Global testing status.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#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
Description of a DB result cell.
const char * fname
Field name of the desired result.
bool * is_null
Points to a location where we should store "true" if the result found is NULL, and otherwise "false".
void * dst
Destination for the data.
bool is_nullable
True if NULL is allowed for a value in the database.
void * cls
Closure for conv and cleaner.
size_t * result_size
Where to store actual size of the result.
size_t dst_size
Allowed size for the data, 0 for variable-size (in this case, the type of dst is a void ** and we nee...

References GNUNET_PQ_ResultSpec::cleaner, cleanup(), GNUNET_PQ_ResultSpec::cls, GNUNET_PQ_ResultSpec::conv, GNUNET_PQ_ResultSpec::dst, GNUNET_PQ_ResultSpec::dst_size, GNUNET_PQ_ResultSpec::fname, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_PQ_ResultSpec::is_null, GNUNET_PQ_ResultSpec::is_nullable, result, GNUNET_PQ_ResultSpec::result_size, and ret.

Referenced by extract_result_cb(), GNUNET_PQ_eval_prepared_singleton_select(), handle_results(), parse_result_call_iterator(), process_keys(), and process_result().

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