diff options
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | configure.ac | 92 | ||||
-rw-r--r-- | po/POTFILES.in | 5 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/datastore/Makefile.am | 64 | ||||
-rw-r--r-- | src/datastore/perf_plugin_datastore_data_mysql.conf | 10 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_mysql.c | 1204 | ||||
-rw-r--r-- | src/datastore/test_datastore_api_data_mysql.conf | 10 | ||||
-rw-r--r-- | src/datastore/test_plugin_datastore_data_mysql.conf | 9 | ||||
-rw-r--r-- | src/include/Makefile.am | 3 | ||||
-rw-r--r-- | src/include/gnunet_my_lib.h | 511 | ||||
-rw-r--r-- | src/include/gnunet_mysql_compat.h.in | 57 | ||||
-rw-r--r-- | src/include/gnunet_mysql_lib.h | 151 | ||||
-rw-r--r-- | src/my/.gitignore | 1 | ||||
-rw-r--r-- | src/my/Makefile.am | 41 | ||||
-rw-r--r-- | src/my/meson.build | 15 | ||||
-rw-r--r-- | src/my/my.c | 270 | ||||
-rw-r--r-- | src/my/my_query_helper.c | 401 | ||||
-rw-r--r-- | src/my/my_result_helper.c | 868 | ||||
-rw-r--r-- | src/my/test_my.c | 301 | ||||
-rw-r--r-- | src/my/test_my.conf | 0 | ||||
-rw-r--r-- | src/mysql/Makefile.am | 18 | ||||
-rw-r--r-- | src/mysql/meson.build | 13 | ||||
-rw-r--r-- | src/mysql/mysql.c | 485 | ||||
-rw-r--r-- | src/regex/Makefile.am | 29 |
25 files changed, 15 insertions, 4553 deletions
@@ -121,7 +121,6 @@ Direct dependencies of GNUnet: | |||
121 | Dependencies of optional components/functionality: | 121 | Dependencies of optional components/functionality: |
122 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 122 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
123 | - Database plugins (alternatives to sqlite): | 123 | - Database plugins (alternatives to sqlite): |
124 | * mysql >= 5.1 | ||
125 | * postgres >= 9.5 | 124 | * postgres >= 9.5 |
126 | - Transport plugins: | 125 | - Transport plugins: |
127 | * bluez (bluetooth transport) | 126 | * bluez (bluetooth transport) |
@@ -315,9 +314,7 @@ traversal). | |||
315 | 314 | ||
316 | GNUnet requires the GNU MP library (https://www.gnu.org/software/gmp/) | 315 | GNUnet requires the GNU MP library (https://www.gnu.org/software/gmp/) |
317 | and libgcrypt (https://www.gnupg.org/). You can specify the path to | 316 | and libgcrypt (https://www.gnupg.org/). You can specify the path to |
318 | libgcrypt by passing "--with-gcrypt=PATH" to configure. You will also | 317 | libgcrypt by passing "--with-gcrypt=PATH" to configure. |
319 | need either sqlite (http://www.sqlite.org/), MySQL | ||
320 | (http://www.mysql.org/) or PostGres (http://www.postgres.org/). | ||
321 | 318 | ||
322 | If you install from source, you need to install GNU libextractor first | 319 | If you install from source, you need to install GNU libextractor first |
323 | (download from https://www.gnu.org/software/libextractor/). We also | 320 | (download from https://www.gnu.org/software/libextractor/). We also |
diff --git a/configure.ac b/configure.ac index 53a640291..34c8608f3 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -904,89 +904,6 @@ AM_CONDITIONAL([HAVE_POSTGRESQL], [test "x$postgres" = "x1"]) | |||
904 | AC_DEFINE_UNQUOTED([HAVE_POSTGRESQL], [$postgres], | 904 | AC_DEFINE_UNQUOTED([HAVE_POSTGRESQL], [$postgres], |
905 | [Define to 1 if Postgres is available]) | 905 | [Define to 1 if Postgres is available]) |
906 | 906 | ||
907 | # check for mysql | ||
908 | SAVE_LDFLAGS="$LDFLAGS" | ||
909 | SAVE_CPPFLAGS="$CPPFLAGS" | ||
910 | AC_ARG_WITH([mysql], | ||
911 | [AS_HELP_STRING([--with-mysql=PFX], [base of mysql installation])], | ||
912 | [AS_CASE([$withval], | ||
913 | [no], | ||
914 | [], | ||
915 | [yes|""], | ||
916 | [AC_CHECK_HEADERS([mysql/mysql.h], | ||
917 | [AC_CHECK_LIB([mysqlclient], [mysql_init], | ||
918 | [mysql=true], [mysql=false])])], | ||
919 | [LDFLAGS="-L$with_mysql/lib -L$with_mysql/lib/mysql $LDFLAGS $ZLIBS" | ||
920 | CPPFLAGS="-I$with_mysql/include $CPPFLAGS" | ||
921 | AC_CHECK_HEADERS([mysql/mysql.h], | ||
922 | [AC_CHECK_LIB([mysqlclient], [mysql_init], | ||
923 | [MYSQL_LDFLAGS="-L$with_mysql/lib -L$with_mysql/lib/mysql" | ||
924 | MYSQL_CPPFLAGS="-I$with_mysql/include" | ||
925 | mysql=true], | ||
926 | [mysql=false])])])], | ||
927 | [AS_IF([test -d "/usr/lib64/mysql"], | ||
928 | [MYSQL_LIBDIR="/usr/lib64/mysql"], | ||
929 | [AS_IF([test -d "/usr/lib/mysql"], | ||
930 | [MYSQL_LIBDIR="/usr/lib/mysql"], | ||
931 | [MYSQL_LIBDIR="/usr/lib"])]) | ||
932 | LDFLAGS="-L$MYSQL_LIBDIR $LDFLAGS $ZLIBS" | ||
933 | AC_CHECK_LIB([mysqlclient], [mysql_init], | ||
934 | [AC_CHECK_HEADERS([mysql/mysql.h], | ||
935 | [MYSQL_LDFLAGS="-L$MYSQL_LIBDIR" | ||
936 | mysql=true], | ||
937 | [mysql=false])], | ||
938 | [mysql=false])]) | ||
939 | AC_SUBST(MYSQL_LDFLAGS) | ||
940 | AC_SUBST(MYSQL_CPPFLAGS) | ||
941 | |||
942 | mysql_bool="bool" | ||
943 | # check for my_bool | ||
944 | AS_IF([test "x$mysql" = "xtrue"], | ||
945 | [AC_MSG_CHECKING([for my_bool]) | ||
946 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM( | ||
947 | [[#include <mysql/mysql.h>] | ||
948 | [typedef int my_bool;]])], # Hint: this fails if my_bool is defined already | ||
949 | [AC_MSG_RESULT([no]) | ||
950 | mysql_bool="bool"], | ||
951 | [AC_MSG_RESULT([yes]) | ||
952 | mysql_bool="my_bool"])]) | ||
953 | |||
954 | AC_SUBST([mysql_bool]) | ||
955 | |||
956 | # additional version checks for mysql | ||
957 | AS_IF([test "x$mysql" = "xtrue"], | ||
958 | [AC_MSG_CHECKING([for mysql version]) | ||
959 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM( | ||
960 | [[#include <mysql/mysql.h>]], | ||
961 | [[#if (MYSQL_VERSION_ID < 40100) | ||
962 | #error required at least version 4.1 | ||
963 | #endif]])], | ||
964 | [mysql=true], | ||
965 | [mysql=false]) | ||
966 | AS_IF([test "x$mysql" = "xfalse"], | ||
967 | [AC_MSG_RESULT([< 4.1]) | ||
968 | AC_MSG_RESULT([mysql version >= 4.1 required. Will not use MySQL])]) | ||
969 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM( | ||
970 | [[#include <mysql/mysql.h>]], | ||
971 | [[#if (MYSQL_VERSION_ID < 80000) | ||
972 | #error needs at least version 8.0 | ||
973 | #endif]])], | ||
974 | [mysql8=true], | ||
975 | [mysql8=false])]) | ||
976 | |||
977 | AS_IF([test "x$mysql" = "xtrue"], | ||
978 | [AS_IF([test "x$mysql8" = "xfalse"], | ||
979 | [AC_MSG_RESULT([between 4.1 and 8.0])], | ||
980 | [AC_MSG_RESULT([> 8.0]) | ||
981 | AC_DEFINE([HAVE_MYSQL8], [1], | ||
982 | [Define to 1 if MySQL is at least version 8])])]) | ||
983 | |||
984 | AM_CONDITIONAL([HAVE_MYSQL], [test "x$mysql" = "xtrue"]) | ||
985 | AM_CONDITIONAL([HAVE_MYSQLE], [false]) | ||
986 | |||
987 | AS_IF([test "x$sqlite3" = "x0" && test "x$mysql" = "xfalse" && test "x$postgres" = "x0"], | ||
988 | [AC_MSG_ERROR([GNUnet requires either SQLite, MySQL/MariaDB or PostgreSQL])]) | ||
989 | |||
990 | LDFLAGS="$SAVE_LDFLAGS" | 907 | LDFLAGS="$SAVE_LDFLAGS" |
991 | CPPFLAGS="$SAVE_CPPFLAGS" | 908 | CPPFLAGS="$SAVE_CPPFLAGS" |
992 | 909 | ||
@@ -1347,12 +1264,10 @@ src/identity/Makefile | |||
1347 | src/identity/identity.conf | 1264 | src/identity/identity.conf |
1348 | src/include/Makefile | 1265 | src/include/Makefile |
1349 | src/include/gnunet_config.h | 1266 | src/include/gnunet_config.h |
1350 | src/include/gnunet_mysql_compat.h | ||
1351 | src/integration-tests/Makefile | 1267 | src/integration-tests/Makefile |
1352 | src/json/Makefile | 1268 | src/json/Makefile |
1353 | src/hostlist/Makefile | 1269 | src/hostlist/Makefile |
1354 | src/my/Makefile | 1270 | src/my/Makefile |
1355 | src/mysql/Makefile | ||
1356 | src/namecache/Makefile | 1271 | src/namecache/Makefile |
1357 | src/namecache/namecache.conf | 1272 | src/namecache/namecache.conf |
1358 | src/namestore/Makefile | 1273 | src/namestore/Makefile |
@@ -1432,7 +1347,6 @@ pkgconfig/gnunetidentity.pc | |||
1432 | pkgconfig/gnunetjson.pc | 1347 | pkgconfig/gnunetjson.pc |
1433 | pkgconfig/gnunetmessenger.pc | 1348 | pkgconfig/gnunetmessenger.pc |
1434 | pkgconfig/gnunetmicrophone.pc | 1349 | pkgconfig/gnunetmicrophone.pc |
1435 | pkgconfig/gnunetmysql.pc | ||
1436 | pkgconfig/gnunetnamestore.pc | 1350 | pkgconfig/gnunetnamestore.pc |
1437 | pkgconfig/gnunetnat.pc | 1351 | pkgconfig/gnunetnat.pc |
1438 | pkgconfig/gnunetnse.pc | 1352 | pkgconfig/gnunetnse.pc |
@@ -1574,11 +1488,6 @@ AS_IF([test "x$sqlite3" = "x1"], | |||
1574 | features_msg="sqlite $features_msg"], | 1488 | features_msg="sqlite $features_msg"], |
1575 | [sqlite_msg="no"]) | 1489 | [sqlite_msg="no"]) |
1576 | 1490 | ||
1577 | AS_IF([test "x$mysql" = "xtrue"], | ||
1578 | [mysql_msg="yes" | ||
1579 | features_msg="mysql $features_msg"], | ||
1580 | [mysql_msg="no"]) | ||
1581 | |||
1582 | AS_IF([test "x$postgres" = "x1"], | 1491 | AS_IF([test "x$postgres" = "x1"], |
1583 | [postgres_msg="yes" | 1492 | [postgres_msg="yes" |
1584 | features_msg="postgres $features_msg"], | 1493 | features_msg="postgres $features_msg"], |
@@ -1607,7 +1516,6 @@ Build Target: ${build_target} | |||
1607 | Default Interface: ${interface_msg} | 1516 | Default Interface: ${interface_msg} |
1608 | 1517 | ||
1609 | sqlite3: ${sqlite_msg} | 1518 | sqlite3: ${sqlite_msg} |
1610 | MySQL: ${mysql_msg} | ||
1611 | PostgreSQL: ${postgres_msg} | 1519 | PostgreSQL: ${postgres_msg} |
1612 | 1520 | ||
1613 | cURL TLS backend: ${curl_tls_backend} | 1521 | cURL TLS backend: ${curl_tls_backend} |
diff --git a/po/POTFILES.in b/po/POTFILES.in index bc8be7a54..3d6c2f6d1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in | |||
@@ -89,7 +89,6 @@ src/datastore/datastore_api.c | |||
89 | src/datastore/gnunet-datastore.c | 89 | src/datastore/gnunet-datastore.c |
90 | src/datastore/gnunet-service-datastore.c | 90 | src/datastore/gnunet-service-datastore.c |
91 | src/datastore/plugin_datastore_heap.c | 91 | src/datastore/plugin_datastore_heap.c |
92 | src/datastore/plugin_datastore_mysql.c | ||
93 | src/datastore/plugin_datastore_postgres.c | 92 | src/datastore/plugin_datastore_postgres.c |
94 | src/datastore/plugin_datastore_sqlite.c | 93 | src/datastore/plugin_datastore_sqlite.c |
95 | src/datastore/plugin_datastore_template.c | 94 | src/datastore/plugin_datastore_template.c |
@@ -233,10 +232,6 @@ src/messenger/messenger_api_util.c | |||
233 | src/messenger/plugin_gnsrecord_messenger.c | 232 | src/messenger/plugin_gnsrecord_messenger.c |
234 | src/messenger/testing_messenger_barrier.c | 233 | src/messenger/testing_messenger_barrier.c |
235 | src/messenger/testing_messenger_setup.c | 234 | src/messenger/testing_messenger_setup.c |
236 | src/my/my.c | ||
237 | src/my/my_query_helper.c | ||
238 | src/my/my_result_helper.c | ||
239 | src/mysql/mysql.c | ||
240 | src/namecache/gnunet-namecache.c | 235 | src/namecache/gnunet-namecache.c |
241 | src/namecache/gnunet-service-namecache.c | 236 | src/namecache/gnunet-service-namecache.c |
242 | src/namecache/namecache_api.c | 237 | src/namecache/namecache_api.c |
diff --git a/src/Makefile.am b/src/Makefile.am index d7c0b51f0..8fb984d4b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -25,10 +25,6 @@ if HAVE_SQLITE | |||
25 | SQLITE_DIR = sq | 25 | SQLITE_DIR = sq |
26 | endif | 26 | endif |
27 | 27 | ||
28 | if HAVE_MYSQL | ||
29 | MYSQL_DIR = mysql my | ||
30 | endif | ||
31 | |||
32 | if HAVE_POSTGRESQL | 28 | if HAVE_POSTGRESQL |
33 | POSTGRES_DIR = pq | 29 | POSTGRES_DIR = pq |
34 | endif | 30 | endif |
@@ -50,7 +46,6 @@ SUBDIRS = \ | |||
50 | $(REST_DIR) \ | 46 | $(REST_DIR) \ |
51 | peerinfo \ | 47 | peerinfo \ |
52 | $(SQLITE_DIR) \ | 48 | $(SQLITE_DIR) \ |
53 | $(MYSQL_DIR) \ | ||
54 | $(POSTGRES_DIR) \ | 49 | $(POSTGRES_DIR) \ |
55 | datacache \ | 50 | datacache \ |
56 | datastore \ | 51 | datastore \ |
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 | ||
59 | if HAVE_MYSQL | ||
60 | MYSQL_PLUGIN = libgnunet_plugin_datastore_mysql.la | ||
61 | if HAVE_BENCHMARKS | ||
62 | MYSQL_BENCHMARKS = \ | ||
63 | perf_datastore_api_mysql \ | ||
64 | perf_plugin_datastore_mysql | ||
65 | endif | ||
66 | MYSQL_TESTS = \ | ||
67 | test_datastore_api_mysql \ | ||
68 | test_datastore_api_management_mysql \ | ||
69 | test_plugin_datastore_mysql \ | ||
70 | $(MYSQL_BENCHMARKS) | ||
71 | endif | ||
72 | if HAVE_SQLITE | 59 | if HAVE_SQLITE |
73 | SQLITE_PLUGIN = libgnunet_plugin_datastore_sqlite.la | 60 | SQLITE_PLUGIN = libgnunet_plugin_datastore_sqlite.la |
74 | if HAVE_BENCHMARKS | 61 | if HAVE_BENCHMARKS |
@@ -98,7 +85,6 @@ endif | |||
98 | 85 | ||
99 | plugin_LTLIBRARIES = \ | 86 | plugin_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 | ||
131 | libgnunet_plugin_datastore_mysql_la_SOURCES = \ | ||
132 | plugin_datastore_mysql.c | ||
133 | libgnunet_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 | ||
138 | libgnunet_plugin_datastore_mysql_la_LDFLAGS = \ | ||
139 | $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient | ||
140 | libgnunet_plugin_datastore_mysql_la_CPPFLAGS = \ | ||
141 | $(MYSQL_CPPFLAGS) $(AM_CPPFLAGS) | ||
142 | |||
143 | libgnunet_plugin_datastore_postgres_la_SOURCES = \ | 117 | libgnunet_plugin_datastore_postgres_la_SOURCES = \ |
144 | plugin_datastore_postgres.c | 118 | plugin_datastore_postgres.c |
145 | libgnunet_plugin_datastore_postgres_la_LIBADD = \ | 119 | libgnunet_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 | ||
173 | if ENABLE_TEST_RUN | 146 | if 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 | ||
246 | test_datastore_api_mysql_SOURCES = \ | ||
247 | test_datastore_api.c | ||
248 | test_datastore_api_mysql_LDADD = \ | ||
249 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
250 | libgnunetdatastore.la \ | ||
251 | $(top_builddir)/src/util/libgnunetutil.la | ||
252 | |||
253 | test_datastore_api_management_mysql_SOURCES = \ | ||
254 | test_datastore_api_management.c | ||
255 | test_datastore_api_management_mysql_LDADD = \ | ||
256 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
257 | libgnunetdatastore.la \ | ||
258 | $(top_builddir)/src/util/libgnunetutil.la | ||
259 | |||
260 | perf_datastore_api_mysql_SOURCES = \ | ||
261 | perf_datastore_api.c | ||
262 | perf_datastore_api_mysql_LDADD = \ | ||
263 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
264 | libgnunetdatastore.la \ | ||
265 | $(top_builddir)/src/util/libgnunetutil.la | ||
266 | |||
267 | test_plugin_datastore_mysql_SOURCES = \ | ||
268 | test_plugin_datastore.c | ||
269 | test_plugin_datastore_mysql_LDADD = \ | ||
270 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
271 | $(top_builddir)/src/util/libgnunetutil.la | ||
272 | |||
273 | perf_plugin_datastore_mysql_SOURCES = \ | ||
274 | perf_plugin_datastore.c | ||
275 | perf_plugin_datastore_mysql_LDADD = \ | ||
276 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
277 | $(top_builddir)/src/util/libgnunetutil.la | ||
278 | |||
279 | |||
280 | test_datastore_api_postgres_SOURCES = \ | 219 | test_datastore_api_postgres_SOURCES = \ |
281 | test_datastore_api.c | 220 | test_datastore_api.c |
282 | test_datastore_api_postgres_LDADD = \ | 221 | test_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] | ||
3 | GNUNET_TEST_HOME = $GNUNET_TMP/perf-gnunet-datastore-mysql/ | ||
4 | |||
5 | [datastore] | ||
6 | DATABASE = mysql | ||
7 | |||
8 | [datastore-mysql] | ||
9 | DATABASE = 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 "Database changed" it probably works. | ||
93 | * | ||
94 | * [If you get "ERROR 2002: Can't connect to local MySQL server | ||
95 | * through socket '/tmp/mysql.sock' (2)" it may be resolvable by | ||
96 | * "ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock" | ||
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 | */ | ||
133 | struct 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 | */ | ||
243 | static int | ||
244 | do_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 | */ | ||
278 | static void | ||
279 | mysql_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 | */ | ||
331 | static void | ||
332 | mysql_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 | */ | ||
455 | static void | ||
456 | execute_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 | */ | ||
548 | static void | ||
549 | mysql_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 | */ | ||
631 | static void | ||
632 | mysql_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 | */ | ||
658 | struct 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 | */ | ||
697 | static int | ||
698 | repl_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 | */ | ||
756 | static void | ||
757 | mysql_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 | */ | ||
821 | static void | ||
822 | mysql_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 | */ | ||
905 | struct 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 | */ | ||
944 | static int | ||
945 | expi_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 | */ | ||
992 | static void | ||
993 | mysql_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 | */ | ||
1022 | static void | ||
1023 | mysql_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 | */ | ||
1045 | static void | ||
1046 | mysql_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 | */ | ||
1105 | void * | ||
1106 | libgnunet_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 | */ | ||
1191 | void * | ||
1192 | libgnunet_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] | ||
3 | GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-datastore-mysql/ | ||
4 | |||
5 | [datastore] | ||
6 | QUOTA = 10 MB | ||
7 | DATABASE = mysql | ||
8 | |||
9 | [datastore-mysql] | ||
10 | DATABASE = 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] | ||
3 | GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-datastore-plugin-mysql/ | ||
4 | |||
5 | [datastore] | ||
6 | DATABASE = mysql | ||
7 | |||
8 | [datastore-mysql] | ||
9 | DATABASE = gnunetcheck | ||
diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 8519883c9..ef18ab01b 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am | |||
@@ -75,9 +75,6 @@ gnunetinclude_HEADERS = \ | |||
75 | gnunet_microphone_lib.h \ | 75 | gnunet_microphone_lib.h \ |
76 | gnunet_mst_lib.h \ | 76 | gnunet_mst_lib.h \ |
77 | gnunet_mq_lib.h \ | 77 | gnunet_mq_lib.h \ |
78 | gnunet_my_lib.h \ | ||
79 | gnunet_mysql_compat.h \ | ||
80 | gnunet_mysql_lib.h \ | ||
81 | gnunet_namecache_plugin.h \ | 78 | gnunet_namecache_plugin.h \ |
82 | gnunet_namecache_service.h \ | 79 | gnunet_namecache_service.h \ |
83 | gnunet_namestore_plugin.h \ | 80 | gnunet_namestore_plugin.h \ |
diff --git a/src/include/gnunet_my_lib.h b/src/include/gnunet_my_lib.h deleted file mode 100644 index 283b2f7e6..000000000 --- a/src/include/gnunet_my_lib.h +++ /dev/null | |||
@@ -1,511 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 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 | */ | ||
20 | /** | ||
21 | * @addtogroup lib_extra | ||
22 | * @{ | ||
23 | * | ||
24 | * @author Christian Grothoff | ||
25 | * @author Christophe Genevey | ||
26 | * @author Martin Schanzenbach | ||
27 | * | ||
28 | * @file | ||
29 | * Helper library to access a MySQL database | ||
30 | * | ||
31 | * @defgroup mysql MySQL library | ||
32 | * Helper library to access a MySQL database. | ||
33 | * @{ | ||
34 | */ | ||
35 | #ifndef GNUNET_MY_LIB_H | ||
36 | #define GNUNET_MY_LIB_H | ||
37 | |||
38 | |||
39 | #include "gnunet_util_lib.h" | ||
40 | #include "gnunet_mysql_lib.h" | ||
41 | #include <mysql/mysql.h> | ||
42 | |||
43 | #ifndef MYSQL_BOOL | ||
44 | #error "You need to define MYSQL_BOOL. See (or include) gnunet_mysql_compat.h" | ||
45 | #endif | ||
46 | |||
47 | #ifdef __cplusplus | ||
48 | extern "C" | ||
49 | { | ||
50 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
51 | } | ||
52 | #endif | ||
53 | #endif | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Information we pass to #GNUNET_MY_exec_prepared() to | ||
58 | * initialize the arguments of the prepared statement. | ||
59 | */ | ||
60 | struct GNUNET_MY_QueryParam; | ||
61 | |||
62 | |||
63 | /** | ||
64 | * Function called to convert input argument into SQL parameters. | ||
65 | * | ||
66 | * @param cls closure | ||
67 | * @param pq data about the query | ||
68 | * @param qbind array of parameters to initialize | ||
69 | * @return -1 on error | ||
70 | */ | ||
71 | typedef int | ||
72 | (*GNUNET_MY_QueryConverter)(void *cls, | ||
73 | const struct GNUNET_MY_QueryParam *qp, | ||
74 | MYSQL_BIND *qbind); | ||
75 | |||
76 | |||
77 | /** | ||
78 | * Function called to cleanup result data. | ||
79 | * | ||
80 | * @param cls closure | ||
81 | * @param rs spec to clean up | ||
82 | */ | ||
83 | typedef void | ||
84 | (*GNUNET_MY_QueryCleanup)(void *cls, | ||
85 | MYSQL_BIND *qbind); | ||
86 | /** | ||
87 | * Information we pass to #GNUNET_MY_exec_prepared() to | ||
88 | * initialize the arguments of the prepared statement. | ||
89 | */ | ||
90 | |||
91 | |||
92 | struct GNUNET_MY_QueryParam | ||
93 | { | ||
94 | /** | ||
95 | * Function to call for the type conversion. | ||
96 | */ | ||
97 | GNUNET_MY_QueryConverter conv; | ||
98 | |||
99 | /** | ||
100 | * Function to call for cleaning up the query. Can be NULL. | ||
101 | */ | ||
102 | GNUNET_MY_QueryCleanup cleaner; | ||
103 | |||
104 | /** | ||
105 | * Closure for @e conv. | ||
106 | */ | ||
107 | void *conv_cls; | ||
108 | |||
109 | /** | ||
110 | * Number of arguments the @a conv converter expects to initialize. | ||
111 | */ | ||
112 | unsigned int num_params; | ||
113 | |||
114 | /** | ||
115 | * Information to pass to @e conv. | ||
116 | */ | ||
117 | const void *data; | ||
118 | |||
119 | /** | ||
120 | * Information to pass to @e conv. Size of @a data. | ||
121 | */ | ||
122 | unsigned long data_len; | ||
123 | }; | ||
124 | |||
125 | /** | ||
126 | * End of query parameter specification. | ||
127 | * | ||
128 | * @return array last entry for the result specification to use | ||
129 | */ | ||
130 | #define GNUNET_MY_query_param_end { NULL, NULL, NULL, 0, NULL, 0 } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Generate query parameter for a buffer @a ptr of | ||
135 | * @a ptr_size bytes.FG | ||
136 | * | ||
137 | * @param ptr pointer to the query parameter to pass | ||
138 | * @param ptr_size number of bytes in @a ptr | ||
139 | */ | ||
140 | struct GNUNET_MY_QueryParam | ||
141 | GNUNET_MY_query_param_fixed_size (const void *ptr, | ||
142 | size_t ptr_size); | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Run a prepared SELECT statement. | ||
147 | * | ||
148 | * @param mc mysql context | ||
149 | * @param sh handle to SELECT statement | ||
150 | * @param params parameters to the statement | ||
151 | * @return TBD | ||
152 | */ | ||
153 | int | ||
154 | GNUNET_MY_exec_prepared (struct GNUNET_MYSQL_Context *mc, | ||
155 | struct GNUNET_MYSQL_StatementHandle *sh, | ||
156 | struct GNUNET_MY_QueryParam *params); | ||
157 | |||
158 | |||
159 | /** | ||
160 | * Information we pass to #GNUNET_MY_extract_result() to | ||
161 | * initialize the arguments of the prepared statement. | ||
162 | */ | ||
163 | struct GNUNET_MY_ResultParam; | ||
164 | |||
165 | /** | ||
166 | * Information we pass to #GNUNET_MY_extract_result() to | ||
167 | * initialize the arguments of the prepared statement. | ||
168 | */ | ||
169 | struct GNUNET_MY_ResultSpec; | ||
170 | |||
171 | /** | ||
172 | * Function called to convert input argument into SQL parameters. | ||
173 | * | ||
174 | * @param cls closure | ||
175 | * @param[in,out] rs | ||
176 | * @param stmt the mysql statement that is being run | ||
177 | * @param column the column that is being processed | ||
178 | * @param[out] results | ||
179 | * @return -1 on error | ||
180 | */ | ||
181 | typedef int | ||
182 | (*GNUNET_MY_ResultConverter)(void *cls, | ||
183 | struct GNUNET_MY_ResultSpec *rs, | ||
184 | MYSQL_STMT *stmt, | ||
185 | unsigned int column, | ||
186 | MYSQL_BIND *results); | ||
187 | |||
188 | /** | ||
189 | * Function called to cleanup result data. | ||
190 | * | ||
191 | * @param cls closure | ||
192 | * @param rs spec to clean up | ||
193 | */ | ||
194 | typedef void | ||
195 | (*GNUNET_MY_ResultCleanup)(void *cls, | ||
196 | struct GNUNET_MY_ResultSpec *rs); | ||
197 | |||
198 | |||
199 | /** | ||
200 | * Information we pass to #GNUNET_MY_extract_result() to | ||
201 | * initialize the arguments of the prepared statement. | ||
202 | */ | ||
203 | struct GNUNET_MY_ResultSpec | ||
204 | { | ||
205 | /** | ||
206 | * Function to call to initialize the MYSQL_BIND array. | ||
207 | */ | ||
208 | GNUNET_MY_ResultConverter pre_conv; | ||
209 | |||
210 | /** | ||
211 | * Function to call for converting the result. Can be NULL. | ||
212 | */ | ||
213 | GNUNET_MY_ResultConverter post_conv; | ||
214 | |||
215 | /** | ||
216 | * Function to call for cleaning up the result. Can be NULL. | ||
217 | */ | ||
218 | GNUNET_MY_ResultCleanup cleaner; | ||
219 | |||
220 | /** | ||
221 | * Closure for @e conv. | ||
222 | */ | ||
223 | void *conv_cls; | ||
224 | |||
225 | /** | ||
226 | * Destination for the data. | ||
227 | */ | ||
228 | void *dst; | ||
229 | |||
230 | /** | ||
231 | * Allowed size for the data, 0 for variable-size | ||
232 | * (in this case, the type of @e dst is a `void **` | ||
233 | * and we need to allocate a buffer of the right size). | ||
234 | */ | ||
235 | size_t dst_size; | ||
236 | |||
237 | /** | ||
238 | * Where to store actual size of the result. | ||
239 | */ | ||
240 | size_t *result_size; | ||
241 | |||
242 | /** | ||
243 | * How many fields does this result specification occupy | ||
244 | * in the result returned by MySQL. | ||
245 | */ | ||
246 | unsigned int num_fields; | ||
247 | |||
248 | /** | ||
249 | * Location where we temporarily store the output buffer | ||
250 | * length from MySQL. Internal to libgnunetmy. | ||
251 | */ | ||
252 | unsigned long mysql_bind_output_length; | ||
253 | |||
254 | /** | ||
255 | * Memory for MySQL to notify us about NULL values. | ||
256 | */ | ||
257 | MYSQL_BOOL is_null; | ||
258 | }; | ||
259 | |||
260 | |||
261 | /** | ||
262 | * End of result speceter specification. | ||
263 | * | ||
264 | * @return array last entry for the result specification to use | ||
265 | */ | ||
266 | #define GNUNET_MY_result_spec_end { NULL, NULL, NULL, 0, NULL, 0, 0 } | ||
267 | |||
268 | |||
269 | /** | ||
270 | * Obtain fixed size result of @a ptr_size bytes from | ||
271 | * MySQL, store in already allocated buffer at @a ptr. | ||
272 | * | ||
273 | * @spec ptr where to write the result | ||
274 | * @param ptr_size number of bytes available at @a ptr | ||
275 | */ | ||
276 | struct GNUNET_MY_ResultSpec | ||
277 | GNUNET_MY_result_spec_fixed_size (void *ptr, | ||
278 | size_t ptr_size); | ||
279 | |||
280 | /** | ||
281 | * Generate query parameter for a string | ||
282 | * | ||
283 | * @param ptr pointer to the string query parameter to pass | ||
284 | */ | ||
285 | struct GNUNET_MY_QueryParam | ||
286 | GNUNET_MY_query_param_string (const char *ptr); | ||
287 | |||
288 | /** | ||
289 | * Generate fixed-size query parameter with size determined | ||
290 | * by variable type. | ||
291 | * | ||
292 | * @param x pointer to the query parameter to pass | ||
293 | */ | ||
294 | #define GNUNET_MY_query_param_auto_from_type( \ | ||
295 | x) GNUNET_MY_query_param_fixed_size ((x), sizeof(*(x))) | ||
296 | |||
297 | /** | ||
298 | * Generate query parameter for an RSA public key. The | ||
299 | * database must contain a BLOB type in the respective position. | ||
300 | * | ||
301 | * @param x the query parameter to pass | ||
302 | * @return array entry for the query parameters to use | ||
303 | */ | ||
304 | struct GNUNET_MY_QueryParam | ||
305 | GNUNET_MY_query_param_rsa_public_key (const struct | ||
306 | GNUNET_CRYPTO_RsaPublicKey *x); | ||
307 | |||
308 | /** | ||
309 | * Generate query parameter for an RSA signature. The | ||
310 | * database must contain a BLOB type in the respective position | ||
311 | * | ||
312 | *@param x the query parameter to pass | ||
313 | *@return array entry for the query parameters to use | ||
314 | */ | ||
315 | struct GNUNET_MY_QueryParam | ||
316 | GNUNET_MY_query_param_rsa_signature (const struct | ||
317 | GNUNET_CRYPTO_RsaSignature *x); | ||
318 | |||
319 | /** | ||
320 | * Generate query parameter for an absolute time value. | ||
321 | * The database must store a 64-bit integer. | ||
322 | * | ||
323 | *@param x pointer to the query parameter to pass | ||
324 | *@return array entry for the query parameters to use | ||
325 | */ | ||
326 | struct GNUNET_MY_QueryParam | ||
327 | GNUNET_MY_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | ||
328 | |||
329 | |||
330 | /** | ||
331 | * Generate query parameter for an absolute time value. | ||
332 | * The database must store a 64-bit integer. | ||
333 | * | ||
334 | *@param x pointer to the query parameter to pass | ||
335 | */ | ||
336 | struct GNUNET_MY_QueryParam | ||
337 | GNUNET_MY_query_param_absolute_time_nbo (const struct | ||
338 | GNUNET_TIME_AbsoluteNBO *x); | ||
339 | |||
340 | /** | ||
341 | * Generate query parameter for an uint16_t in host byte order. | ||
342 | * | ||
343 | * @param x pointer to the query parameter to pass | ||
344 | */ | ||
345 | struct GNUNET_MY_QueryParam | ||
346 | GNUNET_MY_query_param_uint16 (const uint16_t *x); | ||
347 | |||
348 | /** | ||
349 | * Generate query parameter for an uint32_t in host byte order | ||
350 | * | ||
351 | * @param x pointer to the query parameter to pass | ||
352 | */ | ||
353 | struct GNUNET_MY_QueryParam | ||
354 | GNUNET_MY_query_param_uint32 (const uint32_t *x); | ||
355 | |||
356 | /** | ||
357 | * Generate query parameter for an uint64_t in host byte order | ||
358 | * | ||
359 | * @param x pointer to the query parameter to pass | ||
360 | */ | ||
361 | struct GNUNET_MY_QueryParam | ||
362 | GNUNET_MY_query_param_uint64 (const uint64_t *x); | ||
363 | |||
364 | /** | ||
365 | * We expect a fixed-size result, with size determined by the type of `* dst` | ||
366 | * | ||
367 | * @spec name name of the field in the table | ||
368 | * @spec dst point to where to store the result, type fits expected result size | ||
369 | * @return array entry for the result specification to use | ||
370 | */ | ||
371 | #define GNUNET_MY_result_spec_auto_from_type( \ | ||
372 | dst) GNUNET_MY_result_spec_fixed_size ((dst), sizeof(*(dst))) | ||
373 | |||
374 | |||
375 | /** | ||
376 | * Variable-size result expected | ||
377 | * | ||
378 | * @param[out] dst where to store the result, allocated | ||
379 | * @param[out] ptr_size where to store the size of @a dst | ||
380 | * @return array entry for the result specification to use | ||
381 | */ | ||
382 | struct GNUNET_MY_ResultSpec | ||
383 | GNUNET_MY_result_spec_variable_size (void **dst, | ||
384 | size_t *ptr_size); | ||
385 | |||
386 | /** | ||
387 | * RSA public key expected | ||
388 | * | ||
389 | * @param name name of the field in the table | ||
390 | * @param[out] rsa where to store the result | ||
391 | * @return array entry for the result specification to use | ||
392 | */ | ||
393 | struct GNUNET_MY_ResultSpec | ||
394 | GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa); | ||
395 | |||
396 | |||
397 | /** | ||
398 | * RSA signature expected. | ||
399 | * | ||
400 | * @param[out] sig where to store the result; | ||
401 | * @return array entry for the result specification to use | ||
402 | */ | ||
403 | struct GNUNET_MY_ResultSpec | ||
404 | GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig); | ||
405 | |||
406 | /** | ||
407 | * 0- terminated string exprected. | ||
408 | * | ||
409 | * @param[out] dst where to store the result, allocated | ||
410 | * @return array entry for the result specification to use | ||
411 | */ | ||
412 | struct GNUNET_MY_ResultSpec | ||
413 | GNUNET_MY_result_spec_string (char **dst); | ||
414 | |||
415 | /** | ||
416 | * Absolute time expected | ||
417 | * | ||
418 | * @param name name of the field in the table | ||
419 | * @param[out] at where to store the result | ||
420 | * @return array entry for the result specification to use | ||
421 | */ | ||
422 | struct GNUNET_MY_ResultSpec | ||
423 | GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at); | ||
424 | |||
425 | /** | ||
426 | * Absolute time in network byte order expected | ||
427 | * | ||
428 | * @param[out] at where to store the result | ||
429 | * @return array entry for the result specification to use | ||
430 | */ | ||
431 | struct GNUNET_MY_ResultSpec | ||
432 | GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at); | ||
433 | |||
434 | /** | ||
435 | * uint16_t expected | ||
436 | * | ||
437 | * @param[out] u16 where to store the result | ||
438 | * @return array entry for the result specification to use | ||
439 | */ | ||
440 | struct GNUNET_MY_ResultSpec | ||
441 | GNUNET_MY_result_spec_uint16 (uint16_t *u16); | ||
442 | |||
443 | /** | ||
444 | * uint32_t expected | ||
445 | * | ||
446 | * @param[out] u32 where to store the result | ||
447 | * @return array entry for the result specification to use | ||
448 | */ | ||
449 | struct GNUNET_MY_ResultSpec | ||
450 | GNUNET_MY_result_spec_uint32 (uint32_t *u32); | ||
451 | |||
452 | /** | ||
453 | * uint64_t expected. | ||
454 | * | ||
455 | * @param[out] u64 where to store the result | ||
456 | * @return array entry for the result specification to use | ||
457 | */ | ||
458 | struct GNUNET_MY_ResultSpec | ||
459 | GNUNET_MY_result_spec_uint64 (uint64_t *u64); | ||
460 | |||
461 | |||
462 | /** | ||
463 | * Extract results from a query result according to the given | ||
464 | * specification. Always fetches the next row. | ||
465 | * | ||
466 | * @param sh statement that returned results | ||
467 | * @param rs specification to extract for | ||
468 | * @return | ||
469 | * #GNUNET_YES if all results could be extracted | ||
470 | * #GNUNET_NO if there is no more data in the result set | ||
471 | * #GNUNET_SYSERR if a result was invalid | ||
472 | */ | ||
473 | int | ||
474 | GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, | ||
475 | struct GNUNET_MY_ResultSpec *specs); | ||
476 | |||
477 | |||
478 | /** | ||
479 | * Free all memory that was allocated in @a qp during | ||
480 | * #GNUNET_MY_exect_prepared(). | ||
481 | * | ||
482 | * @param qp query specification to clean up | ||
483 | * @param qbind mysql query | ||
484 | */ | ||
485 | void | ||
486 | GNUNET_MY_cleanup_query (struct GNUNET_MY_QueryParam *qp, | ||
487 | MYSQL_BIND *qbind); | ||
488 | |||
489 | |||
490 | /** | ||
491 | * Free all memory that was allocated in @a rs during | ||
492 | * #GNUNET_MY_extract_result(). | ||
493 | * | ||
494 | * @param rs reult specification to clean up | ||
495 | */ | ||
496 | void | ||
497 | GNUNET_MY_cleanup_result (struct GNUNET_MY_ResultSpec *rs); | ||
498 | |||
499 | |||
500 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
501 | { | ||
502 | #endif | ||
503 | #ifdef __cplusplus | ||
504 | } | ||
505 | #endif | ||
506 | |||
507 | #endif | ||
508 | |||
509 | /** @} */ /* end of group */ | ||
510 | |||
511 | /** @} */ /* end of group addition to lib_extra */ | ||
diff --git a/src/include/gnunet_mysql_compat.h.in b/src/include/gnunet_mysql_compat.h.in deleted file mode 100644 index 6218386aa..000000000 --- a/src/include/gnunet_mysql_compat.h.in +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2022 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 | * @author Martin Schanzenbach | ||
22 | * | ||
23 | * @file | ||
24 | * MySQL/MariaDB compatibility insanity helper header | ||
25 | * Note: gnunet_mysql_compat.h is AUTOGENERATED from gnunet_mysql_compat.h.in | ||
26 | * Please do not modify or commit gnunet_mysql_compat.h | ||
27 | * | ||
28 | * @defgroup mysql MySQL library | ||
29 | * Helper library to access a MySQL database. | ||
30 | * @{ | ||
31 | */ | ||
32 | #ifndef GNUNET_MYSQL_COMPAT_H | ||
33 | #define GNUNET_MYSQL_COMPAT_H | ||
34 | |||
35 | |||
36 | #include <mysql/mysql.h> | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | extern "C" | ||
40 | { | ||
41 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
42 | } | ||
43 | #endif | ||
44 | #endif | ||
45 | |||
46 | #define MYSQL_BOOL @mysql_bool@ | ||
47 | |||
48 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
49 | { | ||
50 | #endif | ||
51 | #ifdef __cplusplus | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | #endif | ||
56 | |||
57 | /** @} */ /* end of group */ | ||
diff --git a/src/include/gnunet_mysql_lib.h b/src/include/gnunet_mysql_lib.h deleted file mode 100644 index 52be3ff11..000000000 --- a/src/include/gnunet_mysql_lib.h +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012 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 | * @author Christian Grothoff | ||
22 | * | ||
23 | * @file | ||
24 | * Helper library to access a MySQL database | ||
25 | * | ||
26 | * @defgroup mysql MySQL library | ||
27 | * Helper library to access a MySQL database. | ||
28 | * @{ | ||
29 | */ | ||
30 | #ifndef GNUNET_MYSQL_LIB_H | ||
31 | #define GNUNET_MYSQL_LIB_H | ||
32 | |||
33 | |||
34 | #include "gnunet_util_lib.h" | ||
35 | #include <mysql/mysql.h> | ||
36 | |||
37 | #ifdef __cplusplus | ||
38 | extern "C" | ||
39 | { | ||
40 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
41 | } | ||
42 | #endif | ||
43 | #endif | ||
44 | |||
45 | /** | ||
46 | * Mysql context. | ||
47 | */ | ||
48 | struct GNUNET_MYSQL_Context; | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Handle for a prepared statement. | ||
53 | */ | ||
54 | struct GNUNET_MYSQL_StatementHandle; | ||
55 | |||
56 | |||
57 | /** | ||
58 | * Type of a callback that will be called for each | ||
59 | * data set returned from MySQL. | ||
60 | * | ||
61 | * @param cls user-defined argument | ||
62 | * @param num_values number of elements in values | ||
63 | * @param values values returned by MySQL | ||
64 | * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort | ||
65 | */ | ||
66 | typedef int | ||
67 | (*GNUNET_MYSQL_DataProcessor) (void *cls, | ||
68 | unsigned int num_values, | ||
69 | MYSQL_BIND *values); | ||
70 | |||
71 | |||
72 | /** | ||
73 | * Create a mysql context. | ||
74 | * | ||
75 | * @param cfg configuration | ||
76 | * @param section configuration section to use to get MySQL configuration options | ||
77 | * @return the mysql context | ||
78 | */ | ||
79 | struct GNUNET_MYSQL_Context * | ||
80 | GNUNET_MYSQL_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
81 | const char *section); | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Destroy a mysql context. Also frees all associated prepared statements. | ||
86 | * | ||
87 | * @param mc context to destroy | ||
88 | */ | ||
89 | void | ||
90 | GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc); | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Close database connection and all prepared statements (we got a DB | ||
95 | * error). The connection will automatically be re-opened and | ||
96 | * statements will be re-prepared if they are needed again later. | ||
97 | * | ||
98 | * @param mc mysql context | ||
99 | */ | ||
100 | void | ||
101 | GNUNET_MYSQL_statements_invalidate (struct GNUNET_MYSQL_Context *mc); | ||
102 | |||
103 | |||
104 | /** | ||
105 | * Get internal handle for a prepared statement. This function should rarely | ||
106 | * be used, and if, with caution! On failures during the interaction with | ||
107 | * the handle, you must call #GNUNET_MYSQL_statements_invalidate()! | ||
108 | * | ||
109 | * @param sh prepared statement to introspect | ||
110 | * @return MySQL statement handle, NULL on error | ||
111 | */ | ||
112 | MYSQL_STMT * | ||
113 | GNUNET_MYSQL_statement_get_stmt (struct GNUNET_MYSQL_StatementHandle *sh); | ||
114 | |||
115 | |||
116 | /** | ||
117 | * Prepare a statement. Prepared statements are automatically discarded | ||
118 | * when the MySQL context is destroyed. | ||
119 | * | ||
120 | * @param mc mysql context | ||
121 | * @param query query text | ||
122 | * @return prepared statement, NULL on error | ||
123 | */ | ||
124 | struct GNUNET_MYSQL_StatementHandle * | ||
125 | GNUNET_MYSQL_statement_prepare (struct GNUNET_MYSQL_Context *mc, | ||
126 | const char *query); | ||
127 | |||
128 | |||
129 | /** | ||
130 | * Run a SQL statement. | ||
131 | * | ||
132 | * @param mc mysql context | ||
133 | * @param sql SQL statement to run | ||
134 | * @return #GNUNET_OK on success | ||
135 | * #GNUNET_SYSERR if there was a problem | ||
136 | */ | ||
137 | int | ||
138 | GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, | ||
139 | const char *sql); | ||
140 | |||
141 | |||
142 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
143 | { | ||
144 | #endif | ||
145 | #ifdef __cplusplus | ||
146 | } | ||
147 | #endif | ||
148 | |||
149 | #endif | ||
150 | |||
151 | /** @} */ /* end of group */ | ||
diff --git a/src/my/.gitignore b/src/my/.gitignore deleted file mode 100644 index 3338ba2ea..000000000 --- a/src/my/.gitignore +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | test_my | ||
diff --git a/src/my/Makefile.am b/src/my/Makefile.am deleted file mode 100644 index 51e20e6bf..000000000 --- a/src/my/Makefile.am +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | if USE_COVERAGE | ||
5 | AM_CFLAGS = --coverage | ||
6 | endif | ||
7 | |||
8 | if HAVE_MYSQL | ||
9 | lib_LTLIBRARIES = libgnunetmy.la | ||
10 | endif | ||
11 | |||
12 | libgnunetmy_la_SOURCES = \ | ||
13 | my.c \ | ||
14 | my_query_helper.c \ | ||
15 | my_result_helper.c | ||
16 | |||
17 | libgnunetmy_la_LIBADD = $(MYSQL_LDFLAGS) -lmysqlclient \ | ||
18 | $(top_builddir)/src/mysql/libgnunetmysql.la \ | ||
19 | $(top_builddir)/src/util/libgnunetutil.la | ||
20 | libgnunetmy_la_LDFLAGS = \ | ||
21 | $(GN_LIB_LDFLAGS) \ | ||
22 | -version-info 0:0:0 | ||
23 | |||
24 | if ENABLE_TEST_RUN | ||
25 | TESTS = \ | ||
26 | test_my | ||
27 | endif | ||
28 | |||
29 | EXTRA_DIST = \ | ||
30 | test_my.conf | ||
31 | |||
32 | check_PROGRAMS= \ | ||
33 | test_my | ||
34 | |||
35 | test_my_SOURCES = \ | ||
36 | test_my.c | ||
37 | test_my_LDADD = \ | ||
38 | libgnunetmy.la \ | ||
39 | $(top_builddir)/src/mysql/libgnunetmysql.la \ | ||
40 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
41 | -lmysqlclient $(XLIB) | ||
diff --git a/src/my/meson.build b/src/my/meson.build deleted file mode 100644 index 877e80560..000000000 --- a/src/my/meson.build +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | libgnunetmy_src = ['my.c', | ||
2 | 'my_query_helper.c', | ||
3 | 'my_result_helper.c'] | ||
4 | |||
5 | if get_option('monolith') == false | ||
6 | libgnunetmy = library('gnunetmy', | ||
7 | libgnunetmy_src, | ||
8 | dependencies: [libgnunetutil_dep, libgnunetmysq_dep, my_dep], | ||
9 | include_directories: [incdir, configuration_inc]) | ||
10 | libgnunetmy_dep = declare_dependency(link_with : libgnunetmy) | ||
11 | else | ||
12 | foreach p : libgnunetmy_src | ||
13 | gnunet_src += 'my/' + p | ||
14 | endforeach | ||
15 | endif | ||
diff --git a/src/my/my.c b/src/my/my.c deleted file mode 100644 index b667af4f9..000000000 --- a/src/my/my.c +++ /dev/null | |||
@@ -1,270 +0,0 @@ | |||
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 | */ | ||
20 | /** | ||
21 | * @file my/my.c | ||
22 | * @brief library to help with access to a MySQL database | ||
23 | * @author Christophe Genevey | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include <mysql/mysql.h> | ||
28 | #include "gnunet_mysql_compat.h" | ||
29 | #include "gnunet_my_lib.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Run a prepared SELECT statement. | ||
34 | * | ||
35 | * @param mc mysql context | ||
36 | * @param sh handle to SELECT statement | ||
37 | * @param params parameters to the statement | ||
38 | * @return | ||
39 | #GNUNET_YES if we can prepare all statement | ||
40 | #GNUNET_SYSERR if we can't prepare all statement | ||
41 | */ | ||
42 | int | ||
43 | GNUNET_MY_exec_prepared (struct GNUNET_MYSQL_Context *mc, | ||
44 | struct GNUNET_MYSQL_StatementHandle *sh, | ||
45 | struct GNUNET_MY_QueryParam *params) | ||
46 | { | ||
47 | const struct GNUNET_MY_QueryParam *p; | ||
48 | unsigned int num; | ||
49 | MYSQL_STMT *stmt; | ||
50 | |||
51 | num = 0; | ||
52 | for (unsigned int i = 0; NULL != params[i].conv; i++) | ||
53 | num += params[i].num_params; | ||
54 | { | ||
55 | MYSQL_BIND qbind[num]; | ||
56 | unsigned int off; | ||
57 | |||
58 | memset (qbind, | ||
59 | 0, | ||
60 | sizeof(qbind)); | ||
61 | off = 0; | ||
62 | for (unsigned int i = 0; NULL != (p = ¶ms[i])->conv; i++) | ||
63 | { | ||
64 | if (GNUNET_OK != | ||
65 | p->conv (p->conv_cls, | ||
66 | p, | ||
67 | &qbind[off])) | ||
68 | { | ||
69 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
70 | "Conversion for MySQL query failed at offset %u\n", | ||
71 | i); | ||
72 | return GNUNET_SYSERR; | ||
73 | } | ||
74 | off += p->num_params; | ||
75 | } | ||
76 | stmt = GNUNET_MYSQL_statement_get_stmt (sh); | ||
77 | if (mysql_stmt_bind_param (stmt, | ||
78 | qbind)) | ||
79 | { | ||
80 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
81 | "my", | ||
82 | _ ("`%s' failed at %s:%d with error: %s\n"), | ||
83 | "mysql_stmt_bind_param", | ||
84 | __FILE__, __LINE__, | ||
85 | mysql_stmt_error (stmt)); | ||
86 | GNUNET_MYSQL_statements_invalidate (mc); | ||
87 | return GNUNET_SYSERR; | ||
88 | } | ||
89 | |||
90 | if (mysql_stmt_execute (stmt)) | ||
91 | { | ||
92 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
93 | "my", | ||
94 | _ ("`%s' failed at %s:%d with error: %s\n"), | ||
95 | "mysql_stmt_execute", __FILE__, __LINE__, | ||
96 | mysql_stmt_error (stmt)); | ||
97 | GNUNET_MYSQL_statements_invalidate (mc); | ||
98 | return GNUNET_SYSERR; | ||
99 | } | ||
100 | GNUNET_MY_cleanup_query (params, | ||
101 | qbind); | ||
102 | } | ||
103 | return GNUNET_OK; | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Free all memory that was allocated in @a qp during | ||
109 | * #GNUNET_MY_exec_prepared(). | ||
110 | * | ||
111 | * @param qp query specification to clean up | ||
112 | * @param qbind array of parameter to clean up | ||
113 | */ | ||
114 | void | ||
115 | GNUNET_MY_cleanup_query (struct GNUNET_MY_QueryParam *qp, | ||
116 | MYSQL_BIND *qbind) | ||
117 | { | ||
118 | for (unsigned int i = 0; NULL != qp[i].conv; i++) | ||
119 | if (NULL != qp[i].cleaner) | ||
120 | qp[i].cleaner (qp[i].conv_cls, | ||
121 | &qbind[i]); | ||
122 | } | ||
123 | |||
124 | |||
125 | /** | ||
126 | * Extract results from a query result according to the given | ||
127 | * specification. Always fetches the next row. | ||
128 | * | ||
129 | * @param sh statement that returned results | ||
130 | * @param rs specification to extract for | ||
131 | * @return | ||
132 | * #GNUNET_YES if all results could be extracted | ||
133 | * #GNUNET_NO if there is no more data in the result set | ||
134 | * #GNUNET_SYSERR if a result was invalid | ||
135 | */ | ||
136 | int | ||
137 | GNUNET_MY_extract_result (struct GNUNET_MYSQL_StatementHandle *sh, | ||
138 | struct GNUNET_MY_ResultSpec *rs) | ||
139 | { | ||
140 | unsigned int num_fields; | ||
141 | int ret; | ||
142 | MYSQL_STMT *stmt; | ||
143 | |||
144 | stmt = GNUNET_MYSQL_statement_get_stmt (sh); | ||
145 | if (NULL == stmt) | ||
146 | { | ||
147 | GNUNET_break (0); | ||
148 | return GNUNET_SYSERR; | ||
149 | } | ||
150 | if (NULL == rs) | ||
151 | { | ||
152 | mysql_stmt_free_result (stmt); | ||
153 | return GNUNET_NO; | ||
154 | } | ||
155 | |||
156 | num_fields = 0; | ||
157 | for (unsigned int i = 0; NULL != rs[i].pre_conv; i++) | ||
158 | num_fields += rs[i].num_fields; | ||
159 | |||
160 | if (mysql_stmt_field_count (stmt) != num_fields) | ||
161 | { | ||
162 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
163 | "Number of fields mismatch between SQL result and result specification\n"); | ||
164 | return GNUNET_SYSERR; | ||
165 | } | ||
166 | |||
167 | { | ||
168 | MYSQL_BIND result[num_fields]; | ||
169 | unsigned int field_off; | ||
170 | |||
171 | memset (result, 0, sizeof(MYSQL_BIND) * num_fields); | ||
172 | field_off = 0; | ||
173 | for (unsigned int i = 0; NULL != rs[i].pre_conv; i++) | ||
174 | { | ||
175 | struct GNUNET_MY_ResultSpec *rp = &rs[i]; | ||
176 | |||
177 | if (GNUNET_OK != | ||
178 | rp->pre_conv (rp->conv_cls, | ||
179 | rp, | ||
180 | stmt, | ||
181 | field_off, | ||
182 | &result[field_off])) | ||
183 | |||
184 | { | ||
185 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
186 | "Pre-conversion for MySQL result failed at offset %u\n", | ||
187 | i); | ||
188 | return GNUNET_SYSERR; | ||
189 | } | ||
190 | field_off += rp->num_fields; | ||
191 | } | ||
192 | |||
193 | if (mysql_stmt_bind_result (stmt, result)) | ||
194 | { | ||
195 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
196 | "my", | ||
197 | _ ("%s failed at %s:%d with error: %s\n"), | ||
198 | "mysql_stmt_bind_result", | ||
199 | __FILE__, __LINE__, | ||
200 | mysql_stmt_error (stmt)); | ||
201 | return GNUNET_SYSERR; | ||
202 | } | ||
203 | #if TEST_OPTIMIZATION | ||
204 | (void) mysql_stmt_store_result (stmt); | ||
205 | #endif | ||
206 | ret = mysql_stmt_fetch (stmt); | ||
207 | if (MYSQL_NO_DATA == ret) | ||
208 | { | ||
209 | mysql_stmt_free_result (stmt); | ||
210 | return GNUNET_NO; | ||
211 | } | ||
212 | if (1 == ret) | ||
213 | { | ||
214 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
215 | "my", | ||
216 | _ ("%s failed at %s:%d with error: %s\n"), | ||
217 | "mysql_stmt_fetch", | ||
218 | __FILE__, __LINE__, | ||
219 | mysql_stmt_error (stmt)); | ||
220 | GNUNET_MY_cleanup_result (rs); | ||
221 | mysql_stmt_free_result (stmt); | ||
222 | return GNUNET_SYSERR; | ||
223 | } | ||
224 | field_off = 0; | ||
225 | for (unsigned int i = 0; NULL != rs[i].post_conv; i++) | ||
226 | { | ||
227 | struct GNUNET_MY_ResultSpec *rp = &rs[i]; | ||
228 | |||
229 | if (NULL != rp->post_conv) | ||
230 | if (GNUNET_OK != | ||
231 | rp->post_conv (rp->conv_cls, | ||
232 | rp, | ||
233 | stmt, | ||
234 | field_off, | ||
235 | &result[field_off])) | ||
236 | { | ||
237 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
238 | "Post-conversion for MySQL result failed at offset %u\n", | ||
239 | i); | ||
240 | mysql_stmt_free_result (stmt); | ||
241 | for (unsigned int j = 0; j < i; j++) | ||
242 | if (NULL != rs[j].cleaner) | ||
243 | rs[j].cleaner (rs[j].conv_cls, | ||
244 | rs[j].dst); | ||
245 | return GNUNET_SYSERR; | ||
246 | } | ||
247 | field_off += rp->num_fields; | ||
248 | } | ||
249 | } | ||
250 | return GNUNET_OK; | ||
251 | } | ||
252 | |||
253 | |||
254 | /** | ||
255 | * Free all memory that was allocated in @a rs during | ||
256 | * #GNUNET_MY_extract_result(). | ||
257 | * | ||
258 | * @param rs result specification to clean up | ||
259 | */ | ||
260 | void | ||
261 | GNUNET_MY_cleanup_result (struct GNUNET_MY_ResultSpec *rs) | ||
262 | { | ||
263 | for (unsigned int i = 0; NULL != rs[i].post_conv; i++) | ||
264 | if (NULL != rs[i].cleaner) | ||
265 | rs[i].cleaner (rs[i].conv_cls, | ||
266 | &rs[i]); | ||
267 | } | ||
268 | |||
269 | |||
270 | /* end of my.c */ | ||
diff --git a/src/my/my_query_helper.c b/src/my/my_query_helper.c deleted file mode 100644 index c12970876..000000000 --- a/src/my/my_query_helper.c +++ /dev/null | |||
@@ -1,401 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 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 | */ | ||
20 | /** | ||
21 | * @file my/my_query_helper.c | ||
22 | * @brief library to help with access to a MySQL database | ||
23 | * @author Christian Grothoff | ||
24 | * @author Christophe Genevey | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include <mysql/mysql.h> | ||
28 | #include "gnunet_mysql_compat.h" | ||
29 | #include "gnunet_my_lib.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Function called to clean up memory allocated | ||
34 | * by a #GNUNET_MY_QueryConverter. | ||
35 | * | ||
36 | * @param cls closure | ||
37 | * @param qbind array of parameter to clean up | ||
38 | */ | ||
39 | static void | ||
40 | my_clean_query (void *cls, | ||
41 | MYSQL_BIND *qbind) | ||
42 | { | ||
43 | (void) cls; | ||
44 | GNUNET_free (qbind[0].buffer); | ||
45 | } | ||
46 | |||
47 | |||
48 | /** | ||
49 | * Function called to convert input argument into SQL parameters. | ||
50 | * | ||
51 | * @param cls closure | ||
52 | * @param qp data about the query | ||
53 | * @param qbind array of parameters to initialize | ||
54 | * @return -1 on error | ||
55 | */ | ||
56 | static int | ||
57 | my_conv_fixed_size (void *cls, | ||
58 | const struct GNUNET_MY_QueryParam *qp, | ||
59 | MYSQL_BIND *qbind) | ||
60 | { | ||
61 | (void) cls; | ||
62 | GNUNET_assert (1 == qp->num_params); | ||
63 | qbind->buffer = (void *) qp->data; | ||
64 | qbind->buffer_length = qp->data_len; | ||
65 | qbind->buffer_type = MYSQL_TYPE_BLOB; | ||
66 | |||
67 | return 1; | ||
68 | } | ||
69 | |||
70 | |||
71 | /** | ||
72 | * Generate query parameter for a buffer @a ptr of | ||
73 | * @a ptr_size bytes. | ||
74 | * | ||
75 | * @param ptr pointer to the query parameter to pass | ||
76 | * @param ptr_size number of bytes in @a ptr | ||
77 | */ | ||
78 | struct GNUNET_MY_QueryParam | ||
79 | GNUNET_MY_query_param_fixed_size (const void *ptr, | ||
80 | size_t ptr_size) | ||
81 | { | ||
82 | struct GNUNET_MY_QueryParam qp = { | ||
83 | .conv = &my_conv_fixed_size, | ||
84 | .cleaner = NULL, | ||
85 | .conv_cls = NULL, | ||
86 | .num_params = 1, | ||
87 | .data = ptr, | ||
88 | .data_len = (unsigned long) ptr_size | ||
89 | }; | ||
90 | |||
91 | return qp; | ||
92 | } | ||
93 | |||
94 | |||
95 | /** | ||
96 | * Function called to convert input argument into SQL parameters. | ||
97 | * | ||
98 | * @param cls closure | ||
99 | * @param qp data about the query | ||
100 | * @param qbind array of parameters to initialize | ||
101 | * @return -1 on error | ||
102 | */ | ||
103 | static int | ||
104 | my_conv_string (void *cls, | ||
105 | const struct GNUNET_MY_QueryParam *qp, | ||
106 | MYSQL_BIND *qbind) | ||
107 | { | ||
108 | (void) cls; | ||
109 | GNUNET_assert (1 == qp->num_params); | ||
110 | qbind->buffer = (void *) qp->data; | ||
111 | qbind->buffer_length = qp->data_len; | ||
112 | qbind->buffer_type = MYSQL_TYPE_STRING; | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Generate query parameter for a string | ||
119 | * | ||
120 | * @param ptr pointer to the string query parameter to pass | ||
121 | */ | ||
122 | struct GNUNET_MY_QueryParam | ||
123 | GNUNET_MY_query_param_string (const char *ptr) | ||
124 | { | ||
125 | struct GNUNET_MY_QueryParam qp = { | ||
126 | .conv = &my_conv_string, | ||
127 | .cleaner = NULL, | ||
128 | .conv_cls = NULL, | ||
129 | .num_params = 1, | ||
130 | .data = ptr, | ||
131 | .data_len = strlen (ptr) | ||
132 | }; | ||
133 | |||
134 | return qp; | ||
135 | } | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Function called to convert input argument into SQL parameters | ||
140 | * | ||
141 | * @param cls closure | ||
142 | * @param qp data about the query | ||
143 | * @param qbind array of parameters to initialize | ||
144 | * @return -1 on error | ||
145 | */ | ||
146 | static int | ||
147 | my_conv_uint16 (void *cls, | ||
148 | const struct GNUNET_MY_QueryParam *qp, | ||
149 | MYSQL_BIND *qbind) | ||
150 | { | ||
151 | (void) cls; | ||
152 | GNUNET_assert (1 == qp->num_params); | ||
153 | qbind->buffer = (void *) qp->data; | ||
154 | qbind->buffer_length = sizeof(uint16_t); | ||
155 | qbind->buffer_type = MYSQL_TYPE_SHORT; | ||
156 | qbind->is_unsigned = 1; | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | |||
161 | /** | ||
162 | * Generate query parameter for an uint16_t in host byte order. | ||
163 | * | ||
164 | * @param x pointer to the query parameter to pass | ||
165 | */ | ||
166 | struct GNUNET_MY_QueryParam | ||
167 | GNUNET_MY_query_param_uint16 (const uint16_t *x) | ||
168 | { | ||
169 | struct GNUNET_MY_QueryParam res = { | ||
170 | .conv = &my_conv_uint16, | ||
171 | .cleaner = NULL, | ||
172 | .conv_cls = NULL, | ||
173 | .num_params = 1, | ||
174 | .data = x, | ||
175 | .data_len = sizeof(*x) | ||
176 | }; | ||
177 | |||
178 | return res; | ||
179 | } | ||
180 | |||
181 | |||
182 | /** | ||
183 | * Function called to convert input argument into SQL parameters | ||
184 | * | ||
185 | * @param cls closure | ||
186 | * @param qp data about the query | ||
187 | * @param qbind array of parameters to initialize | ||
188 | * @return -1 on error | ||
189 | */ | ||
190 | static int | ||
191 | my_conv_uint32 (void *cls, | ||
192 | const struct GNUNET_MY_QueryParam *qp, | ||
193 | MYSQL_BIND *qbind) | ||
194 | { | ||
195 | (void) cls; | ||
196 | GNUNET_assert (1 == qp->num_params); | ||
197 | qbind->buffer = (void *) qp->data; | ||
198 | qbind->buffer_length = sizeof(uint32_t); | ||
199 | qbind->buffer_type = MYSQL_TYPE_LONG; | ||
200 | qbind->is_unsigned = 1; | ||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | |||
205 | /** | ||
206 | * Generate query parameter for an uint32_t in host byte order | ||
207 | * | ||
208 | * @param x pointer to the query parameter to pass | ||
209 | */ | ||
210 | struct GNUNET_MY_QueryParam | ||
211 | GNUNET_MY_query_param_uint32 (const uint32_t *x) | ||
212 | { | ||
213 | struct GNUNET_MY_QueryParam res = { | ||
214 | .conv = &my_conv_uint32, | ||
215 | .cleaner = NULL, | ||
216 | .conv_cls = NULL, | ||
217 | .num_params = 1, | ||
218 | .data = x, | ||
219 | .data_len = sizeof(*x) | ||
220 | }; | ||
221 | |||
222 | return res; | ||
223 | } | ||
224 | |||
225 | |||
226 | /** | ||
227 | * Function called to convert input argument into SQL parameters | ||
228 | * | ||
229 | * @param cls closure | ||
230 | * @param qp data about the query | ||
231 | * @param qbind array of parameters to initialize | ||
232 | * @return -1 on error | ||
233 | */ | ||
234 | static int | ||
235 | my_conv_uint64 (void *cls, | ||
236 | const struct GNUNET_MY_QueryParam *qp, | ||
237 | MYSQL_BIND *qbind) | ||
238 | { | ||
239 | (void) cls; | ||
240 | GNUNET_assert (1 == qp->num_params); | ||
241 | qbind->buffer = (void *) qp->data; | ||
242 | qbind->buffer_length = sizeof(uint64_t); | ||
243 | qbind->buffer_type = MYSQL_TYPE_LONGLONG; | ||
244 | qbind->is_unsigned = 1; | ||
245 | return 1; | ||
246 | } | ||
247 | |||
248 | |||
249 | /** | ||
250 | * Generate query parameter for an uint64_t in host byte order | ||
251 | * | ||
252 | * @param x pointer to the query parameter to pass | ||
253 | */ | ||
254 | struct GNUNET_MY_QueryParam | ||
255 | GNUNET_MY_query_param_uint64 (const uint64_t *x) | ||
256 | { | ||
257 | struct GNUNET_MY_QueryParam res = { | ||
258 | .conv = &my_conv_uint64, | ||
259 | .cleaner = NULL, | ||
260 | .conv_cls = NULL, | ||
261 | .num_params = 1, | ||
262 | .data = x, | ||
263 | .data_len = sizeof(*x) | ||
264 | }; | ||
265 | |||
266 | return res; | ||
267 | } | ||
268 | |||
269 | |||
270 | /** | ||
271 | * Function called to convert input argument into SQL parameters | ||
272 | * | ||
273 | * @param cls closure | ||
274 | * @param qp data about the query | ||
275 | * @param qbind array of parameters to initialize | ||
276 | * @return -1 on error | ||
277 | */ | ||
278 | static int | ||
279 | my_conv_rsa_public_key (void *cls, | ||
280 | const struct GNUNET_MY_QueryParam *qp, | ||
281 | MYSQL_BIND *qbind) | ||
282 | { | ||
283 | const struct GNUNET_CRYPTO_RsaPublicKey *rsa = qp->data; | ||
284 | void *buf; | ||
285 | size_t buf_size; | ||
286 | |||
287 | (void) cls; | ||
288 | GNUNET_assert (1 == qp->num_params); | ||
289 | buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa, | ||
290 | &buf); | ||
291 | qbind->buffer = buf; | ||
292 | qbind->buffer_length = buf_size; | ||
293 | qbind->buffer_type = MYSQL_TYPE_BLOB; | ||
294 | return 1; | ||
295 | } | ||
296 | |||
297 | |||
298 | /** | ||
299 | * Generate query parameter for an RSA public key. The | ||
300 | * database must contain a BLOB type in the respective position. | ||
301 | * | ||
302 | * @param x the query parameter to pass | ||
303 | * @return array entry for the query parameters to use | ||
304 | */ | ||
305 | struct GNUNET_MY_QueryParam | ||
306 | GNUNET_MY_query_param_rsa_public_key (const struct | ||
307 | GNUNET_CRYPTO_RsaPublicKey *x) | ||
308 | { | ||
309 | struct GNUNET_MY_QueryParam res = { | ||
310 | .conv = &my_conv_rsa_public_key, | ||
311 | .cleaner = &my_clean_query, | ||
312 | .conv_cls = NULL, | ||
313 | .num_params = 1, | ||
314 | .data = x, | ||
315 | .data_len = 0 | ||
316 | }; | ||
317 | |||
318 | return res; | ||
319 | } | ||
320 | |||
321 | |||
322 | /** | ||
323 | * Function called to convert input argument into SQL parameters | ||
324 | * | ||
325 | *@param cls closure | ||
326 | *@param qp data about the query | ||
327 | *@param qbind array of parameters to initialize | ||
328 | *@return -1 on error | ||
329 | */ | ||
330 | static int | ||
331 | my_conv_rsa_signature (void *cls, | ||
332 | const struct GNUNET_MY_QueryParam *qp, | ||
333 | MYSQL_BIND *qbind) | ||
334 | { | ||
335 | const struct GNUNET_CRYPTO_RsaSignature *sig = qp->data; | ||
336 | void *buf; | ||
337 | size_t buf_size; | ||
338 | |||
339 | (void) cls; | ||
340 | GNUNET_assert (1 == qp->num_params); | ||
341 | buf_size = GNUNET_CRYPTO_rsa_signature_encode (sig, | ||
342 | &buf); | ||
343 | qbind->buffer = buf; | ||
344 | qbind->buffer_length = buf_size; | ||
345 | qbind->buffer_type = MYSQL_TYPE_BLOB; | ||
346 | return 1; | ||
347 | } | ||
348 | |||
349 | |||
350 | /** | ||
351 | * Generate query parameter for an RSA signature. The | ||
352 | * database must contain a BLOB type in the respective position | ||
353 | * | ||
354 | * @param x the query parameter to pass | ||
355 | * @return array entry for the query parameters to use | ||
356 | */ | ||
357 | struct GNUNET_MY_QueryParam | ||
358 | GNUNET_MY_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) | ||
359 | { | ||
360 | struct GNUNET_MY_QueryParam res = { | ||
361 | .conv = &my_conv_rsa_signature, | ||
362 | .cleaner = &my_clean_query, | ||
363 | .conv_cls = NULL, | ||
364 | .num_params = 1, | ||
365 | .data = (x), | ||
366 | .data_len = 0 | ||
367 | }; | ||
368 | |||
369 | return res; | ||
370 | } | ||
371 | |||
372 | |||
373 | /** | ||
374 | * Generate query parameter for an absolute time value. | ||
375 | * The database must store a 64-bit integer. | ||
376 | * | ||
377 | * @param x pointer to the query parameter to pass | ||
378 | * @return array entry for the query parameters to use | ||
379 | */ | ||
380 | struct GNUNET_MY_QueryParam | ||
381 | GNUNET_MY_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) | ||
382 | { | ||
383 | return GNUNET_MY_query_param_uint64 (&x->abs_value_us); | ||
384 | } | ||
385 | |||
386 | |||
387 | /** | ||
388 | * Generate query parameter for an absolute time value. | ||
389 | * The database must store a 64-bit integer. | ||
390 | * | ||
391 | * @param x pointer to the query parameter to pass | ||
392 | */ | ||
393 | struct GNUNET_MY_QueryParam | ||
394 | GNUNET_MY_query_param_absolute_time_nbo (const struct | ||
395 | GNUNET_TIME_AbsoluteNBO *x) | ||
396 | { | ||
397 | return GNUNET_MY_query_param_auto_from_type (&x->abs_value_us__); | ||
398 | } | ||
399 | |||
400 | |||
401 | /* end of my_query_helper.c */ | ||
diff --git a/src/my/my_result_helper.c b/src/my/my_result_helper.c deleted file mode 100644 index ceebc6f37..000000000 --- a/src/my/my_result_helper.c +++ /dev/null | |||
@@ -1,868 +0,0 @@ | |||
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 | */ | ||
20 | /** | ||
21 | * @file my/my_result_helper.c | ||
22 | * @brief functions to extract result values | ||
23 | * @author Christophe Genevey | ||
24 | */ | ||
25 | |||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_mysql_compat.h" | ||
29 | #include "gnunet_my_lib.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * extract data from a Mysql database @a result at row @a row | ||
34 | * | ||
35 | * @param cls closure | ||
36 | * @param[in,out] rs | ||
37 | * @param stmt the mysql statement that is being run | ||
38 | * @param column the column that is being processed | ||
39 | * @param[out] result mysql result | ||
40 | * @return | ||
41 | * #GNUNET_OK if all results could be extracted | ||
42 | * #GNUNET_SYSERR if a result was invalid | ||
43 | */ | ||
44 | static int | ||
45 | pre_extract_varsize_blob (void *cls, | ||
46 | struct GNUNET_MY_ResultSpec *rs, | ||
47 | MYSQL_STMT *stmt, | ||
48 | unsigned int column, | ||
49 | MYSQL_BIND *results) | ||
50 | { | ||
51 | results[0].buffer = NULL; | ||
52 | results[0].buffer_length = 0; | ||
53 | results[0].length = &rs->mysql_bind_output_length; | ||
54 | results[0].is_null = &rs->is_null; | ||
55 | rs->is_null = 0; | ||
56 | |||
57 | return GNUNET_OK; | ||
58 | } | ||
59 | |||
60 | |||
61 | /** | ||
62 | * extract data from a Mysql database @a result at row @a row | ||
63 | * | ||
64 | * @param cls closure | ||
65 | * @param[in,out] rs | ||
66 | * @param stmt the mysql statement that is being run | ||
67 | * @param column the column that is being processed | ||
68 | * @param[out] results | ||
69 | * @return | ||
70 | * #GNUNET_OK if all results could be extracted | ||
71 | * #GNUNET_SYSERR if a result was invalid | ||
72 | */ | ||
73 | static int | ||
74 | post_extract_varsize_blob (void *cls, | ||
75 | struct GNUNET_MY_ResultSpec *rs, | ||
76 | MYSQL_STMT *stmt, | ||
77 | unsigned int column, | ||
78 | MYSQL_BIND *results) | ||
79 | { | ||
80 | void *buf; | ||
81 | size_t size; | ||
82 | |||
83 | if (*results->is_null) | ||
84 | return GNUNET_SYSERR; | ||
85 | size = (size_t) rs->mysql_bind_output_length; | ||
86 | |||
87 | if (rs->mysql_bind_output_length != size) | ||
88 | return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */ | ||
89 | |||
90 | buf = GNUNET_malloc (size); | ||
91 | |||
92 | results[0].buffer = buf; | ||
93 | results[0].buffer_length = size; | ||
94 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
95 | |||
96 | if (0 != | ||
97 | mysql_stmt_fetch_column (stmt, | ||
98 | results, | ||
99 | column, | ||
100 | 0)) | ||
101 | { | ||
102 | GNUNET_free (buf); | ||
103 | return GNUNET_SYSERR; | ||
104 | } | ||
105 | |||
106 | *(void **) rs->dst = buf; | ||
107 | *rs->result_size = size; | ||
108 | |||
109 | return GNUNET_OK; | ||
110 | } | ||
111 | |||
112 | |||
113 | /** | ||
114 | * extract data from a Mysql database @a result at row @a row | ||
115 | * | ||
116 | * @param cls closure | ||
117 | * @param[in,out] rs | ||
118 | */ | ||
119 | static void | ||
120 | cleanup_varsize_blob (void *cls, | ||
121 | struct GNUNET_MY_ResultSpec *rs) | ||
122 | { | ||
123 | void **ptr = (void **) rs->dst; | ||
124 | |||
125 | if (NULL != *ptr) | ||
126 | { | ||
127 | GNUNET_free (*ptr); | ||
128 | *ptr = NULL; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | |||
133 | struct GNUNET_MY_ResultSpec | ||
134 | GNUNET_MY_result_spec_variable_size (void **dst, | ||
135 | size_t *ptr_size) | ||
136 | { | ||
137 | struct GNUNET_MY_ResultSpec res = { | ||
138 | .pre_conv = &pre_extract_varsize_blob, | ||
139 | .post_conv = &post_extract_varsize_blob, | ||
140 | .cleaner = &cleanup_varsize_blob, | ||
141 | .dst = (void *) (dst), | ||
142 | .result_size = ptr_size, | ||
143 | .num_fields = 1 | ||
144 | }; | ||
145 | |||
146 | return res; | ||
147 | } | ||
148 | |||
149 | |||
150 | /** | ||
151 | * Extract data from a Mysql database @a result at row @a row | ||
152 | * | ||
153 | * @param cls closure | ||
154 | * @param[in,out] rs | ||
155 | * @param stmt the mysql statement that is being run | ||
156 | * @param column the column that is being processed | ||
157 | * @param[out] results | ||
158 | * @return | ||
159 | * #GNUNET_OK if all results could be extracted | ||
160 | * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL) | ||
161 | */ | ||
162 | static int | ||
163 | pre_extract_fixed_blob (void *cls, | ||
164 | struct GNUNET_MY_ResultSpec *rs, | ||
165 | MYSQL_STMT *stmt, | ||
166 | unsigned int column, | ||
167 | MYSQL_BIND *results) | ||
168 | { | ||
169 | results[0].buffer = rs->dst; | ||
170 | results[0].buffer_length = rs->dst_size; | ||
171 | results[0].length = &rs->mysql_bind_output_length; | ||
172 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
173 | results[0].is_null = &rs->is_null; | ||
174 | rs->is_null = 0; | ||
175 | |||
176 | return GNUNET_OK; | ||
177 | } | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Check size of extracted fixed size data from a Mysql database @a | ||
182 | * result at row @a row | ||
183 | * | ||
184 | * @param cls closure | ||
185 | * @param[in,out] rs | ||
186 | * @param stmt the mysql statement that is being run | ||
187 | * @param column the column that is being processed | ||
188 | * @param[out] results | ||
189 | * @return | ||
190 | * #GNUNET_OK if all results could be extracted | ||
191 | * #GNUNET_SYSERR if a result was invalid(non-existing field or NULL) | ||
192 | */ | ||
193 | static int | ||
194 | post_extract_fixed_blob (void *cls, | ||
195 | struct GNUNET_MY_ResultSpec *rs, | ||
196 | MYSQL_STMT *stmt, | ||
197 | unsigned int column, | ||
198 | MYSQL_BIND *results) | ||
199 | { | ||
200 | if (*results->is_null) | ||
201 | return GNUNET_SYSERR; | ||
202 | if (rs->dst_size != rs->mysql_bind_output_length) | ||
203 | return GNUNET_SYSERR; | ||
204 | return GNUNET_OK; | ||
205 | } | ||
206 | |||
207 | |||
208 | /** | ||
209 | * Fixed-size result expected. | ||
210 | * | ||
211 | * @param name name of the field in the table | ||
212 | * @param[out] dst where to store the result | ||
213 | * @param ptr_size number of bytes in @a dst | ||
214 | * @return array entry for the result specification to use | ||
215 | */ | ||
216 | struct GNUNET_MY_ResultSpec | ||
217 | GNUNET_MY_result_spec_fixed_size (void *ptr, | ||
218 | size_t ptr_size) | ||
219 | { | ||
220 | struct GNUNET_MY_ResultSpec res = { | ||
221 | .pre_conv = &pre_extract_fixed_blob, | ||
222 | .post_conv = &post_extract_fixed_blob, | ||
223 | .cleaner = NULL, | ||
224 | .dst = (void *) (ptr), | ||
225 | .dst_size = ptr_size, | ||
226 | .num_fields = 1 | ||
227 | }; | ||
228 | |||
229 | return res; | ||
230 | } | ||
231 | |||
232 | |||
233 | /** | ||
234 | * Extract data from a Mysql database @a result at row @a row | ||
235 | * | ||
236 | * @param cls closure | ||
237 | * @param[in,out] rs | ||
238 | * @param stmt the mysql statement that is being run | ||
239 | * @param column the column that is being processed | ||
240 | * @param[out] results | ||
241 | * @return | ||
242 | * #GNUNET_OK if all results could be extracted | ||
243 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
244 | */ | ||
245 | static int | ||
246 | pre_extract_rsa_public_key (void *cls, | ||
247 | struct GNUNET_MY_ResultSpec *rs, | ||
248 | MYSQL_STMT *stmt, | ||
249 | unsigned int column, | ||
250 | MYSQL_BIND *results) | ||
251 | { | ||
252 | results[0].buffer = NULL; | ||
253 | results[0].buffer_length = 0; | ||
254 | results[0].length = &rs->mysql_bind_output_length; | ||
255 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
256 | results[0].is_null = &rs->is_null; | ||
257 | rs->is_null = 0; | ||
258 | |||
259 | return GNUNET_OK; | ||
260 | } | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Check size of extracted fixed size data from a Mysql database @a | ||
265 | * result at row @a row | ||
266 | * | ||
267 | * @param cls closure | ||
268 | * @param[in,out] rs | ||
269 | * @param stmt the mysql statement that is being run | ||
270 | * @param column the column that is being processed | ||
271 | * @param[out] results | ||
272 | * @return | ||
273 | * #GNUNET_OK if all results could be extracted | ||
274 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
275 | */ | ||
276 | static int | ||
277 | post_extract_rsa_public_key (void *cls, | ||
278 | struct GNUNET_MY_ResultSpec *rs, | ||
279 | MYSQL_STMT *stmt, | ||
280 | unsigned int column, | ||
281 | MYSQL_BIND *results) | ||
282 | |||
283 | { | ||
284 | struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst; | ||
285 | void *buf; | ||
286 | size_t size; | ||
287 | |||
288 | if (*results->is_null) | ||
289 | return GNUNET_SYSERR; | ||
290 | size = (size_t) rs->mysql_bind_output_length; | ||
291 | |||
292 | if (rs->mysql_bind_output_length != size) | ||
293 | return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */ | ||
294 | buf = GNUNET_malloc (size); | ||
295 | |||
296 | results[0].buffer = buf; | ||
297 | results[0].buffer_length = size; | ||
298 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
299 | if (0 != | ||
300 | mysql_stmt_fetch_column (stmt, | ||
301 | results, | ||
302 | column, | ||
303 | 0)) | ||
304 | { | ||
305 | GNUNET_free (buf); | ||
306 | return GNUNET_SYSERR; | ||
307 | } | ||
308 | |||
309 | *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf, | ||
310 | size); | ||
311 | GNUNET_free (buf); | ||
312 | if (NULL == *pk) | ||
313 | { | ||
314 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
315 | "Results contains bogus public key value (fail to decode)\n"); | ||
316 | return GNUNET_SYSERR; | ||
317 | } | ||
318 | |||
319 | return GNUNET_OK; | ||
320 | } | ||
321 | |||
322 | |||
323 | /** | ||
324 | * Function called to clean up memory allocated | ||
325 | * by a #GNUNET_MY_ResultConverter. | ||
326 | * | ||
327 | * @param cls closure | ||
328 | * @param rs result data to clean up | ||
329 | */ | ||
330 | static void | ||
331 | clean_rsa_public_key (void *cls, | ||
332 | struct GNUNET_MY_ResultSpec *rs) | ||
333 | { | ||
334 | struct GNUNET_CRYPTO_RsaPublicKey **pk = rs->dst; | ||
335 | |||
336 | if (NULL != *pk) | ||
337 | { | ||
338 | GNUNET_CRYPTO_rsa_public_key_free (*pk); | ||
339 | *pk = NULL; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | |||
344 | /** | ||
345 | * RSA public key expected | ||
346 | * | ||
347 | * @param name name of the field in the table | ||
348 | * @param[out] rsa where to store the result | ||
349 | * @return array entry for the result specification to use | ||
350 | */ | ||
351 | struct GNUNET_MY_ResultSpec | ||
352 | GNUNET_MY_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa) | ||
353 | { | ||
354 | struct GNUNET_MY_ResultSpec res = { | ||
355 | .pre_conv = &pre_extract_rsa_public_key, | ||
356 | .post_conv = &post_extract_rsa_public_key, | ||
357 | .cleaner = &clean_rsa_public_key, | ||
358 | .dst = (void *) rsa, | ||
359 | .dst_size = 0, | ||
360 | .num_fields = 1 | ||
361 | }; | ||
362 | |||
363 | return res; | ||
364 | } | ||
365 | |||
366 | |||
367 | /** | ||
368 | * Extract data from a Mysql database @a result at row @a row. | ||
369 | * | ||
370 | * @param cls closure | ||
371 | * @param[in,out] rs | ||
372 | * @param stmt the mysql statement that is being run | ||
373 | * @param column the column that is being processed | ||
374 | * @param[out] results | ||
375 | * @return | ||
376 | * #GNUNET_OK if all results could be extracted | ||
377 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
378 | */ | ||
379 | static int | ||
380 | pre_extract_rsa_signature (void *cls, | ||
381 | struct GNUNET_MY_ResultSpec *rs, | ||
382 | MYSQL_STMT *stmt, | ||
383 | unsigned int column, | ||
384 | MYSQL_BIND *results) | ||
385 | { | ||
386 | results[0].buffer = 0; | ||
387 | results[0].buffer_length = 0; | ||
388 | results[0].length = &rs->mysql_bind_output_length; | ||
389 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
390 | results[0].is_null = &rs->is_null; | ||
391 | rs->is_null = 0; | ||
392 | |||
393 | return GNUNET_OK; | ||
394 | } | ||
395 | |||
396 | |||
397 | /** | ||
398 | * Extract data from a Mysql database @a result at row @a row. | ||
399 | * | ||
400 | * @param cls closure | ||
401 | * @param[in,out] rs | ||
402 | * @param stmt the mysql statement that is being run | ||
403 | * @param column the column that is being processed | ||
404 | * @param[out] results | ||
405 | * @return | ||
406 | * #GNUNET_OK if all results could be extracted | ||
407 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
408 | */ | ||
409 | static int | ||
410 | post_extract_rsa_signature (void *cls, | ||
411 | struct GNUNET_MY_ResultSpec *rs, | ||
412 | MYSQL_STMT *stmt, | ||
413 | unsigned int column, | ||
414 | MYSQL_BIND *results) | ||
415 | { | ||
416 | struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst; | ||
417 | void *buf; | ||
418 | size_t size; | ||
419 | |||
420 | if (*results->is_null) | ||
421 | return GNUNET_SYSERR; | ||
422 | size = (size_t) rs->mysql_bind_output_length; | ||
423 | |||
424 | if (rs->mysql_bind_output_length != size) | ||
425 | return GNUNET_SYSERR; /* 'unsigned long' does not fit in size_t!? */ | ||
426 | buf = GNUNET_malloc (size); | ||
427 | |||
428 | results[0].buffer = buf; | ||
429 | results[0].buffer_length = size; | ||
430 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
431 | if (0 != | ||
432 | mysql_stmt_fetch_column (stmt, | ||
433 | results, | ||
434 | column, | ||
435 | 0)) | ||
436 | { | ||
437 | GNUNET_free (buf); | ||
438 | return GNUNET_SYSERR; | ||
439 | } | ||
440 | |||
441 | *sig = GNUNET_CRYPTO_rsa_signature_decode (buf, | ||
442 | size); | ||
443 | GNUNET_free (buf); | ||
444 | if (NULL == *sig) | ||
445 | { | ||
446 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
447 | "Resuls contains bogus signature value (fails to decode)\n"); | ||
448 | return GNUNET_SYSERR; | ||
449 | } | ||
450 | return GNUNET_OK; | ||
451 | } | ||
452 | |||
453 | |||
454 | /** | ||
455 | * Function called to clean up memory allocated | ||
456 | * by a #GNUNET_MY_ResultConverter. | ||
457 | * | ||
458 | * @param cls closure | ||
459 | * @param rd result data to clean up | ||
460 | */ | ||
461 | static void | ||
462 | clean_rsa_signature (void *cls, | ||
463 | struct GNUNET_MY_ResultSpec *rs) | ||
464 | { | ||
465 | struct GNUNET_CRYPTO_RsaSignature **sig = rs->dst; | ||
466 | |||
467 | if (NULL != *sig) | ||
468 | { | ||
469 | GNUNET_CRYPTO_rsa_signature_free (*sig); | ||
470 | *sig = NULL; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | |||
475 | /** | ||
476 | * RSA signature expected. | ||
477 | * | ||
478 | * @param[out] sig where to store the result; | ||
479 | * @return array entry for the result specification to use | ||
480 | */ | ||
481 | struct GNUNET_MY_ResultSpec | ||
482 | GNUNET_MY_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig) | ||
483 | { | ||
484 | struct GNUNET_MY_ResultSpec res = { | ||
485 | .pre_conv = &pre_extract_rsa_signature, | ||
486 | .post_conv = &post_extract_rsa_signature, | ||
487 | .cleaner = &clean_rsa_signature, | ||
488 | .dst = (void *) sig, | ||
489 | .dst_size = 0, | ||
490 | .num_fields = 1 | ||
491 | }; | ||
492 | |||
493 | return res; | ||
494 | } | ||
495 | |||
496 | |||
497 | /** | ||
498 | * Extract data from a Mysql database @a result at row @a row | ||
499 | * | ||
500 | * @param cls closure | ||
501 | * @param[in,out] rs | ||
502 | * @param stmt the mysql statement that is being run | ||
503 | * @param column the column that is being processed | ||
504 | * @param[out] results | ||
505 | * @return | ||
506 | * #GNUNET_OK if all results could be extracted | ||
507 | * #GNUNET_SYSERR if a result was invalid (non existing field or NULL) | ||
508 | */ | ||
509 | static int | ||
510 | pre_extract_string (void *cls, | ||
511 | struct GNUNET_MY_ResultSpec *rs, | ||
512 | MYSQL_STMT *stmt, | ||
513 | unsigned int column, | ||
514 | MYSQL_BIND *results) | ||
515 | { | ||
516 | results[0].buffer = NULL; | ||
517 | results[0].buffer_length = 0; | ||
518 | results[0].length = &rs->mysql_bind_output_length; | ||
519 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
520 | results[0].is_null = &rs->is_null; | ||
521 | rs->is_null = 0; | ||
522 | |||
523 | return GNUNET_OK; | ||
524 | } | ||
525 | |||
526 | |||
527 | /** | ||
528 | * Check size of extracted fixed size data from a Mysql database | ||
529 | * | ||
530 | * @param cls closure | ||
531 | * @param[in,out] rs | ||
532 | * @param stmt the mysql statement that is being run | ||
533 | * @param column the column that is being processed | ||
534 | * @param[out] results | ||
535 | * @return | ||
536 | * #GNUNET_OK if all results could be extracted | ||
537 | * #GNUNET_SYSERR if a result was invalid (non existing field or NULL) | ||
538 | */ | ||
539 | static int | ||
540 | post_extract_string (void *cls, | ||
541 | struct GNUNET_MY_ResultSpec *rs, | ||
542 | MYSQL_STMT *stmt, | ||
543 | unsigned int column, | ||
544 | MYSQL_BIND *results) | ||
545 | { | ||
546 | size_t size = (size_t) rs->mysql_bind_output_length; | ||
547 | char *buf; | ||
548 | |||
549 | if (rs->mysql_bind_output_length != size) | ||
550 | return GNUNET_SYSERR; | ||
551 | if (*results->is_null) | ||
552 | { | ||
553 | *(void **) rs->dst = NULL; | ||
554 | return GNUNET_OK; | ||
555 | } | ||
556 | |||
557 | buf = GNUNET_malloc (size); | ||
558 | results[0].buffer = buf; | ||
559 | results[0].buffer_length = size; | ||
560 | results[0].buffer_type = MYSQL_TYPE_BLOB; | ||
561 | |||
562 | if (0 != | ||
563 | mysql_stmt_fetch_column (stmt, | ||
564 | results, | ||
565 | column, | ||
566 | 0)) | ||
567 | { | ||
568 | GNUNET_free (buf); | ||
569 | return GNUNET_SYSERR; | ||
570 | } | ||
571 | buf[size] = '\0'; | ||
572 | *(void **) rs->dst = buf; | ||
573 | return GNUNET_OK; | ||
574 | } | ||
575 | |||
576 | |||
577 | /** | ||
578 | * 0- terminated string exprected. | ||
579 | * | ||
580 | * @param[out] dst where to store the result, allocated | ||
581 | * @return array entry for the result specification to use | ||
582 | */ | ||
583 | struct GNUNET_MY_ResultSpec | ||
584 | GNUNET_MY_result_spec_string (char **dst) | ||
585 | { | ||
586 | struct GNUNET_MY_ResultSpec res = { | ||
587 | .pre_conv = &pre_extract_string, | ||
588 | .post_conv = &post_extract_string, | ||
589 | .cleaner = NULL, | ||
590 | .dst = (void *) dst, | ||
591 | .dst_size = 0, | ||
592 | .num_fields = 1 | ||
593 | }; | ||
594 | |||
595 | return res; | ||
596 | } | ||
597 | |||
598 | |||
599 | /** | ||
600 | * Absolute time expected | ||
601 | * | ||
602 | * @param name name of the field in the table | ||
603 | * @param[out] at where to store the result | ||
604 | * @return array entry for the result specification to use | ||
605 | */ | ||
606 | struct GNUNET_MY_ResultSpec | ||
607 | GNUNET_MY_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at) | ||
608 | { | ||
609 | return GNUNET_MY_result_spec_uint64 (&at->abs_value_us); | ||
610 | } | ||
611 | |||
612 | |||
613 | /** | ||
614 | * Absolute time in network byte order expected | ||
615 | * | ||
616 | * @param[out] at where to store the result | ||
617 | * @return array entry for the result specification to use | ||
618 | */ | ||
619 | struct GNUNET_MY_ResultSpec | ||
620 | GNUNET_MY_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at) | ||
621 | { | ||
622 | struct GNUNET_MY_ResultSpec res = | ||
623 | GNUNET_MY_result_spec_auto_from_type (&at->abs_value_us__); | ||
624 | |||
625 | return res; | ||
626 | } | ||
627 | |||
628 | |||
629 | /** | ||
630 | * Extract data from a Postgres database @a result at row @a row. | ||
631 | * | ||
632 | * @param cls closure | ||
633 | * @param[in,out] rs | ||
634 | * @param stmt the mysql statement that is being run | ||
635 | * @param column the column that is being processed | ||
636 | * @param[out] results | ||
637 | * @return | ||
638 | * #GNUNET_YES if all results could be extracted | ||
639 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
640 | */ | ||
641 | static int | ||
642 | pre_extract_uint16 (void *cls, | ||
643 | struct GNUNET_MY_ResultSpec *rs, | ||
644 | MYSQL_STMT *stmt, | ||
645 | unsigned int column, | ||
646 | MYSQL_BIND *results) | ||
647 | { | ||
648 | results[0].buffer = rs->dst; | ||
649 | results[0].buffer_length = rs->dst_size; | ||
650 | results[0].length = &rs->mysql_bind_output_length; | ||
651 | results[0].buffer_type = MYSQL_TYPE_SHORT; | ||
652 | results[0].is_null = &rs->is_null; | ||
653 | rs->is_null = 0; | ||
654 | |||
655 | return GNUNET_OK; | ||
656 | } | ||
657 | |||
658 | |||
659 | /** | ||
660 | * Check size of extracted fixed size data from a Mysql database. | ||
661 | * | ||
662 | * @param cls closure | ||
663 | * @param[in,out] rs | ||
664 | * @param stmt the mysql statement that is being run | ||
665 | * @param column the column that is being processed | ||
666 | * @param[out] results | ||
667 | * @return | ||
668 | * #GNUNET_YES if all results could be extracted | ||
669 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
670 | */ | ||
671 | static int | ||
672 | post_extract_uint16 (void *cls, | ||
673 | struct GNUNET_MY_ResultSpec *rs, | ||
674 | MYSQL_STMT *stmt, | ||
675 | unsigned int column, | ||
676 | MYSQL_BIND *results) | ||
677 | { | ||
678 | if (rs->dst_size != rs->mysql_bind_output_length) | ||
679 | return GNUNET_SYSERR; | ||
680 | if (*results->is_null) | ||
681 | return GNUNET_SYSERR; | ||
682 | return GNUNET_OK; | ||
683 | } | ||
684 | |||
685 | |||
686 | /** | ||
687 | * uint16_t expected | ||
688 | * | ||
689 | * @param[out] u16 where to store the result | ||
690 | * @return array entry for the result specification to use | ||
691 | */ | ||
692 | struct GNUNET_MY_ResultSpec | ||
693 | GNUNET_MY_result_spec_uint16 (uint16_t *u16) | ||
694 | { | ||
695 | struct GNUNET_MY_ResultSpec res = { | ||
696 | .pre_conv = &pre_extract_uint16, | ||
697 | .post_conv = &post_extract_uint16, | ||
698 | .cleaner = NULL, | ||
699 | .dst = (void *) u16, | ||
700 | .dst_size = sizeof(*u16), | ||
701 | .num_fields = 1 | ||
702 | }; | ||
703 | |||
704 | return res; | ||
705 | } | ||
706 | |||
707 | |||
708 | /** | ||
709 | * Extract data from a MYSQL database @a result at row @a row | ||
710 | * | ||
711 | * @param cls closure | ||
712 | * @param[in,out] rs | ||
713 | * @param stmt the mysql statement that is being run | ||
714 | * @param column the column that is being processed | ||
715 | * @param[out] results | ||
716 | * @return | ||
717 | * #GNUNET_OK if all results could be extracted | ||
718 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
719 | */ | ||
720 | static int | ||
721 | pre_extract_uint32 (void *cls, | ||
722 | struct GNUNET_MY_ResultSpec *rs, | ||
723 | MYSQL_STMT *stmt, | ||
724 | unsigned int column, | ||
725 | MYSQL_BIND *results) | ||
726 | { | ||
727 | results[0].buffer = rs->dst; | ||
728 | results[0].buffer_length = rs->dst_size; | ||
729 | results[0].length = &rs->mysql_bind_output_length; | ||
730 | results[0].buffer_type = MYSQL_TYPE_LONG; | ||
731 | results[0].is_null = &rs->is_null; | ||
732 | rs->is_null = 0; | ||
733 | |||
734 | return GNUNET_OK; | ||
735 | } | ||
736 | |||
737 | |||
738 | /** | ||
739 | * Extract data from a MYSQL database @a result at row @a row | ||
740 | * | ||
741 | * @param cls closure | ||
742 | * @param[in,out] rs | ||
743 | * @param stmt the mysql statement that is being run | ||
744 | * @param column the column that is being processed | ||
745 | * @param[out] results | ||
746 | * @return | ||
747 | * #GNUNET_OK if all results could be extracted | ||
748 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
749 | */ | ||
750 | static int | ||
751 | post_extract_uint32 (void *cls, | ||
752 | struct GNUNET_MY_ResultSpec *rs, | ||
753 | MYSQL_STMT *stmt, | ||
754 | unsigned int column, | ||
755 | MYSQL_BIND *results) | ||
756 | { | ||
757 | if (rs->dst_size != rs->mysql_bind_output_length) | ||
758 | return GNUNET_SYSERR; | ||
759 | if (*results->is_null) | ||
760 | return GNUNET_SYSERR; | ||
761 | return GNUNET_OK; | ||
762 | } | ||
763 | |||
764 | |||
765 | /** | ||
766 | * uint32_t expected | ||
767 | * | ||
768 | * @param[out] u32 where to store the result | ||
769 | * @return array entry for the result specification to use | ||
770 | */ | ||
771 | struct GNUNET_MY_ResultSpec | ||
772 | GNUNET_MY_result_spec_uint32 (uint32_t *u32) | ||
773 | { | ||
774 | struct GNUNET_MY_ResultSpec res = { | ||
775 | .pre_conv = &pre_extract_uint32, | ||
776 | .post_conv = &post_extract_uint32, | ||
777 | .cleaner = NULL, | ||
778 | .dst = (void *) u32, | ||
779 | .dst_size = sizeof(*u32), | ||
780 | .num_fields = 1 | ||
781 | }; | ||
782 | |||
783 | return res; | ||
784 | } | ||
785 | |||
786 | |||
787 | /** | ||
788 | * Extract data from a MYSQL database @a result at row @a row | ||
789 | * | ||
790 | * @param cls closure | ||
791 | * @param[in,out] rs | ||
792 | * @param stmt the mysql statement that is being run | ||
793 | * @param column the column that is being processed | ||
794 | * @param[out] results | ||
795 | * @return | ||
796 | * #GNUNET_OK if all results could be extracted | ||
797 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
798 | */ | ||
799 | static int | ||
800 | pre_extract_uint64 (void *cls, | ||
801 | struct GNUNET_MY_ResultSpec *rs, | ||
802 | MYSQL_STMT *stmt, | ||
803 | unsigned int column, | ||
804 | MYSQL_BIND *results) | ||
805 | { | ||
806 | if (sizeof(uint64_t) != rs->dst_size) | ||
807 | return GNUNET_SYSERR; | ||
808 | results[0].buffer = rs->dst; | ||
809 | results[0].buffer_length = rs->dst_size; | ||
810 | results[0].length = &rs->mysql_bind_output_length; | ||
811 | results[0].buffer_type = MYSQL_TYPE_LONGLONG; | ||
812 | results[0].is_null = &rs->is_null; | ||
813 | rs->is_null = 0; | ||
814 | |||
815 | return GNUNET_OK; | ||
816 | } | ||
817 | |||
818 | |||
819 | /** | ||
820 | * Check size of extracted fixed-size data from a Mysql database | ||
821 | * | ||
822 | * @param cls closure | ||
823 | * @param[in,out] rs | ||
824 | * @param stmt the mysql statement that is being run | ||
825 | * @param column the column that is being processed | ||
826 | * @param[out] results | ||
827 | * @return | ||
828 | * #GNUNET_OK if all results could be extracted | ||
829 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
830 | */ | ||
831 | static int | ||
832 | post_extract_uint64 (void *cls, | ||
833 | struct GNUNET_MY_ResultSpec *rs, | ||
834 | MYSQL_STMT *stmt, | ||
835 | unsigned int column, | ||
836 | MYSQL_BIND *results) | ||
837 | { | ||
838 | if (sizeof(uint64_t) != rs->dst_size) | ||
839 | return GNUNET_SYSERR; | ||
840 | if (*results->is_null) | ||
841 | return GNUNET_SYSERR; | ||
842 | return GNUNET_OK; | ||
843 | } | ||
844 | |||
845 | |||
846 | /** | ||
847 | * uint64_t expected. | ||
848 | * | ||
849 | * @param[out] u64 where to store the result | ||
850 | * @return array entry for the result specification to use | ||
851 | */ | ||
852 | struct GNUNET_MY_ResultSpec | ||
853 | GNUNET_MY_result_spec_uint64 (uint64_t *u64) | ||
854 | { | ||
855 | struct GNUNET_MY_ResultSpec res = { | ||
856 | .pre_conv = &pre_extract_uint64, | ||
857 | .post_conv = &post_extract_uint64, | ||
858 | .cleaner = NULL, | ||
859 | .dst = (void *) u64, | ||
860 | .dst_size = sizeof(*u64), | ||
861 | .num_fields = 1 | ||
862 | }; | ||
863 | |||
864 | return res; | ||
865 | } | ||
866 | |||
867 | |||
868 | /* end of my_result_helper.c */ | ||
diff --git a/src/my/test_my.c b/src/my/test_my.c deleted file mode 100644 index e646c0fd5..000000000 --- a/src/my/test_my.c +++ /dev/null | |||
@@ -1,301 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 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 | */ | ||
20 | /** | ||
21 | * @file my/test_my.c | ||
22 | * @brief Tests for convenience MySQL database | ||
23 | * @author Christophe Genevey | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include <mysql/mysql.h> | ||
27 | #include "gnunet_mysql_compat.h" | ||
28 | #include "gnunet_my_lib.h" | ||
29 | #include "gnunet_mysql_lib.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Run actual test queries. | ||
35 | * | ||
36 | * @param contexte the current context of mysql | ||
37 | * @return 0 on success | ||
38 | */ | ||
39 | static int | ||
40 | run_queries (struct GNUNET_MYSQL_Context *context) | ||
41 | { | ||
42 | struct GNUNET_CRYPTO_RsaPublicKey *pub = NULL; | ||
43 | struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL; | ||
44 | struct GNUNET_CRYPTO_RsaSignature *sig = NULL;; | ||
45 | struct GNUNET_CRYPTO_RsaSignature *sig2 = NULL; | ||
46 | struct GNUNET_TIME_Absolute abs_time = GNUNET_TIME_absolute_get (); | ||
47 | struct GNUNET_TIME_Absolute abs_time2; | ||
48 | struct GNUNET_TIME_Absolute forever = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
49 | struct GNUNET_TIME_Absolute forever2; | ||
50 | const struct GNUNET_TIME_AbsoluteNBO abs_time_nbo = | ||
51 | GNUNET_TIME_absolute_hton (abs_time); | ||
52 | struct GNUNET_HashCode hc; | ||
53 | struct GNUNET_HashCode hc2; | ||
54 | const char msg[] = "hello"; | ||
55 | void *msg2 = NULL; | ||
56 | size_t msg2_len; | ||
57 | |||
58 | const char msg3[] = "world"; | ||
59 | char *msg4 = ""; | ||
60 | |||
61 | uint16_t u16; | ||
62 | uint16_t u162; | ||
63 | uint32_t u32; | ||
64 | uint32_t u322; | ||
65 | uint64_t u64; | ||
66 | uint64_t u642; | ||
67 | |||
68 | int ret; | ||
69 | |||
70 | struct GNUNET_MYSQL_StatementHandle *statements_handle_insert = NULL; | ||
71 | struct GNUNET_MYSQL_StatementHandle *statements_handle_select = NULL; | ||
72 | |||
73 | struct GNUNET_CRYPTO_RsaPrivateKey *priv = NULL; | ||
74 | struct GNUNET_HashCode hmsg; | ||
75 | |||
76 | priv = GNUNET_CRYPTO_rsa_private_key_create (1024); | ||
77 | pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv); | ||
78 | memset (&hmsg, 42, sizeof(hmsg)); | ||
79 | sig = GNUNET_CRYPTO_rsa_sign_fdh (priv, | ||
80 | &hmsg); | ||
81 | u16 = 16; | ||
82 | u32 = 32; | ||
83 | u64 = UINT64_MAX; | ||
84 | |||
85 | memset (&hc, 0, sizeof(hc)); | ||
86 | memset (&hc2, 0, sizeof(hc2)); | ||
87 | |||
88 | statements_handle_insert | ||
89 | = GNUNET_MYSQL_statement_prepare (context, | ||
90 | "INSERT INTO test_my2 (" | ||
91 | " pub" | ||
92 | ",sig" | ||
93 | ",abs_time" | ||
94 | ",forever" | ||
95 | ",abs_time_nbo" | ||
96 | ",hash" | ||
97 | ",vsize" | ||
98 | ",str" | ||
99 | ",u16" | ||
100 | ",u32" | ||
101 | ",u64" | ||
102 | ") VALUES " | ||
103 | "( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); | ||
104 | |||
105 | if (NULL == statements_handle_insert) | ||
106 | { | ||
107 | fprintf (stderr, "Failed to prepared statement INSERT\n"); | ||
108 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
109 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
110 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | struct GNUNET_MY_QueryParam params_insert[] = { | ||
115 | GNUNET_MY_query_param_rsa_public_key (pub), | ||
116 | GNUNET_MY_query_param_rsa_signature (sig), | ||
117 | GNUNET_MY_query_param_absolute_time (&abs_time), | ||
118 | GNUNET_MY_query_param_absolute_time (&forever), | ||
119 | GNUNET_MY_query_param_absolute_time_nbo (&abs_time_nbo), | ||
120 | GNUNET_MY_query_param_auto_from_type (&hc), | ||
121 | GNUNET_MY_query_param_fixed_size (msg, strlen (msg)), | ||
122 | GNUNET_MY_query_param_string (msg3), | ||
123 | GNUNET_MY_query_param_uint16 (&u16), | ||
124 | GNUNET_MY_query_param_uint32 (&u32), | ||
125 | GNUNET_MY_query_param_uint64 (&u64), | ||
126 | GNUNET_MY_query_param_end | ||
127 | }; | ||
128 | |||
129 | if (GNUNET_OK != GNUNET_MY_exec_prepared (context, | ||
130 | statements_handle_insert, | ||
131 | params_insert)) | ||
132 | { | ||
133 | fprintf (stderr, "Failed to execute prepared statement INSERT\n"); | ||
134 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
135 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
136 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
137 | return 1; | ||
138 | } | ||
139 | |||
140 | statements_handle_select | ||
141 | = GNUNET_MYSQL_statement_prepare (context, | ||
142 | "SELECT" | ||
143 | " pub" | ||
144 | ",sig" | ||
145 | ",abs_time" | ||
146 | ",forever" | ||
147 | ",hash" | ||
148 | ",vsize" | ||
149 | ",str" | ||
150 | ",u16" | ||
151 | ",u32" | ||
152 | ",u64" | ||
153 | " FROM test_my2"); | ||
154 | |||
155 | if (NULL == statements_handle_select) | ||
156 | { | ||
157 | fprintf (stderr, "Failed to prepared statement SELECT\n"); | ||
158 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
159 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
160 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
161 | return 1; | ||
162 | } | ||
163 | |||
164 | struct GNUNET_MY_QueryParam params_select[] = { | ||
165 | GNUNET_MY_query_param_end | ||
166 | }; | ||
167 | |||
168 | if (GNUNET_OK != GNUNET_MY_exec_prepared (context, | ||
169 | statements_handle_select, | ||
170 | params_select)) | ||
171 | { | ||
172 | fprintf (stderr, "Failed to execute prepared statement SELECT\n"); | ||
173 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
174 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
175 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | struct GNUNET_MY_ResultSpec results_select[] = { | ||
180 | GNUNET_MY_result_spec_rsa_public_key (&pub2), | ||
181 | GNUNET_MY_result_spec_rsa_signature (&sig2), | ||
182 | GNUNET_MY_result_spec_absolute_time (&abs_time2), | ||
183 | GNUNET_MY_result_spec_absolute_time (&forever2), | ||
184 | GNUNET_MY_result_spec_auto_from_type (&hc2), | ||
185 | GNUNET_MY_result_spec_variable_size (&msg2, &msg2_len), | ||
186 | GNUNET_MY_result_spec_string (&msg4), | ||
187 | GNUNET_MY_result_spec_uint16 (&u162), | ||
188 | GNUNET_MY_result_spec_uint32 (&u322), | ||
189 | GNUNET_MY_result_spec_uint64 (&u642), | ||
190 | GNUNET_MY_result_spec_end | ||
191 | }; | ||
192 | |||
193 | ret = GNUNET_MY_extract_result (statements_handle_select, | ||
194 | results_select); | ||
195 | |||
196 | GNUNET_assert (GNUNET_YES == ret); | ||
197 | GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us); | ||
198 | GNUNET_break (forever.abs_value_us == forever2.abs_value_us); | ||
199 | GNUNET_break (0 == | ||
200 | memcmp (&hc, | ||
201 | &hc2, | ||
202 | sizeof(struct GNUNET_HashCode))); | ||
203 | |||
204 | GNUNET_assert (NULL != sig2); | ||
205 | GNUNET_assert (NULL != pub2); | ||
206 | GNUNET_break (0 == | ||
207 | GNUNET_CRYPTO_rsa_signature_cmp (sig, | ||
208 | sig2)); | ||
209 | GNUNET_break (0 == | ||
210 | GNUNET_CRYPTO_rsa_public_key_cmp (pub, | ||
211 | pub2)); | ||
212 | |||
213 | GNUNET_break (strlen (msg) == msg2_len); | ||
214 | GNUNET_break (0 == | ||
215 | strncmp (msg, | ||
216 | msg2, | ||
217 | msg2_len)); | ||
218 | |||
219 | GNUNET_break (strlen (msg3) == strlen (msg4)); | ||
220 | GNUNET_break (0 == | ||
221 | strcmp (msg3, | ||
222 | msg4)); | ||
223 | |||
224 | GNUNET_break (16 == u162); | ||
225 | GNUNET_break (32 == u322); | ||
226 | GNUNET_break (UINT64_MAX == u642); | ||
227 | |||
228 | GNUNET_MY_cleanup_result (results_select); | ||
229 | |||
230 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
231 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
232 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
233 | |||
234 | if (GNUNET_OK != ret) | ||
235 | return 1; | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | |||
241 | int | ||
242 | main (int argc, const char *const argv[]) | ||
243 | { | ||
244 | struct GNUNET_CONFIGURATION_Handle *config; | ||
245 | struct GNUNET_MYSQL_Context *context; | ||
246 | int ret; | ||
247 | |||
248 | GNUNET_log_setup ("test-my", | ||
249 | "WARNING", | ||
250 | NULL); | ||
251 | |||
252 | config = GNUNET_CONFIGURATION_create (); | ||
253 | if (GNUNET_OK != | ||
254 | GNUNET_CONFIGURATION_parse (config, "test_my.conf")) | ||
255 | { | ||
256 | fprintf (stderr, "Failed to parse configuration\n"); | ||
257 | return 1; | ||
258 | } | ||
259 | |||
260 | context = GNUNET_MYSQL_context_create (config, | ||
261 | "datastore-mysql"); | ||
262 | if (NULL == context) | ||
263 | { | ||
264 | fprintf (stderr, "Failed to connect to database\n"); | ||
265 | return 77; | ||
266 | } | ||
267 | |||
268 | (void) GNUNET_MYSQL_statement_run (context, | ||
269 | "DROP TABLE test_my2;"); | ||
270 | |||
271 | if (GNUNET_OK != | ||
272 | GNUNET_MYSQL_statement_run (context, | ||
273 | "CREATE TABLE IF NOT EXISTS test_my2(" | ||
274 | " pub BLOB NOT NULL" | ||
275 | ",sig BLOB NOT NULL" | ||
276 | ",abs_time BIGINT NOT NULL" | ||
277 | ",forever BIGINT NOT NULL" | ||
278 | ",abs_time_nbo BIGINT NOT NULL" | ||
279 | ",hash BLOB NOT NULL CHECK(LENGTH(hash)=64)" | ||
280 | ",vsize BLOB NOT NULL" | ||
281 | ",str BLOB NOT NULL" | ||
282 | ",u16 SMALLINT NOT NULL" | ||
283 | ",u32 INT NOT NULL" | ||
284 | ",u64 BIGINT NOT NULL" | ||
285 | ")")) | ||
286 | { | ||
287 | fprintf (stderr, | ||
288 | "Failed to create table. Database likely not setup correctly.\n"); | ||
289 | GNUNET_MYSQL_statements_invalidate (context); | ||
290 | GNUNET_MYSQL_context_destroy (context); | ||
291 | |||
292 | return 77; | ||
293 | } | ||
294 | |||
295 | ret = run_queries (context); | ||
296 | |||
297 | GNUNET_MYSQL_context_destroy (context); | ||
298 | GNUNET_free (config); | ||
299 | |||
300 | return ret; | ||
301 | } | ||
diff --git a/src/my/test_my.conf b/src/my/test_my.conf deleted file mode 100644 index e69de29bb..000000000 --- a/src/my/test_my.conf +++ /dev/null | |||
diff --git a/src/mysql/Makefile.am b/src/mysql/Makefile.am deleted file mode 100644 index 3bfb929cd..000000000 --- a/src/mysql/Makefile.am +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | if USE_COVERAGE | ||
5 | AM_CFLAGS = --coverage | ||
6 | endif | ||
7 | |||
8 | if HAVE_MYSQL | ||
9 | lib_LTLIBRARIES = libgnunetmysql.la | ||
10 | endif | ||
11 | |||
12 | libgnunetmysql_la_SOURCES = \ | ||
13 | mysql.c | ||
14 | libgnunetmysql_la_LIBADD = $(MYSQL_LDFLAGS) -lmysqlclient \ | ||
15 | $(top_builddir)/src/util/libgnunetutil.la | ||
16 | libgnunetmysql_la_LDFLAGS = \ | ||
17 | $(GN_LIB_LDFLAGS) \ | ||
18 | -version-info 0:0:0 | ||
diff --git a/src/mysql/meson.build b/src/mysql/meson.build deleted file mode 100644 index 1464fc45e..000000000 --- a/src/mysql/meson.build +++ /dev/null | |||
@@ -1,13 +0,0 @@ | |||
1 | libgnunetmysq_src = ['mysql.c'] | ||
2 | |||
3 | if get_option('monolith') == false | ||
4 | libgnunetmysq = library('gnunetmysq', | ||
5 | libgnunetmysq_src, | ||
6 | dependencies: [libgnunetutil_dep, my_dep], | ||
7 | include_directories: [incdir, configuration_inc]) | ||
8 | libgnunetmysq_dep = declare_dependency(link_with : libgnunetmysq) | ||
9 | else | ||
10 | foreach p : libgnunetmysq_src | ||
11 | gnunet_src += 'mysql/' + p | ||
12 | endforeach | ||
13 | endif | ||
diff --git a/src/mysql/mysql.c b/src/mysql/mysql.c deleted file mode 100644 index 056c2f07f..000000000 --- a/src/mysql/mysql.c +++ /dev/null | |||
@@ -1,485 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012 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 | * @file mysql/mysql.c | ||
22 | * @brief library to help with access to a MySQL database | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include <mysql/mysql.h> | ||
27 | #include "gnunet_mysql_lib.h" | ||
28 | #include "gnunet_mysql_compat.h" | ||
29 | |||
30 | /** | ||
31 | * Maximum number of supported parameters for a prepared | ||
32 | * statement. Increase if needed. | ||
33 | */ | ||
34 | #define MAX_PARAM 16 | ||
35 | |||
36 | |||
37 | /** | ||
38 | * Die with an error message that indicates | ||
39 | * a failure of the command 'cmd' with the message given | ||
40 | * by strerror(errno). | ||
41 | */ | ||
42 | #define DIE_MYSQL(cmd, dbh) \ | ||
43 | do \ | ||
44 | { \ | ||
45 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, \ | ||
46 | "mysql", \ | ||
47 | _ ("`%s' failed at %s:%d with error: %s\n"), \ | ||
48 | cmd, \ | ||
49 | __FILE__, \ | ||
50 | __LINE__, \ | ||
51 | mysql_error ((dbh)->dbf)); \ | ||
52 | GNUNET_assert (0); \ | ||
53 | } while (0); | ||
54 | |||
55 | /** | ||
56 | * Log an error message at log-level 'level' that indicates | ||
57 | * a failure of the command 'cmd' on file 'filename' | ||
58 | * with the message given by strerror(errno). | ||
59 | */ | ||
60 | #define LOG_MYSQL(level, cmd, dbh) \ | ||
61 | do \ | ||
62 | { \ | ||
63 | GNUNET_log_from (level, \ | ||
64 | "mysql", \ | ||
65 | _ ("`%s' failed at %s:%d with error: %s\n"), \ | ||
66 | cmd, \ | ||
67 | __FILE__, \ | ||
68 | __LINE__, \ | ||
69 | mysql_error ((dbh)->dbf)); \ | ||
70 | } while (0); | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Mysql context. | ||
75 | */ | ||
76 | struct GNUNET_MYSQL_Context | ||
77 | { | ||
78 | /** | ||
79 | * Our configuration. | ||
80 | */ | ||
81 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
82 | |||
83 | /** | ||
84 | * Our section. | ||
85 | */ | ||
86 | const char *section; | ||
87 | |||
88 | /** | ||
89 | * Handle to the mysql database. | ||
90 | */ | ||
91 | MYSQL *dbf; | ||
92 | |||
93 | /** | ||
94 | * Head of list of our prepared statements. | ||
95 | */ | ||
96 | struct GNUNET_MYSQL_StatementHandle *shead; | ||
97 | |||
98 | /** | ||
99 | * Tail of list of our prepared statements. | ||
100 | */ | ||
101 | struct GNUNET_MYSQL_StatementHandle *stail; | ||
102 | |||
103 | /** | ||
104 | * Filename of "my.cnf" (msyql configuration). | ||
105 | */ | ||
106 | char *cnffile; | ||
107 | }; | ||
108 | |||
109 | |||
110 | /** | ||
111 | * Handle for a prepared statement. | ||
112 | */ | ||
113 | struct GNUNET_MYSQL_StatementHandle | ||
114 | { | ||
115 | /** | ||
116 | * Kept in a DLL. | ||
117 | */ | ||
118 | struct GNUNET_MYSQL_StatementHandle *next; | ||
119 | |||
120 | /** | ||
121 | * Kept in a DLL. | ||
122 | */ | ||
123 | struct GNUNET_MYSQL_StatementHandle *prev; | ||
124 | |||
125 | /** | ||
126 | * Mysql Context the statement handle belongs to. | ||
127 | */ | ||
128 | struct GNUNET_MYSQL_Context *mc; | ||
129 | |||
130 | /** | ||
131 | * Original query string. | ||
132 | */ | ||
133 | char *query; | ||
134 | |||
135 | /** | ||
136 | * Handle to MySQL prepared statement. | ||
137 | */ | ||
138 | MYSQL_STMT *statement; | ||
139 | |||
140 | /** | ||
141 | * Is the MySQL prepared statement valid, or do we need to re-initialize it? | ||
142 | */ | ||
143 | int valid; | ||
144 | }; | ||
145 | |||
146 | |||
147 | /** | ||
148 | * Obtain the location of ".my.cnf". | ||
149 | * | ||
150 | * @param cfg our configuration | ||
151 | * @param section the section | ||
152 | * @return NULL on error | ||
153 | */ | ||
154 | static char * | ||
155 | get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
156 | const char *section) | ||
157 | { | ||
158 | char *cnffile; | ||
159 | char *home_dir; | ||
160 | struct stat st; | ||
161 | |||
162 | struct passwd *pw; | ||
163 | |||
164 | int configured; | ||
165 | |||
166 | pw = getpwuid (getuid ()); | ||
167 | if (! pw) | ||
168 | { | ||
169 | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_ERROR, "mysql", "getpwuid"); | ||
170 | return NULL; | ||
171 | } | ||
172 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, section, "CONFIG")) | ||
173 | { | ||
174 | GNUNET_assert (GNUNET_OK == | ||
175 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
176 | section, | ||
177 | "CONFIG", | ||
178 | &cnffile)); | ||
179 | configured = GNUNET_YES; | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | home_dir = GNUNET_strdup (pw->pw_dir); | ||
184 | GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); | ||
185 | GNUNET_free (home_dir); | ||
186 | configured = GNUNET_NO; | ||
187 | } | ||
188 | |||
189 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | ||
190 | "mysql", | ||
191 | _ ("Trying to use file `%s' for MySQL configuration.\n"), | ||
192 | cnffile); | ||
193 | if ((0 != stat (cnffile, &st)) || (0 != access (cnffile, R_OK)) || | ||
194 | (! S_ISREG (st.st_mode))) | ||
195 | { | ||
196 | if (configured == GNUNET_YES) | ||
197 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
198 | "mysql", | ||
199 | _ ("Could not access file `%s': %s\n"), | ||
200 | cnffile, | ||
201 | strerror (errno)); | ||
202 | GNUNET_free (cnffile); | ||
203 | return NULL; | ||
204 | } | ||
205 | return cnffile; | ||
206 | } | ||
207 | |||
208 | |||
209 | /** | ||
210 | * Open the connection with the database (and initialize | ||
211 | * our default options). | ||
212 | * | ||
213 | * @param mc database context to initialize | ||
214 | * @return #GNUNET_OK on success | ||
215 | */ | ||
216 | static int | ||
217 | iopen (struct GNUNET_MYSQL_Context *mc) | ||
218 | { | ||
219 | char *mysql_dbname; | ||
220 | char *mysql_server; | ||
221 | char *mysql_user; | ||
222 | char *mysql_password; | ||
223 | unsigned long long mysql_port; | ||
224 | MYSQL_BOOL reconnect; | ||
225 | unsigned int timeout; | ||
226 | |||
227 | mc->dbf = mysql_init (NULL); | ||
228 | if (mc->dbf == NULL) | ||
229 | return GNUNET_SYSERR; | ||
230 | if (mc->cnffile != NULL) | ||
231 | mysql_options (mc->dbf, MYSQL_READ_DEFAULT_FILE, mc->cnffile); | ||
232 | mysql_options (mc->dbf, MYSQL_READ_DEFAULT_GROUP, "client"); | ||
233 | reconnect = 0; | ||
234 | mysql_options (mc->dbf, MYSQL_OPT_RECONNECT, &reconnect); | ||
235 | mysql_options (mc->dbf, MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout); | ||
236 | mysql_options (mc->dbf, MYSQL_SET_CHARSET_NAME, "UTF8"); | ||
237 | timeout = 60; /* in seconds */ | ||
238 | mysql_options (mc->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout); | ||
239 | mysql_options (mc->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout); | ||
240 | mysql_dbname = NULL; | ||
241 | if (GNUNET_YES == | ||
242 | GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "DATABASE")) | ||
243 | GNUNET_assert (GNUNET_OK == | ||
244 | GNUNET_CONFIGURATION_get_value_string (mc->cfg, | ||
245 | mc->section, | ||
246 | "DATABASE", | ||
247 | &mysql_dbname)); | ||
248 | else | ||
249 | mysql_dbname = GNUNET_strdup ("gnunet"); | ||
250 | mysql_user = NULL; | ||
251 | if (GNUNET_YES == | ||
252 | GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "USER")) | ||
253 | { | ||
254 | GNUNET_assert (GNUNET_OK == | ||
255 | GNUNET_CONFIGURATION_get_value_string (mc->cfg, | ||
256 | mc->section, | ||
257 | "USER", | ||
258 | &mysql_user)); | ||
259 | } | ||
260 | mysql_password = NULL; | ||
261 | if (GNUNET_YES == | ||
262 | GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "PASSWORD")) | ||
263 | { | ||
264 | GNUNET_assert (GNUNET_OK == | ||
265 | GNUNET_CONFIGURATION_get_value_string (mc->cfg, | ||
266 | mc->section, | ||
267 | "PASSWORD", | ||
268 | &mysql_password)); | ||
269 | } | ||
270 | mysql_server = NULL; | ||
271 | if (GNUNET_YES == | ||
272 | GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "HOST")) | ||
273 | { | ||
274 | GNUNET_assert (GNUNET_OK == | ||
275 | GNUNET_CONFIGURATION_get_value_string (mc->cfg, | ||
276 | mc->section, | ||
277 | "HOST", | ||
278 | &mysql_server)); | ||
279 | } | ||
280 | mysql_port = 0; | ||
281 | if (GNUNET_YES == | ||
282 | GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "PORT")) | ||
283 | { | ||
284 | GNUNET_assert (GNUNET_OK == | ||
285 | GNUNET_CONFIGURATION_get_value_number (mc->cfg, | ||
286 | mc->section, | ||
287 | "PORT", | ||
288 | &mysql_port)); | ||
289 | } | ||
290 | |||
291 | GNUNET_assert (mysql_dbname != NULL); | ||
292 | mysql_real_connect (mc->dbf, | ||
293 | mysql_server, | ||
294 | mysql_user, | ||
295 | mysql_password, | ||
296 | mysql_dbname, | ||
297 | (unsigned int) mysql_port, | ||
298 | NULL, | ||
299 | CLIENT_IGNORE_SIGPIPE); | ||
300 | GNUNET_free (mysql_server); | ||
301 | GNUNET_free (mysql_user); | ||
302 | GNUNET_free (mysql_password); | ||
303 | GNUNET_free (mysql_dbname); | ||
304 | if (mysql_error (mc->dbf)[0]) | ||
305 | { | ||
306 | LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_real_connect", mc); | ||
307 | return GNUNET_SYSERR; | ||
308 | } | ||
309 | return GNUNET_OK; | ||
310 | } | ||
311 | |||
312 | |||
313 | /** | ||
314 | * Create a mysql context. | ||
315 | * | ||
316 | * @param cfg configuration | ||
317 | * @param section configuration section to use to get MySQL configuration options | ||
318 | * @return the mysql context | ||
319 | */ | ||
320 | struct GNUNET_MYSQL_Context * | ||
321 | GNUNET_MYSQL_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
322 | const char *section) | ||
323 | { | ||
324 | struct GNUNET_MYSQL_Context *mc; | ||
325 | |||
326 | mc = GNUNET_new (struct GNUNET_MYSQL_Context); | ||
327 | mc->cfg = cfg; | ||
328 | mc->section = section; | ||
329 | mc->cnffile = get_my_cnf_path (cfg, section); | ||
330 | |||
331 | return mc; | ||
332 | } | ||
333 | |||
334 | |||
335 | /** | ||
336 | * Close database connection and all prepared statements (we got a DB | ||
337 | * error). | ||
338 | * | ||
339 | * @param mc mysql context | ||
340 | */ | ||
341 | void | ||
342 | GNUNET_MYSQL_statements_invalidate (struct GNUNET_MYSQL_Context *mc) | ||
343 | { | ||
344 | struct GNUNET_MYSQL_StatementHandle *sh; | ||
345 | |||
346 | for (sh = mc->shead; NULL != sh; sh = sh->next) | ||
347 | { | ||
348 | if (GNUNET_YES == sh->valid) | ||
349 | { | ||
350 | mysql_stmt_close (sh->statement); | ||
351 | sh->valid = GNUNET_NO; | ||
352 | } | ||
353 | sh->statement = NULL; | ||
354 | } | ||
355 | if (NULL != mc->dbf) | ||
356 | { | ||
357 | mysql_close (mc->dbf); | ||
358 | mc->dbf = NULL; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Destroy a mysql context. Also frees all associated prepared statements. | ||
365 | * | ||
366 | * @param mc context to destroy | ||
367 | */ | ||
368 | void | ||
369 | GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc) | ||
370 | { | ||
371 | struct GNUNET_MYSQL_StatementHandle *sh; | ||
372 | |||
373 | GNUNET_MYSQL_statements_invalidate (mc); | ||
374 | while (NULL != (sh = mc->shead)) | ||
375 | { | ||
376 | GNUNET_CONTAINER_DLL_remove (mc->shead, mc->stail, sh); | ||
377 | GNUNET_free (sh->query); | ||
378 | GNUNET_free (sh); | ||
379 | } | ||
380 | GNUNET_free (mc); | ||
381 | mysql_library_end (); | ||
382 | } | ||
383 | |||
384 | |||
385 | /** | ||
386 | * Prepare a statement. Prepared statements are automatically discarded | ||
387 | * when the MySQL context is destroyed. | ||
388 | * | ||
389 | * @param mc mysql context | ||
390 | * @param query query text | ||
391 | * @return prepared statement, NULL on error | ||
392 | */ | ||
393 | struct GNUNET_MYSQL_StatementHandle * | ||
394 | GNUNET_MYSQL_statement_prepare (struct GNUNET_MYSQL_Context *mc, | ||
395 | const char *query) | ||
396 | { | ||
397 | struct GNUNET_MYSQL_StatementHandle *sh; | ||
398 | |||
399 | sh = GNUNET_new (struct GNUNET_MYSQL_StatementHandle); | ||
400 | sh->mc = mc; | ||
401 | sh->query = GNUNET_strdup (query); | ||
402 | GNUNET_CONTAINER_DLL_insert (mc->shead, mc->stail, sh); | ||
403 | return sh; | ||
404 | } | ||
405 | |||
406 | |||
407 | /** | ||
408 | * Run a SQL statement. | ||
409 | * | ||
410 | * @param mc mysql context | ||
411 | * @param sql SQL statement to run | ||
412 | * @return #GNUNET_OK on success | ||
413 | * #GNUNET_SYSERR if there was a problem | ||
414 | */ | ||
415 | int | ||
416 | GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, const char *sql) | ||
417 | { | ||
418 | if ((NULL == mc->dbf) && (GNUNET_OK != iopen (mc))) | ||
419 | return GNUNET_SYSERR; | ||
420 | mysql_query (mc->dbf, sql); | ||
421 | if (mysql_error (mc->dbf)[0]) | ||
422 | { | ||
423 | LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", mc); | ||
424 | GNUNET_MYSQL_statements_invalidate (mc); | ||
425 | return GNUNET_SYSERR; | ||
426 | } | ||
427 | return GNUNET_OK; | ||
428 | } | ||
429 | |||
430 | |||
431 | /** | ||
432 | * Prepare a statement for running. | ||
433 | * | ||
434 | * @param sh statement handle to prepare | ||
435 | * @return #GNUNET_OK on success | ||
436 | */ | ||
437 | static int | ||
438 | prepare_statement (struct GNUNET_MYSQL_StatementHandle *sh) | ||
439 | { | ||
440 | struct GNUNET_MYSQL_Context *mc = sh->mc; | ||
441 | |||
442 | if (GNUNET_YES == sh->valid) | ||
443 | return GNUNET_OK; | ||
444 | if ((NULL == mc->dbf) && (GNUNET_OK != iopen (mc))) | ||
445 | return GNUNET_SYSERR; | ||
446 | sh->statement = mysql_stmt_init (mc->dbf); | ||
447 | if (NULL == sh->statement) | ||
448 | { | ||
449 | GNUNET_MYSQL_statements_invalidate (mc); | ||
450 | return GNUNET_SYSERR; | ||
451 | } | ||
452 | if (0 != mysql_stmt_prepare (sh->statement, sh->query, strlen (sh->query))) | ||
453 | { | ||
454 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
455 | "mysql", | ||
456 | "prepare_statement: %s\n", | ||
457 | sh->query); | ||
458 | LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", mc); | ||
459 | mysql_stmt_close (sh->statement); | ||
460 | sh->statement = NULL; | ||
461 | GNUNET_MYSQL_statements_invalidate (mc); | ||
462 | return GNUNET_SYSERR; | ||
463 | } | ||
464 | sh->valid = GNUNET_YES; | ||
465 | return GNUNET_OK; | ||
466 | } | ||
467 | |||
468 | |||
469 | /** | ||
470 | * Get internal handle for a prepared statement. This function should rarely | ||
471 | * be used, and if, with caution! On failures during the interaction with | ||
472 | * the handle, you must call 'GNUNET_MYSQL_statements_invalidate'! | ||
473 | * | ||
474 | * @param sh prepared statement to introspect | ||
475 | * @return MySQL statement handle, NULL on error | ||
476 | */ | ||
477 | MYSQL_STMT * | ||
478 | GNUNET_MYSQL_statement_get_stmt (struct GNUNET_MYSQL_StatementHandle *sh) | ||
479 | { | ||
480 | (void) prepare_statement (sh); | ||
481 | return sh->statement; | ||
482 | } | ||
483 | |||
484 | |||
485 | /* end of mysql.c */ | ||
diff --git a/src/regex/Makefile.am b/src/regex/Makefile.am index a6c9c0903..b7d14bc41 100644 --- a/src/regex/Makefile.am +++ b/src/regex/Makefile.am | |||
@@ -78,21 +78,20 @@ libgnunet_plugin_block_regex_la_LDFLAGS = \ | |||
78 | $(GN_LIBINTL) \ | 78 | $(GN_LIBINTL) \ |
79 | $(GN_PLUGIN_LDFLAGS) | 79 | $(GN_PLUGIN_LDFLAGS) |
80 | 80 | ||
81 | if HAVE_MYSQL | 81 | # FIXME we phased out mysql. If we want to keep, needs rewrite |
82 | noinst_mysql_progs = \ | 82 | #if HAVE_MYSQL |
83 | gnunet-regex-simulation-profiler | 83 | #noinst_mysql_progs = \ |
84 | 84 | # gnunet-regex-simulation-profiler | |
85 | gnunet_regex_simulation_profiler_SOURCES = \ | 85 | |
86 | $(REGEX_INTERNAL) gnunet-regex-simulation-profiler.c | 86 | #gnunet_regex_simulation_profiler_SOURCES = \ |
87 | gnunet_regex_simulation_profiler_LDADD = \ | 87 | # $(REGEX_INTERNAL) gnunet-regex-simulation-profiler.c |
88 | libgnunetregexblock.la \ | 88 | #gnunet_regex_simulation_profiler_LDADD = \ |
89 | $(top_builddir)/src/util/libgnunetutil.la \ | 89 | # libgnunetregexblock.la \ |
90 | $(top_builddir)/src/dht/libgnunetdht.la \ | 90 | # $(top_builddir)/src/util/libgnunetutil.la \ |
91 | $(top_builddir)/src/my/libgnunetmy.la \ | 91 | # $(top_builddir)/src/dht/libgnunetdht.la \ |
92 | $(top_builddir)/src/mysql/libgnunetmysql.la \ | 92 | # $(top_builddir)/src/block/libgnunetblock.la \ |
93 | $(top_builddir)/src/block/libgnunetblock.la \ | 93 | # $(top_builddir)/src/statistics/libgnunetstatistics.la |
94 | $(top_builddir)/src/statistics/libgnunetstatistics.la | 94 | #endif |
95 | endif | ||
96 | 95 | ||
97 | noinst_PROGRAMS = $(noinst_mysql_progs) \ | 96 | noinst_PROGRAMS = $(noinst_mysql_progs) \ |
98 | perf-regex \ | 97 | perf-regex \ |