GNUnet  0.10.x
plugin_datastore_mysql.c
Go to the documentation of this file.
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 
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_my_lib.h"
125 
126 #define MAX_DATUM_SIZE 65536
127 
128 
132 struct Plugin {
137 
142 
146 #define INSERT_ENTRY "INSERT INTO gn090 (repl,type,prio,anonLevel,expire,rvalue,hash,vhash,value) VALUES (?,?,?,?,?,?,?,?,?)"
148 
149 #define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?"
151 
152 #define DELETE_ENTRY_BY_HASH_VALUE "DELETE FROM gn090 " \
153  "WHERE hash = ? AND " \
154  "value = ? " \
155  "LIMIT 1"
157 
158 #define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, uid"
159 
160 #define SELECT_ENTRY "SELECT " RESULT_COLUMNS " FROM gn090 " \
161  "WHERE uid >= ? AND " \
162  "(rvalue >= ? OR 0 = ?) " \
163  "ORDER BY uid LIMIT 1"
165 
166 #define SELECT_ENTRY_BY_HASH "SELECT " RESULT_COLUMNS " FROM gn090 " \
167  "FORCE INDEX (idx_hash_type_uid) " \
168  "WHERE hash=? AND " \
169  "uid >= ? AND " \
170  "(rvalue >= ? OR 0 = ?) " \
171  "ORDER BY uid LIMIT 1"
173 
174 #define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT " RESULT_COLUMNS " FROM gn090 " \
175  "FORCE INDEX (idx_hash_type_uid) " \
176  "WHERE hash = ? AND " \
177  "type = ? AND " \
178  "uid >= ? AND " \
179  "(rvalue >= ? OR 0 = ?) " \
180  "ORDER BY uid LIMIT 1"
182 
183 #define UPDATE_ENTRY "UPDATE gn090 SET " \
184  "prio = prio + ?, " \
185  "repl = repl + ?, " \
186  "expire = GREATEST(expire, ?) " \
187  "WHERE hash = ? AND vhash = ?"
189 
190 #define DEC_REPL "UPDATE gn090 SET repl=GREATEST (1, repl) - 1 WHERE uid=?"
192 
193 #define SELECT_SIZE "SELECT SUM(LENGTH(value)+256) FROM gn090"
195 
196 #define SELECT_IT_NON_ANONYMOUS "SELECT " RESULT_COLUMNS " FROM gn090 " \
197  "FORCE INDEX (idx_anonLevel_type_rvalue) " \
198  "WHERE anonLevel=0 AND " \
199  "type=? AND " \
200  "uid >= ? " \
201  "ORDER BY uid LIMIT 1"
203 
204 #define SELECT_IT_EXPIRATION "SELECT " RESULT_COLUMNS " FROM gn090 " \
205  "FORCE INDEX (idx_expire) " \
206  "WHERE expire < ? " \
207  "ORDER BY expire ASC LIMIT 1"
209 
210 #define SELECT_IT_PRIORITY "SELECT " RESULT_COLUMNS " FROM gn090 " \
211  "FORCE INDEX (idx_prio) " \
212  "ORDER BY prio ASC LIMIT 1"
214 
215 #define SELECT_IT_REPLICATION "SELECT " RESULT_COLUMNS " FROM gn090 " \
216  "FORCE INDEX (idx_repl_rvalue) " \
217  "WHERE repl=? AND " \
218  " (rvalue>=? OR" \
219  " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) " \
220  "ORDER BY rvalue ASC " \
221  "LIMIT 1"
223 
224 #define SELECT_MAX_REPL "SELECT MAX(repl) FROM gn090"
226 
227 #define GET_ALL_KEYS "SELECT hash from gn090"
229 };
230 
231 #define MAX_PARAM 16
232 
240 static int
242  unsigned long long uid)
243 {
244  int ret;
245  uint64_t uid64 = (uint64_t)uid;
246  struct GNUNET_MY_QueryParam params_delete[] = {
249  };
250 
252  "Deleting value %llu from gn090 table\n",
253  uid);
254  ret = GNUNET_MY_exec_prepared(plugin->mc,
255  plugin->delete_entry_by_uid,
256  params_delete);
257  if (ret >= 0)
258  {
259  return GNUNET_OK;
260  }
262  "Deleting value %llu from gn090 table failed\n",
263  (unsigned long long)uid);
264  return ret;
265 }
266 
267 
275 static void
277  unsigned long long *estimate)
278 {
279  struct Plugin *plugin = cls;
280  uint64_t total;
281  int ret;
282  struct GNUNET_MY_QueryParam params_get[] = {
284  };
285  struct GNUNET_MY_ResultSpec results_get[] = {
288  };
289 
290  ret = GNUNET_MY_exec_prepared(plugin->mc,
291  plugin->get_size,
292  params_get);
293  *estimate = 0;
294  total = UINT64_MAX;
295  if ((GNUNET_OK == ret) &&
296  (GNUNET_OK ==
298  results_get)))
299  {
300  *estimate = (unsigned long long)total;
302  "Size estimate for MySQL payload is %lld\n",
303  (long long)total);
304  GNUNET_assert(UINT64_MAX != total);
307  NULL));
308  }
309 }
310 
311 
328 static void
330  const struct GNUNET_HashCode *key,
331  bool absent,
332  uint32_t size,
333  const void *data,
334  enum GNUNET_BLOCK_Type type,
335  uint32_t priority,
336  uint32_t anonymity,
337  uint32_t replication,
339  PluginPutCont cont,
340  void *cont_cls)
341 {
342  struct Plugin *plugin = cls;
343  uint64_t lexpiration = expiration.abs_value_us;
344  struct GNUNET_HashCode vhash;
345 
346  GNUNET_CRYPTO_hash(data,
347  size,
348  &vhash);
349  if (!absent)
350  {
351  struct GNUNET_MY_QueryParam params_update[] = {
352  GNUNET_MY_query_param_uint32(&priority),
353  GNUNET_MY_query_param_uint32(&replication),
354  GNUNET_MY_query_param_uint64(&lexpiration),
358  };
359 
360  if (GNUNET_OK !=
361  GNUNET_MY_exec_prepared(plugin->mc,
362  plugin->update_entry,
363  params_update))
364  {
365  cont(cont_cls,
366  key,
367  size,
369  _("MySQL statement run failure"));
370  return;
371  }
372 
373  MYSQL_STMT *stmt = GNUNET_MYSQL_statement_get_stmt(plugin->update_entry);
374  my_ulonglong rows = mysql_stmt_affected_rows(stmt);
375 
378  NULL));
379  if (0 != rows)
380  {
381  cont(cont_cls,
382  key,
383  size,
384  GNUNET_NO,
385  NULL);
386  return;
387  }
388  }
389 
391  UINT64_MAX);
392  struct GNUNET_MY_QueryParam params_insert[] = {
393  GNUNET_MY_query_param_uint32(&replication),
395  GNUNET_MY_query_param_uint32(&priority),
396  GNUNET_MY_query_param_uint32(&anonymity),
397  GNUNET_MY_query_param_uint64(&lexpiration),
403  };
404 
405  if (size > MAX_DATUM_SIZE)
406  {
407  GNUNET_break(0);
408  cont(cont_cls, key, size, GNUNET_SYSERR, _("Data too large"));
409  return;
410  }
411 
412  if (GNUNET_OK !=
413  GNUNET_MY_exec_prepared(plugin->mc,
414  plugin->insert_entry,
415  params_insert))
416  {
417  cont(cont_cls,
418  key,
419  size,
421  _("MySQL statement run failure"));
422  return;
423  }
425  "Inserted value `%s' with size %u into gn090 table\n",
426  GNUNET_h2s(key),
427  (unsigned int)size);
428  if (size > 0)
429  plugin->env->duc(plugin->env->cls,
430  size);
433  NULL));
434  cont(cont_cls,
435  key,
436  size,
437  GNUNET_OK,
438  NULL);
439 }
440 
441 
452 static void
454  struct GNUNET_MYSQL_StatementHandle *stmt,
456  void *proc_cls,
457  struct GNUNET_MY_QueryParam *params_select)
458 {
459  int ret;
460  uint32_t replication;
461  uint32_t type;
462  uint32_t priority;
463  uint32_t anonymity;
464  uint64_t uid;
465  size_t value_size;
466  void *value;
467  struct GNUNET_HashCode key;
468  struct GNUNET_TIME_Absolute expiration;
469  struct GNUNET_MY_ResultSpec results_select[] = {
470  GNUNET_MY_result_spec_uint32(&replication),
472  GNUNET_MY_result_spec_uint32(&priority),
473  GNUNET_MY_result_spec_uint32(&anonymity),
476  GNUNET_MY_result_spec_variable_size(&value, &value_size),
479  };
480 
481  ret = GNUNET_MY_exec_prepared(plugin->mc,
482  stmt,
483  params_select);
484  if (GNUNET_OK != ret)
485  {
486  proc(proc_cls,
487  NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
488  return;
489  }
490 
491  ret = GNUNET_MY_extract_result(stmt,
492  results_select);
493  if (GNUNET_OK != ret)
494  {
495  proc(proc_cls,
496  NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
497  return;
498  }
499 
501  "Found %u-byte value under key `%s' with prio %u, anon %u, expire %s selecting from gn090 table\n",
502  (unsigned int)value_size,
503  GNUNET_h2s(&key),
504  (unsigned int)priority,
505  (unsigned int)anonymity,
507  GNUNET_assert(value_size < MAX_DATUM_SIZE);
510  NULL));
511  ret = proc(proc_cls,
512  &key,
513  value_size,
514  value,
515  type,
516  priority,
517  anonymity,
518  replication,
519  expiration,
520  uid);
521  GNUNET_MY_cleanup_result(results_select);
522  if (GNUNET_NO == ret)
523  {
524  do_delete_entry(plugin, uid);
525  if (0 != value_size)
526  plugin->env->duc(plugin->env->cls,
527  -value_size);
528  }
529 }
530 
531 
545 static void
547  uint64_t next_uid,
548  bool random,
549  const struct GNUNET_HashCode *key,
550  enum GNUNET_BLOCK_Type type,
552  void *proc_cls)
553 {
554  struct Plugin *plugin = cls;
555  uint64_t rvalue;
556 
557  if (random)
558  {
560  UINT64_MAX);
561  next_uid = 0;
562  }
563  else
564  rvalue = 0;
565 
566  if (NULL == key)
567  {
568  struct GNUNET_MY_QueryParam params_select[] = {
569  GNUNET_MY_query_param_uint64(&next_uid),
573  };
574 
575  execute_select(plugin,
576  plugin->select_entry,
577  proc,
578  proc_cls,
579  params_select);
580  }
581  else if (type != GNUNET_BLOCK_TYPE_ANY)
582  {
583  struct GNUNET_MY_QueryParam params_select[] = {
586  GNUNET_MY_query_param_uint64(&next_uid),
590  };
591 
592  execute_select(plugin,
594  proc,
595  proc_cls,
596  params_select);
597  }
598  else
599  {
600  struct GNUNET_MY_QueryParam params_select[] = {
602  GNUNET_MY_query_param_uint64(&next_uid),
606  };
607 
608  execute_select(plugin,
609  plugin->select_entry_by_hash,
610  proc,
611  proc_cls,
612  params_select);
613  }
614 }
615 
616 
628 static void
630  uint64_t next_uid,
631  enum GNUNET_BLOCK_Type type,
633  void *proc_cls)
634 {
635  struct Plugin *plugin = cls;
636  uint32_t typei = (uint32_t)type;
637 
638  struct GNUNET_MY_QueryParam params_zero_iter[] = {
640  GNUNET_MY_query_param_uint64(&next_uid),
642  };
643 
644  execute_select(plugin,
645  plugin->zero_iter,
646  proc,
647  proc_cls,
648  params_zero_iter);
649 }
650 
651 
655 struct ReplCtx {
659  struct Plugin *plugin;
660 
665 
669  void *proc_cls;
670 };
671 
672 
693 static int
694 repl_proc(void *cls,
695  const struct GNUNET_HashCode *key,
696  uint32_t size,
697  const void *data,
698  enum GNUNET_BLOCK_Type type,
699  uint32_t priority,
700  uint32_t anonymity,
701  uint32_t replication,
703  uint64_t uid)
704 {
705  struct ReplCtx *rc = cls;
706  struct Plugin *plugin = rc->plugin;
707  int ret;
708  int iret;
709 
710  ret = rc->proc(rc->proc_cls,
711  key,
712  size,
713  data,
714  type,
715  priority,
716  anonymity,
717  replication,
718  expiration,
719  uid);
720  if (NULL != key)
721  {
722  struct GNUNET_MY_QueryParam params_proc[] = {
725  };
726 
727  iret = GNUNET_MY_exec_prepared(plugin->mc,
728  plugin->dec_repl,
729  params_proc);
730  if (GNUNET_SYSERR == iret)
731  {
733  "Failed to reduce replication counter\n");
734  return GNUNET_SYSERR;
735  }
736  }
737  return ret;
738 }
739 
740 
752 static void
755  void *proc_cls)
756 {
757  struct Plugin *plugin = cls;
758  uint64_t rvalue;
759  uint32_t repl;
760  struct ReplCtx rc;
761  struct GNUNET_MY_QueryParam params_get[] = {
763  };
764  struct GNUNET_MY_ResultSpec results_get[] = {
767  };
768  struct GNUNET_MY_QueryParam params_select[] = {
774  };
775 
776  rc.plugin = plugin;
777  rc.proc = proc;
778  rc.proc_cls = proc_cls;
779 
780  if (1 !=
781  GNUNET_MY_exec_prepared(plugin->mc,
782  plugin->max_repl,
783  params_get))
784  {
785  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
786  return;
787  }
788 
789  if (GNUNET_OK !=
791  results_get))
792  {
793  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
794  return;
795  }
798  NULL));
800  UINT64_MAX);
801 
802  execute_select(plugin,
803  plugin->select_replication,
804  &repl_proc,
805  &rc,
806  params_select);
807 }
808 
809 
817 static void
819  PluginKeyProcessor proc,
820  void *proc_cls)
821 {
822  struct Plugin *plugin = cls;
823  int ret;
824  MYSQL_STMT *statement;
825  unsigned int cnt;
826  struct GNUNET_HashCode key;
827  struct GNUNET_HashCode last;
828  struct GNUNET_MY_QueryParam params_select[] = {
830  };
831  struct GNUNET_MY_ResultSpec results_select[] = {
834  };
835 
836  GNUNET_assert(NULL != proc);
837  statement = GNUNET_MYSQL_statement_get_stmt(plugin->get_all_keys);
838  if (GNUNET_OK !=
839  GNUNET_MY_exec_prepared(plugin->mc,
840  plugin->get_all_keys,
841  params_select))
842  {
844  _("`%s' for `%s' failed at %s:%d with error: %s\n"),
845  "mysql_stmt_execute",
846  GET_ALL_KEYS,
847  __FILE__,
848  __LINE__,
849  mysql_stmt_error(statement));
851  proc(proc_cls, NULL, 0);
852  return;
853  }
854  memset(&last, 0, sizeof(last)); /* make static analysis happy */
855  ret = GNUNET_YES;
856  cnt = 0;
857  while (ret == GNUNET_YES)
858  {
860  results_select);
861  if (0 != GNUNET_memcmp(&last,
862  &key))
863  {
864  if (0 != cnt)
865  proc(proc_cls,
866  &last,
867  cnt);
868  cnt = 1;
869  last = key;
870  }
871  else
872  {
873  cnt++;
874  }
875  }
876  if (0 != cnt)
877  proc(proc_cls,
878  &last,
879  cnt);
880  /* finally, let app know we are done */
881  proc(proc_cls,
882  NULL,
883  0);
884  if (GNUNET_SYSERR == ret)
885  {
887  _("`%s' failed at %s:%d with error: %s\n"),
888  "mysql_stmt_fetch",
889  __FILE__,
890  __LINE__,
891  mysql_stmt_error(statement));
893  return;
894  }
895 }
896 
897 
901 struct ExpiCtx {
905  struct Plugin *plugin;
906 
911 
915  void *proc_cls;
916 };
917 
918 
919 
940 static int
941 expi_proc(void *cls,
942  const struct GNUNET_HashCode *key,
943  uint32_t size,
944  const void *data,
945  enum GNUNET_BLOCK_Type type,
946  uint32_t priority,
947  uint32_t anonymity,
948  uint32_t replication,
950  uint64_t uid)
951 {
952  struct ExpiCtx *rc = cls;
953  struct Plugin *plugin = rc->plugin;
954  struct GNUNET_MY_QueryParam params_select[] = {
956  };
957 
958  if (NULL == key)
959  {
960  execute_select(plugin,
961  plugin->select_priority,
962  rc->proc,
963  rc->proc_cls,
964  params_select);
965  return GNUNET_SYSERR;
966  }
967  return rc->proc(rc->proc_cls,
968  key,
969  size,
970  data,
971  type,
972  priority,
973  anonymity,
974  replication,
975  expiration,
976  uid);
977 }
978 
979 
988 static void
991  void *proc_cls)
992 {
993  struct Plugin *plugin = cls;
994  struct GNUNET_TIME_Absolute now;
995  struct GNUNET_MY_QueryParam params_select[] = {
998  };
999  struct ExpiCtx rc;
1000 
1001  rc.plugin = plugin;
1002  rc.proc = proc;
1003  rc.proc_cls = proc_cls;
1004  now = GNUNET_TIME_absolute_get();
1005  execute_select(plugin,
1006  plugin->select_expiration,
1007  expi_proc,
1008  &rc,
1009  params_select);
1010 }
1011 
1012 
1018 static void
1020 {
1021  struct Plugin *plugin = cls;
1022 
1023  if (GNUNET_OK !=
1025  "DROP TABLE gn090"))
1026  return; /* error */
1027  plugin->env->duc(plugin->env->cls, 0);
1028 }
1029 
1030 
1041 static void
1043  const struct GNUNET_HashCode *key,
1044  uint32_t size,
1045  const void *data,
1046  PluginRemoveCont cont,
1047  void *cont_cls)
1048 {
1049  struct Plugin *plugin = cls;
1050  struct GNUNET_MY_QueryParam params_delete[] = {
1054  };
1055 
1056  if (GNUNET_OK !=
1057  GNUNET_MY_exec_prepared(plugin->mc,
1059  params_delete))
1060  {
1062  "Removing key `%s' from gn090 table failed\n",
1063  GNUNET_h2s(key));
1064  cont(cont_cls,
1065  key,
1066  size,
1067  GNUNET_SYSERR,
1068  _("MySQL statement run failure"));
1069  return;
1070  }
1071 
1072  MYSQL_STMT *stmt = GNUNET_MYSQL_statement_get_stmt(plugin->delete_entry_by_hash_value);
1073  my_ulonglong rows = mysql_stmt_affected_rows(stmt);
1074 
1075  if (0 == rows)
1076  {
1077  cont(cont_cls,
1078  key,
1079  size,
1080  GNUNET_NO,
1081  NULL);
1082  return;
1083  }
1084  plugin->env->duc(plugin->env->cls,
1085  -size);
1086  cont(cont_cls,
1087  key,
1088  size,
1089  GNUNET_OK,
1090  NULL);
1091 }
1092 
1093 
1100 void *
1102 {
1105  struct Plugin *plugin;
1106 
1107  plugin = GNUNET_new(struct Plugin);
1108  plugin->env = env;
1109  plugin->mc = GNUNET_MYSQL_context_create(env->cfg,
1110  "datastore-mysql");
1111  if (NULL == plugin->mc)
1112  {
1113  GNUNET_free(plugin);
1114  return NULL;
1115  }
1116 #define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run(plugin->mc, a))
1117 #define PINIT(a, b) (NULL == (a = GNUNET_MYSQL_statement_prepare(plugin->mc, b)))
1118  if (MRUNS
1119  ("CREATE TABLE IF NOT EXISTS gn090 ("
1120  " repl INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1121  " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1122  " prio INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1123  " anonLevel INT(11) UNSIGNED NOT NULL DEFAULT 0,"
1124  " expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
1125  " rvalue BIGINT UNSIGNED NOT NULL,"
1126  " hash BINARY(64) NOT NULL DEFAULT '',"
1127  " vhash BINARY(64) NOT NULL DEFAULT '',"
1128  " value BLOB NOT NULL DEFAULT ''," " uid BIGINT NOT NULL AUTO_INCREMENT,"
1129  " PRIMARY KEY (uid),"
1130  " INDEX idx_hash_type_uid (hash(64),type,rvalue),"
1131  " INDEX idx_prio (prio),"
1132  " INDEX idx_repl_rvalue (repl,rvalue),"
1133  " INDEX idx_expire (expire),"
1134  " INDEX idx_anonLevel_type_rvalue (anonLevel,type,rvalue)"
1135  ") ENGINE=InnoDB") || MRUNS("SET AUTOCOMMIT = 1") ||
1136  PINIT(plugin->insert_entry, INSERT_ENTRY) ||
1139  PINIT(plugin->select_entry, SELECT_ENTRY) ||
1143  PINIT(plugin->get_size, SELECT_SIZE) ||
1144  PINIT(plugin->update_entry, UPDATE_ENTRY) ||
1145  PINIT(plugin->dec_repl, DEC_REPL) ||
1149  PINIT(plugin->max_repl, SELECT_MAX_REPL) ||
1150  PINIT(plugin->get_all_keys, GET_ALL_KEYS) ||
1152  false)
1153  {
1155  GNUNET_free(plugin);
1156  return NULL;
1157  }
1158 #undef PINIT
1159 #undef MRUNS
1160 
1162  api->cls = plugin;
1164  api->put = &mysql_plugin_put;
1165  api->get_key = &mysql_plugin_get_key;
1170  api->drop = &mysql_plugin_drop;
1173  _("Mysql database running\n"));
1174  return api;
1175 }
1176 
1177 
1184 void *
1186 {
1188  struct Plugin *plugin = api->cls;
1189 
1191  GNUNET_free(plugin);
1192  GNUNET_free(api);
1193  return NULL;
1194 }
1195 
1196 /* end of plugin_datastore_mysql.c */
struct GNUNET_MYSQL_Context * mc
Handle to talk to MySQL.
struct GNUNET_MYSQL_StatementHandle * select_entry_by_hash_and_type
struct GNUNET_MYSQL_StatementHandle * select_expiration
PluginGetKeys get_keys
Iterate over all keys in the database.
PluginPut put
Function to store an item in the datastore.
#define GNUNET_MY_query_param_auto_from_type(x)
Generate fixed-size query parameter with size determined by variable type.
int(* PluginDatumProcessor)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
An processor over a set of items stored in the datastore.
#define PINIT(a, b)
void * proc_cls
Closure for proc.
PluginGetType get_zero_anonymity
Get datum (of the specified type) with anonymity level zero.
static char * expiration
Credential TTL.
struct GNUNET_MY_QueryParam GNUNET_MY_query_param_uint64(const uint64_t *x)
Generate query parameter for an uint64_t in host byte order.
struct Plugin * plugin
Plugin handle.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
#define MRUNS(a)
void * proc_cls
Closure for proc.
struct GNUNET_MYSQL_StatementHandle * insert_entry
struct GNUNET_MYSQL_Context * GNUNET_MYSQL_context_create(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Create a mysql context.
Definition: mysql.c:319
Any type of block, used as a wildcard when searching.
#define SELECT_IT_EXPIRATION
#define UPDATE_ENTRY
#define GNUNET_MY_result_spec_end
End of result speceter specification.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
struct GNUNET_MY_ResultSpec GNUNET_MY_result_spec_uint64(uint64_t *u64)
uint64_t expected.
struct GNUNET_MY_QueryParam GNUNET_MY_query_param_fixed_size(const void *ptr, size_t ptr_size)
Generate query parameter for a buffer ptr of ptr_size bytes.FG.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
struct GNUNET_MYSQL_StatementHandle * delete_entry_by_hash_value
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define SELECT_IT_REPLICATION
static void mysql_plugin_get_keys(void *cls, PluginKeyProcessor proc, void *proc_cls)
Get all of the keys in the datastore.
void * libgnunet_plugin_datastore_mysql_done(void *cls)
Exit point from the plugin.
struct GNUNET_MYSQL_StatementHandle * delete_entry_by_uid
PluginRemoveKey remove_key
Function to remove an item from the database.
char * key
TLS key.
struct GNUNET_MY_QueryParam GNUNET_MY_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x)
Generate query parameter for an absolute time value.
static unsigned int replication
Information we pass to GNUNET_MY_exec_prepared() to initialize the arguments of the prepared statemen...
Definition: gnunet_my_lib.h:84
PluginEstimateSize estimate_size
Calculate the current on-disk size of the SQ store.
#define SELECT_IT_PRIORITY
static int repl_proc(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
Wrapper for the processor for mysql_plugin_get_replication().
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_MY_ResultSpec GNUNET_MY_result_spec_absolute_time(struct GNUNET_TIME_Absolute *at)
Absolute time expected.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_MYSQL_StatementHandle * zero_iter
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Handle for a prepared statement.
Definition: mysql.c:112
void * libgnunet_plugin_datastore_mysql_init(void *cls)
Entry point for the plugin.
int GNUNET_MY_exec_prepared(struct GNUNET_MYSQL_Context *mc, struct GNUNET_MYSQL_StatementHandle *sh, struct GNUNET_MY_QueryParam *params)
Run a prepared SELECT statement.
Definition: my.c:42
static int ret
Final status code.
Definition: gnunet-arm.c:89
static void mysql_plugin_remove_key(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, PluginRemoveCont cont, void *cont_cls)
Remove a particular key in the datastore.
void(* PluginPutCont)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Put continuation.
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define DELETE_ENTRY_BY_UID
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:46
#define SELECT_SIZE
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
PluginGetRandom get_replication
Function to get a random item with high replication score from the database, lowering the item&#39;s repl...
static int expi_proc(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
Wrapper for the processor for mysql_plugin_get_expiration().
PluginDrop drop
Delete the database.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
Information we pass to GNUNET_MY_extract_result() to initialize the arguments of the prepared stateme...
static void mysql_plugin_get_key(void *cls, uint64_t next_uid, bool random, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
Get one of the results for a particular key in the datastore.
static void mysql_plugin_drop(void *cls)
Drop database.
#define DEC_REPL
#define DELETE_ENTRY_BY_HASH_VALUE
static char * value
Value of the record to add/remove.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
void(* PluginKeyProcessor)(void *cls, const struct GNUNET_HashCode *key, unsigned int count)
An processor over a set of keys stored in the datastore.
PluginGetRandom get_expiration
Function to get a random expired item or, if none are expired, either the oldest entry or one with a ...
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
void GNUNET_MYSQL_context_destroy(struct GNUNET_MYSQL_Context *mc)
Destroy a mysql context.
Definition: mysql.c:367
#define SELECT_MAX_REPL
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
#define INSERT_ENTRY
Prepared statements.
void GNUNET_MY_cleanup_result(struct GNUNET_MY_ResultSpec *rs)
Free all memory that was allocated in rs during GNUNET_MY_extract_result().
Definition: my.c:257
Context for expi_proc() function.
MYSQL_STMT * GNUNET_MYSQL_statement_get_stmt(struct GNUNET_MYSQL_StatementHandle *sh)
Get internal handle for a prepared statement.
Definition: mysql.c:477
void GNUNET_MYSQL_statements_invalidate(struct GNUNET_MYSQL_Context *mc)
Close database connection and all prepared statements (we got a DB error).
Definition: mysql.c:340
struct GNUNET_MYSQL_StatementHandle * dec_repl
#define SELECT_ENTRY_BY_HASH_AND_TYPE
PluginDatumProcessor proc
Function to call for the result (or the NULL).
struct GNUNET_MYSQL_StatementHandle * max_repl
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
A 512-bit hashcode.
#define GET_ALL_KEYS
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
int GNUNET_MY_extract_result(struct GNUNET_MYSQL_StatementHandle *sh, struct GNUNET_MY_ResultSpec *specs)
Extract results from a query result according to the given specification.
Definition: my.c:136
#define SELECT_ENTRY_BY_HASH
static void mysql_plugin_estimate_size(void *cls, unsigned long long *estimate)
Get an estimate of how much space the database is currently using.
struct GNUNET_MYSQL_StatementHandle * get_all_keys
struct GNUNET_MYSQL_StatementHandle * select_priority
#define GNUNET_MY_result_spec_auto_from_type(dst)
We expect a fixed-size result, with size determined by the type of * dst
#define GNUNET_MY_query_param_end
End of query parameter specification.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
Context for repl_proc() function.
struct GNUNET_MYSQL_StatementHandle * select_entry_by_hash
struct GNUNET_MY_ResultSpec GNUNET_MY_result_spec_uint32(uint32_t *u32)
uint32_t expected
Mysql context.
Definition: mysql.c:76
void(* PluginRemoveCont)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Remove continuation.
void * cls
Closure to use for all of the following callbacks (except "next_request").
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_MY_QueryParam GNUNET_MY_query_param_uint32(const uint32_t *x)
Generate query parameter for an uint32_t in host byte order.
struct GNUNET_MYSQL_StatementHandle * select_entry
unsigned long long size
Size of all values we&#39;re storing.
Handle for a plugin.
Definition: block.c:37
int GNUNET_MYSQL_statement_run(struct GNUNET_MYSQL_Context *mc, const char *sql)
Run a SQL statement.
Definition: mysql.c:414
static void mysql_plugin_put(void *cls, const struct GNUNET_HashCode *key, bool absent, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, PluginPutCont cont, void *cont_cls)
Store an item in the datastore.
struct Plugin * plugin
Plugin handle.
PluginDatumProcessor proc
Function to call for the result (or the NULL).
#define GNUNET_log(kind,...)
#define MAX_DATUM_SIZE
struct GNUNET_MYSQL_StatementHandle * get_size
static void mysql_plugin_get_replication(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for replication.
void * cls
Closure to use for callbacks.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void mysql_plugin_get_expiration(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for expiration.
static unsigned int anonymity
#define SELECT_IT_NON_ANONYMOUS
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:741
#define GNUNET_log_from(kind, comp,...)
PluginGetKey get_key
Get a particular datum matching a given hash from the datastore.
struct GNUNET_MYSQL_StatementHandle * update_entry
uint32_t data
The data value.
static void mysql_plugin_get_zero_anonymity(void *cls, uint64_t next_uid, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
Get a zero-anonymity datum from the datastore.
struct GNUNET_MYSQL_StatementHandle * select_replication
struct GNUNET_MY_ResultSpec GNUNET_MY_result_spec_variable_size(void **dst, size_t *ptr_size)
Variable-size result expected.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
#define GNUNET_free(ptr)
Wrapper around free.
static int do_delete_entry(struct Plugin *plugin, unsigned long long uid)
Delete an entry from the gn090 table.
#define SELECT_ENTRY
static void execute_select(struct Plugin *plugin, struct GNUNET_MYSQL_StatementHandle *stmt, PluginDatumProcessor proc, void *proc_cls, struct GNUNET_MY_QueryParam *params_select)
Run the given select statement and call &#39;proc&#39; on the resulting values (which must be in particular p...