GNUnet  0.10.x
pq.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_pq_lib.h"
30 
31 
40 PGresult *
41 GNUNET_PQ_exec_prepared(PGconn *db_conn,
42  const char *name,
43  const struct GNUNET_PQ_QueryParam *params)
44 {
45  unsigned int len;
46  unsigned int i;
47 
49  "Running prepared statement `%s' on %p\n",
50  name,
51  db_conn);
52  /* count the number of parameters */
53  len = 0;
54  for (i = 0; 0 != params[i].num_params; i++)
55  len += params[i].num_params;
56 
57  /* new scope to allow stack allocation without alloca */
58  {
59  /* Scratch buffer for temporary storage */
60  void *scratch[len];
61  /* Parameter array we are building for the query */
62  void *param_values[len];
63  int param_lengths[len];
64  int param_formats[len];
65  unsigned int off;
66  /* How many entries in the scratch buffer are in use? */
67  unsigned int soff;
68  PGresult *res;
69  int ret;
70 
71  off = 0;
72  soff = 0;
73  for (i = 0; 0 != params[i].num_params; i++)
74  {
75  const struct GNUNET_PQ_QueryParam *x = &params[i];
76 
77  ret = x->conv(x->conv_cls,
78  x->data,
79  x->size,
80  &param_values[off],
81  &param_lengths[off],
82  &param_formats[off],
83  x->num_params,
84  &scratch[soff],
85  len - soff);
86  if (ret < 0)
87  {
88  for (off = 0; off < soff; off++)
89  GNUNET_free(scratch[off]);
90  return NULL;
91  }
92  soff += ret;
93  off += x->num_params;
94  }
95  GNUNET_assert(off == len);
97  "pq",
98  "Executing prepared SQL statement `%s'\n",
99  name);
100  res = PQexecPrepared(db_conn,
101  name,
102  len,
103  (const char **)param_values,
104  param_lengths,
105  param_formats,
106  1);
107  for (off = 0; off < soff; off++)
108  GNUNET_free(scratch[off]);
109  return res;
110  }
111 }
112 
113 
120 void
122 {
123  unsigned int i;
124 
125  for (i = 0; NULL != rs[i].conv; i++)
126  if (NULL != rs[i].cleaner)
127  rs[i].cleaner(rs[i].cls,
128  rs[i].dst);
129 }
130 
131 
143 int
145  struct GNUNET_PQ_ResultSpec *rs,
146  int row)
147 {
148  unsigned int i;
149  int ret;
150 
151  for (i = 0; NULL != rs[i].conv; i++)
152  {
153  struct GNUNET_PQ_ResultSpec *spec;
154 
155  spec = &rs[i];
156  ret = spec->conv(spec->cls,
157  result,
158  row,
159  spec->fname,
160  &spec->dst_size,
161  spec->dst);
162  if (GNUNET_OK != ret)
163  {
165  return GNUNET_SYSERR;
166  }
167  if (NULL != spec->result_size)
168  *spec->result_size = spec->dst_size;
169  }
170  return GNUNET_OK;
171 }
172 
173 
174 /* end of pq/pq.c */
GNUNET_PQ_QueryConverter conv
Function for how to handle this type of entry.
Definition: gnunet_pq_lib.h:67
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * fname
Field name of the desired result.
Description of a DB result cell.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
const void * data
Data or NULL.
Definition: gnunet_pq_lib.h:77
static int ret
Final status code.
Definition: gnunet-arm.c:89
void GNUNET_PQ_cleanup_result(struct GNUNET_PQ_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_PQ_extract_result().
Definition: pq.c:121
void * cls
Closure for conv and cleaner.
void * conv_cls
Closure for conv.
Definition: gnunet_pq_lib.h:72
static int result
Global testing status.
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...
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
static int res
GNUNET_PQ_ResultCleanup cleaner
Function to clean up result data, NULL if cleanup is not necessary.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
helper functions for Postgres DB interactions
const char * name
unsigned int num_params
Number of parameters eaten by this operation.
Definition: gnunet_pq_lib.h:87
Description of a DB query parameter.
Definition: gnunet_pq_lib.h:63
#define GNUNET_log(kind,...)
void * dst
Destination for the data.
size_t size
Size of data.
Definition: gnunet_pq_lib.h:82
#define GNUNET_log_from(kind, comp,...)
size_t * result_size
Where to store actual size of the result.
GNUNET_PQ_ResultConverter conv
What is the format of the result?
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
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...