aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-08-03 14:54:15 +0000
committerChristian Grothoff <christian@grothoff.org>2010-08-03 14:54:15 +0000
commit09ab545e236ac5493bbdb07a9db9e9d8f75735b8 (patch)
tree2b21946a2921cc7140240c3293fe1cee3565aa4d /src
parent13eaa0fb07e617de117caffcf1b3d960e611b4b2 (diff)
downloadgnunet-09ab545e236ac5493bbdb07a9db9e9d8f75735b8.tar.gz
gnunet-09ab545e236ac5493bbdb07a9db9e9d8f75735b8.zip
mysql hacking
Diffstat (limited to 'src')
-rw-r--r--src/datastore/perf_datastore_api.c2
-rw-r--r--src/datastore/plugin_datastore_mysql.c541
-rw-r--r--src/datastore/test_datastore_api.c5
-rw-r--r--src/datastore/test_datastore_api_management.c5
4 files changed, 317 insertions, 236 deletions
diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c
index 8b040c222..61724e964 100644
--- a/src/datastore/perf_datastore_api.c
+++ b/src/datastore/perf_datastore_api.c
@@ -363,7 +363,7 @@ check ()
363#if VERBOSE 363#if VERBOSE
364 "-L", "DEBUG", 364 "-L", "DEBUG",
365#endif 365#endif
366 "-c", "test_datastore_api_data.conf", NULL); 366 "-c", cfg_name, NULL);
367 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, 367 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
368 argv, "perf-datastore-api", "nohelp", 368 argv, "perf-datastore-api", "nohelp",
369 options, &run, NULL); 369 options, &run, NULL);
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index 234e2fd93..447ce7176 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -211,10 +211,45 @@ struct GNUNET_MysqlStatementHandle
211 211
212}; 212};
213 213
214/**
215 * Context for the universal iterator.
216 */
217struct NextRequestClosure;
218
219/**
220 * Type of a function that will prepare
221 * the next iteration.
222 *
223 * @param cls closure
224 * @param nc the next context; NULL for the last
225 * call which gives the callback a chance to
226 * clean up the closure
227 * @return GNUNET_OK on success, GNUNET_NO if there are
228 * no more values, GNUNET_SYSERR on error
229 */
230typedef int (*PrepareFunction)(void *cls,
231 struct NextRequestClosure *nc);
232
233
214struct NextRequestClosure 234struct NextRequestClosure
215{ 235{
216 struct Plugin *plugin; 236 struct Plugin *plugin;
217 237
238 struct GNUNET_TIME_Absolute now;
239
240 /**
241 * Function to call to prepare the next
242 * iteration.
243 */
244 PrepareFunction prep;
245
246 /**
247 * Closure for prep.
248 */
249 void *prep_cls;
250
251 MYSQL_BIND rbind[7];
252
218 unsigned int type; 253 unsigned int type;
219 254
220 unsigned int iter_select; 255 unsigned int iter_select;
@@ -254,7 +289,6 @@ struct Plugin
254 */ 289 */
255 char *cnffile; 290 char *cnffile;
256 291
257
258 /** 292 /**
259 * Closure of the 'next_task' (must be freed if 'next_task' is cancelled). 293 * Closure of the 'next_task' (must be freed if 'next_task' is cancelled).
260 */ 294 */
@@ -380,6 +414,25 @@ get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg)
380} 414}
381 415
382 416
417
418/**
419 * Free a prepared statement.
420 */
421static void
422prepared_statement_destroy (struct Plugin *plugin,
423 struct GNUNET_MysqlStatementHandle
424 *s)
425{
426 GNUNET_CONTAINER_DLL_remove (plugin->shead,
427 plugin->stail,
428 s);
429 if (s->valid)
430 mysql_stmt_close (s->statement);
431 GNUNET_free (s->query);
432 GNUNET_free (s);
433}
434
435
383/** 436/**
384 * Close database connection and all prepared statements (we got a DB 437 * Close database connection and all prepared statements (we got a DB
385 * disconnect error). 438 * disconnect error).
@@ -390,16 +443,9 @@ iclose (struct Plugin *plugin)
390 struct GNUNET_MysqlStatementHandle *spos; 443 struct GNUNET_MysqlStatementHandle *spos;
391 444
392 spos = plugin->shead; 445 spos = plugin->shead;
393 while (spos != NULL) 446 while (NULL != plugin->shead)
394 { 447 prepared_statement_destroy (plugin,
395 if (spos->statement != NULL) 448 plugin->shead);
396 {
397 mysql_stmt_close (spos->statement);
398 spos->statement = NULL;
399 }
400 spos->valid = GNUNET_NO;
401 spos = spos->next;
402 }
403 if (plugin->dbf != NULL) 449 if (plugin->dbf != NULL)
404 { 450 {
405 mysql_close (plugin->dbf); 451 mysql_close (plugin->dbf);
@@ -521,6 +567,7 @@ run_statement (struct Plugin *plugin,
521} 567}
522 568
523 569
570#if 0
524/** 571/**
525 * Run the given MySQL SELECT statement. The statement 572 * Run the given MySQL SELECT statement. The statement
526 * must have only a single result (one column, one row). 573 * must have only a single result (one column, one row).
@@ -557,6 +604,7 @@ run_statement_select (struct Plugin *plugin,
557 mysql_free_result (sql_res); 604 mysql_free_result (sql_res);
558 return ret; 605 return ret;
559} 606}
607#endif
560 608
561 609
562/** 610/**
@@ -613,24 +661,7 @@ prepare_statement (struct Plugin *plugin,
613 } 661 }
614 ret->valid = GNUNET_YES; 662 ret->valid = GNUNET_YES;
615 return GNUNET_OK; 663 return GNUNET_OK;
616}
617
618 664
619/**
620 * Free a prepared statement.
621 */
622static void
623prepared_statement_destroy (struct Plugin *plugin,
624 struct GNUNET_MysqlStatementHandle
625 *s)
626{
627 GNUNET_CONTAINER_DLL_remove (plugin->shead,
628 plugin->stail,
629 s);
630 if (s->valid)
631 mysql_stmt_close (s->statement);
632 GNUNET_free (s->query);
633 GNUNET_free (s);
634} 665}
635 666
636 667
@@ -925,65 +956,17 @@ return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values)
925} 956}
926 957
927 958
928/** 959static int
929 * Continuation of "sqlite_next_request". 960iterator_helper_prepare (void *cls,
930 * 961 struct NextRequestClosure *nrc)
931 * @param next_cls the next context
932 * @param tc the task context (unused)
933 */
934static void
935sqlite_next_request_cont (void *next_cls,
936 const struct GNUNET_SCHEDULER_TaskContext *tc)
937{ 962{
938 struct NextRequestClosure *nrc = next_cls;
939 struct Plugin *plugin; 963 struct Plugin *plugin;
940 int ret; 964 int ret;
941 unsigned int size;
942 unsigned int type;
943 unsigned int priority;
944 unsigned int anonymity;
945 unsigned long long exp;
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;
953 unsigned long length;
954 MYSQL_BIND dbind[1];
955 char datum[GNUNET_SERVER_MAX_MESSAGE_SIZE];
956 965
957 AGAIN: 966 if (nrc == NULL)
967 return GNUNET_NO;
958 plugin = nrc->plugin; 968 plugin = nrc->plugin;
959 plugin->next_task = GNUNET_SCHEDULER_NO_TASK; 969 ret = GNUNET_SYSERR;
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;
985
986 now = GNUNET_TIME_absolute_get ();
987 switch (nrc->iter_select) 970 switch (nrc->iter_select)
988 { 971 {
989 case 0: 972 case 0:
@@ -991,7 +974,7 @@ sqlite_next_request_cont (void *next_cls,
991 ret = prepared_statement_run_select (plugin, 974 ret = prepared_statement_run_select (plugin,
992 plugin->iter[nrc->iter_select], 975 plugin->iter[nrc->iter_select],
993 7, 976 7,
994 rbind, 977 nrc->rbind,
995 &return_ok, 978 &return_ok,
996 NULL, 979 NULL,
997 MYSQL_TYPE_LONG, 980 MYSQL_TYPE_LONG,
@@ -1011,7 +994,7 @@ sqlite_next_request_cont (void *next_cls,
1011 ret = prepared_statement_run_select (plugin, 994 ret = prepared_statement_run_select (plugin,
1012 plugin->iter[nrc->iter_select], 995 plugin->iter[nrc->iter_select],
1013 7, 996 7,
1014 rbind, 997 nrc->rbind,
1015 &return_ok, 998 &return_ok,
1016 NULL, 999 NULL,
1017 MYSQL_TYPE_LONGLONG, 1000 MYSQL_TYPE_LONGLONG,
@@ -1031,7 +1014,7 @@ sqlite_next_request_cont (void *next_cls,
1031 ret = prepared_statement_run_select (plugin, 1014 ret = prepared_statement_run_select (plugin,
1032 plugin->iter[nrc->iter_select], 1015 plugin->iter[nrc->iter_select],
1033 7, 1016 7,
1034 rbind, 1017 nrc->rbind,
1035 &return_ok, 1018 &return_ok,
1036 NULL, 1019 NULL,
1037 MYSQL_TYPE_LONGLONG, 1020 MYSQL_TYPE_LONGLONG,
@@ -1041,7 +1024,7 @@ sqlite_next_request_cont (void *next_cls,
1041 &nrc->last_vkey, 1024 &nrc->last_vkey,
1042 GNUNET_YES, 1025 GNUNET_YES,
1043 MYSQL_TYPE_LONGLONG, 1026 MYSQL_TYPE_LONGLONG,
1044 &now.value, 1027 &nrc->now.value,
1045 GNUNET_YES, 1028 GNUNET_YES,
1046 MYSQL_TYPE_LONGLONG, 1029 MYSQL_TYPE_LONGLONG,
1047 &nrc->last_expire, 1030 &nrc->last_expire,
@@ -1050,15 +1033,80 @@ sqlite_next_request_cont (void *next_cls,
1050 &nrc->last_vkey, 1033 &nrc->last_vkey,
1051 GNUNET_YES, 1034 GNUNET_YES,
1052 MYSQL_TYPE_LONGLONG, 1035 MYSQL_TYPE_LONGLONG,
1053 &now.value, 1036 &nrc->now.value,
1054 GNUNET_YES, -1); 1037 GNUNET_YES, -1);
1055 break; 1038 break;
1056 default: 1039 default:
1057 GNUNET_assert (0); 1040 GNUNET_assert (0);
1058 return;
1059 } 1041 }
1042 return ret;
1043}
1044
1045
1046/**
1047 * Continuation of "sqlite_next_request".
1048 *
1049 * @param next_cls the next context
1050 * @param tc the task context (unused)
1051 */
1052static void
1053sqlite_next_request_cont (void *next_cls,
1054 const struct GNUNET_SCHEDULER_TaskContext *tc)
1055{
1056 struct NextRequestClosure *nrc = next_cls;
1057 struct Plugin *plugin;
1058 int ret;
1059 unsigned int size;
1060 unsigned int type;
1061 unsigned int priority;
1062 unsigned int anonymity;
1063 unsigned long long exp;
1064 unsigned long long vkey;
1065 unsigned long hashSize;
1066 GNUNET_HashCode key;
1067 struct GNUNET_TIME_Absolute expiration;
1068 unsigned int contentSize;
1069 unsigned long length;
1070 MYSQL_BIND *rbind; /* size 7 */
1071 MYSQL_BIND dbind[1];
1072 char datum[GNUNET_SERVER_MAX_MESSAGE_SIZE];
1073
1074 plugin = nrc->plugin;
1075 plugin->next_task = GNUNET_SCHEDULER_NO_TASK;
1076 plugin->next_task_nc = NULL;
1077
1078 AGAIN:
1079 ret = nrc->prep (nrc->prep_cls,
1080 nrc);
1060 if (ret != GNUNET_OK) 1081 if (ret != GNUNET_OK)
1061 goto END_SET; 1082 goto END_SET;
1083 nrc->now = GNUNET_TIME_absolute_get ();
1084 hashSize = sizeof (GNUNET_HashCode);
1085 memset (nrc->rbind, 0, sizeof (nrc->rbind));
1086 rbind = nrc->rbind;
1087 rbind[0].buffer_type = MYSQL_TYPE_LONG;
1088 rbind[0].buffer = &size;
1089 rbind[0].is_unsigned = 1;
1090 rbind[1].buffer_type = MYSQL_TYPE_LONG;
1091 rbind[1].buffer = &type;
1092 rbind[1].is_unsigned = 1;
1093 rbind[2].buffer_type = MYSQL_TYPE_LONG;
1094 rbind[2].buffer = &priority;
1095 rbind[2].is_unsigned = 1;
1096 rbind[3].buffer_type = MYSQL_TYPE_LONG;
1097 rbind[3].buffer = &anonymity;
1098 rbind[3].is_unsigned = 1;
1099 rbind[4].buffer_type = MYSQL_TYPE_LONGLONG;
1100 rbind[4].buffer = &exp;
1101 rbind[4].is_unsigned = 1;
1102 rbind[5].buffer_type = MYSQL_TYPE_BLOB;
1103 rbind[5].buffer = &key;
1104 rbind[5].buffer_length = hashSize;
1105 rbind[5].length = &hashSize;
1106 rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
1107 rbind[6].buffer = &vkey;
1108 rbind[6].is_unsigned = GNUNET_YES;
1109
1062 nrc->last_vkey = vkey; 1110 nrc->last_vkey = vkey;
1063 nrc->last_prio = priority; 1111 nrc->last_prio = priority;
1064 nrc->last_expire = exp; 1112 nrc->last_expire = exp;
@@ -1142,7 +1190,11 @@ sqlite_next_request_cont (void *next_cls,
1142 return; 1190 return;
1143 END_SET: 1191 END_SET:
1144 /* call dviter with "end of set" */ 1192 /* call dviter with "end of set" */
1145 return; 1193 nrc->dviter (nrc->dviter_cls,
1194 NULL, NULL, 0, NULL, 0, 0, 0,
1195 GNUNET_TIME_UNIT_ZERO_ABS, 0);
1196 nrc->prep (nrc->prep_cls, NULL);
1197 GNUNET_free (nrc);
1146} 1198}
1147 1199
1148 1200
@@ -1199,7 +1251,7 @@ iterateHelper (struct Plugin *plugin,
1199 nrc->iter_select = iter_select; 1251 nrc->iter_select = iter_select;
1200 nrc->dviter = dviter; 1252 nrc->dviter = dviter;
1201 nrc->dviter_cls = dviter_cls; 1253 nrc->dviter_cls = dviter_cls;
1202 1254 nrc->prep = &iterator_helper_prepare;
1203 if (is_asc) 1255 if (is_asc)
1204 { 1256 {
1205 nrc->last_prio = 0; 1257 nrc->last_prio = 0;
@@ -1334,6 +1386,128 @@ mysql_plugin_iter_low_priority (void *cls,
1334} 1386}
1335 1387
1336 1388
1389struct GetContext
1390{
1391 GNUNET_HashCode key;
1392 GNUNET_HashCode vhash;
1393
1394 unsigned int prio;
1395 unsigned int anonymity;
1396 unsigned int limit_off;
1397 unsigned long long expiration;
1398 unsigned long long vkey;
1399 unsigned long long total;
1400 int off;
1401 int count;
1402 int have_vhash;
1403 unsigned long size; /* OBSOLETE! */
1404 unsigned long hashSize;
1405};
1406
1407
1408static int
1409get_statement_prepare (void *cls,
1410 struct NextRequestClosure *nrc)
1411{
1412 struct GetContext *gc = cls;
1413 struct Plugin *plugin;
1414 MYSQL_BIND *rbind;
1415 int ret;
1416
1417 if (NULL == nrc)
1418 {
1419 GNUNET_free (gc);
1420 return GNUNET_NO;
1421 }
1422 if (gc->count == gc->total)
1423 return GNUNET_NO;
1424 plugin = nrc->plugin;
1425 memset (nrc->rbind, 0, sizeof (nrc->rbind));
1426 gc->hashSize = sizeof (GNUNET_HashCode);
1427 rbind = nrc->rbind;
1428 rbind[0].buffer_type = MYSQL_TYPE_LONG;
1429 rbind[0].buffer = &gc->size;
1430 rbind[0].is_unsigned = GNUNET_YES;
1431 rbind[1].buffer_type = MYSQL_TYPE_LONG;
1432 rbind[1].buffer = &nrc->type;
1433 rbind[1].is_unsigned = GNUNET_YES;
1434 rbind[2].buffer_type = MYSQL_TYPE_LONG;
1435 rbind[2].buffer = &nrc->last_prio;
1436 rbind[2].is_unsigned = GNUNET_YES;
1437 rbind[3].buffer_type = MYSQL_TYPE_LONG;
1438 rbind[3].buffer = &gc->anonymity;
1439 rbind[3].is_unsigned = GNUNET_YES;
1440 rbind[4].buffer_type = MYSQL_TYPE_LONGLONG;
1441 rbind[4].buffer = &gc->expiration;
1442 rbind[4].is_unsigned = GNUNET_YES;
1443 rbind[5].buffer_type = MYSQL_TYPE_BLOB;
1444 rbind[5].buffer = &gc->key;
1445 rbind[5].buffer_length = gc->hashSize;
1446 rbind[5].length = &gc->hashSize;
1447 rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
1448 rbind[6].buffer = &gc->vkey;
1449 rbind[6].is_unsigned = GNUNET_YES;
1450 if (gc->count == 0)
1451 gc->limit_off = gc->off;
1452 else
1453 gc->limit_off = 0;
1454
1455 if (nrc->type != 0)
1456 {
1457 if (gc->have_vhash)
1458 {
1459 ret =
1460 prepared_statement_run_select
1461 (plugin,
1462 plugin->select_entry_by_hash_vhash_and_type, 7, nrc->rbind, &return_ok,
1463 NULL, MYSQL_TYPE_BLOB, &gc->key, gc->hashSize, &gc->hashSize,
1464 MYSQL_TYPE_BLOB, &gc->vhash, gc->hashSize, &gc->hashSize,
1465 MYSQL_TYPE_LONGLONG, &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG,
1466 &nrc->type, GNUNET_YES, MYSQL_TYPE_LONG, &gc->limit_off, GNUNET_YES,
1467 -1);
1468 }
1469 else
1470 {
1471 ret =
1472 prepared_statement_run_select
1473 (plugin,
1474 plugin->select_entry_by_hash_and_type, 7, nrc->rbind, &return_ok, NULL,
1475 MYSQL_TYPE_BLOB, &gc->key, gc->hashSize, &gc->hashSize,
1476 MYSQL_TYPE_LONGLONG, &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG,
1477 &nrc->type, GNUNET_YES, MYSQL_TYPE_LONG, &gc->limit_off, GNUNET_YES,
1478 -1);
1479 }
1480 }
1481 else
1482 {
1483 if (gc->have_vhash)
1484 {
1485 ret =
1486 prepared_statement_run_select
1487 (plugin,
1488 plugin->select_entry_by_hash_and_vhash, 7, nrc->rbind, &return_ok, NULL,
1489 MYSQL_TYPE_BLOB, &gc->key, gc->hashSize, &gc->hashSize, MYSQL_TYPE_BLOB,
1490 &gc->vhash, gc->hashSize, &gc->hashSize, MYSQL_TYPE_LONGLONG,
1491 &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, &gc->limit_off,
1492 GNUNET_YES, -1);
1493 }
1494 else
1495 {
1496 ret =
1497 prepared_statement_run_select
1498 (plugin,
1499 plugin->select_entry_by_hash, 7, nrc->rbind, &return_ok, NULL,
1500 MYSQL_TYPE_BLOB, &gc->key, gc->hashSize, &gc->hashSize,
1501 MYSQL_TYPE_LONGLONG, &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG,
1502 &gc->limit_off, GNUNET_YES, -1);
1503 }
1504 }
1505 if (gc->count + gc->off == gc->total)
1506 nrc->last_vkey = 0; /* back to start */
1507 return ret;
1508}
1509
1510
1337/** 1511/**
1338 * Iterate over the results for a particular key 1512 * Iterate over the results for a particular key
1339 * in the datastore. 1513 * in the datastore.
@@ -1359,21 +1533,12 @@ mysql_plugin_get (void *cls,
1359 PluginIterator iter, void *iter_cls) 1533 PluginIterator iter, void *iter_cls)
1360{ 1534{
1361 struct Plugin *plugin = cls; 1535 struct Plugin *plugin = cls;
1362 int count;
1363 unsigned long long total;
1364 int off;
1365 int ret; 1536 int ret;
1366 unsigned int size; 1537 MYSQL_BIND cbind[1];
1367 unsigned int rtype; 1538 struct GetContext *gc;
1368 unsigned int prio; 1539 struct NextRequestClosure *nrc;
1369 unsigned int level; 1540 unsigned long long total;
1370 unsigned int limit_off;
1371 unsigned long long expiration;
1372 unsigned long long vkey;
1373 unsigned long long last_vkey;
1374 unsigned long hashSize; 1541 unsigned long hashSize;
1375 unsigned long hashSize2;
1376 MYSQL_BIND rbind[7];
1377 1542
1378 if (iter == NULL) 1543 if (iter == NULL)
1379 return; 1544 return;
@@ -1385,12 +1550,11 @@ mysql_plugin_get (void *cls,
1385 return; 1550 return;
1386 } 1551 }
1387 hashSize = sizeof (GNUNET_HashCode); 1552 hashSize = sizeof (GNUNET_HashCode);
1388 hashSize2 = sizeof (GNUNET_HashCode); 1553 memset (cbind, 0, sizeof (cbind));
1389 memset (rbind, 0, sizeof (rbind));
1390 total = -1; 1554 total = -1;
1391 rbind[0].buffer_type = MYSQL_TYPE_LONGLONG; 1555 cbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
1392 rbind[0].buffer = &total; 1556 cbind[0].buffer = &total;
1393 rbind[0].is_unsigned = GNUNET_YES; 1557 cbind[0].is_unsigned = GNUNET_YES;
1394 if (type != 0) 1558 if (type != 0)
1395 { 1559 {
1396 if (vhash != NULL) 1560 if (vhash != NULL)
@@ -1398,9 +1562,9 @@ mysql_plugin_get (void *cls,
1398 ret = 1562 ret =
1399 prepared_statement_run_select 1563 prepared_statement_run_select
1400 (plugin, 1564 (plugin,
1401 plugin->count_entry_by_hash_vhash_and_type, 1, rbind, &return_ok, NULL, 1565 plugin->count_entry_by_hash_vhash_and_type, 1, cbind, &return_ok, NULL,
1402 MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, 1566 MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB,
1403 vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONG, &type, GNUNET_YES, 1567 vhash, hashSize, &hashSize, MYSQL_TYPE_LONG, &type, GNUNET_YES,
1404 -1); 1568 -1);
1405 } 1569 }
1406 else 1570 else
@@ -1408,8 +1572,8 @@ mysql_plugin_get (void *cls,
1408 ret = 1572 ret =
1409 prepared_statement_run_select 1573 prepared_statement_run_select
1410 (plugin, 1574 (plugin,
1411 plugin->count_entry_by_hash_and_type, 1, rbind, &return_ok, NULL, 1575 plugin->count_entry_by_hash_and_type, 1, cbind, &return_ok, NULL,
1412 MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_LONG, 1576 MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_LONG,
1413 &type, GNUNET_YES, -1); 1577 &type, GNUNET_YES, -1);
1414 1578
1415 } 1579 }
@@ -1421,9 +1585,9 @@ mysql_plugin_get (void *cls,
1421 ret = 1585 ret =
1422 prepared_statement_run_select 1586 prepared_statement_run_select
1423 (plugin, 1587 (plugin,
1424 plugin->count_entry_by_hash_and_vhash, 1, rbind, &return_ok, NULL, 1588 plugin->count_entry_by_hash_and_vhash, 1, cbind, &return_ok, NULL,
1425 MYSQL_TYPE_BLOB, key, hashSize2, &hashSize2, MYSQL_TYPE_BLOB, 1589 MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB,
1426 vhash, hashSize2, &hashSize2, -1); 1590 vhash, hashSize, &hashSize, -1);
1427 1591
1428 } 1592 }
1429 else 1593 else
@@ -1431,126 +1595,40 @@ mysql_plugin_get (void *cls,
1431 ret = 1595 ret =
1432 prepared_statement_run_select (plugin, 1596 prepared_statement_run_select (plugin,
1433 plugin->count_entry_by_hash, 1597 plugin->count_entry_by_hash,
1434 1, rbind, &return_ok, 1598 1, cbind, &return_ok,
1435 NULL, MYSQL_TYPE_BLOB, 1599 NULL, MYSQL_TYPE_BLOB,
1436 key, hashSize2, 1600 key, hashSize,
1437 &hashSize2, -1); 1601 &hashSize, -1);
1438 } 1602 }
1439 } 1603 }
1440 if ((ret != GNUNET_OK) || (-1 == total)) 1604 if ((ret != GNUNET_OK) || (-1 == total) || (0 == total))
1441 return;
1442 if (total == 0)
1443 return;
1444
1445 last_vkey = 0;
1446 count = 0;
1447 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
1448
1449 memset (rbind, 0, sizeof (rbind));
1450 rbind[0].buffer_type = MYSQL_TYPE_LONG;
1451 rbind[0].buffer = &size;
1452 rbind[0].is_unsigned = GNUNET_YES;
1453 rbind[1].buffer_type = MYSQL_TYPE_LONG;
1454 rbind[1].buffer = &rtype;
1455 rbind[1].is_unsigned = GNUNET_YES;
1456 rbind[2].buffer_type = MYSQL_TYPE_LONG;
1457 rbind[2].buffer = &prio;
1458 rbind[2].is_unsigned = GNUNET_YES;
1459 rbind[3].buffer_type = MYSQL_TYPE_LONG;
1460 rbind[3].buffer = &level;
1461 rbind[3].is_unsigned = GNUNET_YES;
1462 rbind[4].buffer_type = MYSQL_TYPE_LONGLONG;
1463 rbind[4].buffer = &expiration;
1464 rbind[4].is_unsigned = GNUNET_YES;
1465 rbind[5].buffer_type = MYSQL_TYPE_BLOB;
1466 rbind[5].buffer = (void*) key;
1467 rbind[5].buffer_length = hashSize;
1468 rbind[5].length = &hashSize;
1469 rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
1470 rbind[6].buffer = &vkey;
1471 rbind[6].is_unsigned = GNUNET_YES;
1472 while (1)
1473 { 1605 {
1474 if (count == 0) 1606 iter (iter_cls,
1475 limit_off = off; 1607 NULL, NULL, 0, NULL, 0, 0, 0,
1476 else 1608 GNUNET_TIME_UNIT_ZERO_ABS, 0);
1477 limit_off = 0; 1609 return;
1478 if (type != 0) 1610 }
1479 { 1611 gc = GNUNET_malloc (sizeof (struct GetContext));
1480 if (vhash != NULL) 1612 gc->key = *key;
1481 { 1613 if (vhash != NULL)
1482 ret = 1614 {
1483 prepared_statement_run_select 1615 gc->have_vhash = GNUNET_YES;
1484 (plugin, 1616 gc->vhash = *vhash;
1485 plugin->select_entry_by_hash_vhash_and_type, 7, rbind, &return_ok,
1486 NULL, MYSQL_TYPE_BLOB, key, hashSize, &hashSize,
1487 MYSQL_TYPE_BLOB, vhash, hashSize2, &hashSize2,
1488 MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG,
1489 &type, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, GNUNET_YES,
1490 -1);
1491 }
1492 else
1493 {
1494 ret =
1495 prepared_statement_run_select
1496 (plugin,
1497 plugin->select_entry_by_hash_and_type, 7, rbind, &return_ok, NULL,
1498 MYSQL_TYPE_BLOB, key, hashSize, &hashSize,
1499 MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG,
1500 &type, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, GNUNET_YES,
1501 -1);
1502 }
1503 }
1504 else
1505 {
1506 if (vhash != NULL)
1507 {
1508 ret =
1509 prepared_statement_run_select
1510 (plugin,
1511 plugin->select_entry_by_hash_and_vhash, 7, rbind, &return_ok, NULL,
1512 MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB,
1513 vhash, hashSize2, &hashSize2, MYSQL_TYPE_LONGLONG,
1514 &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off,
1515 GNUNET_YES, -1);
1516 }
1517 else
1518 {
1519 ret =
1520 prepared_statement_run_select
1521 (plugin,
1522 plugin->select_entry_by_hash, 7, rbind, &return_ok, NULL,
1523 MYSQL_TYPE_BLOB, key, hashSize, &hashSize,
1524 MYSQL_TYPE_LONGLONG, &last_vkey, GNUNET_YES, MYSQL_TYPE_LONG,
1525 &limit_off, GNUNET_YES, -1);
1526 }
1527 }
1528 if (ret != GNUNET_OK)
1529 break;
1530 last_vkey = vkey;
1531#if FIXME
1532 datum = assembleDatum (rbind);
1533 if (datum == NULL)
1534 continue;
1535 count++;
1536 ret = iter (iter_cls, key, datum, vkey);
1537#endif
1538 ret = GNUNET_SYSERR;
1539 if (ret == GNUNET_SYSERR)
1540 {
1541 break;
1542 }
1543 if (ret == GNUNET_NO)
1544 {
1545 do_delete_value (plugin, vkey);
1546 do_delete_entry_by_vkey (plugin, vkey);
1547 plugin->content_size -= size;
1548 }
1549 if (count + off == total)
1550 last_vkey = 0; /* back to start */
1551 if (count == total)
1552 break;
1553 } 1617 }
1618 gc->total = total;
1619 gc->off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
1620
1621
1622 nrc = GNUNET_malloc (sizeof (struct NextRequestClosure));
1623 nrc->plugin = plugin;
1624 nrc->type = type;
1625 nrc->iter_select = -1;
1626 nrc->dviter = iter;
1627 nrc->dviter_cls = iter_cls;
1628 nrc->prep = &get_statement_prepare;
1629 nrc->prep_cls = gc;
1630 nrc->last_vkey = 0; // FIXME: used to be 'vkey', why? where did vkey come from?
1631 mysql_plugin_next_request (nrc, GNUNET_NO);
1554} 1632}
1555 1633
1556 1634
@@ -1821,6 +1899,7 @@ libgnunet_plugin_datastore_mysql_done (void *cls)
1821 GNUNET_SCHEDULER_cancel (plugin->env->sched, 1899 GNUNET_SCHEDULER_cancel (plugin->env->sched,
1822 plugin->next_task); 1900 plugin->next_task);
1823 plugin->next_task = GNUNET_SCHEDULER_NO_TASK; 1901 plugin->next_task = GNUNET_SCHEDULER_NO_TASK;
1902 plugin->next_task_nc->prep (plugin->next_task_nc->prep_cls, NULL);
1824 GNUNET_free (plugin->next_task_nc); 1903 GNUNET_free (plugin->next_task_nc);
1825 plugin->next_task_nc = NULL; 1904 plugin->next_task_nc = NULL;
1826 } 1905 }
diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c
index af2f15da8..ec83e9196 100644
--- a/src/datastore/test_datastore_api.c
+++ b/src/datastore/test_datastore_api.c
@@ -599,9 +599,10 @@ check ()
599{ 599{
600 char cfg_name[128]; 600 char cfg_name[128];
601 pid_t pid; 601 pid_t pid;
602 char *const argv[] = { "test-datastore-api", 602 char *const argv[] = {
603 "test-datastore-api",
603 "-c", 604 "-c",
604 "test_datastore_api_data.conf", 605 cfg_name,
605#if VERBOSE 606#if VERBOSE
606 "-L", "DEBUG", 607 "-L", "DEBUG",
607#endif 608#endif
diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c
index da0eb354b..d0278094f 100644
--- a/src/datastore/test_datastore_api_management.c
+++ b/src/datastore/test_datastore_api_management.c
@@ -321,9 +321,10 @@ check ()
321{ 321{
322 pid_t pid; 322 pid_t pid;
323 char cfg_name[128]; 323 char cfg_name[128];
324 char *const argv[] = { "test-datastore-api-management", 324 char *const argv[] = {
325 "test-datastore-api-management",
325 "-c", 326 "-c",
326 "test_datastore_api_data.conf", 327 cfg_name,
327#if VERBOSE 328#if VERBOSE
328 "-L", "DEBUG", 329 "-L", "DEBUG",
329#endif 330#endif