aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-03-21 14:09:53 +0000
committerChristian Grothoff <christian@grothoff.org>2012-03-21 14:09:53 +0000
commitfc17092ebec34ed577000aa6502ee07a1af7ba59 (patch)
tree4122cd3b2d910faa08e918797daeb98b214d3bbe /src
parentc164ecb84e1b98ebcdade7b9250bb3e051156842 (diff)
downloadgnunet-fc17092ebec34ed577000aa6502ee07a1af7ba59.tar.gz
gnunet-fc17092ebec34ed577000aa6502ee07a1af7ba59.zip
-abstracting out mysql helper library
Diffstat (limited to 'src')
-rw-r--r--src/datacache/Makefile.am1
-rw-r--r--src/datacache/plugin_datacache_mysql.c573
-rw-r--r--src/include/gnunet_mysql_lib.h1
-rw-r--r--src/mysql/mysql.c1
4 files changed, 25 insertions, 551 deletions
diff --git a/src/datacache/Makefile.am b/src/datacache/Makefile.am
index 6b3f91638..88545dcdc 100644
--- a/src/datacache/Makefile.am
+++ b/src/datacache/Makefile.am
@@ -59,6 +59,7 @@ libgnunet_plugin_datacache_mysql_la_SOURCES = \
59 plugin_datacache_mysql.c 59 plugin_datacache_mysql.c
60libgnunet_plugin_datacache_mysql_la_LIBADD = \ 60libgnunet_plugin_datacache_mysql_la_LIBADD = \
61 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 61 $(top_builddir)/src/statistics/libgnunetstatistics.la \
62 $(top_builddir)/src/mysql/libgnunetmysql.la \
62 $(top_builddir)/src/util/libgnunetutil.la \ 63 $(top_builddir)/src/util/libgnunetutil.la \
63 $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient 64 $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient
64libgnunet_plugin_datacache_mysql_la_CPPFLAGS = \ 65libgnunet_plugin_datacache_mysql_la_CPPFLAGS = \
diff --git a/src/datacache/plugin_datacache_mysql.c b/src/datacache/plugin_datacache_mysql.c
index 9185c5ca1..2ececa797 100644
--- a/src/datacache/plugin_datacache_mysql.c
+++ b/src/datacache/plugin_datacache_mysql.c
@@ -80,6 +80,7 @@
80#include "platform.h" 80#include "platform.h"
81#include "gnunet_util_lib.h" 81#include "gnunet_util_lib.h"
82#include "gnunet_datacache_plugin.h" 82#include "gnunet_datacache_plugin.h"
83#include "gnunet_mysql_lib.h"
83#include <mysql/mysql.h> 84#include <mysql/mysql.h>
84 85
85#define DEBUG_DATACACHE_MYSQL GNUNET_EXTRA_LOGGING 86#define DEBUG_DATACACHE_MYSQL GNUNET_EXTRA_LOGGING
@@ -90,12 +91,6 @@
90#define OVERHEAD ((4*2+4*2+8*2+8*2+sizeof(GNUNET_HashCode)*5+8)) 91#define OVERHEAD ((4*2+4*2+8*2+8*2+sizeof(GNUNET_HashCode)*5+8))
91 92
92/** 93/**
93 * Maximum number of supported parameters for a prepared
94 * statement. Increase if needed.
95 */
96#define MAX_PARAM 16
97
98/**
99 * Die with an error message that indicates 94 * Die with an error message that indicates
100 * a failure of the command 'cmd' with the message given 95 * a failure of the command 'cmd' with the message given
101 * by strerror(errno). 96 * by strerror(errno).
@@ -109,20 +104,6 @@
109 */ 104 */
110#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0); 105#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0);
111 106
112struct GNUNET_MysqlStatementHandle
113{
114 struct GNUNET_MysqlStatementHandle *next;
115
116 struct GNUNET_MysqlStatementHandle *prev;
117
118 char *query;
119
120 MYSQL_STMT *statement;
121
122 int valid;
123
124};
125
126 107
127/** 108/**
128 * Context for all functions in this plugin. 109 * Context for all functions in this plugin.
@@ -137,536 +118,32 @@ struct Plugin
137 /** 118 /**
138 * Handle to the mysql database. 119 * Handle to the mysql database.
139 */ 120 */
140 MYSQL *dbf; 121 struct GNUNET_MYSQL_Context *mc;
141
142 struct GNUNET_MysqlStatementHandle *shead;
143
144 struct GNUNET_MysqlStatementHandle *stail;
145
146 /**
147 * Filename of "my.cnf" (msyql configuration).
148 */
149 char *cnffile;
150 122
151#define SELECT_VALUE_STMT "SELECT value,expire FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?" 123#define SELECT_VALUE_STMT "SELECT value,expire FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?"
152 struct GNUNET_MysqlStatementHandle *select_value; 124 struct GNUNET_MYSQL_StatementHandle *select_value;
153 125
154#define COUNT_VALUE_STMT "SELECT count(*) FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ?" 126#define COUNT_VALUE_STMT "SELECT count(*) FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ?"
155 struct GNUNET_MysqlStatementHandle *count_value; 127 struct GNUNET_MYSQL_StatementHandle *count_value;
156 128
157#define SELECT_OLD_VALUE_STMT "SELECT hash, vhash, type, value FROM gn080dstore FORCE INDEX (expireidx) ORDER BY puttime ASC LIMIT 1" 129#define SELECT_OLD_VALUE_STMT "SELECT hash, vhash, type, value FROM gn080dstore FORCE INDEX (expireidx) ORDER BY puttime ASC LIMIT 1"
158 struct GNUNET_MysqlStatementHandle *select_old_value; 130 struct GNUNET_MYSQL_StatementHandle *select_old_value;
159 131
160#define DELETE_VALUE_STMT "DELETE FROM gn080dstore WHERE hash = ? AND vhash = ? AND type = ? AND value = ?" 132#define DELETE_VALUE_STMT "DELETE FROM gn080dstore WHERE hash = ? AND vhash = ? AND type = ? AND value = ?"
161 struct GNUNET_MysqlStatementHandle *delete_value; 133 struct GNUNET_MYSQL_StatementHandle *delete_value;
162 134
163#define INSERT_VALUE_STMT "INSERT INTO gn080dstore (type, puttime, expire, hash, vhash, value) "\ 135#define INSERT_VALUE_STMT "INSERT INTO gn080dstore (type, puttime, expire, hash, vhash, value) "\
164 "VALUES (?, ?, ?, ?, ?, ?)" 136 "VALUES (?, ?, ?, ?, ?, ?)"
165 struct GNUNET_MysqlStatementHandle *insert_value; 137 struct GNUNET_MYSQL_StatementHandle *insert_value;
166 138
167#define UPDATE_VALUE_STMT "UPDATE gn080dstore FORCE INDEX (allidx) SET puttime=?, expire=? "\ 139#define UPDATE_VALUE_STMT "UPDATE gn080dstore FORCE INDEX (allidx) SET puttime=?, expire=? "\
168 "WHERE hash=? AND vhash=? AND type=?" 140 "WHERE hash=? AND vhash=? AND type=?"
169 struct GNUNET_MysqlStatementHandle *update_value; 141 struct GNUNET_MYSQL_StatementHandle *update_value;
170 142
171}; 143};
172 144
173 145
174/** 146/**
175 * Obtain the location of ".my.cnf".
176 *
177 * @param cfg our configuration
178 * @return NULL on error
179 */
180static char *
181get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg)
182{
183 char *cnffile;
184 char *home_dir;
185 struct stat st;
186
187#ifndef WINDOWS
188 struct passwd *pw;
189#endif
190 int configured;
191
192#ifndef WINDOWS
193 pw = getpwuid (getuid ());
194 if (!pw)
195 {
196 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getpwuid");
197 return NULL;
198 }
199 if (GNUNET_YES ==
200 GNUNET_CONFIGURATION_have_value (cfg, "datacache-mysql", "CONFIG"))
201 {
202 GNUNET_assert (GNUNET_OK ==
203 GNUNET_CONFIGURATION_get_value_filename (cfg,
204 "datacache-mysql",
205 "CONFIG",
206 &cnffile));
207 configured = GNUNET_YES;
208 }
209 else
210 {
211 home_dir = GNUNET_strdup (pw->pw_dir);
212 GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir);
213 GNUNET_free (home_dir);
214 configured = GNUNET_NO;
215 }
216#else
217 home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1);
218 plibc_conv_to_win_path ("~/", home_dir);
219 GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir);
220 GNUNET_free (home_dir);
221 configured = GNUNET_NO;
222#endif
223 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
224 _("Trying to use file `%s' for MySQL configuration.\n"), cnffile);
225 if ((0 != STAT (cnffile, &st)) || (0 != ACCESS (cnffile, R_OK)) ||
226 (!S_ISREG (st.st_mode)))
227 {
228 if (configured == GNUNET_YES)
229 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
230 _("Could not access file `%s': %s\n"), cnffile,
231 STRERROR (errno));
232 GNUNET_free (cnffile);
233 return NULL;
234 }
235 return cnffile;
236}
237
238
239/**
240 * Free a prepared statement.
241 *
242 * @param plugin plugin context
243 * @param s prepared statement
244 */
245static void
246prepared_statement_destroy (struct Plugin *plugin,
247 struct GNUNET_MysqlStatementHandle *s)
248{
249 GNUNET_CONTAINER_DLL_remove (plugin->shead, plugin->stail, s);
250 if (s->valid)
251 mysql_stmt_close (s->statement);
252 GNUNET_free (s->query);
253 GNUNET_free (s);
254}
255
256
257/**
258 * Close database connection and all prepared statements (we got a DB
259 * disconnect error).
260 */
261static int
262iclose (struct Plugin *plugin)
263{
264 while (NULL != plugin->shead)
265 prepared_statement_destroy (plugin, plugin->shead);
266 if (plugin->dbf != NULL)
267 {
268 mysql_close (plugin->dbf);
269 plugin->dbf = NULL;
270 }
271 return GNUNET_OK;
272}
273
274
275/**
276 * Open the connection with the database (and initialize
277 * our default options).
278 *
279 * @return GNUNET_OK on success
280 */
281static int
282iopen (struct Plugin *ret)
283{
284 char *mysql_dbname;
285 char *mysql_server;
286 char *mysql_user;
287 char *mysql_password;
288 unsigned long long mysql_port;
289 my_bool reconnect;
290 unsigned int timeout;
291
292 ret->dbf = mysql_init (NULL);
293 if (ret->dbf == NULL)
294 return GNUNET_SYSERR;
295 if (ret->cnffile != NULL)
296 mysql_options (ret->dbf, MYSQL_READ_DEFAULT_FILE, ret->cnffile);
297 mysql_options (ret->dbf, MYSQL_READ_DEFAULT_GROUP, "client");
298 reconnect = 0;
299 mysql_options (ret->dbf, MYSQL_OPT_RECONNECT, &reconnect);
300 mysql_options (ret->dbf, MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout);
301 mysql_options (ret->dbf, MYSQL_SET_CHARSET_NAME, "UTF8");
302 timeout = 60; /* in seconds */
303 mysql_options (ret->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
304 mysql_options (ret->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
305 mysql_dbname = NULL;
306 if (GNUNET_YES ==
307 GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql",
308 "DATABASE"))
309 GNUNET_assert (GNUNET_OK ==
310 GNUNET_CONFIGURATION_get_value_string (ret->env->cfg,
311 "datacache-mysql",
312 "DATABASE",
313 &mysql_dbname));
314 else
315 mysql_dbname = GNUNET_strdup ("gnunet");
316 mysql_user = NULL;
317 if (GNUNET_YES ==
318 GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql",
319 "USER"))
320 {
321 GNUNET_assert (GNUNET_OK ==
322 GNUNET_CONFIGURATION_get_value_string (ret->env->cfg,
323 "datacache-mysql",
324 "USER", &mysql_user));
325 }
326 mysql_password = NULL;
327 if (GNUNET_YES ==
328 GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql",
329 "PASSWORD"))
330 {
331 GNUNET_assert (GNUNET_OK ==
332 GNUNET_CONFIGURATION_get_value_string (ret->env->cfg,
333 "datacache-mysql",
334 "PASSWORD",
335 &mysql_password));
336 }
337 mysql_server = NULL;
338 if (GNUNET_YES ==
339 GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql",
340 "HOST"))
341 {
342 GNUNET_assert (GNUNET_OK ==
343 GNUNET_CONFIGURATION_get_value_string (ret->env->cfg,
344 "datacache-mysql",
345 "HOST",
346 &mysql_server));
347 }
348 mysql_port = 0;
349 if (GNUNET_YES ==
350 GNUNET_CONFIGURATION_have_value (ret->env->cfg, "datacache-mysql",
351 "PORT"))
352 {
353 GNUNET_assert (GNUNET_OK ==
354 GNUNET_CONFIGURATION_get_value_number (ret->env->cfg,
355 "datacache-mysql",
356 "PORT", &mysql_port));
357 }
358
359 GNUNET_assert (mysql_dbname != NULL);
360 mysql_real_connect (ret->dbf, mysql_server, mysql_user, mysql_password,
361 mysql_dbname, (unsigned int) mysql_port, NULL,
362 CLIENT_IGNORE_SIGPIPE);
363 GNUNET_free_non_null (mysql_server);
364 GNUNET_free_non_null (mysql_user);
365 GNUNET_free_non_null (mysql_password);
366 GNUNET_free (mysql_dbname);
367 if (mysql_error (ret->dbf)[0])
368 {
369 LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_real_connect", ret);
370 return GNUNET_SYSERR;
371 }
372 return GNUNET_OK;
373}
374
375
376/**
377 * Run the given MySQL statement.
378 *
379 * @return GNUNET_OK on success, GNUNET_SYSERR on error
380 */
381static int
382run_statement (struct Plugin *plugin, const char *statement)
383{
384 if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin)))
385 return GNUNET_SYSERR;
386 mysql_query (plugin->dbf, statement);
387 if (mysql_error (plugin->dbf)[0])
388 {
389 LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", plugin);
390 iclose (plugin);
391 return GNUNET_SYSERR;
392 }
393 return GNUNET_OK;
394}
395
396/**
397 * Create a prepared statement.
398 *
399 * @return NULL on error
400 */
401static struct GNUNET_MysqlStatementHandle *
402prepared_statement_create (struct Plugin *plugin, const char *statement)
403{
404 struct GNUNET_MysqlStatementHandle *ret;
405
406 ret = GNUNET_malloc (sizeof (struct GNUNET_MysqlStatementHandle));
407 ret->query = GNUNET_strdup (statement);
408 GNUNET_CONTAINER_DLL_insert (plugin->shead, plugin->stail, ret);
409 return ret;
410}
411
412
413/**
414 * Prepare a statement for running.
415 *
416 * @return GNUNET_OK on success
417 */
418static int
419prepare_statement (struct Plugin *plugin,
420 struct GNUNET_MysqlStatementHandle *ret)
421{
422 if (GNUNET_YES == ret->valid)
423 return GNUNET_OK;
424 if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin)))
425 return GNUNET_SYSERR;
426 ret->statement = mysql_stmt_init (plugin->dbf);
427 if (ret->statement == NULL)
428 {
429 iclose (plugin);
430 return GNUNET_SYSERR;
431 }
432 if (mysql_stmt_prepare (ret->statement, ret->query, strlen (ret->query)))
433 {
434 LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", plugin);
435 mysql_stmt_close (ret->statement);
436 ret->statement = NULL;
437 iclose (plugin);
438 return GNUNET_SYSERR;
439 }
440 ret->valid = GNUNET_YES;
441 return GNUNET_OK;
442
443}
444
445
446/**
447 * Bind the parameters for the given MySQL statement
448 * and run it.
449 *
450 * @param plugin plugin context
451 * @param s statement to bind and run
452 * @param ap arguments for the binding
453 * @return GNUNET_SYSERR on error, GNUNET_OK on success
454 */
455static int
456init_params (struct Plugin *plugin, struct GNUNET_MysqlStatementHandle *s,
457 va_list ap)
458{
459 MYSQL_BIND qbind[MAX_PARAM];
460 unsigned int pc;
461 unsigned int off;
462 enum enum_field_types ft;
463
464 pc = mysql_stmt_param_count (s->statement);
465 if (pc > MAX_PARAM)
466 {
467 /* increase internal constant! */
468 GNUNET_break (0);
469 return GNUNET_SYSERR;
470 }
471 memset (qbind, 0, sizeof (qbind));
472 off = 0;
473 ft = 0;
474 while ((pc > 0) && (-1 != (int) (ft = va_arg (ap, enum enum_field_types))))
475 {
476 qbind[off].buffer_type = ft;
477 switch (ft)
478 {
479 case MYSQL_TYPE_FLOAT:
480 qbind[off].buffer = va_arg (ap, float *);
481
482 break;
483 case MYSQL_TYPE_LONGLONG:
484 qbind[off].buffer = va_arg (ap, unsigned long long *);
485 qbind[off].is_unsigned = va_arg (ap, int);
486
487 break;
488 case MYSQL_TYPE_LONG:
489 qbind[off].buffer = va_arg (ap, unsigned int *);
490 qbind[off].is_unsigned = va_arg (ap, int);
491
492 break;
493 case MYSQL_TYPE_VAR_STRING:
494 case MYSQL_TYPE_STRING:
495 case MYSQL_TYPE_BLOB:
496 qbind[off].buffer = va_arg (ap, void *);
497 qbind[off].buffer_length = va_arg (ap, unsigned long);
498 qbind[off].length = va_arg (ap, unsigned long *);
499
500 break;
501 default:
502 /* unsupported type */
503 GNUNET_break (0);
504 return GNUNET_SYSERR;
505 }
506 pc--;
507 off++;
508 }
509 if (!((pc == 0) && (-1 != (int) ft) && (va_arg (ap, int) == -1)))
510 {
511 GNUNET_break (0);
512 return GNUNET_SYSERR;
513 }
514 if (mysql_stmt_bind_param (s->statement, qbind))
515 {
516 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
517 _("`%s' failed at %s:%d with error: %s\n"),
518 "mysql_stmt_bind_param", __FILE__, __LINE__,
519 mysql_stmt_error (s->statement));
520 iclose (plugin);
521 return GNUNET_SYSERR;
522 }
523 if (mysql_stmt_execute (s->statement))
524 {
525 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
526 _("`%s' failed at %s:%d with error: %s\n"),
527 "mysql_stmt_execute", __FILE__, __LINE__,
528 mysql_stmt_error (s->statement));
529 iclose (plugin);
530 return GNUNET_SYSERR;
531 }
532 return GNUNET_OK;
533}
534
535/**
536 * Type of a callback that will be called for each
537 * data set returned from MySQL.
538 *
539 * @param cls user-defined argument
540 * @param num_values number of elements in values
541 * @param values values returned by MySQL
542 * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort
543 */
544typedef int (*GNUNET_MysqlDataProcessor) (void *cls, unsigned int num_values,
545 MYSQL_BIND * values);
546
547
548/**
549 * Run a prepared SELECT statement.
550 *
551 * @param plugin plugin context
552 * @param s handle to SELECT statment
553 * @param result_size number of elements in results array
554 * @param results pointer to already initialized MYSQL_BIND
555 * array (of sufficient size) for passing results
556 * @param processor function to call on each result
557 * @param processor_cls extra argument to processor
558 * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
559 * values (size + buffer-reference for pointers); terminated
560 * with "-1"
561 * @return GNUNET_SYSERR on error, otherwise
562 * the number of successfully affected (or queried) rows
563 */
564static int
565prepared_statement_run_select (struct Plugin *plugin,
566 struct GNUNET_MysqlStatementHandle *s,
567 unsigned int result_size, MYSQL_BIND * results,
568 GNUNET_MysqlDataProcessor processor,
569 void *processor_cls, ...)
570{
571 va_list ap;
572 int ret;
573 unsigned int rsize;
574 int total;
575
576 if (GNUNET_OK != prepare_statement (plugin, s))
577 {
578 GNUNET_break (0);
579 return GNUNET_SYSERR;
580 }
581 va_start (ap, processor_cls);
582 if (GNUNET_OK != init_params (plugin, s, ap))
583 {
584 GNUNET_break (0);
585 va_end (ap);
586 return GNUNET_SYSERR;
587 }
588 va_end (ap);
589 rsize = mysql_stmt_field_count (s->statement);
590 if (rsize > result_size)
591 {
592 GNUNET_break (0);
593 return GNUNET_SYSERR;
594 }
595 if (mysql_stmt_bind_result (s->statement, results))
596 {
597 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
598 _("`%s' failed at %s:%d with error: %s\n"),
599 "mysql_stmt_bind_result", __FILE__, __LINE__,
600 mysql_stmt_error (s->statement));
601 iclose (plugin);
602 return GNUNET_SYSERR;
603 }
604
605 total = 0;
606 while (1)
607 {
608 ret = mysql_stmt_fetch (s->statement);
609 if (ret == MYSQL_NO_DATA)
610 break;
611 if (ret != 0)
612 {
613 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
614 _("`%s' failed at %s:%d with error: %s\n"),
615 "mysql_stmt_fetch", __FILE__, __LINE__,
616 mysql_stmt_error (s->statement));
617 iclose (plugin);
618 return GNUNET_SYSERR;
619 }
620 if (processor != NULL)
621 if (GNUNET_OK != processor (processor_cls, rsize, results))
622 break;
623 total++;
624 }
625 mysql_stmt_reset (s->statement);
626 return total;
627}
628
629
630
631/**
632 * Run a prepared statement that does NOT produce results.
633 *
634 * @param plugin plugin context
635 * @param s handle to SELECT statment
636 * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
637 * values (size + buffer-reference for pointers); terminated
638 * with "-1"
639 * @param insert_id NULL or address where to store the row ID of whatever
640 * was inserted (only for INSERT statements!)
641 * @return GNUNET_SYSERR on error, otherwise
642 * the number of successfully affected rows
643 */
644static int
645prepared_statement_run (struct Plugin *plugin,
646 struct GNUNET_MysqlStatementHandle *s,
647 unsigned long long *insert_id, ...)
648{
649 va_list ap;
650 int affected;
651
652 if (GNUNET_OK != prepare_statement (plugin, s))
653 return GNUNET_SYSERR;
654 va_start (ap, insert_id);
655 if (GNUNET_OK != init_params (plugin, s, ap))
656 {
657 va_end (ap);
658 return GNUNET_SYSERR;
659 }
660 va_end (ap);
661 affected = mysql_stmt_affected_rows (s->statement);
662 if (NULL != insert_id)
663 *insert_id = (unsigned long long) mysql_stmt_insert_id (s->statement);
664 mysql_stmt_reset (s->statement);
665 return affected;
666}
667
668
669/**
670 * Create temporary table and prepare statements. 147 * Create temporary table and prepare statements.
671 * 148 *
672 * @param plugin plugin context 149 * @param plugin plugin context
@@ -675,7 +152,7 @@ prepared_statement_run (struct Plugin *plugin,
675static int 152static int
676itable (struct Plugin *plugin) 153itable (struct Plugin *plugin)
677{ 154{
678#define MRUNS(a) (GNUNET_OK != run_statement (plugin, a) ) 155#define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, a) )
679 if (MRUNS 156 if (MRUNS
680 ("CREATE TEMPORARY TABLE gn080dstore (" 157 ("CREATE TEMPORARY TABLE gn080dstore ("
681 " type INT(11) UNSIGNED NOT NULL DEFAULT 0," 158 " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
@@ -689,7 +166,7 @@ itable (struct Plugin *plugin)
689 ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1")) 166 ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1"))
690 return GNUNET_SYSERR; 167 return GNUNET_SYSERR;
691#undef MRUNS 168#undef MRUNS
692#define PINIT(a,b) (NULL == (a = prepared_statement_create(plugin, b))) 169#define PINIT(a,b) (NULL == (a = GNUNET_MYSQL_statement_prepare (plugin->mc, b)))
693 if (PINIT (plugin->select_value, SELECT_VALUE_STMT) || 170 if (PINIT (plugin->select_value, SELECT_VALUE_STMT) ||
694 PINIT (plugin->count_value, COUNT_VALUE_STMT) || 171 PINIT (plugin->count_value, COUNT_VALUE_STMT) ||
695 PINIT (plugin->select_old_value, SELECT_OLD_VALUE_STMT) || 172 PINIT (plugin->select_old_value, SELECT_OLD_VALUE_STMT) ||
@@ -742,7 +219,7 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, size_t size,
742 v_now = (unsigned long long) now.abs_value; 219 v_now = (unsigned long long) now.abs_value;
743 v_discard_time = (unsigned long long) discard_time.abs_value; 220 v_discard_time = (unsigned long long) discard_time.abs_value;
744 if (GNUNET_OK == 221 if (GNUNET_OK ==
745 prepared_statement_run (plugin, plugin->update_value, NULL, 222 GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->update_value, NULL,
746 MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES, 223 MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
747 MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES, 224 MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES,
748 MYSQL_TYPE_BLOB, key, sizeof (GNUNET_HashCode), 225 MYSQL_TYPE_BLOB, key, sizeof (GNUNET_HashCode),
@@ -757,7 +234,7 @@ mysql_plugin_put (void *cls, const GNUNET_HashCode * key, size_t size,
757 v_length = size; 234 v_length = size;
758 if (GNUNET_OK != 235 if (GNUNET_OK !=
759 (ret = 236 (ret =
760 prepared_statement_run (plugin, plugin->insert_value, NULL, 237 GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_value, NULL,
761 MYSQL_TYPE_LONG, &type, GNUNET_YES, 238 MYSQL_TYPE_LONG, &type, GNUNET_YES,
762 MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES, 239 MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
763 MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES, 240 MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES,
@@ -825,7 +302,7 @@ mysql_plugin_get (void *cls, const GNUNET_HashCode * key,
825 v_now = (unsigned long long) now.abs_value; 302 v_now = (unsigned long long) now.abs_value;
826 if ((GNUNET_OK != 303 if ((GNUNET_OK !=
827 (ret = 304 (ret =
828 prepared_statement_run_select (plugin, plugin->count_value, 1, rbind, 305 GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_value, 1, rbind,
829 return_ok, NULL, MYSQL_TYPE_BLOB, key, 306 return_ok, NULL, MYSQL_TYPE_BLOB, key,
830 sizeof (GNUNET_HashCode), &h_length, 307 sizeof (GNUNET_HashCode), &h_length,
831 MYSQL_TYPE_LONG, &v_type, GNUNET_YES, 308 MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
@@ -854,7 +331,7 @@ mysql_plugin_get (void *cls, const GNUNET_HashCode * key,
854 off = (off + 1) % total; 331 off = (off + 1) % total;
855 if (GNUNET_OK != 332 if (GNUNET_OK !=
856 (ret = 333 (ret =
857 prepared_statement_run_select (plugin, plugin->select_value, 2, rbind, 334 GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->select_value, 2, rbind,
858 return_ok, NULL, MYSQL_TYPE_BLOB, key, 335 return_ok, NULL, MYSQL_TYPE_BLOB, key,
859 sizeof (GNUNET_HashCode), &h_length, 336 sizeof (GNUNET_HashCode), &h_length,
860 MYSQL_TYPE_LONG, &v_type, GNUNET_YES, 337 MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
@@ -917,11 +394,11 @@ mysql_plugin_del (void *cls)
917 rbind[3].buffer = buffer; 394 rbind[3].buffer = buffer;
918 if ((GNUNET_OK != 395 if ((GNUNET_OK !=
919 (ret = 396 (ret =
920 prepared_statement_run_select (plugin, plugin->select_old_value, 4, 397 GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->select_old_value, 4,
921 rbind, return_ok, NULL, -1))) || 398 rbind, return_ok, NULL, -1))) ||
922 (GNUNET_OK != 399 (GNUNET_OK !=
923 (ret = 400 (ret =
924 prepared_statement_run (plugin, plugin->delete_value, NULL, 401 GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->delete_value, NULL,
925 MYSQL_TYPE_BLOB, &v_key, 402 MYSQL_TYPE_BLOB, &v_key,
926 sizeof (GNUNET_HashCode), &k_length, 403 sizeof (GNUNET_HashCode), &k_length,
927 MYSQL_TYPE_BLOB, &vhash, 404 MYSQL_TYPE_BLOB, &vhash,
@@ -956,17 +433,12 @@ libgnunet_plugin_datacache_mysql_init (void *cls)
956 433
957 plugin = GNUNET_malloc (sizeof (struct Plugin)); 434 plugin = GNUNET_malloc (sizeof (struct Plugin));
958 plugin->env = env; 435 plugin->env = env;
959 plugin->cnffile = get_my_cnf_path (env->cfg); 436 plugin->mc = GNUNET_MYSQL_context_create (env->cfg, "datacache-mysql");
960 if (GNUNET_OK != iopen (plugin)) 437 if ( (NULL == plugin->mc) ||
961 { 438 (GNUNET_OK != itable (plugin)) )
962 GNUNET_free_non_null (plugin->cnffile);
963 GNUNET_free (plugin);
964 return NULL;
965 }
966 if (GNUNET_OK != itable (plugin))
967 { 439 {
968 iclose (plugin); 440 if (NULL != plugin->mc)
969 GNUNET_free_non_null (plugin->cnffile); 441 GNUNET_MYSQL_context_destroy (plugin->mc);
970 GNUNET_free (plugin); 442 GNUNET_free (plugin);
971 return NULL; 443 return NULL;
972 } 444 }
@@ -993,8 +465,7 @@ libgnunet_plugin_datacache_mysql_done (void *cls)
993 struct GNUNET_DATACACHE_PluginFunctions *api = cls; 465 struct GNUNET_DATACACHE_PluginFunctions *api = cls;
994 struct Plugin *plugin = api->cls; 466 struct Plugin *plugin = api->cls;
995 467
996 iclose (plugin); 468 GNUNET_MYSQL_context_destroy (plugin->mc);
997 GNUNET_free_non_null (plugin->cnffile);
998 GNUNET_free (plugin); 469 GNUNET_free (plugin);
999 GNUNET_free (api); 470 GNUNET_free (api);
1000 mysql_library_end (); 471 mysql_library_end ();
diff --git a/src/include/gnunet_mysql_lib.h b/src/include/gnunet_mysql_lib.h
index 5673fe502..678b7669d 100644
--- a/src/include/gnunet_mysql_lib.h
+++ b/src/include/gnunet_mysql_lib.h
@@ -28,6 +28,7 @@
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_bandwidth_lib.h" 29#include "gnunet_bandwidth_lib.h"
30#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
31#include <mysql/mysql.h>
31 32
32#ifdef __cplusplus 33#ifdef __cplusplus
33extern "C" 34extern "C"
diff --git a/src/mysql/mysql.c b/src/mysql/mysql.c
index 0fc98308c..1c3166dc7 100644
--- a/src/mysql/mysql.c
+++ b/src/mysql/mysql.c
@@ -359,6 +359,7 @@ GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc)
359 GNUNET_free (sh); 359 GNUNET_free (sh);
360 } 360 }
361 GNUNET_free (mc); 361 GNUNET_free (mc);
362 mysql_library_end ();
362} 363}
363 364
364 365