diff options
Diffstat (limited to 'src/datastore/plugin_datastore_mysql.c')
-rw-r--r-- | src/datastore/plugin_datastore_mysql.c | 770 |
1 files changed, 410 insertions, 360 deletions
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c index fb0ea0557..234e2fd93 100644 --- a/src/datastore/plugin_datastore_mysql.c +++ b/src/datastore/plugin_datastore_mysql.c | |||
@@ -121,10 +121,17 @@ | |||
121 | * is that mysql is basically operational, that you can connect | 121 | * is that mysql is basically operational, that you can connect |
122 | * to it, create tables, issue queries etc. | 122 | * to it, create tables, issue queries etc. |
123 | * | 123 | * |
124 | * TODO: | ||
125 | * - implement GET | ||
126 | * - remove 'size' field in gn080. | ||
127 | * - use FOREIGN KEY for 'uid/vkey' | ||
128 | * - consistent naming of uid/vkey | ||
124 | */ | 129 | */ |
125 | 130 | ||
126 | #include "platform.h" | 131 | #include "platform.h" |
127 | #include "plugin_datastore.h" | 132 | #include "plugin_datastore.h" |
133 | #include "gnunet_util_lib.h" | ||
134 | #include <mysql/mysql.h> | ||
128 | 135 | ||
129 | #define DEBUG_MYSQL GNUNET_NO | 136 | #define DEBUG_MYSQL GNUNET_NO |
130 | 137 | ||
@@ -204,6 +211,27 @@ struct GNUNET_MysqlStatementHandle | |||
204 | 211 | ||
205 | }; | 212 | }; |
206 | 213 | ||
214 | struct NextRequestClosure | ||
215 | { | ||
216 | struct Plugin *plugin; | ||
217 | |||
218 | unsigned int type; | ||
219 | |||
220 | unsigned int iter_select; | ||
221 | |||
222 | PluginIterator dviter; | ||
223 | |||
224 | void *dviter_cls; | ||
225 | |||
226 | unsigned int last_prio; | ||
227 | |||
228 | unsigned long long last_expire; | ||
229 | |||
230 | unsigned long long last_vkey; | ||
231 | |||
232 | int end_it; | ||
233 | }; | ||
234 | |||
207 | 235 | ||
208 | /** | 236 | /** |
209 | * Context for all functions in this plugin. | 237 | * Context for all functions in this plugin. |
@@ -226,13 +254,24 @@ struct Plugin | |||
226 | */ | 254 | */ |
227 | char *cnffile; | 255 | char *cnffile; |
228 | 256 | ||
257 | |||
258 | /** | ||
259 | * Closure of the 'next_task' (must be freed if 'next_task' is cancelled). | ||
260 | */ | ||
261 | struct NextRequestClosure *next_task_nc; | ||
262 | |||
263 | /** | ||
264 | * Pending task with scheduler for running the next request. | ||
265 | */ | ||
266 | GNUNET_SCHEDULER_TaskIdentifier next_task; | ||
267 | |||
229 | /** | 268 | /** |
230 | * Statements dealing with gn072 table | 269 | * Statements dealing with gn072 table |
231 | */ | 270 | */ |
232 | #define SELECT_VALUE "SELECT value FROM gn072 WHERE vkey=?" | 271 | #define SELECT_VALUE "SELECT value FROM gn072 WHERE vkey=?" |
233 | struct GNUNET_MysqlStatementHandle *select_value; | 272 | struct GNUNET_MysqlStatementHandle *select_value; |
234 | 273 | ||
235 | #define DELETE_VALUE "DELETE FROM gn072 WHERE vkey=?"o | 274 | #define DELETE_VALUE "DELETE FROM gn072 WHERE vkey=?" |
236 | struct GNUNET_MysqlStatementHandle *delete_value; | 275 | struct GNUNET_MysqlStatementHandle *delete_value; |
237 | 276 | ||
238 | #define INSERT_VALUE "INSERT INTO gn072 (value) VALUES (?)" | 277 | #define INSERT_VALUE "INSERT INTO gn072 (value) VALUES (?)" |
@@ -291,7 +330,7 @@ struct Plugin | |||
291 | * @return NULL on error | 330 | * @return NULL on error |
292 | */ | 331 | */ |
293 | static char * | 332 | static char * |
294 | get_my_cnf_path (struct GNUNET_ConfigurationHandle *cfg) | 333 | get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg) |
295 | { | 334 | { |
296 | char *cnffile; | 335 | char *cnffile; |
297 | char *home_dir; | 336 | char *home_dir; |
@@ -308,18 +347,23 @@ get_my_cnf_path (struct GNUNET_ConfigurationHandle *cfg) | |||
308 | "getpwuid"); | 347 | "getpwuid"); |
309 | return NULL; | 348 | return NULL; |
310 | } | 349 | } |
311 | home_dir = GNUNET_strdup (pw->pw_dir); | 350 | if (GNUNET_YES == |
351 | GNUNET_CONFIGURATION_have_value (cfg, | ||
352 | "MYSQL", "CONFIG")) | ||
353 | { | ||
354 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
355 | "MYSQL", "CONFIG", &cnffile); | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | home_dir = GNUNET_strdup (pw->pw_dir); | ||
312 | #else | 360 | #else |
313 | home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); | 361 | home_dir = (char *) GNUNET_malloc (_MAX_PATH + 1); |
314 | plibc_conv_to_win_path ("~/", home_dir); | 362 | plibc_conv_to_win_path ("~/", home_dir); |
315 | #endif | 363 | #endif |
316 | GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); | 364 | GNUNET_asprintf (&cnffile, "%s/.my.cnf", home_dir); |
317 | GNUNET_free (home_dir); | 365 | GNUNET_free (home_dir); |
318 | GNUNET_CONFIUGRATION_get_value_filename (cfg, | 366 | } |
319 | "MYSQL", "CONFIG", cnffile, | ||
320 | &home_dir); | ||
321 | GNUNET_free (cnffile); | ||
322 | cnffile = home_dir; | ||
323 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 367 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
324 | _("Trying to use file `%s' for MySQL configuration.\n"), | 368 | _("Trying to use file `%s' for MySQL configuration.\n"), |
325 | cnffile); | 369 | cnffile); |
@@ -418,25 +462,25 @@ iopen (struct Plugin *ret) | |||
418 | "MYSQL", "PASSWORD")) | 462 | "MYSQL", "PASSWORD")) |
419 | { | 463 | { |
420 | GNUNET_break (GNUNET_OK == | 464 | GNUNET_break (GNUNET_OK == |
421 | GNUNET_CONFIGURATION_get_value_string (ret->cfg, | 465 | GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, |
422 | "MYSQL", "PASSWORD", | 466 | "MYSQL", "PASSWORD", |
423 | &mysql_password)); | 467 | &mysql_password)); |
424 | } | 468 | } |
425 | mysql_server = NULL; | 469 | mysql_server = NULL; |
426 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->cfg, | 470 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->env->cfg, |
427 | "MYSQL", "HOST")) | 471 | "MYSQL", "HOST")) |
428 | { | 472 | { |
429 | GNUNET_break (GNUNET_OK == | 473 | GNUNET_break (GNUNET_OK == |
430 | GNUNET_CONFIGURATION_get_value_string (ret->cfg, | 474 | GNUNET_CONFIGURATION_get_value_string (ret->env->cfg, |
431 | "MYSQL", "HOST", "", | 475 | "MYSQL", "HOST", |
432 | &mysql_server)); | 476 | &mysql_server)); |
433 | } | 477 | } |
434 | mysql_port = 0; | 478 | mysql_port = 0; |
435 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->cfg, | 479 | if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (ret->env->cfg, |
436 | "MYSQL", "PORT")) | 480 | "MYSQL", "PORT")) |
437 | { | 481 | { |
438 | GNUNET_break (GNUNET_OK == | 482 | GNUNET_break (GNUNET_OK == |
439 | GNUNET_CONFIGURATION_get_value_number (ret->cfg, "MYSQL", | 483 | GNUNET_CONFIGURATION_get_value_number (ret->env->cfg, "MYSQL", |
440 | "PORT", &mysql_port)); | 484 | "PORT", &mysql_port)); |
441 | } | 485 | } |
442 | 486 | ||
@@ -450,7 +494,6 @@ iopen (struct Plugin *ret) | |||
450 | "mysql_real_connect", ret); | 494 | "mysql_real_connect", ret); |
451 | return GNUNET_SYSERR; | 495 | return GNUNET_SYSERR; |
452 | } | 496 | } |
453 | ret->valid = GNUNET_YES; | ||
454 | return GNUNET_OK; | 497 | return GNUNET_OK; |
455 | } | 498 | } |
456 | 499 | ||
@@ -464,7 +507,7 @@ static int | |||
464 | run_statement (struct Plugin *plugin, | 507 | run_statement (struct Plugin *plugin, |
465 | const char *statement) | 508 | const char *statement) |
466 | { | 509 | { |
467 | if ((NULL == plugin->dbh) && (GNUNET_OK != iopen (plugin))) | 510 | if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) |
468 | return GNUNET_SYSERR; | 511 | return GNUNET_SYSERR; |
469 | mysql_query (plugin->dbf, statement); | 512 | mysql_query (plugin->dbf, statement); |
470 | if (mysql_error (plugin->dbf)[0]) | 513 | if (mysql_error (plugin->dbf)[0]) |
@@ -492,7 +535,7 @@ run_statement_select (struct Plugin *plugin, | |||
492 | MYSQL_ROW sql_row; | 535 | MYSQL_ROW sql_row; |
493 | char *ret; | 536 | char *ret; |
494 | 537 | ||
495 | if ((NULL == plugin->dbh) && (GNUNET_OK != iopen (plugin))) | 538 | if ((NULL == plugin->dbf) && (GNUNET_OK != iopen (plugin))) |
496 | return NULL; | 539 | return NULL; |
497 | mysql_query (plugin->dbf, statement); | 540 | mysql_query (plugin->dbf, statement); |
498 | if ((mysql_error (plugin->dbf)[0]) || | 541 | if ((mysql_error (plugin->dbf)[0]) || |
@@ -547,7 +590,7 @@ prepare_statement (struct Plugin *plugin, | |||
547 | { | 590 | { |
548 | if (GNUNET_YES == ret->valid) | 591 | if (GNUNET_YES == ret->valid) |
549 | return GNUNET_OK; | 592 | return GNUNET_OK; |
550 | if ((NULL == plugin->dbh) && | 593 | if ((NULL == plugin->dbf) && |
551 | (GNUNET_OK != iopen (plugin))) | 594 | (GNUNET_OK != iopen (plugin))) |
552 | return GNUNET_SYSERR; | 595 | return GNUNET_SYSERR; |
553 | ret->statement = mysql_stmt_init (plugin->dbf); | 596 | ret->statement = mysql_stmt_init (plugin->dbf); |
@@ -816,14 +859,16 @@ prepared_statement_run (struct Plugin *plugin, | |||
816 | * @return GNUNET_OK on success, GNUNET_NO if no such value exists, GNUNET_SYSERR on error | 859 | * @return GNUNET_OK on success, GNUNET_NO if no such value exists, GNUNET_SYSERR on error |
817 | */ | 860 | */ |
818 | static int | 861 | static int |
819 | do_delete_value (unsigned long long vkey) | 862 | do_delete_value (struct Plugin *plugin, |
863 | unsigned long long vkey) | ||
820 | { | 864 | { |
821 | int ret; | 865 | int ret; |
822 | 866 | ||
823 | ret = GNUNET_MYSQL_prepared_statement_run (delete_value, | 867 | ret = prepared_statement_run (plugin, |
824 | NULL, | 868 | plugin->delete_value, |
825 | MYSQL_TYPE_LONGLONG, | 869 | NULL, |
826 | &vkey, GNUNET_YES, -1); | 870 | MYSQL_TYPE_LONGLONG, |
871 | &vkey, GNUNET_YES, -1); | ||
827 | if (ret > 0) | 872 | if (ret > 0) |
828 | ret = GNUNET_OK; | 873 | ret = GNUNET_OK; |
829 | return ret; | 874 | return ret; |
@@ -838,15 +883,17 @@ do_delete_value (unsigned long long vkey) | |||
838 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 883 | * @return GNUNET_OK on success, GNUNET_SYSERR on error |
839 | */ | 884 | */ |
840 | static int | 885 | static int |
841 | do_insert_value (const void *value, unsigned int size, | 886 | do_insert_value (struct Plugin *plugin, |
887 | const void *value, unsigned int size, | ||
842 | unsigned long long *vkey) | 888 | unsigned long long *vkey) |
843 | { | 889 | { |
844 | unsigned long length = size; | 890 | unsigned long length = size; |
845 | 891 | ||
846 | return GNUNET_MYSQL_prepared_statement_run (insert_value, | 892 | return prepared_statement_run (plugin, |
847 | vkey, | 893 | plugin->insert_value, |
848 | MYSQL_TYPE_BLOB, | 894 | vkey, |
849 | value, length, &length, -1); | 895 | MYSQL_TYPE_BLOB, |
896 | value, length, &length, -1); | ||
850 | } | 897 | } |
851 | 898 | ||
852 | /** | 899 | /** |
@@ -856,14 +903,16 @@ do_insert_value (const void *value, unsigned int size, | |||
856 | * @return GNUNET_OK on success, GNUNET_NO if no such value exists, GNUNET_SYSERR on error | 903 | * @return GNUNET_OK on success, GNUNET_NO if no such value exists, GNUNET_SYSERR on error |
857 | */ | 904 | */ |
858 | static int | 905 | static int |
859 | do_delete_entry_by_vkey (unsigned long long vkey) | 906 | do_delete_entry_by_vkey (struct Plugin *plugin, |
907 | unsigned long long vkey) | ||
860 | { | 908 | { |
861 | int ret; | 909 | int ret; |
862 | 910 | ||
863 | ret = GNUNET_MYSQL_prepared_statement_run (delete_entry_by_vkey, | 911 | ret = prepared_statement_run (plugin, |
864 | NULL, | 912 | plugin->delete_entry_by_vkey, |
865 | MYSQL_TYPE_LONGLONG, | 913 | NULL, |
866 | &vkey, GNUNET_YES, -1); | 914 | MYSQL_TYPE_LONGLONG, |
915 | &vkey, GNUNET_YES, -1); | ||
867 | if (ret > 0) | 916 | if (ret > 0) |
868 | ret = GNUNET_OK; | 917 | ret = GNUNET_OK; |
869 | return ret; | 918 | return ret; |
@@ -875,106 +924,256 @@ return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values) | |||
875 | return GNUNET_OK; | 924 | return GNUNET_OK; |
876 | } | 925 | } |
877 | 926 | ||
927 | |||
878 | /** | 928 | /** |
879 | * Given a full (SELECT *) result set from gn080 table, | 929 | * Continuation of "sqlite_next_request". |
880 | * assemble it into a GNUNET_DatastoreValue representation. | ||
881 | * | ||
882 | * Call *without* holding the lock, but while within | ||
883 | * mysql_thread_start/end. | ||
884 | * | 930 | * |
885 | * @param result location where mysql_stmt_fetch stored the results | 931 | * @param next_cls the next context |
886 | * @return NULL on error | 932 | * @param tc the task context (unused) |
887 | */ | 933 | */ |
888 | static GNUNET_DatastoreValue * | 934 | static void |
889 | assembleDatum (MYSQL_BIND * result) | 935 | sqlite_next_request_cont (void *next_cls, |
936 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
890 | { | 937 | { |
891 | GNUNET_DatastoreValue *datum; | 938 | struct NextRequestClosure *nrc = next_cls; |
892 | unsigned int contentSize; | 939 | struct Plugin *plugin; |
940 | int ret; | ||
941 | unsigned int size; | ||
893 | unsigned int type; | 942 | unsigned int type; |
894 | unsigned int prio; | 943 | unsigned int priority; |
895 | unsigned int level; | 944 | unsigned int anonymity; |
896 | unsigned long long exp; | 945 | unsigned long long exp; |
897 | unsigned long long vkey; | 946 | unsigned long long vkey; |
947 | unsigned long hashSize; | ||
948 | GNUNET_HashCode key; | ||
949 | struct GNUNET_TIME_Absolute now; | ||
950 | struct GNUNET_TIME_Absolute expiration; | ||
951 | MYSQL_BIND rbind[7]; | ||
952 | unsigned int contentSize; | ||
898 | unsigned long length; | 953 | unsigned long length; |
899 | MYSQL_BIND rbind[1]; | 954 | MYSQL_BIND dbind[1]; |
900 | int ret; | 955 | char datum[GNUNET_SERVER_MAX_MESSAGE_SIZE]; |
956 | |||
957 | AGAIN: | ||
958 | plugin = nrc->plugin; | ||
959 | plugin->next_task = GNUNET_SCHEDULER_NO_TASK; | ||
960 | plugin->next_task_nc = NULL; | ||
961 | hashSize = sizeof (GNUNET_HashCode); | ||
962 | memset (rbind, 0, sizeof (rbind)); | ||
963 | rbind[0].buffer_type = MYSQL_TYPE_LONG; | ||
964 | rbind[0].buffer = &size; | ||
965 | rbind[0].is_unsigned = 1; | ||
966 | rbind[1].buffer_type = MYSQL_TYPE_LONG; | ||
967 | rbind[1].buffer = &type; | ||
968 | rbind[1].is_unsigned = 1; | ||
969 | rbind[2].buffer_type = MYSQL_TYPE_LONG; | ||
970 | rbind[2].buffer = &priority; | ||
971 | rbind[2].is_unsigned = 1; | ||
972 | rbind[3].buffer_type = MYSQL_TYPE_LONG; | ||
973 | rbind[3].buffer = &anonymity; | ||
974 | rbind[3].is_unsigned = 1; | ||
975 | rbind[4].buffer_type = MYSQL_TYPE_LONGLONG; | ||
976 | rbind[4].buffer = &exp; | ||
977 | rbind[4].is_unsigned = 1; | ||
978 | rbind[5].buffer_type = MYSQL_TYPE_BLOB; | ||
979 | rbind[5].buffer = &key; | ||
980 | rbind[5].buffer_length = hashSize; | ||
981 | rbind[5].length = &hashSize; | ||
982 | rbind[6].buffer_type = MYSQL_TYPE_LONGLONG; | ||
983 | rbind[6].buffer = &vkey; | ||
984 | rbind[6].is_unsigned = GNUNET_YES; | ||
901 | 985 | ||
902 | if ((result[0].buffer_type != MYSQL_TYPE_LONG) || | 986 | now = GNUNET_TIME_absolute_get (); |
903 | (!result[0].is_unsigned) || | 987 | switch (nrc->iter_select) |
904 | (result[1].buffer_type != MYSQL_TYPE_LONG) || | ||
905 | (!result[1].is_unsigned) || | ||
906 | (result[2].buffer_type != MYSQL_TYPE_LONG) || | ||
907 | (!result[2].is_unsigned) || | ||
908 | (result[3].buffer_type != MYSQL_TYPE_LONG) || | ||
909 | (!result[3].is_unsigned) || | ||
910 | (result[4].buffer_type != MYSQL_TYPE_LONGLONG) || | ||
911 | (!result[4].is_unsigned) || | ||
912 | (result[5].buffer_type != MYSQL_TYPE_BLOB) || | ||
913 | (result[5].buffer_length != sizeof (GNUNET_HashCode)) || | ||
914 | (*result[5].length != sizeof (GNUNET_HashCode)) || | ||
915 | (result[6].buffer_type != MYSQL_TYPE_LONGLONG) || | ||
916 | (!result[6].is_unsigned)) | ||
917 | { | 988 | { |
918 | GNUNET_break (0); | 989 | case 0: |
919 | return NULL; /* error */ | 990 | case 1: |
991 | ret = prepared_statement_run_select (plugin, | ||
992 | plugin->iter[nrc->iter_select], | ||
993 | 7, | ||
994 | rbind, | ||
995 | &return_ok, | ||
996 | NULL, | ||
997 | MYSQL_TYPE_LONG, | ||
998 | &nrc->last_prio, | ||
999 | GNUNET_YES, | ||
1000 | MYSQL_TYPE_LONGLONG, | ||
1001 | &nrc->last_vkey, | ||
1002 | GNUNET_YES, | ||
1003 | MYSQL_TYPE_LONG, | ||
1004 | &nrc->last_prio, | ||
1005 | GNUNET_YES, | ||
1006 | MYSQL_TYPE_LONGLONG, | ||
1007 | &nrc->last_vkey, | ||
1008 | GNUNET_YES, -1); | ||
1009 | break; | ||
1010 | case 2: | ||
1011 | ret = prepared_statement_run_select (plugin, | ||
1012 | plugin->iter[nrc->iter_select], | ||
1013 | 7, | ||
1014 | rbind, | ||
1015 | &return_ok, | ||
1016 | NULL, | ||
1017 | MYSQL_TYPE_LONGLONG, | ||
1018 | &nrc->last_expire, | ||
1019 | GNUNET_YES, | ||
1020 | MYSQL_TYPE_LONGLONG, | ||
1021 | &nrc->last_vkey, | ||
1022 | GNUNET_YES, | ||
1023 | MYSQL_TYPE_LONGLONG, | ||
1024 | &nrc->last_expire, | ||
1025 | GNUNET_YES, | ||
1026 | MYSQL_TYPE_LONGLONG, | ||
1027 | &nrc->last_vkey, | ||
1028 | GNUNET_YES, -1); | ||
1029 | break; | ||
1030 | case 3: | ||
1031 | ret = prepared_statement_run_select (plugin, | ||
1032 | plugin->iter[nrc->iter_select], | ||
1033 | 7, | ||
1034 | rbind, | ||
1035 | &return_ok, | ||
1036 | NULL, | ||
1037 | MYSQL_TYPE_LONGLONG, | ||
1038 | &nrc->last_expire, | ||
1039 | GNUNET_YES, | ||
1040 | MYSQL_TYPE_LONGLONG, | ||
1041 | &nrc->last_vkey, | ||
1042 | GNUNET_YES, | ||
1043 | MYSQL_TYPE_LONGLONG, | ||
1044 | &now.value, | ||
1045 | GNUNET_YES, | ||
1046 | MYSQL_TYPE_LONGLONG, | ||
1047 | &nrc->last_expire, | ||
1048 | GNUNET_YES, | ||
1049 | MYSQL_TYPE_LONGLONG, | ||
1050 | &nrc->last_vkey, | ||
1051 | GNUNET_YES, | ||
1052 | MYSQL_TYPE_LONGLONG, | ||
1053 | &now.value, | ||
1054 | GNUNET_YES, -1); | ||
1055 | break; | ||
1056 | default: | ||
1057 | GNUNET_assert (0); | ||
1058 | return; | ||
920 | } | 1059 | } |
921 | 1060 | if (ret != GNUNET_OK) | |
922 | contentSize = *(unsigned int *) result[0].buffer; | 1061 | goto END_SET; |
923 | if (contentSize < sizeof (GNUNET_DatastoreValue)) | 1062 | nrc->last_vkey = vkey; |
924 | return NULL; /* error */ | 1063 | nrc->last_prio = priority; |
925 | if (contentSize > GNUNET_MAX_BUFFER_SIZE) | 1064 | nrc->last_expire = exp; |
1065 | if ((rbind[0].buffer_type != MYSQL_TYPE_LONG) || | ||
1066 | (!rbind[0].is_unsigned) || | ||
1067 | (rbind[1].buffer_type != MYSQL_TYPE_LONG) || | ||
1068 | (!rbind[1].is_unsigned) || | ||
1069 | (rbind[2].buffer_type != MYSQL_TYPE_LONG) || | ||
1070 | (!rbind[2].is_unsigned) || | ||
1071 | (rbind[3].buffer_type != MYSQL_TYPE_LONG) || | ||
1072 | (!rbind[3].is_unsigned) || | ||
1073 | (rbind[4].buffer_type != MYSQL_TYPE_LONGLONG) || | ||
1074 | (!rbind[4].is_unsigned) || | ||
1075 | (rbind[5].buffer_type != MYSQL_TYPE_BLOB) || | ||
1076 | (rbind[5].buffer_length != sizeof (GNUNET_HashCode)) || | ||
1077 | (*rbind[5].length != sizeof (GNUNET_HashCode)) || | ||
1078 | (rbind[6].buffer_type != MYSQL_TYPE_LONGLONG) || | ||
1079 | (!rbind[6].is_unsigned)) | ||
926 | { | 1080 | { |
927 | GNUNET_break (0); /* far too big */ | 1081 | GNUNET_break (0); |
928 | return NULL; | 1082 | goto END_SET; |
1083 | } | ||
1084 | contentSize = *(unsigned int *) rbind[0].buffer; | ||
1085 | if (contentSize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1086 | { | ||
1087 | GNUNET_break (0); /* far too big */ | ||
1088 | goto END_SET; | ||
929 | } | 1089 | } |
930 | contentSize -= sizeof (GNUNET_DatastoreValue); | ||
931 | type = *(unsigned int *) result[1].buffer; | ||
932 | prio = *(unsigned int *) result[2].buffer; | ||
933 | level = *(unsigned int *) result[3].buffer; | ||
934 | exp = *(unsigned long long *) result[4].buffer; | ||
935 | vkey = *(unsigned long long *) result[6].buffer; | ||
936 | datum = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + contentSize); | ||
937 | datum->size = htonl (contentSize + sizeof (GNUNET_DatastoreValue)); | ||
938 | datum->type = htonl (type); | ||
939 | datum->priority = htonl (prio); | ||
940 | datum->anonymity_level = htonl (level); | ||
941 | datum->expiration_time = GNUNET_htonll (exp); | ||
942 | |||
943 | /* now do query on gn072 */ | 1090 | /* now do query on gn072 */ |
944 | length = contentSize; | 1091 | length = contentSize; |
945 | memset (rbind, 0, sizeof (rbind)); | 1092 | memset (rbind, 0, sizeof (rbind)); |
946 | rbind[0].buffer_type = MYSQL_TYPE_BLOB; | 1093 | rbind[0].buffer_type = MYSQL_TYPE_BLOB; |
947 | rbind[0].buffer_length = contentSize; | 1094 | rbind[0].buffer_length = contentSize; |
948 | rbind[0].length = &length; | 1095 | rbind[0].length = &length; |
949 | rbind[0].buffer = &datum[1]; | 1096 | rbind[0].buffer = datum; |
950 | ret = GNUNET_MYSQL_prepared_statement_run_select (select_value, | 1097 | ret = prepared_statement_run_select (plugin, |
951 | 1, | 1098 | plugin->select_value, |
952 | rbind, | 1099 | 1, |
953 | &return_ok, | 1100 | dbind, |
954 | NULL, | 1101 | &return_ok, |
955 | MYSQL_TYPE_LONGLONG, | 1102 | NULL, |
956 | &vkey, GNUNET_YES, -1); | 1103 | MYSQL_TYPE_LONGLONG, |
957 | GNUNET_break (ret <= 1); /* should only have one result! */ | 1104 | &vkey, GNUNET_YES, -1); |
1105 | GNUNET_break (ret <= 1); /* should only have one rbind! */ | ||
958 | if (ret > 0) | 1106 | if (ret > 0) |
959 | ret = GNUNET_OK; | 1107 | ret = GNUNET_OK; |
960 | if ((ret != GNUNET_OK) || | 1108 | if ((ret != GNUNET_OK) || |
961 | (rbind[0].buffer_length != contentSize) || (length != contentSize)) | 1109 | (dbind[0].buffer_length != contentSize) || (length != contentSize)) |
962 | { | 1110 | { |
963 | GNUNET_break (ret != 0); /* should have one result! */ | 1111 | GNUNET_break (ret != 0); /* should have one rbind! */ |
964 | GNUNET_break (length == contentSize); /* length should match! */ | 1112 | GNUNET_break (length == contentSize); /* length should match! */ |
965 | GNUNET_break (rbind[0].buffer_length == contentSize); /* length should be internally consistent! */ | 1113 | GNUNET_break (dbind[0].buffer_length == contentSize); /* length should be internally consistent! */ |
966 | do_delete_value (vkey); | 1114 | do_delete_value (plugin, vkey); |
967 | if (ret != 0) | 1115 | if (ret != 0) |
968 | do_delete_entry_by_vkey (vkey); | 1116 | do_delete_entry_by_vkey (plugin, vkey); |
969 | content_size -= ntohl (datum->size); | 1117 | plugin->content_size -= contentSize; |
970 | GNUNET_free (datum); | 1118 | goto AGAIN; |
971 | return NULL; | 1119 | } |
1120 | expiration.value = exp; | ||
1121 | ret = nrc->dviter (nrc->dviter_cls, | ||
1122 | nrc, | ||
1123 | &key, | ||
1124 | contentSize, | ||
1125 | datum, | ||
1126 | type, | ||
1127 | priority, | ||
1128 | anonymity, | ||
1129 | expiration, | ||
1130 | vkey); | ||
1131 | if (ret == GNUNET_SYSERR) | ||
1132 | { | ||
1133 | /* is this correct, or should we not call iter again period? */ | ||
1134 | goto END_SET; | ||
1135 | } | ||
1136 | if (ret == GNUNET_NO) | ||
1137 | { | ||
1138 | do_delete_value (plugin, vkey); | ||
1139 | do_delete_entry_by_vkey (plugin, vkey); | ||
1140 | plugin->content_size -= contentSize; | ||
972 | } | 1141 | } |
973 | return datum; | 1142 | return; |
1143 | END_SET: | ||
1144 | /* call dviter with "end of set" */ | ||
1145 | return; | ||
974 | } | 1146 | } |
975 | 1147 | ||
976 | 1148 | ||
977 | /** | 1149 | /** |
1150 | * Function invoked on behalf of a "PluginIterator" | ||
1151 | * asking the database plugin to call the iterator | ||
1152 | * with the next item. | ||
1153 | * | ||
1154 | * @param next_cls whatever argument was given | ||
1155 | * to the PluginIterator as "next_cls". | ||
1156 | * @param end_it set to GNUNET_YES if we | ||
1157 | * should terminate the iteration early | ||
1158 | * (iterator should be still called once more | ||
1159 | * to signal the end of the iteration). | ||
1160 | */ | ||
1161 | static void | ||
1162 | mysql_plugin_next_request (void *next_cls, | ||
1163 | int end_it) | ||
1164 | { | ||
1165 | struct NextRequestClosure *nrc = next_cls; | ||
1166 | |||
1167 | if (GNUNET_YES == end_it) | ||
1168 | nrc->end_it = GNUNET_YES; | ||
1169 | nrc->plugin->next_task_nc = nrc; | ||
1170 | nrc->plugin->next_task = GNUNET_SCHEDULER_add_now (nrc->plugin->env->sched, | ||
1171 | &sqlite_next_request_cont, | ||
1172 | nrc); | ||
1173 | } | ||
1174 | |||
1175 | |||
1176 | /** | ||
978 | * Iterate over the items in the datastore | 1177 | * Iterate over the items in the datastore |
979 | * using the given query to select and order | 1178 | * using the given query to select and order |
980 | * the items. | 1179 | * the items. |
@@ -983,175 +1182,40 @@ assembleDatum (MYSQL_BIND * result) | |||
983 | * Use 0 for any type. | 1182 | * Use 0 for any type. |
984 | * @param iter never NULL | 1183 | * @param iter never NULL |
985 | * @param is_asc are we using ascending order? | 1184 | * @param is_asc are we using ascending order? |
986 | * @return the number of results, GNUNET_SYSERR if the | ||
987 | * iter is non-NULL and aborted the iteration | ||
988 | */ | 1185 | */ |
989 | static int | 1186 | static void |
990 | iterateHelper (struct Plugin *plugin, | 1187 | iterateHelper (struct Plugin *plugin, |
991 | unsigned int type, | 1188 | unsigned int type, |
992 | int is_asc, | 1189 | int is_asc, |
993 | unsigned int iter_select, GNUNET_DatastoreValueIterator dviter, | 1190 | unsigned int iter_select, |
994 | void *closure) | 1191 | PluginIterator dviter, |
1192 | void *dviter_cls) | ||
995 | { | 1193 | { |
996 | GNUNET_DatastoreValue *datum; | 1194 | struct NextRequestClosure *nrc; |
997 | int count; | 1195 | |
998 | int ret; | 1196 | nrc = GNUNET_malloc (sizeof (struct NextRequestClosure)); |
999 | unsigned int last_prio; | 1197 | nrc->plugin = plugin; |
1000 | unsigned long long last_expire; | 1198 | nrc->type = type; |
1001 | unsigned long long last_vkey; | 1199 | nrc->iter_select = iter_select; |
1002 | unsigned int size; | 1200 | nrc->dviter = dviter; |
1003 | unsigned int rtype; | 1201 | nrc->dviter_cls = dviter_cls; |
1004 | unsigned int prio; | ||
1005 | unsigned int level; | ||
1006 | unsigned long long expiration; | ||
1007 | unsigned long long vkey; | ||
1008 | unsigned long hashSize; | ||
1009 | GNUNET_HashCode key; | ||
1010 | GNUNET_CronTime now; | ||
1011 | MYSQL_BIND rbind[7]; | ||
1012 | 1202 | ||
1013 | if (is_asc) | 1203 | if (is_asc) |
1014 | { | 1204 | { |
1015 | last_prio = 0; | 1205 | nrc->last_prio = 0; |
1016 | last_vkey = 0; | 1206 | nrc->last_vkey = 0; |
1017 | last_expire = 0; | 1207 | nrc->last_expire = 0; |
1018 | } | 1208 | } |
1019 | else | 1209 | else |
1020 | { | 1210 | { |
1021 | last_prio = 0x7FFFFFFFL; | 1211 | nrc->last_prio = 0x7FFFFFFFL; |
1022 | last_vkey = 0x7FFFFFFFFFFFFFFFLL; /* MySQL only supports 63 bits */ | 1212 | nrc->last_vkey = 0x7FFFFFFFFFFFFFFFLL; /* MySQL only supports 63 bits */ |
1023 | last_expire = 0x7FFFFFFFFFFFFFFFLL; /* MySQL only supports 63 bits */ | 1213 | nrc->last_expire = 0x7FFFFFFFFFFFFFFFLL; /* MySQL only supports 63 bits */ |
1024 | } | 1214 | } |
1025 | hashSize = sizeof (GNUNET_HashCode); | 1215 | mysql_plugin_next_request (nrc, GNUNET_NO); |
1026 | memset (rbind, 0, sizeof (rbind)); | ||
1027 | rbind[0].buffer_type = MYSQL_TYPE_LONG; | ||
1028 | rbind[0].buffer = &size; | ||
1029 | rbind[0].is_unsigned = 1; | ||
1030 | rbind[1].buffer_type = MYSQL_TYPE_LONG; | ||
1031 | rbind[1].buffer = &rtype; | ||
1032 | rbind[1].is_unsigned = 1; | ||
1033 | rbind[2].buffer_type = MYSQL_TYPE_LONG; | ||
1034 | rbind[2].buffer = &prio; | ||
1035 | rbind[2].is_unsigned = 1; | ||
1036 | rbind[3].buffer_type = MYSQL_TYPE_LONG; | ||
1037 | rbind[3].buffer = &level; | ||
1038 | rbind[3].is_unsigned = 1; | ||
1039 | rbind[4].buffer_type = MYSQL_TYPE_LONGLONG; | ||
1040 | rbind[4].buffer = &expiration; | ||
1041 | rbind[4].is_unsigned = 1; | ||
1042 | rbind[5].buffer_type = MYSQL_TYPE_BLOB; | ||
1043 | rbind[5].buffer = &key; | ||
1044 | rbind[5].buffer_length = hashSize; | ||
1045 | rbind[5].length = &hashSize; | ||
1046 | rbind[6].buffer_type = MYSQL_TYPE_LONGLONG; | ||
1047 | rbind[6].buffer = &vkey; | ||
1048 | rbind[6].is_unsigned = GNUNET_YES; | ||
1049 | |||
1050 | now = GNUNET_get_time (); | ||
1051 | count = 0; | ||
1052 | while (1) | ||
1053 | { | ||
1054 | switch (iter_select) | ||
1055 | { | ||
1056 | case 0: | ||
1057 | case 1: | ||
1058 | ret = prepared_statement_run_select (iter[iter_select], | ||
1059 | 7, | ||
1060 | rbind, | ||
1061 | &return_ok, | ||
1062 | NULL, | ||
1063 | MYSQL_TYPE_LONG, | ||
1064 | &last_prio, | ||
1065 | GNUNET_YES, | ||
1066 | MYSQL_TYPE_LONGLONG, | ||
1067 | &last_vkey, | ||
1068 | GNUNET_YES, | ||
1069 | MYSQL_TYPE_LONG, | ||
1070 | &last_prio, | ||
1071 | GNUNET_YES, | ||
1072 | MYSQL_TYPE_LONGLONG, | ||
1073 | &last_vkey, | ||
1074 | GNUNET_YES, -1); | ||
1075 | break; | ||
1076 | case 2: | ||
1077 | ret = prepared_statement_run_select (iter[iter_select], | ||
1078 | 7, | ||
1079 | rbind, | ||
1080 | &return_ok, | ||
1081 | NULL, | ||
1082 | MYSQL_TYPE_LONGLONG, | ||
1083 | &last_expire, | ||
1084 | GNUNET_YES, | ||
1085 | MYSQL_TYPE_LONGLONG, | ||
1086 | &last_vkey, | ||
1087 | GNUNET_YES, | ||
1088 | MYSQL_TYPE_LONGLONG, | ||
1089 | &last_expire, | ||
1090 | GNUNET_YES, | ||
1091 | MYSQL_TYPE_LONGLONG, | ||
1092 | &last_vkey, | ||
1093 | GNUNET_YES, -1); | ||
1094 | break; | ||
1095 | case 3: | ||
1096 | ret = prepared_statement_run_select (iter[iter_select], | ||
1097 | 7, | ||
1098 | rbind, | ||
1099 | &return_ok, | ||
1100 | NULL, | ||
1101 | MYSQL_TYPE_LONGLONG, | ||
1102 | &last_expire, | ||
1103 | GNUNET_YES, | ||
1104 | MYSQL_TYPE_LONGLONG, | ||
1105 | &last_vkey, | ||
1106 | GNUNET_YES, | ||
1107 | MYSQL_TYPE_LONGLONG, | ||
1108 | &now, | ||
1109 | GNUNET_YES, | ||
1110 | MYSQL_TYPE_LONGLONG, | ||
1111 | &last_expire, | ||
1112 | GNUNET_YES, | ||
1113 | MYSQL_TYPE_LONGLONG, | ||
1114 | &last_vkey, | ||
1115 | GNUNET_YES, | ||
1116 | MYSQL_TYPE_LONGLONG, | ||
1117 | &now, | ||
1118 | GNUNET_YES, -1); | ||
1119 | break; | ||
1120 | default: | ||
1121 | GNUNET_break (0); | ||
1122 | return GNUNET_SYSERR; | ||
1123 | } | ||
1124 | if (ret != GNUNET_OK) | ||
1125 | break; | ||
1126 | last_vkey = vkey; | ||
1127 | last_prio = prio; | ||
1128 | last_expire = expiration; | ||
1129 | count++; | ||
1130 | if (dviter != NULL) | ||
1131 | { | ||
1132 | datum = assembleDatum (rbind); | ||
1133 | if (datum == NULL) | ||
1134 | continue; | ||
1135 | ret = dviter (&key, datum, closure, vkey); | ||
1136 | if (ret == GNUNET_SYSERR) | ||
1137 | { | ||
1138 | GNUNET_free (datum); | ||
1139 | break; | ||
1140 | } | ||
1141 | if (ret == GNUNET_NO) | ||
1142 | { | ||
1143 | do_delete_value (vkey); | ||
1144 | do_delete_entry_by_vkey (vkey); | ||
1145 | content_size -= ntohl (datum->size); | ||
1146 | } | ||
1147 | GNUNET_free (datum); | ||
1148 | } | ||
1149 | } | ||
1150 | return count; | ||
1151 | } | 1216 | } |
1152 | 1217 | ||
1153 | 1218 | ||
1154 | |||
1155 | /** | 1219 | /** |
1156 | * Get an estimate of how much space the database is | 1220 | * Get an estimate of how much space the database is |
1157 | * currently using. | 1221 | * currently using. |
@@ -1193,39 +1257,25 @@ mysql_plugin_put (void *cls, | |||
1193 | char **msg) | 1257 | char **msg) |
1194 | { | 1258 | { |
1195 | struct Plugin *plugin = cls; | 1259 | struct Plugin *plugin = cls; |
1196 | |||
1197 | unsigned long contentSize; | ||
1198 | unsigned long hashSize; | 1260 | unsigned long hashSize; |
1199 | unsigned long hashSize2; | 1261 | unsigned long hashSize2; |
1200 | unsigned int size; | ||
1201 | unsigned int type; | ||
1202 | unsigned int prio; | ||
1203 | unsigned int level; | ||
1204 | unsigned long long expiration; | ||
1205 | unsigned long long vkey; | 1262 | unsigned long long vkey; |
1206 | GNUNET_HashCode vhash; | 1263 | GNUNET_HashCode vhash; |
1207 | 1264 | ||
1208 | if (((ntohl (value->size) < sizeof (GNUNET_DatastoreValue))) || | 1265 | if (size > MAX_DATUM_SIZE) |
1209 | ((ntohl (value->size) - sizeof (GNUNET_DatastoreValue)) > | ||
1210 | MAX_DATUM_SIZE)) | ||
1211 | { | 1266 | { |
1212 | GNUNET_break (0); | 1267 | GNUNET_break (0); |
1213 | return GNUNET_SYSERR; | 1268 | return GNUNET_SYSERR; |
1214 | } | 1269 | } |
1215 | hashSize = sizeof (GNUNET_HashCode); | 1270 | hashSize = sizeof (GNUNET_HashCode); |
1216 | hashSize2 = sizeof (GNUNET_HashCode); | 1271 | hashSize2 = sizeof (GNUNET_HashCode); |
1217 | size = ntohl (value->size); | 1272 | GNUNET_CRYPTO_hash (data, size, &vhash); |
1218 | type = ntohl (value->type); | 1273 | if (GNUNET_OK != do_insert_value (plugin, |
1219 | prio = ntohl (value->priority); | 1274 | data, size, &vkey)) |
1220 | level = ntohl (value->anonymity_level); | ||
1221 | expiration = GNUNET_ntohll (value->expiration_time); | ||
1222 | contentSize = ntohl (value->size) - sizeof (GNUNET_DatastoreValue); | ||
1223 | GNUNET_hash (&value[1], contentSize, &vhash); | ||
1224 | |||
1225 | if (GNUNET_OK != do_insert_value (&value[1], contentSize, &vkey)) | ||
1226 | return GNUNET_SYSERR; | 1275 | return GNUNET_SYSERR; |
1227 | if (GNUNET_OK != | 1276 | if (GNUNET_OK != |
1228 | prepared_statement_run (insert_entry, | 1277 | prepared_statement_run (plugin, |
1278 | plugin->insert_entry, | ||
1229 | NULL, | 1279 | NULL, |
1230 | MYSQL_TYPE_LONG, | 1280 | MYSQL_TYPE_LONG, |
1231 | &size, | 1281 | &size, |
@@ -1234,13 +1284,13 @@ mysql_plugin_put (void *cls, | |||
1234 | &type, | 1284 | &type, |
1235 | GNUNET_YES, | 1285 | GNUNET_YES, |
1236 | MYSQL_TYPE_LONG, | 1286 | MYSQL_TYPE_LONG, |
1237 | &prio, | 1287 | &priority, |
1238 | GNUNET_YES, | 1288 | GNUNET_YES, |
1239 | MYSQL_TYPE_LONG, | 1289 | MYSQL_TYPE_LONG, |
1240 | &level, | 1290 | &anonymity, |
1241 | GNUNET_YES, | 1291 | GNUNET_YES, |
1242 | MYSQL_TYPE_LONGLONG, | 1292 | MYSQL_TYPE_LONGLONG, |
1243 | &expiration, | 1293 | &expiration.value, |
1244 | GNUNET_YES, | 1294 | GNUNET_YES, |
1245 | MYSQL_TYPE_BLOB, | 1295 | MYSQL_TYPE_BLOB, |
1246 | key, | 1296 | key, |
@@ -1253,32 +1303,34 @@ mysql_plugin_put (void *cls, | |||
1253 | MYSQL_TYPE_LONGLONG, | 1303 | MYSQL_TYPE_LONGLONG, |
1254 | &vkey, GNUNET_YES, -1)) | 1304 | &vkey, GNUNET_YES, -1)) |
1255 | { | 1305 | { |
1256 | do_delete_value (vkey); | 1306 | do_delete_value (plugin, vkey); |
1257 | return GNUNET_SYSERR; | 1307 | return GNUNET_SYSERR; |
1258 | } | 1308 | } |
1259 | plugin->content_size += ntohl (value->size); | 1309 | plugin->content_size += size; |
1260 | return GNUNET_OK; | 1310 | return GNUNET_OK; |
1261 | } | 1311 | } |
1262 | 1312 | ||
1263 | 1313 | ||
1264 | /** | 1314 | /** |
1265 | * Function invoked on behalf of a "PluginIterator" | 1315 | * Select a subset of the items in the datastore and call |
1266 | * asking the database plugin to call the iterator | 1316 | * the given iterator for each of them. |
1267 | * with the next item. | ||
1268 | * | 1317 | * |
1269 | * @param next_cls whatever argument was given | 1318 | * @param cls our "struct Plugin*" |
1270 | * to the PluginIterator as "next_cls". | 1319 | * @param type entries of which type should be considered? |
1271 | * @param end_it set to GNUNET_YES if we | 1320 | * Use 0 for any type. |
1272 | * should terminate the iteration early | 1321 | * @param iter function to call on each matching value; |
1273 | * (iterator should be still called once more | 1322 | * will be called once with a NULL value at the end |
1274 | * to signal the end of the iteration). | 1323 | * @param iter_cls closure for iter |
1275 | */ | 1324 | */ |
1276 | static void | 1325 | static void |
1277 | mysql_plugin_next_request (void *next_cls, | 1326 | mysql_plugin_iter_low_priority (void *cls, |
1278 | int end_it) | 1327 | enum GNUNET_BLOCK_Type type, |
1328 | PluginIterator iter, | ||
1329 | void *iter_cls) | ||
1279 | { | 1330 | { |
1280 | struct Plugin *plugin = cls; | 1331 | struct Plugin *plugin = cls; |
1281 | GNUNET_break (0); | 1332 | iterateHelper (plugin, type, GNUNET_YES, |
1333 | 0, iter, iter_cls); | ||
1282 | } | 1334 | } |
1283 | 1335 | ||
1284 | 1336 | ||
@@ -1319,14 +1371,19 @@ mysql_plugin_get (void *cls, | |||
1319 | unsigned long long expiration; | 1371 | unsigned long long expiration; |
1320 | unsigned long long vkey; | 1372 | unsigned long long vkey; |
1321 | unsigned long long last_vkey; | 1373 | unsigned long long last_vkey; |
1322 | GNUNET_DatastoreValue *datum; | ||
1323 | GNUNET_HashCode key; | ||
1324 | unsigned long hashSize; | 1374 | unsigned long hashSize; |
1325 | unsigned long hashSize2; | 1375 | unsigned long hashSize2; |
1326 | MYSQL_BIND rbind[7]; | 1376 | MYSQL_BIND rbind[7]; |
1327 | 1377 | ||
1378 | if (iter == NULL) | ||
1379 | return; | ||
1328 | if (key == NULL) | 1380 | if (key == NULL) |
1329 | return iterateLowPriority (type, iter, closure); | 1381 | { |
1382 | mysql_plugin_iter_low_priority (plugin, | ||
1383 | type, | ||
1384 | iter, iter_cls); | ||
1385 | return; | ||
1386 | } | ||
1330 | hashSize = sizeof (GNUNET_HashCode); | 1387 | hashSize = sizeof (GNUNET_HashCode); |
1331 | hashSize2 = sizeof (GNUNET_HashCode); | 1388 | hashSize2 = sizeof (GNUNET_HashCode); |
1332 | memset (rbind, 0, sizeof (rbind)); | 1389 | memset (rbind, 0, sizeof (rbind)); |
@@ -1340,7 +1397,8 @@ mysql_plugin_get (void *cls, | |||
1340 | { | 1397 | { |
1341 | ret = | 1398 | ret = |
1342 | prepared_statement_run_select | 1399 | prepared_statement_run_select |
1343 | (count_entry_by_hash_vhash_and_type, 1, rbind, &return_ok, NULL, | 1400 | (plugin, |
1401 | plugin->count_entry_by_hash_vhash_and_type, 1, rbind, &return_ok, NULL, | ||
1344 | MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, | 1402 | MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, |
1345 | vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONG, &type, GNUNET_YES, | 1403 | vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONG, &type, GNUNET_YES, |
1346 | -1); | 1404 | -1); |
@@ -1349,7 +1407,8 @@ mysql_plugin_get (void *cls, | |||
1349 | { | 1407 | { |
1350 | ret = | 1408 | ret = |
1351 | prepared_statement_run_select | 1409 | prepared_statement_run_select |
1352 | (count_entry_by_hash_and_type, 1, rbind, &return_ok, NULL, | 1410 | (plugin, |
1411 | plugin->count_entry_by_hash_and_type, 1, rbind, &return_ok, NULL, | ||
1353 | MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_LONG, | 1412 | MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_LONG, |
1354 | &type, GNUNET_YES, -1); | 1413 | &type, GNUNET_YES, -1); |
1355 | 1414 | ||
@@ -1361,7 +1420,8 @@ mysql_plugin_get (void *cls, | |||
1361 | { | 1420 | { |
1362 | ret = | 1421 | ret = |
1363 | prepared_statement_run_select | 1422 | prepared_statement_run_select |
1364 | (count_entry_by_hash_and_vhash, 1, rbind, &return_ok, NULL, | 1423 | (plugin, |
1424 | plugin->count_entry_by_hash_and_vhash, 1, rbind, &return_ok, NULL, | ||
1365 | MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, | 1425 | MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, |
1366 | vhash, hashSize2, &hashSize2, -1); | 1426 | vhash, hashSize2, &hashSize2, -1); |
1367 | 1427 | ||
@@ -1369,21 +1429,22 @@ mysql_plugin_get (void *cls, | |||
1369 | else | 1429 | else |
1370 | { | 1430 | { |
1371 | ret = | 1431 | ret = |
1372 | GNUNET_MYSQL_prepared_statement_run_select (count_entry_by_hash, | 1432 | prepared_statement_run_select (plugin, |
1373 | 1, rbind, &return_ok, | 1433 | plugin->count_entry_by_hash, |
1374 | NULL, MYSQL_TYPE_BLOB, | 1434 | 1, rbind, &return_ok, |
1375 | key, hashSize2, | 1435 | NULL, MYSQL_TYPE_BLOB, |
1376 | &hashSize2, -1); | 1436 | key, hashSize2, |
1437 | &hashSize2, -1); | ||
1377 | } | 1438 | } |
1378 | } | 1439 | } |
1379 | if ((ret != GNUNET_OK) || (-1 == total)) | 1440 | if ((ret != GNUNET_OK) || (-1 == total)) |
1380 | return GNUNET_SYSERR; | 1441 | return; |
1381 | if ((iter == NULL) || (total == 0)) | 1442 | if (total == 0) |
1382 | return (int) total; | 1443 | return; |
1383 | 1444 | ||
1384 | last_vkey = 0; | 1445 | last_vkey = 0; |
1385 | count = 0; | 1446 | count = 0; |
1386 | off = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, total); | 1447 | off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total); |
1387 | 1448 | ||
1388 | memset (rbind, 0, sizeof (rbind)); | 1449 | memset (rbind, 0, sizeof (rbind)); |
1389 | rbind[0].buffer_type = MYSQL_TYPE_LONG; | 1450 | rbind[0].buffer_type = MYSQL_TYPE_LONG; |
@@ -1402,7 +1463,7 @@ mysql_plugin_get (void *cls, | |||
1402 | rbind[4].buffer = &expiration; | 1463 | rbind[4].buffer = &expiration; |
1403 | rbind[4].is_unsigned = GNUNET_YES; | 1464 | rbind[4].is_unsigned = GNUNET_YES; |
1404 | rbind[5].buffer_type = MYSQL_TYPE_BLOB; | 1465 | rbind[5].buffer_type = MYSQL_TYPE_BLOB; |
1405 | rbind[5].buffer = &key; | 1466 | rbind[5].buffer = (void*) key; |
1406 | rbind[5].buffer_length = hashSize; | 1467 | rbind[5].buffer_length = hashSize; |
1407 | rbind[5].length = &hashSize; | 1468 | rbind[5].length = &hashSize; |
1408 | rbind[6].buffer_type = MYSQL_TYPE_LONGLONG; | 1469 | rbind[6].buffer_type = MYSQL_TYPE_LONGLONG; |
@@ -1420,7 +1481,8 @@ mysql_plugin_get (void *cls, | |||
1420 | { | 1481 | { |
1421 | ret = | 1482 | ret = |
1422 | prepared_statement_run_select | 1483 | prepared_statement_run_select |
1423 | (select_entry_by_hash_vhash_and_type, 7, rbind, &return_ok, | 1484 | (plugin, |
1485 | plugin->select_entry_by_hash_vhash_and_type, 7, rbind, &return_ok, | ||
1424 | NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, | 1486 | NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1425 | MYSQL_TYPE_BLOB, vhash, hashSize2, &hashSize2, | 1487 | MYSQL_TYPE_BLOB, vhash, hashSize2, &hashSize2, |
1426 | MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, | 1488 | MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, |
@@ -1431,7 +1493,8 @@ mysql_plugin_get (void *cls, | |||
1431 | { | 1493 | { |
1432 | ret = | 1494 | ret = |
1433 | prepared_statement_run_select | 1495 | prepared_statement_run_select |
1434 | (select_entry_by_hash_and_type, 7, rbind, &return_ok, NULL, | 1496 | (plugin, |
1497 | plugin->select_entry_by_hash_and_type, 7, rbind, &return_ok, NULL, | ||
1435 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, | 1498 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1436 | MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, | 1499 | MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, |
1437 | &type, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, GNUNET_YES, | 1500 | &type, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, GNUNET_YES, |
@@ -1444,7 +1507,8 @@ mysql_plugin_get (void *cls, | |||
1444 | { | 1507 | { |
1445 | ret = | 1508 | ret = |
1446 | prepared_statement_run_select | 1509 | prepared_statement_run_select |
1447 | (select_entry_by_hash_and_vhash, 7, rbind, &return_ok, NULL, | 1510 | (plugin, |
1511 | plugin->select_entry_by_hash_and_vhash, 7, rbind, &return_ok, NULL, | ||
1448 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, | 1512 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, |
1449 | vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONGLONG, | 1513 | vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONGLONG, |
1450 | &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, | 1514 | &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, |
@@ -1454,7 +1518,8 @@ mysql_plugin_get (void *cls, | |||
1454 | { | 1518 | { |
1455 | ret = | 1519 | ret = |
1456 | prepared_statement_run_select | 1520 | prepared_statement_run_select |
1457 | (select_entry_by_hash, 7, rbind, &return_ok, NULL, | 1521 | (plugin, |
1522 | plugin->select_entry_by_hash, 7, rbind, &return_ok, NULL, | ||
1458 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, | 1523 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1459 | MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, | 1524 | MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, |
1460 | &limit_off, GNUNET_YES, -1); | 1525 | &limit_off, GNUNET_YES, -1); |
@@ -1463,23 +1528,24 @@ mysql_plugin_get (void *cls, | |||
1463 | if (ret != GNUNET_OK) | 1528 | if (ret != GNUNET_OK) |
1464 | break; | 1529 | break; |
1465 | last_vkey = vkey; | 1530 | last_vkey = vkey; |
1531 | #if FIXME | ||
1466 | datum = assembleDatum (rbind); | 1532 | datum = assembleDatum (rbind); |
1467 | if (datum == NULL) | 1533 | if (datum == NULL) |
1468 | continue; | 1534 | continue; |
1469 | count++; | 1535 | count++; |
1470 | ret = iter (&key, datum, closure, vkey); | 1536 | ret = iter (iter_cls, key, datum, vkey); |
1537 | #endif | ||
1538 | ret = GNUNET_SYSERR; | ||
1471 | if (ret == GNUNET_SYSERR) | 1539 | if (ret == GNUNET_SYSERR) |
1472 | { | 1540 | { |
1473 | GNUNET_free (datum); | ||
1474 | break; | 1541 | break; |
1475 | } | 1542 | } |
1476 | if (ret == GNUNET_NO) | 1543 | if (ret == GNUNET_NO) |
1477 | { | 1544 | { |
1478 | do_delete_value (vkey); | 1545 | do_delete_value (plugin, vkey); |
1479 | do_delete_entry_by_vkey (vkey); | 1546 | do_delete_entry_by_vkey (plugin, vkey); |
1480 | content_size -= ntohl (datum->size); | 1547 | plugin->content_size -= size; |
1481 | } | 1548 | } |
1482 | GNUNET_free (datum); | ||
1483 | if (count + off == total) | 1549 | if (count + off == total) |
1484 | last_vkey = 0; /* back to start */ | 1550 | last_vkey = 0; /* back to start */ |
1485 | if (count == total) | 1551 | if (count == total) |
@@ -1551,36 +1617,13 @@ mysql_plugin_update (void *cls, | |||
1551 | * @param iter_cls closure for iter | 1617 | * @param iter_cls closure for iter |
1552 | */ | 1618 | */ |
1553 | static void | 1619 | static void |
1554 | mysql_plugin_iter_low_priority (void *cls, | ||
1555 | enum GNUNET_BLOCK_Type type, | ||
1556 | PluginIterator iter, | ||
1557 | void *iter_cls) | ||
1558 | { | ||
1559 | struct Plugin *plugin = cls; | ||
1560 | iterateHelper (plugin, type, GNUNET_YES, | ||
1561 | 0, iter, iter_cls); | ||
1562 | } | ||
1563 | |||
1564 | |||
1565 | /** | ||
1566 | * Select a subset of the items in the datastore and call | ||
1567 | * the given iterator for each of them. | ||
1568 | * | ||
1569 | * @param cls our "struct Plugin*" | ||
1570 | * @param type entries of which type should be considered? | ||
1571 | * Use 0 for any type. | ||
1572 | * @param iter function to call on each matching value; | ||
1573 | * will be called once with a NULL value at the end | ||
1574 | * @param iter_cls closure for iter | ||
1575 | */ | ||
1576 | static void | ||
1577 | mysql_plugin_iter_zero_anonymity (void *cls, | 1620 | mysql_plugin_iter_zero_anonymity (void *cls, |
1578 | enum GNUNET_BLOCK_Type type, | 1621 | enum GNUNET_BLOCK_Type type, |
1579 | PluginIterator iter, | 1622 | PluginIterator iter, |
1580 | void *iter_cls) | 1623 | void *iter_cls) |
1581 | { | 1624 | { |
1582 | struct Plugin *plugin = cls; | 1625 | struct Plugin *plugin = cls; |
1583 | iterateHelper (plugin, type, GNUNET_NO, 1, iter, closure); | 1626 | iterateHelper (plugin, type, GNUNET_NO, 1, iter, iter_cls); |
1584 | } | 1627 | } |
1585 | 1628 | ||
1586 | 1629 | ||
@@ -1602,7 +1645,7 @@ mysql_plugin_iter_ascending_expiration (void *cls, | |||
1602 | void *iter_cls) | 1645 | void *iter_cls) |
1603 | { | 1646 | { |
1604 | struct Plugin *plugin = cls; | 1647 | struct Plugin *plugin = cls; |
1605 | iterateHelper (plugin, type, GNUNET_YES, 2, iter, closure); | 1648 | iterateHelper (plugin, type, GNUNET_YES, 2, iter, iter_cls); |
1606 | } | 1649 | } |
1607 | 1650 | ||
1608 | 1651 | ||
@@ -1624,7 +1667,7 @@ mysql_plugin_iter_migration_order (void *cls, | |||
1624 | void *iter_cls) | 1667 | void *iter_cls) |
1625 | { | 1668 | { |
1626 | struct Plugin *plugin = cls; | 1669 | struct Plugin *plugin = cls; |
1627 | iterateHelper (plugin, 0, GNUNET_NO, 3, iter, closure); | 1670 | iterateHelper (plugin, 0, GNUNET_NO, 3, iter, iter_cls); |
1628 | } | 1671 | } |
1629 | 1672 | ||
1630 | 1673 | ||
@@ -1641,12 +1684,12 @@ mysql_plugin_iter_migration_order (void *cls, | |||
1641 | */ | 1684 | */ |
1642 | static void | 1685 | static void |
1643 | mysql_plugin_iter_all_now (void *cls, | 1686 | mysql_plugin_iter_all_now (void *cls, |
1644 | enum GNUNET_BLOCK_Type type, | 1687 | enum GNUNET_BLOCK_Type type, |
1645 | PluginIterator iter, | 1688 | PluginIterator iter, |
1646 | void *iter_cls) | 1689 | void *iter_cls) |
1647 | { | 1690 | { |
1648 | struct Plugin *plugin = cls; | 1691 | struct Plugin *plugin = cls; |
1649 | iterateHelper (plugin, 0, GNUNET_YES, 0, iter, closure); | 1692 | iterateHelper (plugin, 0, GNUNET_YES, 0, iter, iter_cls); |
1650 | } | 1693 | } |
1651 | 1694 | ||
1652 | 1695 | ||
@@ -1734,14 +1777,14 @@ libgnunet_plugin_datastore_mysql_init (void *cls) | |||
1734 | || PINIT (plugin->iter[2], SELECT_IT_EXPIRATION_TIME) | 1777 | || PINIT (plugin->iter[2], SELECT_IT_EXPIRATION_TIME) |
1735 | || PINIT (plugin->iter[3], SELECT_IT_MIGRATION_ORDER)) | 1778 | || PINIT (plugin->iter[3], SELECT_IT_MIGRATION_ORDER)) |
1736 | { | 1779 | { |
1737 | GNUNET_MYSQL_database_close (db); | 1780 | iclose (plugin); |
1738 | db = NULL; | 1781 | GNUNET_free_non_null (plugin->cnffile); |
1739 | return GNUNET_SYSERR; | 1782 | GNUNET_free (plugin); |
1783 | return NULL; | ||
1740 | } | 1784 | } |
1741 | #undef PINIT | 1785 | #undef PINIT |
1742 | #undef MRUNS | 1786 | #undef MRUNS |
1743 | 1787 | ||
1744 | |||
1745 | api = GNUNET_malloc (sizeof (struct GNUNET_DATASTORE_PluginFunctions)); | 1788 | api = GNUNET_malloc (sizeof (struct GNUNET_DATASTORE_PluginFunctions)); |
1746 | api->cls = plugin; | 1789 | api->cls = plugin; |
1747 | api->get_size = &mysql_plugin_get_size; | 1790 | api->get_size = &mysql_plugin_get_size; |
@@ -1773,9 +1816,16 @@ libgnunet_plugin_datastore_mysql_done (void *cls) | |||
1773 | struct Plugin *plugin = api->cls; | 1816 | struct Plugin *plugin = api->cls; |
1774 | 1817 | ||
1775 | iclose (plugin); | 1818 | iclose (plugin); |
1819 | if (plugin->next_task != GNUNET_SCHEDULER_NO_TASK) | ||
1820 | { | ||
1821 | GNUNET_SCHEDULER_cancel (plugin->env->sched, | ||
1822 | plugin->next_task); | ||
1823 | plugin->next_task = GNUNET_SCHEDULER_NO_TASK; | ||
1824 | GNUNET_free (plugin->next_task_nc); | ||
1825 | plugin->next_task_nc = NULL; | ||
1826 | } | ||
1776 | GNUNET_free_non_null (plugin->cnffile); | 1827 | GNUNET_free_non_null (plugin->cnffile); |
1777 | GNUNET_free (plugin); | 1828 | GNUNET_free (plugin); |
1778 | GNUNET_free (plugin); | ||
1779 | GNUNET_free (api); | 1829 | GNUNET_free (api); |
1780 | mysql_library_end (); | 1830 | mysql_library_end (); |
1781 | return NULL; | 1831 | return NULL; |