GNUnet  0.10.x
my.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2016, 2018 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  */
26 #include "platform.h"
27 #include <mysql/mysql.h>
28 #include "gnunet_my_lib.h"
29 
30 
41 int
44  struct GNUNET_MY_QueryParam *params)
45 {
46  const struct GNUNET_MY_QueryParam *p;
47  unsigned int num;
48  MYSQL_STMT *stmt;
49 
50  num = 0;
51  for (unsigned int i = 0; NULL != params[i].conv; i++)
52  num += params[i].num_params;
53  {
54  MYSQL_BIND qbind[num];
55  unsigned int off;
56 
57  memset(qbind,
58  0,
59  sizeof(qbind));
60  off = 0;
61  for (unsigned int i = 0; NULL != (p = &params[i])->conv; i++)
62  {
63  if (GNUNET_OK !=
64  p->conv(p->conv_cls,
65  p,
66  &qbind[off]))
67  {
69  "Conversion for MySQL query failed at offset %u\n",
70  i);
71  return GNUNET_SYSERR;
72  }
73  off += p->num_params;
74  }
76  if (mysql_stmt_bind_param(stmt,
77  qbind))
78  {
80  "my",
81  _("`%s' failed at %s:%d with error: %s\n"),
82  "mysql_stmt_bind_param",
83  __FILE__, __LINE__,
84  mysql_stmt_error(stmt));
86  return GNUNET_SYSERR;
87  }
88 
89  if (mysql_stmt_execute(stmt))
90  {
92  "my",
93  _("`%s' failed at %s:%d with error: %s\n"),
94  "mysql_stmt_execute", __FILE__, __LINE__,
95  mysql_stmt_error(stmt));
97  return GNUNET_SYSERR;
98  }
100  qbind);
101  }
102  return GNUNET_OK;
103 }
104 
105 
113 void
115  MYSQL_BIND *qbind)
116 {
117  for (unsigned int i = 0; NULL != qp[i].conv; i++)
118  if (NULL != qp[i].cleaner)
119  qp[i].cleaner(qp[i].conv_cls,
120  &qbind[i]);
121 }
122 
123 
135 int
137  struct GNUNET_MY_ResultSpec *rs)
138 {
139  unsigned int num_fields;
140  int ret;
141  MYSQL_STMT *stmt;
142 
144  if (NULL == stmt)
145  {
146  GNUNET_break(0);
147  return GNUNET_SYSERR;
148  }
149  if (NULL == rs)
150  {
151  mysql_stmt_free_result(stmt);
152  return GNUNET_NO;
153  }
154 
155  num_fields = 0;
156  for (unsigned int i = 0; NULL != rs[i].pre_conv; i++)
157  num_fields += rs[i].num_fields;
158 
159  if (mysql_stmt_field_count(stmt) != num_fields)
160  {
162  "Number of fields mismatch between SQL result and result specification\n");
163  return GNUNET_SYSERR;
164  }
165 
166  {
167  MYSQL_BIND result[num_fields];
168  unsigned int field_off;
169 
170  memset(result, 0, sizeof(MYSQL_BIND) * num_fields);
171  field_off = 0;
172  for (unsigned int i = 0; NULL != rs[i].pre_conv; i++)
173  {
174  struct GNUNET_MY_ResultSpec *rp = &rs[i];
175 
176  if (GNUNET_OK !=
177  rp->pre_conv(rp->conv_cls,
178  rp,
179  stmt,
180  field_off,
181  &result[field_off]))
182 
183  {
185  "Pre-conversion for MySQL result failed at offset %u\n",
186  i);
187  return GNUNET_SYSERR;
188  }
189  field_off += rp->num_fields;
190  }
191 
192  if (mysql_stmt_bind_result(stmt, result))
193  {
195  "my",
196  _("%s failed at %s:%d with error: %s\n"),
197  "mysql_stmt_bind_result",
198  __FILE__, __LINE__,
199  mysql_stmt_error(stmt));
200  return GNUNET_SYSERR;
201  }
202 #if TEST_OPTIMIZATION
203  (void)mysql_stmt_store_result(stmt);
204 #endif
205  ret = mysql_stmt_fetch(stmt);
206  if (MYSQL_NO_DATA == ret)
207  {
208  mysql_stmt_free_result(stmt);
209  return GNUNET_NO;
210  }
211  if (1 == ret)
212  {
214  "my",
215  _("%s failed at %s:%d with error: %s\n"),
216  "mysql_stmt_fetch",
217  __FILE__, __LINE__,
218  mysql_stmt_error(stmt));
220  mysql_stmt_free_result(stmt);
221  return GNUNET_SYSERR;
222  }
223  field_off = 0;
224  for (unsigned int i = 0; NULL != rs[i].post_conv; i++)
225  {
226  struct GNUNET_MY_ResultSpec *rp = &rs[i];
227 
228  if (NULL != rp->post_conv)
229  if (GNUNET_OK !=
230  rp->post_conv(rp->conv_cls,
231  rp,
232  stmt,
233  field_off,
234  &result[field_off]))
235  {
237  "Post-conversion for MySQL result failed at offset %u\n",
238  i);
239  mysql_stmt_free_result(stmt);
241  return GNUNET_SYSERR;
242  }
243  field_off += rp->num_fields;
244  }
245  }
246  return GNUNET_OK;
247 }
248 
249 
256 void
258 {
259  for (unsigned int i = 0; NULL != rs[i].post_conv; i++)
260  if (NULL != rs[i].cleaner)
261  rs[i].cleaner(rs[i].conv_cls,
262  &rs[i]);
263 }
264 
265 
266 /* end of my.c */
static GstElement * conv
GNUNET_MY_ResultCleanup cleaner
Function to call for cleaning up the result.
Information we pass to GNUNET_MY_exec_prepared() to initialize the arguments of the prepared statemen...
Definition: gnunet_my_lib.h:84
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
unsigned int num_params
Number of arguments the conv converter expects to initialize.
Handle for a prepared statement.
Definition: mysql.c:112
int GNUNET_MY_exec_prepared(struct GNUNET_MYSQL_Context *mc, struct GNUNET_MYSQL_StatementHandle *sh, struct GNUNET_MY_QueryParam *params)
Run a prepared SELECT statement.
Definition: my.c:42
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void * conv_cls
Closure for conv.
Information we pass to GNUNET_MY_extract_result() to initialize the arguments of the prepared stateme...
GNUNET_MY_QueryConverter conv
Function to call for the type conversion.
Definition: gnunet_my_lib.h:88
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static struct SolverHandle * sh
void GNUNET_MY_cleanup_result(struct GNUNET_MY_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_MY_extract_result().
Definition: my.c:257
MYSQL_STMT * GNUNET_MYSQL_statement_get_stmt(struct GNUNET_MYSQL_StatementHandle *sh)
Get internal handle for a prepared statement.
Definition: mysql.c:477
void GNUNET_MYSQL_statements_invalidate(struct GNUNET_MYSQL_Context *mc)
Close database connection and all prepared statements (we got a DB error).
Definition: mysql.c:340
static int result
Global testing status.
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
int GNUNET_MY_extract_result(struct GNUNET_MYSQL_StatementHandle *sh, struct GNUNET_MY_ResultSpec *rs)
Extract results from a query result according to the given specification.
Definition: my.c:136
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
void GNUNET_MY_cleanup_query(struct GNUNET_MY_QueryParam *qp, MYSQL_BIND *qbind)
Free all memory that was allocated in qp during GNUNET_MY_exec_prepared().
Definition: my.c:114
Mysql context.
Definition: mysql.c:76
GNUNET_MY_ResultConverter post_conv
Function to call for converting the result.
GNUNET_MY_ResultConverter pre_conv
Function to call to initialize the MYSQL_BIND array.
#define GNUNET_log(kind,...)
static char * rp
Relying party.
GNUNET_MY_QueryCleanup cleaner
Function to call for cleaning up the query.
Definition: gnunet_my_lib.h:93
void * conv_cls
Closure for conv.
Definition: gnunet_my_lib.h:98
unsigned int num_fields
How many fields does this result specification occupy in the result returned by MySQL.
#define GNUNET_log_from(kind, comp,...)