aboutsummaryrefslogtreecommitdiff
path: root/src/datastore
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2023-09-24 11:13:02 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2023-09-24 11:13:02 +0200
commit757fe39278b2f3f29459f33c5ec41f0181142e18 (patch)
treed670abdd8b3b4da21bef3d097e4d66ddad6c5047 /src/datastore
parent3ee4f3c6fb9986fcb67de0cb0bb32d6f12ab44cf (diff)
downloadgnunet-757fe39278b2f3f29459f33c5ec41f0181142e18.tar.gz
gnunet-757fe39278b2f3f29459f33c5ec41f0181142e18.zip
MYSQL: phase out
Diffstat (limited to 'src/datastore')
-rw-r--r--src/datastore/Makefile.am64
-rw-r--r--src/datastore/perf_plugin_datastore_data_mysql.conf10
-rw-r--r--src/datastore/plugin_datastore_mysql.c1204
-rw-r--r--src/datastore/test_datastore_api_data_mysql.conf10
-rw-r--r--src/datastore/test_plugin_datastore_data_mysql.conf9
5 files changed, 0 insertions, 1297 deletions
diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am
index b73a0497b..595c7da3d 100644
--- a/src/datastore/Makefile.am
+++ b/src/datastore/Makefile.am
@@ -56,19 +56,6 @@ gnunet_datastore_LDADD = \
56 $(GN_LIBINTL) 56 $(GN_LIBINTL)
57 57
58 58
59if HAVE_MYSQL
60 MYSQL_PLUGIN = libgnunet_plugin_datastore_mysql.la
61if HAVE_BENCHMARKS
62 MYSQL_BENCHMARKS = \
63 perf_datastore_api_mysql \
64 perf_plugin_datastore_mysql
65endif
66 MYSQL_TESTS = \
67 test_datastore_api_mysql \
68 test_datastore_api_management_mysql \
69 test_plugin_datastore_mysql \
70 $(MYSQL_BENCHMARKS)
71endif
72if HAVE_SQLITE 59if HAVE_SQLITE
73 SQLITE_PLUGIN = libgnunet_plugin_datastore_sqlite.la 60 SQLITE_PLUGIN = libgnunet_plugin_datastore_sqlite.la
74if HAVE_BENCHMARKS 61if HAVE_BENCHMARKS
@@ -98,7 +85,6 @@ endif
98 85
99plugin_LTLIBRARIES = \ 86plugin_LTLIBRARIES = \
100 $(SQLITE_PLUGIN) \ 87 $(SQLITE_PLUGIN) \
101 $(MYSQL_PLUGIN) \
102 $(POSTGRES_PLUGIN) \ 88 $(POSTGRES_PLUGIN) \
103 libgnunet_plugin_datastore_heap.la 89 libgnunet_plugin_datastore_heap.la
104 90
@@ -128,18 +114,6 @@ libgnunet_plugin_datastore_heap_la_LDFLAGS = \
128 $(GN_PLUGIN_LDFLAGS) 114 $(GN_PLUGIN_LDFLAGS)
129 115
130 116
131libgnunet_plugin_datastore_mysql_la_SOURCES = \
132 plugin_datastore_mysql.c
133libgnunet_plugin_datastore_mysql_la_LIBADD = \
134 $(top_builddir)/src/my/libgnunetmy.la \
135 $(top_builddir)/src/mysql/libgnunetmysql.la \
136 $(top_builddir)/src/statistics/libgnunetstatistics.la \
137 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) $(Z_LIBS) -lmysqlclient
138libgnunet_plugin_datastore_mysql_la_LDFLAGS = \
139 $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient
140libgnunet_plugin_datastore_mysql_la_CPPFLAGS = \
141 $(MYSQL_CPPFLAGS) $(AM_CPPFLAGS)
142
143libgnunet_plugin_datastore_postgres_la_SOURCES = \ 117libgnunet_plugin_datastore_postgres_la_SOURCES = \
144 plugin_datastore_postgres.c 118 plugin_datastore_postgres.c
145libgnunet_plugin_datastore_postgres_la_LIBADD = \ 119libgnunet_plugin_datastore_postgres_la_LIBADD = \
@@ -167,7 +141,6 @@ check_PROGRAMS = \
167 perf_plugin_datastore_heap \ 141 perf_plugin_datastore_heap \
168 test_plugin_datastore_heap \ 142 test_plugin_datastore_heap \
169 $(SQLITE_TESTS) \ 143 $(SQLITE_TESTS) \
170 $(MYSQL_TESTS) \
171 $(POSTGRES_TESTS) 144 $(POSTGRES_TESTS)
172 145
173if ENABLE_TEST_RUN 146if ENABLE_TEST_RUN
@@ -243,40 +216,6 @@ test_plugin_datastore_sqlite_LDADD = \
243 $(top_builddir)/src/util/libgnunetutil.la 216 $(top_builddir)/src/util/libgnunetutil.la
244 217
245 218
246test_datastore_api_mysql_SOURCES = \
247 test_datastore_api.c
248test_datastore_api_mysql_LDADD = \
249 $(top_builddir)/src/testing/libgnunettesting.la \
250 libgnunetdatastore.la \
251 $(top_builddir)/src/util/libgnunetutil.la
252
253test_datastore_api_management_mysql_SOURCES = \
254 test_datastore_api_management.c
255test_datastore_api_management_mysql_LDADD = \
256 $(top_builddir)/src/testing/libgnunettesting.la \
257 libgnunetdatastore.la \
258 $(top_builddir)/src/util/libgnunetutil.la
259
260perf_datastore_api_mysql_SOURCES = \
261 perf_datastore_api.c
262perf_datastore_api_mysql_LDADD = \
263 $(top_builddir)/src/testing/libgnunettesting.la \
264 libgnunetdatastore.la \
265 $(top_builddir)/src/util/libgnunetutil.la
266
267test_plugin_datastore_mysql_SOURCES = \
268 test_plugin_datastore.c
269test_plugin_datastore_mysql_LDADD = \
270 $(top_builddir)/src/testing/libgnunettesting.la \
271 $(top_builddir)/src/util/libgnunetutil.la
272
273perf_plugin_datastore_mysql_SOURCES = \
274 perf_plugin_datastore.c
275perf_plugin_datastore_mysql_LDADD = \
276 $(top_builddir)/src/testing/libgnunettesting.la \
277 $(top_builddir)/src/util/libgnunetutil.la
278
279
280test_datastore_api_postgres_SOURCES = \ 219test_datastore_api_postgres_SOURCES = \
281 test_datastore_api.c 220 test_datastore_api.c
282test_datastore_api_postgres_LDADD = \ 221test_datastore_api_postgres_LDADD = \
@@ -319,9 +258,6 @@ EXTRA_DIST = \
319 test_datastore_api_data_heap.conf \ 258 test_datastore_api_data_heap.conf \
320 perf_plugin_datastore_data_heap.conf \ 259 perf_plugin_datastore_data_heap.conf \
321 test_plugin_datastore_data_heap.conf \ 260 test_plugin_datastore_data_heap.conf \
322 test_datastore_api_data_mysql.conf \
323 perf_plugin_datastore_data_mysql.conf \
324 test_plugin_datastore_data_mysql.conf \
325 test_datastore_api_data_postgres.conf \ 261 test_datastore_api_data_postgres.conf \
326 perf_plugin_datastore_data_postgres.conf \ 262 perf_plugin_datastore_data_postgres.conf \
327 test_plugin_datastore_data_postgres.conf \ 263 test_plugin_datastore_data_postgres.conf \
diff --git a/src/datastore/perf_plugin_datastore_data_mysql.conf b/src/datastore/perf_plugin_datastore_data_mysql.conf
deleted file mode 100644
index a32b830c3..000000000
--- a/src/datastore/perf_plugin_datastore_data_mysql.conf
+++ /dev/null
@@ -1,10 +0,0 @@
1@INLINE@ test_defaults.conf
2[PATHS]
3GNUNET_TEST_HOME = $GNUNET_TMP/perf-gnunet-datastore-mysql/
4
5[datastore]
6DATABASE = mysql
7
8[datastore-mysql]
9DATABASE = gnunetcheck
10
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
deleted file mode 100644
index f62c51778..000000000
--- a/src/datastore/plugin_datastore_mysql.c
+++ /dev/null
@@ -1,1204 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2009, 2010, 2011 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 */
20
21/**
22 * @file datastore/plugin_datastore_mysql.c
23 * @brief mysql-based datastore backend
24 * @author Igor Wronsky
25 * @author Christian Grothoff
26 * @author Christophe Genevey
27 *
28 * NOTE: This db module does NOT work with mysql prior to 4.1 since
29 * it uses prepared statements. MySQL 5.0.46 promises to fix a bug
30 * in MyISAM that is causing us grief. At the time of this writing,
31 * that version is yet to be released. In anticipation, the code
32 * will use MyISAM with 5.0.46 (and higher). If you run such a
33 * version, please run "make check" to verify that the MySQL bug
34 * was actually fixed in your version (and if not, change the
35 * code below to use MyISAM for gn071).
36 *
37 * HIGHLIGHTS
38 *
39 * Pros
40 * + On up-to-date hardware where mysql can be used comfortably, this
41 * module will have better performance than the other db choices
42 * (according to our tests).
43 * + Its often possible to recover the mysql database from internal
44 * inconsistencies. The other db choices do not support repair!
45 * Cons
46 * - Memory usage (Comment: "I have 1G and it never caused me trouble")
47 * - Manual setup
48 *
49 * MANUAL SETUP INSTRUCTIONS
50 *
51 * 1) in gnunet.conf, set
52 * @verbatim
53 [datastore]
54 DATABASE = "mysql"
55 @endverbatim
56 * 2) Then access mysql as root,
57 * @verbatim
58 $ mysql -u root -p
59 @endverbatim
60 * and do the following. [You should replace $USER with the username
61 * that will be running the gnunetd process].
62 * @verbatim
63 CREATE DATABASE gnunet;
64 GRANT select,insert,update,delete,create,alter,drop,create temporary tables
65 ON gnunet.* TO $USER@localhost;
66 SET PASSWORD FOR $USER@localhost=PASSWORD('$the_password_you_like');
67 FLUSH PRIVILEGES;
68 @endverbatim
69 * 3) In the $HOME directory of $USER, create a ".my.cnf" file
70 * with the following lines
71 * @verbatim
72 [client]
73 user=$USER
74 password=$the_password_you_like
75 @endverbatim
76 *
77 * That's it. Note that .my.cnf file is a security risk unless its on
78 * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic
79 * link. Even greater security risk can be achieved by setting no
80 * password for $USER. Luckily $USER has only privileges to mess
81 * up GNUnet's tables, nothing else (unless you give them more,
82 * of course).<p>
83 *
84 * 4) Still, perhaps you should briefly try if the DB connection
85 * works. First, login as $USER. Then use,
86 *
87 * @verbatim
88 $ mysql -u $USER -p $the_password_you_like
89 mysql> use gnunet;
90 @endverbatim
91 *
92 * If you get the message &quot;Database changed&quot; it probably works.
93 *
94 * [If you get &quot;ERROR 2002: Can't connect to local MySQL server
95 * through socket '/tmp/mysql.sock' (2)&quot; it may be resolvable by
96 * &quot;ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock&quot;
97 * so there may be some additional trouble depending on your mysql setup.]
98 *
99 * REPAIRING TABLES
100 *
101 * - Its probably healthy to check your tables for inconsistencies
102 * every now and then.
103 * - If you get odd SEGVs on gnunetd startup, it might be that the mysql
104 * databases have been corrupted.
105 * - The tables can be verified/fixed in two ways;
106 * 1) by running mysqlcheck -A, or
107 * 2) by executing (inside of mysql using the GNUnet database):
108 * @verbatim
109 mysql> REPAIR TABLE gn090;
110 @endverbatim
111 *
112 * PROBLEMS?
113 *
114 * If you have problems related to the mysql module, your best
115 * friend is probably the mysql manual. The first thing to check
116 * is that mysql is basically operational, that you can connect
117 * to it, create tables, issue queries etc.
118 */
119
120#include "platform.h"
121#include "gnunet_datastore_plugin.h"
122#include "gnunet_util_lib.h"
123#include "gnunet_mysql_lib.h"
124#include "gnunet_mysql_compat.h"
125#include "gnunet_my_lib.h"
126
127#define MAX_DATUM_SIZE 65536
128
129
130/**
131 * Context for all functions in this plugin.
132 */
133struct Plugin
134{
135 /**
136 * Our execution environment.
137 */
138 struct GNUNET_DATASTORE_PluginEnvironment *env;
139
140 /**
141 * Handle to talk to MySQL.
142 */
143 struct GNUNET_MYSQL_Context *mc;
144
145 /**
146 * Prepared statements.
147 */
148#define INSERT_ENTRY \
149 "INSERT INTO gn090 (repl,type,prio,anonLevel,expire,rvalue,hash,vhash,value) VALUES (?,?,?,?,?,?,?,?,?)"
150 struct GNUNET_MYSQL_StatementHandle *insert_entry;
151
152#define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?"
153 struct GNUNET_MYSQL_StatementHandle *delete_entry_by_uid;
154
155#define DELETE_ENTRY_BY_HASH_VALUE "DELETE FROM gn090 " \
156 "WHERE hash = ? AND " \
157 "value = ? " \
158 "LIMIT 1"
159 struct GNUNET_MYSQL_StatementHandle *delete_entry_by_hash_value;
160
161#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, uid"
162
163#define SELECT_ENTRY "SELECT " RESULT_COLUMNS " FROM gn090 " \
164 "WHERE uid >= ? AND " \
165 "(rvalue >= ? OR 0 = ?) " \
166 "ORDER BY uid LIMIT 1"
167 struct GNUNET_MYSQL_StatementHandle *select_entry;
168
169#define SELECT_ENTRY_BY_HASH "SELECT " RESULT_COLUMNS " FROM gn090 " \
170 "FORCE INDEX (idx_hash_type_uid) " \
171 "WHERE hash=? AND " \
172 "uid >= ? AND " \
173 "(rvalue >= ? OR 0 = ?) " \
174 "ORDER BY uid LIMIT 1"
175 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash;
176
177#define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT " RESULT_COLUMNS " FROM gn090 " \
178 "FORCE INDEX (idx_hash_type_uid) " \
179 "WHERE hash = ? AND " \
180 "type = ? AND " \
181 "uid >= ? AND " \
182 "(rvalue >= ? OR 0 = ?) " \
183 "ORDER BY uid LIMIT 1"
184 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_type;
185
186#define UPDATE_ENTRY "UPDATE gn090 SET " \
187 "prio = prio + ?, " \
188 "repl = repl + ?, " \
189 "expire = GREATEST(expire, ?) " \
190 "WHERE hash = ? AND vhash = ?"
191 struct GNUNET_MYSQL_StatementHandle *update_entry;
192
193#define DEC_REPL "UPDATE gn090 SET repl=GREATEST (1, repl) - 1 WHERE uid=?"
194 struct GNUNET_MYSQL_StatementHandle *dec_repl;
195
196#define SELECT_SIZE "SELECT SUM(LENGTH(value)+256) FROM gn090"
197 struct GNUNET_MYSQL_StatementHandle *get_size;
198
199#define SELECT_IT_NON_ANONYMOUS "SELECT " RESULT_COLUMNS " FROM gn090 " \
200 "FORCE INDEX (idx_anonLevel_type_rvalue) " \
201 "WHERE anonLevel=0 AND " \
202 "type=? AND " \
203 "uid >= ? " \
204 "ORDER BY uid LIMIT 1"
205 struct GNUNET_MYSQL_StatementHandle *zero_iter;
206
207#define SELECT_IT_EXPIRATION "SELECT " RESULT_COLUMNS " FROM gn090 " \
208 "FORCE INDEX (idx_expire) " \
209 "WHERE expire < ? " \
210 "ORDER BY expire ASC LIMIT 1"
211 struct GNUNET_MYSQL_StatementHandle *select_expiration;
212
213#define SELECT_IT_PRIORITY "SELECT " RESULT_COLUMNS " FROM gn090 " \
214 "FORCE INDEX (idx_prio) " \
215 "ORDER BY prio ASC LIMIT 1"
216 struct GNUNET_MYSQL_StatementHandle *select_priority;
217
218#define SELECT_IT_REPLICATION "SELECT " RESULT_COLUMNS " FROM gn090 " \
219 "FORCE INDEX (idx_repl_rvalue) " \
220 "WHERE repl=? AND " \
221 " (rvalue>=? OR" \
222 " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) " \
223 "ORDER BY rvalue ASC " \
224 "LIMIT 1"
225 struct GNUNET_MYSQL_StatementHandle *select_replication;
226
227#define SELECT_MAX_REPL "SELECT MAX(repl) FROM gn090"
228 struct GNUNET_MYSQL_StatementHandle *max_repl;
229
230#define GET_ALL_KEYS "SELECT hash from gn090"
231 struct GNUNET_MYSQL_StatementHandle *get_all_keys;
232};
233
234#define MAX_PARAM 16
235
236/**
237 * Delete an entry from the gn090 table.
238 *
239 * @param plugin plugin context
240 * @param uid unique ID of the entry to delete
241 * @return #GNUNET_OK on success, #GNUNET_NO if no such value exists, #GNUNET_SYSERR on error
242 */
243static int
244do_delete_entry (struct Plugin *plugin,
245 unsigned long long uid)
246{
247 int ret;
248 uint64_t uid64 = (uint64_t) uid;
249 struct GNUNET_MY_QueryParam params_delete[] = {
250 GNUNET_MY_query_param_uint64 (&uid64),
251 GNUNET_MY_query_param_end
252 };
253
254 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
255 "Deleting value %llu from gn090 table\n",
256 uid);
257 ret = GNUNET_MY_exec_prepared (plugin->mc,
258 plugin->delete_entry_by_uid,
259 params_delete);
260 if (ret >= 0)
261 {
262 return GNUNET_OK;
263 }
264 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
265 "Deleting value %llu from gn090 table failed\n",
266 (unsigned long long) uid);
267 return ret;
268}
269
270
271/**
272 * Get an estimate of how much space the database is
273 * currently using.
274 *
275 * @param cls our `struct Plugin *`
276 * @return number of bytes used on disk
277 */
278static void
279mysql_plugin_estimate_size (void *cls,
280 unsigned long long *estimate)
281{
282 struct Plugin *plugin = cls;
283 uint64_t total;
284 int ret;
285 struct GNUNET_MY_QueryParam params_get[] = {
286 GNUNET_MY_query_param_end
287 };
288 struct GNUNET_MY_ResultSpec results_get[] = {
289 GNUNET_MY_result_spec_uint64 (&total),
290 GNUNET_MY_result_spec_end
291 };
292
293 ret = GNUNET_MY_exec_prepared (plugin->mc,
294 plugin->get_size,
295 params_get);
296 *estimate = 0;
297 total = UINT64_MAX;
298 if ((GNUNET_OK == ret) &&
299 (GNUNET_OK ==
300 GNUNET_MY_extract_result (plugin->get_size,
301 results_get)))
302 {
303 *estimate = (unsigned long long) total;
304 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
305 "Size estimate for MySQL payload is %lld\n",
306 (long long) total);
307 GNUNET_assert (UINT64_MAX != total);
308 GNUNET_break (GNUNET_NO ==
309 GNUNET_MY_extract_result (plugin->get_size,
310 NULL));
311 }
312}
313
314
315/**
316 * Store an item in the datastore.
317 *
318 * @param cls closure
319 * @param key key for the item
320 * @param absent true if the key was not found in the bloom filter
321 * @param size number of bytes in @a data
322 * @param data content stored
323 * @param type type of the content
324 * @param priority priority of the content
325 * @param anonymity anonymity-level for the content
326 * @param replication replication-level for the content
327 * @param expiration expiration time for the content
328 * @param cont continuation called with success or failure status
329 * @param cont_cls closure for @a cont
330 */
331static void
332mysql_plugin_put (void *cls,
333 const struct GNUNET_HashCode *key,
334 bool absent,
335 uint32_t size,
336 const void *data,
337 enum GNUNET_BLOCK_Type type,
338 uint32_t priority,
339 uint32_t anonymity,
340 uint32_t replication,
341 struct GNUNET_TIME_Absolute expiration,
342 PluginPutCont cont,
343 void *cont_cls)
344{
345 struct Plugin *plugin = cls;
346 uint64_t lexpiration = expiration.abs_value_us;
347 struct GNUNET_HashCode vhash;
348
349 GNUNET_CRYPTO_hash (data,
350 size,
351 &vhash);
352 if (! absent)
353 {
354 struct GNUNET_MY_QueryParam params_update[] = {
355 GNUNET_MY_query_param_uint32 (&priority),
356 GNUNET_MY_query_param_uint32 (&replication),
357 GNUNET_MY_query_param_uint64 (&lexpiration),
358 GNUNET_MY_query_param_auto_from_type (key),
359 GNUNET_MY_query_param_auto_from_type (&vhash),
360 GNUNET_MY_query_param_end
361 };
362
363 if (GNUNET_OK !=
364 GNUNET_MY_exec_prepared (plugin->mc,
365 plugin->update_entry,
366 params_update))
367 {
368 cont (cont_cls,
369 key,
370 size,
371 GNUNET_SYSERR,
372 _ ("MySQL statement run failure"));
373 return;
374 }
375
376 MYSQL_STMT *stmt = GNUNET_MYSQL_statement_get_stmt (plugin->update_entry);
377 my_ulonglong rows = mysql_stmt_affected_rows (stmt);
378
379 GNUNET_break (GNUNET_NO ==
380 GNUNET_MY_extract_result (plugin->update_entry,
381 NULL));
382 if (0 != rows)
383 {
384 cont (cont_cls,
385 key,
386 size,
387 GNUNET_NO,
388 NULL);
389 return;
390 }
391 }
392
393 uint64_t lrvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
394 UINT64_MAX);
395 struct GNUNET_MY_QueryParam params_insert[] = {
396 GNUNET_MY_query_param_uint32 (&replication),
397 GNUNET_MY_query_param_uint32 (&type),
398 GNUNET_MY_query_param_uint32 (&priority),
399 GNUNET_MY_query_param_uint32 (&anonymity),
400 GNUNET_MY_query_param_uint64 (&lexpiration),
401 GNUNET_MY_query_param_uint64 (&lrvalue),
402 GNUNET_MY_query_param_auto_from_type (key),
403 GNUNET_MY_query_param_auto_from_type (&vhash),
404 GNUNET_MY_query_param_fixed_size (data, size),
405 GNUNET_MY_query_param_end
406 };
407
408 if (size > MAX_DATUM_SIZE)
409 {
410 GNUNET_break (0);
411 cont (cont_cls, key, size, GNUNET_SYSERR, _ ("Data too large"));
412 return;
413 }
414
415 if (GNUNET_OK !=
416 GNUNET_MY_exec_prepared (plugin->mc,
417 plugin->insert_entry,
418 params_insert))
419 {
420 cont (cont_cls,
421 key,
422 size,
423 GNUNET_SYSERR,
424 _ ("MySQL statement run failure"));
425 return;
426 }
427 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
428 "Inserted value `%s' with size %u into gn090 table\n",
429 GNUNET_h2s (key),
430 (unsigned int) size);
431 if (size > 0)
432 plugin->env->duc (plugin->env->cls,
433 size);
434 GNUNET_break (GNUNET_NO ==
435 GNUNET_MY_extract_result (plugin->insert_entry,
436 NULL));
437 cont (cont_cls,
438 key,
439 size,
440 GNUNET_OK,
441 NULL);
442}
443
444
445/**
446 * Run the given select statement and call 'proc' on the resulting
447 * values (which must be in particular positions).
448 *
449 * @param plugin the plugin handle
450 * @param stmt select statement to run
451 * @param proc function to call on result
452 * @param proc_cls closure for @a proc
453 * @param params_select arguments to initialize stmt
454 */
455static void
456execute_select (struct Plugin *plugin,
457 struct GNUNET_MYSQL_StatementHandle *stmt,
458 PluginDatumProcessor proc,
459 void *proc_cls,
460 struct GNUNET_MY_QueryParam *params_select)
461{
462 int ret;
463 uint32_t replication;
464 uint32_t type;
465 uint32_t priority;
466 uint32_t anonymity;
467 uint64_t uid;
468 size_t value_size;
469 void *value;
470 struct GNUNET_HashCode key;
471 struct GNUNET_TIME_Absolute expiration;
472 struct GNUNET_MY_ResultSpec results_select[] = {
473 GNUNET_MY_result_spec_uint32 (&replication),
474 GNUNET_MY_result_spec_uint32 (&type),
475 GNUNET_MY_result_spec_uint32 (&priority),
476 GNUNET_MY_result_spec_uint32 (&anonymity),
477 GNUNET_MY_result_spec_absolute_time (&expiration),
478 GNUNET_MY_result_spec_auto_from_type (&key),
479 GNUNET_MY_result_spec_variable_size (&value, &value_size),
480 GNUNET_MY_result_spec_uint64 (&uid),
481 GNUNET_MY_result_spec_end
482 };
483
484 ret = GNUNET_MY_exec_prepared (plugin->mc,
485 stmt,
486 params_select);
487 if (GNUNET_OK != ret)
488 {
489 proc (proc_cls,
490 NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
491 return;
492 }
493
494 ret = GNUNET_MY_extract_result (stmt,
495 results_select);
496 if (GNUNET_OK != ret)
497 {
498 proc (proc_cls,
499 NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
500 return;
501 }
502
503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
504 "Found %u-byte value under key `%s' with prio %u, anon %u, expire %s selecting from gn090 table\n",
505 (unsigned int) value_size,
506 GNUNET_h2s (&key),
507 (unsigned int) priority,
508 (unsigned int) anonymity,
509 GNUNET_STRINGS_absolute_time_to_string (expiration));
510 GNUNET_assert (value_size < MAX_DATUM_SIZE);
511 GNUNET_break (GNUNET_NO ==
512 GNUNET_MY_extract_result (stmt,
513 NULL));
514 ret = proc (proc_cls,
515 &key,
516 value_size,
517 value,
518 type,
519 priority,
520 anonymity,
521 replication,
522 expiration,
523 uid);
524 GNUNET_MY_cleanup_result (results_select);
525 if (GNUNET_NO == ret)
526 {
527 do_delete_entry (plugin, uid);
528 if (0 != value_size)
529 plugin->env->duc (plugin->env->cls,
530 -value_size);
531 }
532}
533
534
535/**
536 * Get one of the results for a particular key in the datastore.
537 *
538 * @param cls closure
539 * @param next_uid return the result with lowest uid >= next_uid
540 * @param random if true, return a random result instead of using next_uid
541 * @param key key to match, never NULL
542 * @param type entries of which type are relevant?
543 * Use 0 for any type.
544 * @param proc function to call on the matching value,
545 * with NULL for if no value matches
546 * @param proc_cls closure for @a proc
547 */
548static void
549mysql_plugin_get_key (void *cls,
550 uint64_t next_uid,
551 bool random,
552 const struct GNUNET_HashCode *key,
553 enum GNUNET_BLOCK_Type type,
554 PluginDatumProcessor proc,
555 void *proc_cls)
556{
557 struct Plugin *plugin = cls;
558 uint64_t rvalue;
559
560 if (random)
561 {
562 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
563 UINT64_MAX);
564 next_uid = 0;
565 }
566 else
567 rvalue = 0;
568
569 if (NULL == key)
570 {
571 struct GNUNET_MY_QueryParam params_select[] = {
572 GNUNET_MY_query_param_uint64 (&next_uid),
573 GNUNET_MY_query_param_uint64 (&rvalue),
574 GNUNET_MY_query_param_uint64 (&rvalue),
575 GNUNET_MY_query_param_end
576 };
577
578 execute_select (plugin,
579 plugin->select_entry,
580 proc,
581 proc_cls,
582 params_select);
583 }
584 else if (type != GNUNET_BLOCK_TYPE_ANY)
585 {
586 struct GNUNET_MY_QueryParam params_select[] = {
587 GNUNET_MY_query_param_auto_from_type (key),
588 GNUNET_MY_query_param_uint32 (&type),
589 GNUNET_MY_query_param_uint64 (&next_uid),
590 GNUNET_MY_query_param_uint64 (&rvalue),
591 GNUNET_MY_query_param_uint64 (&rvalue),
592 GNUNET_MY_query_param_end
593 };
594
595 execute_select (plugin,
596 plugin->select_entry_by_hash_and_type,
597 proc,
598 proc_cls,
599 params_select);
600 }
601 else
602 {
603 struct GNUNET_MY_QueryParam params_select[] = {
604 GNUNET_MY_query_param_auto_from_type (key),
605 GNUNET_MY_query_param_uint64 (&next_uid),
606 GNUNET_MY_query_param_uint64 (&rvalue),
607 GNUNET_MY_query_param_uint64 (&rvalue),
608 GNUNET_MY_query_param_end
609 };
610
611 execute_select (plugin,
612 plugin->select_entry_by_hash,
613 proc,
614 proc_cls,
615 params_select);
616 }
617}
618
619
620/**
621 * Get a zero-anonymity datum from the datastore.
622 *
623 * @param cls our `struct Plugin *`
624 * @param next_uid return the result with lowest uid >= next_uid
625 * @param type entries of which type should be considered?
626 * Must not be zero (ANY).
627 * @param proc function to call on a matching value;
628 * will be called with NULL if no value matches
629 * @param proc_cls closure for @a proc
630 */
631static void
632mysql_plugin_get_zero_anonymity (void *cls,
633 uint64_t next_uid,
634 enum GNUNET_BLOCK_Type type,
635 PluginDatumProcessor proc,
636 void *proc_cls)
637{
638 struct Plugin *plugin = cls;
639 uint32_t typei = (uint32_t) type;
640
641 struct GNUNET_MY_QueryParam params_zero_iter[] = {
642 GNUNET_MY_query_param_uint32 (&typei),
643 GNUNET_MY_query_param_uint64 (&next_uid),
644 GNUNET_MY_query_param_end
645 };
646
647 execute_select (plugin,
648 plugin->zero_iter,
649 proc,
650 proc_cls,
651 params_zero_iter);
652}
653
654
655/**
656 * Context for #repl_proc() function.
657 */
658struct ReplCtx
659{
660 /**
661 * Plugin handle.
662 */
663 struct Plugin *plugin;
664
665 /**
666 * Function to call for the result (or the NULL).
667 */
668 PluginDatumProcessor proc;
669
670 /**
671 * Closure for @e proc.
672 */
673 void *proc_cls;
674};
675
676
677/**
678 * Wrapper for the processor for #mysql_plugin_get_replication().
679 * Decrements the replication counter and calls the original
680 * iterator.
681 *
682 * @param cls closure
683 * @param key key for the content
684 * @param size number of bytes in @a data
685 * @param data content stored
686 * @param type type of the content
687 * @param priority priority of the content
688 * @param anonymity anonymity-level for the content
689 * @param replication replication-level for the content
690 * @param expiration expiration time for the content
691 * @param uid unique identifier for the datum;
692 * maybe 0 if no unique identifier is available
693 * @return #GNUNET_SYSERR to abort the iteration, #GNUNET_OK to continue
694 * (continue on call to "next", of course),
695 * #GNUNET_NO to delete the item and continue (if supported)
696 */
697static int
698repl_proc (void *cls,
699 const struct GNUNET_HashCode *key,
700 uint32_t size,
701 const void *data,
702 enum GNUNET_BLOCK_Type type,
703 uint32_t priority,
704 uint32_t anonymity,
705 uint32_t replication,
706 struct GNUNET_TIME_Absolute expiration,
707 uint64_t uid)
708{
709 struct ReplCtx *rc = cls;
710 struct Plugin *plugin = rc->plugin;
711 int ret;
712 int iret;
713
714 ret = rc->proc (rc->proc_cls,
715 key,
716 size,
717 data,
718 type,
719 priority,
720 anonymity,
721 replication,
722 expiration,
723 uid);
724 if (NULL != key)
725 {
726 struct GNUNET_MY_QueryParam params_proc[] = {
727 GNUNET_MY_query_param_uint64 (&uid),
728 GNUNET_MY_query_param_end
729 };
730
731 iret = GNUNET_MY_exec_prepared (plugin->mc,
732 plugin->dec_repl,
733 params_proc);
734 if (GNUNET_SYSERR == iret)
735 {
736 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
737 "Failed to reduce replication counter\n");
738 return GNUNET_SYSERR;
739 }
740 }
741 return ret;
742}
743
744
745/**
746 * Get a random item for replication. Returns a single, not expired,
747 * random item from those with the highest replication counters. The
748 * item's replication counter is decremented by one IF it was positive
749 * before. Call @a proc with all values ZERO or NULL if the datastore
750 * is empty.
751 *
752 * @param cls closure
753 * @param proc function to call the value (once only).
754 * @param proc_cls closure for @a proc
755 */
756static void
757mysql_plugin_get_replication (void *cls,
758 PluginDatumProcessor proc,
759 void *proc_cls)
760{
761 struct Plugin *plugin = cls;
762 uint64_t rvalue;
763 uint32_t repl;
764 struct ReplCtx rc;
765 struct GNUNET_MY_QueryParam params_get[] = {
766 GNUNET_MY_query_param_end
767 };
768 struct GNUNET_MY_ResultSpec results_get[] = {
769 GNUNET_MY_result_spec_uint32 (&repl),
770 GNUNET_MY_result_spec_end
771 };
772 struct GNUNET_MY_QueryParam params_select[] = {
773 GNUNET_MY_query_param_uint32 (&repl),
774 GNUNET_MY_query_param_uint64 (&rvalue),
775 GNUNET_MY_query_param_uint32 (&repl),
776 GNUNET_MY_query_param_uint64 (&rvalue),
777 GNUNET_MY_query_param_end
778 };
779
780 rc.plugin = plugin;
781 rc.proc = proc;
782 rc.proc_cls = proc_cls;
783
784 if (1 !=
785 GNUNET_MY_exec_prepared (plugin->mc,
786 plugin->max_repl,
787 params_get))
788 {
789 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
790 return;
791 }
792
793 if (GNUNET_OK !=
794 GNUNET_MY_extract_result (plugin->max_repl,
795 results_get))
796 {
797 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
798 return;
799 }
800 GNUNET_break (GNUNET_NO ==
801 GNUNET_MY_extract_result (plugin->max_repl,
802 NULL));
803 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
804 UINT64_MAX);
805
806 execute_select (plugin,
807 plugin->select_replication,
808 &repl_proc,
809 &rc,
810 params_select);
811}
812
813
814/**
815 * Get all of the keys in the datastore.
816 *
817 * @param cls closure
818 * @param proc function to call on each key
819 * @param proc_cls closure for @a proc
820 */
821static void
822mysql_plugin_get_keys (void *cls,
823 PluginKeyProcessor proc,
824 void *proc_cls)
825{
826 struct Plugin *plugin = cls;
827 int ret;
828 MYSQL_STMT *statement;
829 unsigned int cnt;
830 struct GNUNET_HashCode key;
831 struct GNUNET_HashCode last;
832 struct GNUNET_MY_QueryParam params_select[] = {
833 GNUNET_MY_query_param_end
834 };
835 struct GNUNET_MY_ResultSpec results_select[] = {
836 GNUNET_MY_result_spec_auto_from_type (&key),
837 GNUNET_MY_result_spec_end
838 };
839
840 GNUNET_assert (NULL != proc);
841 statement = GNUNET_MYSQL_statement_get_stmt (plugin->get_all_keys);
842 if (GNUNET_OK !=
843 GNUNET_MY_exec_prepared (plugin->mc,
844 plugin->get_all_keys,
845 params_select))
846 {
847 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
848 _ ("`%s' for `%s' failed at %s:%d with error: %s\n"),
849 "mysql_stmt_execute",
850 GET_ALL_KEYS,
851 __FILE__,
852 __LINE__,
853 mysql_stmt_error (statement));
854 GNUNET_MYSQL_statements_invalidate (plugin->mc);
855 proc (proc_cls, NULL, 0);
856 return;
857 }
858 memset (&last, 0, sizeof(last)); /* make static analysis happy */
859 ret = GNUNET_YES;
860 cnt = 0;
861 while (ret == GNUNET_YES)
862 {
863 ret = GNUNET_MY_extract_result (plugin->get_all_keys,
864 results_select);
865 if (0 != GNUNET_memcmp (&last,
866 &key))
867 {
868 if (0 != cnt)
869 proc (proc_cls,
870 &last,
871 cnt);
872 cnt = 1;
873 last = key;
874 }
875 else
876 {
877 cnt++;
878 }
879 }
880 if (0 != cnt)
881 proc (proc_cls,
882 &last,
883 cnt);
884 /* finally, let app know we are done */
885 proc (proc_cls,
886 NULL,
887 0);
888 if (GNUNET_SYSERR == ret)
889 {
890 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
891 _ ("`%s' failed at %s:%d with error: %s\n"),
892 "mysql_stmt_fetch",
893 __FILE__,
894 __LINE__,
895 mysql_stmt_error (statement));
896 GNUNET_MYSQL_statements_invalidate (plugin->mc);
897 return;
898 }
899}
900
901
902/**
903 * Context for #expi_proc() function.
904 */
905struct ExpiCtx
906{
907 /**
908 * Plugin handle.
909 */
910 struct Plugin *plugin;
911
912 /**
913 * Function to call for the result (or the NULL).
914 */
915 PluginDatumProcessor proc;
916
917 /**
918 * Closure for @e proc.
919 */
920 void *proc_cls;
921};
922
923
924/**
925 * Wrapper for the processor for #mysql_plugin_get_expiration().
926 * If no expired value was found, we do a second query for
927 * low-priority content.
928 *
929 * @param cls closure
930 * @param key key for the content
931 * @param size number of bytes in data
932 * @param data content stored
933 * @param type type of the content
934 * @param priority priority of the content
935 * @param anonymity anonymity-level for the content
936 * @param replication replication-level for the content
937 * @param expiration expiration time for the content
938 * @param uid unique identifier for the datum;
939 * maybe 0 if no unique identifier is available
940 * @return #GNUNET_SYSERR to abort the iteration, #GNUNET_OK to continue
941 * (continue on call to "next", of course),
942 * #GNUNET_NO to delete the item and continue (if supported)
943 */
944static int
945expi_proc (void *cls,
946 const struct GNUNET_HashCode *key,
947 uint32_t size,
948 const void *data,
949 enum GNUNET_BLOCK_Type type,
950 uint32_t priority,
951 uint32_t anonymity,
952 uint32_t replication,
953 struct GNUNET_TIME_Absolute expiration,
954 uint64_t uid)
955{
956 struct ExpiCtx *rc = cls;
957 struct Plugin *plugin = rc->plugin;
958 struct GNUNET_MY_QueryParam params_select[] = {
959 GNUNET_MY_query_param_end
960 };
961
962 if (NULL == key)
963 {
964 execute_select (plugin,
965 plugin->select_priority,
966 rc->proc,
967 rc->proc_cls,
968 params_select);
969 return GNUNET_SYSERR;
970 }
971 return rc->proc (rc->proc_cls,
972 key,
973 size,
974 data,
975 type,
976 priority,
977 anonymity,
978 replication,
979 expiration,
980 uid);
981}
982
983
984/**
985 * Get a random item for expiration.
986 * Call @a proc with all values ZERO or NULL if the datastore is empty.
987 *
988 * @param cls closure
989 * @param proc function to call the value (once only).
990 * @param proc_cls closure for @a proc
991 */
992static void
993mysql_plugin_get_expiration (void *cls,
994 PluginDatumProcessor proc,
995 void *proc_cls)
996{
997 struct Plugin *plugin = cls;
998 struct GNUNET_TIME_Absolute now = { 0 };
999 struct GNUNET_MY_QueryParam params_select[] = {
1000 GNUNET_MY_query_param_absolute_time (&now),
1001 GNUNET_MY_query_param_end
1002 };
1003 struct ExpiCtx rc;
1004
1005 rc.plugin = plugin;
1006 rc.proc = proc;
1007 rc.proc_cls = proc_cls;
1008 now = GNUNET_TIME_absolute_get ();
1009 execute_select (plugin,
1010 plugin->select_expiration,
1011 expi_proc,
1012 &rc,
1013 params_select);
1014}
1015
1016
1017/**
1018 * Drop database.
1019 *
1020 * @param cls the `struct Plugin *`
1021 */
1022static void
1023mysql_plugin_drop (void *cls)
1024{
1025 struct Plugin *plugin = cls;
1026
1027 if (GNUNET_OK !=
1028 GNUNET_MYSQL_statement_run (plugin->mc,
1029 "DROP TABLE gn090"))
1030 return; /* error */
1031 plugin->env->duc (plugin->env->cls, 0);
1032}
1033
1034
1035/**
1036 * Remove a particular key in the datastore.
1037 *
1038 * @param cls closure
1039 * @param key key for the content
1040 * @param size number of bytes in data
1041 * @param data content stored
1042 * @param cont continuation called with success or failure status
1043 * @param cont_cls continuation closure for @a cont
1044 */
1045static void
1046mysql_plugin_remove_key (void *cls,
1047 const struct GNUNET_HashCode *key,
1048 uint32_t size,
1049 const void *data,
1050 PluginRemoveCont cont,
1051 void *cont_cls)
1052{
1053 struct Plugin *plugin = cls;
1054 struct GNUNET_MY_QueryParam params_delete[] = {
1055 GNUNET_MY_query_param_auto_from_type (key),
1056 GNUNET_MY_query_param_fixed_size (data, size),
1057 GNUNET_MY_query_param_end
1058 };
1059
1060 if (GNUNET_OK !=
1061 GNUNET_MY_exec_prepared (plugin->mc,
1062 plugin->delete_entry_by_hash_value,
1063 params_delete))
1064 {
1065 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1066 "Removing key `%s' from gn090 table failed\n",
1067 GNUNET_h2s (key));
1068 cont (cont_cls,
1069 key,
1070 size,
1071 GNUNET_SYSERR,
1072 _ ("MySQL statement run failure"));
1073 return;
1074 }
1075
1076 MYSQL_STMT *stmt = GNUNET_MYSQL_statement_get_stmt (
1077 plugin->delete_entry_by_hash_value);
1078 my_ulonglong rows = mysql_stmt_affected_rows (stmt);
1079
1080 if (0 == rows)
1081 {
1082 cont (cont_cls,
1083 key,
1084 size,
1085 GNUNET_NO,
1086 NULL);
1087 return;
1088 }
1089 plugin->env->duc (plugin->env->cls,
1090 -size);
1091 cont (cont_cls,
1092 key,
1093 size,
1094 GNUNET_OK,
1095 NULL);
1096}
1097
1098
1099/**
1100 * Entry point for the plugin.
1101 *
1102 * @param cls the `struct GNUNET_DATASTORE_PluginEnvironment *`
1103 * @return our `struct Plugin *`
1104 */
1105void *
1106libgnunet_plugin_datastore_mysql_init (void *cls)
1107{
1108 struct GNUNET_DATASTORE_PluginEnvironment *env = cls;
1109 struct GNUNET_DATASTORE_PluginFunctions *api;
1110 struct Plugin *plugin;
1111
1112 plugin = GNUNET_new (struct Plugin);
1113 plugin->env = env;
1114 plugin->mc = GNUNET_MYSQL_context_create (env->cfg,
1115 "datastore-mysql");
1116 if (NULL == plugin->mc)
1117 {
1118 GNUNET_free (plugin);
1119 return NULL;
1120 }
1121#define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, a))
1122#define PINIT(a, b) (NULL == (a = GNUNET_MYSQL_statement_prepare (plugin->mc, \
1123 b)))
1124 if (MRUNS
1125 ("CREATE TABLE IF NOT EXISTS gn090 ("
1126 " repl INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1127 " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1128 " prio INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1129 " anonLevel INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1130 " expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
1131 " rvalue BIGINT UNSIGNED NOT NULL,"
1132 " hash BINARY(64) NOT NULL DEFAULT '',"
1133 " vhash BINARY(64) NOT NULL DEFAULT '',"
1134 " value BLOB NOT NULL DEFAULT '',"
1135 " uid BIGINT NOT NULL AUTO_INCREMENT,"
1136 " PRIMARY KEY (uid),"
1137 " INDEX idx_hash_type_uid (hash(64),type,rvalue),"
1138 " INDEX idx_prio (prio),"
1139 " INDEX idx_repl_rvalue (repl,rvalue),"
1140 " INDEX idx_expire (expire),"
1141 " INDEX idx_anonLevel_type_rvalue (anonLevel,type,rvalue)"
1142 ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1") ||
1143 PINIT (plugin->insert_entry, INSERT_ENTRY) ||
1144 PINIT (plugin->delete_entry_by_uid, DELETE_ENTRY_BY_UID) ||
1145 PINIT (plugin->delete_entry_by_hash_value, DELETE_ENTRY_BY_HASH_VALUE) ||
1146 PINIT (plugin->select_entry, SELECT_ENTRY) ||
1147 PINIT (plugin->select_entry_by_hash, SELECT_ENTRY_BY_HASH) ||
1148 PINIT (plugin->select_entry_by_hash_and_type,
1149 SELECT_ENTRY_BY_HASH_AND_TYPE) ||
1150 PINIT (plugin->get_size, SELECT_SIZE) ||
1151 PINIT (plugin->update_entry, UPDATE_ENTRY) ||
1152 PINIT (plugin->dec_repl, DEC_REPL) ||
1153 PINIT (plugin->zero_iter, SELECT_IT_NON_ANONYMOUS) ||
1154 PINIT (plugin->select_expiration, SELECT_IT_EXPIRATION) ||
1155 PINIT (plugin->select_priority, SELECT_IT_PRIORITY) ||
1156 PINIT (plugin->max_repl, SELECT_MAX_REPL) ||
1157 PINIT (plugin->get_all_keys, GET_ALL_KEYS) ||
1158 PINIT (plugin->select_replication, SELECT_IT_REPLICATION) ||
1159 false)
1160 {
1161 GNUNET_MYSQL_context_destroy (plugin->mc);
1162 GNUNET_free (plugin);
1163 return NULL;
1164 }
1165#undef PINIT
1166#undef MRUNS
1167
1168 api = GNUNET_new (struct GNUNET_DATASTORE_PluginFunctions);
1169 api->cls = plugin;
1170 api->estimate_size = &mysql_plugin_estimate_size;
1171 api->put = &mysql_plugin_put;
1172 api->get_key = &mysql_plugin_get_key;
1173 api->get_replication = &mysql_plugin_get_replication;
1174 api->get_expiration = &mysql_plugin_get_expiration;
1175 api->get_zero_anonymity = &mysql_plugin_get_zero_anonymity;
1176 api->get_keys = &mysql_plugin_get_keys;
1177 api->drop = &mysql_plugin_drop;
1178 api->remove_key = &mysql_plugin_remove_key;
1179 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "mysql",
1180 _ ("Mysql database running\n"));
1181 return api;
1182}
1183
1184
1185/**
1186 * Exit point from the plugin.
1187 *
1188 * @param cls our `struct Plugin *`
1189 * @return always NULL
1190 */
1191void *
1192libgnunet_plugin_datastore_mysql_done (void *cls)
1193{
1194 struct GNUNET_DATASTORE_PluginFunctions *api = cls;
1195 struct Plugin *plugin = api->cls;
1196
1197 GNUNET_MYSQL_context_destroy (plugin->mc);
1198 GNUNET_free (plugin);
1199 GNUNET_free (api);
1200 return NULL;
1201}
1202
1203
1204/* end of plugin_datastore_mysql.c */
diff --git a/src/datastore/test_datastore_api_data_mysql.conf b/src/datastore/test_datastore_api_data_mysql.conf
deleted file mode 100644
index c0052c5ea..000000000
--- a/src/datastore/test_datastore_api_data_mysql.conf
+++ /dev/null
@@ -1,10 +0,0 @@
1@INLINE@ test_defaults.conf
2[PATHS]
3GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-datastore-mysql/
4
5[datastore]
6QUOTA = 10 MB
7DATABASE = mysql
8
9[datastore-mysql]
10DATABASE = gnunetcheck
diff --git a/src/datastore/test_plugin_datastore_data_mysql.conf b/src/datastore/test_plugin_datastore_data_mysql.conf
deleted file mode 100644
index 07d3ec58e..000000000
--- a/src/datastore/test_plugin_datastore_data_mysql.conf
+++ /dev/null
@@ -1,9 +0,0 @@
1@INLINE@ test_defaults.conf
2[PATHS]
3GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-datastore-plugin-mysql/
4
5[datastore]
6DATABASE = mysql
7
8[datastore-mysql]
9DATABASE = gnunetcheck