diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-04-13 19:41:26 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-04-13 19:41:26 +0000 |
commit | 57a074bce8ef0c538d1b1906c9de7482275232fb (patch) | |
tree | 0d8730be01a7e6b42496c406e0715eb0c9ca94e7 /src/datastore | |
parent | 47f30b90cf1f18ac682b6fd3a8c9585811368ee9 (diff) | |
download | gnunet-57a074bce8ef0c538d1b1906c9de7482275232fb.tar.gz gnunet-57a074bce8ef0c538d1b1906c9de7482275232fb.zip |
getting mysql code to compile again, fixes to sqlite code
Diffstat (limited to 'src/datastore')
-rw-r--r-- | src/datastore/plugin_datastore_mysql.c | 572 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_sqlite.c | 135 |
2 files changed, 288 insertions, 419 deletions
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c index f2c4419be..c759763c7 100644 --- a/src/datastore/plugin_datastore_mysql.c +++ b/src/datastore/plugin_datastore_mysql.c | |||
@@ -106,7 +106,6 @@ | |||
106 | * 2) by executing (inside of mysql using the GNUnet database): | 106 | * 2) by executing (inside of mysql using the GNUnet database): |
107 | * @verbatim | 107 | * @verbatim |
108 | mysql> REPAIR TABLE gn090; | 108 | mysql> REPAIR TABLE gn090; |
109 | mysql> REPAIR TABLE gn072; | ||
110 | @endverbatim | 109 | @endverbatim |
111 | * | 110 | * |
112 | * PROBLEMS? | 111 | * PROBLEMS? |
@@ -115,10 +114,6 @@ | |||
115 | * friend is probably the mysql manual. The first thing to check | 114 | * friend is probably the mysql manual. The first thing to check |
116 | * is that mysql is basically operational, that you can connect | 115 | * is that mysql is basically operational, that you can connect |
117 | * to it, create tables, issue queries etc. | 116 | * to it, create tables, issue queries etc. |
118 | * | ||
119 | * TODO: | ||
120 | * - use FOREIGN KEY for 'uid/vkey' | ||
121 | * - consistent naming of uid/vkey | ||
122 | */ | 117 | */ |
123 | 118 | ||
124 | #include "platform.h" | 119 | #include "platform.h" |
@@ -202,7 +197,7 @@ struct NextRequestClosure | |||
202 | */ | 197 | */ |
203 | void *prep_cls; | 198 | void *prep_cls; |
204 | 199 | ||
205 | MYSQL_BIND rbind[6]; | 200 | MYSQL_BIND rbind[7]; |
206 | 201 | ||
207 | enum GNUNET_BLOCK_Type type; | 202 | enum GNUNET_BLOCK_Type type; |
208 | 203 | ||
@@ -210,9 +205,7 @@ struct NextRequestClosure | |||
210 | 205 | ||
211 | void *dviter_cls; | 206 | void *dviter_cls; |
212 | 207 | ||
213 | unsigned long long last_vkey; | 208 | unsigned int count; |
214 | |||
215 | unsigned int last_prio; | ||
216 | 209 | ||
217 | int end_it; | 210 | int end_it; |
218 | }; | 211 | }; |
@@ -228,10 +221,19 @@ struct Plugin | |||
228 | */ | 221 | */ |
229 | struct GNUNET_DATASTORE_PluginEnvironment *env; | 222 | struct GNUNET_DATASTORE_PluginEnvironment *env; |
230 | 223 | ||
224 | /** | ||
225 | * Handle to talk to MySQL. | ||
226 | */ | ||
231 | MYSQL *dbf; | 227 | MYSQL *dbf; |
232 | 228 | ||
229 | /** | ||
230 | * We keep all prepared statements in a DLL. This is the head. | ||
231 | */ | ||
233 | struct GNUNET_MysqlStatementHandle *shead; | 232 | struct GNUNET_MysqlStatementHandle *shead; |
234 | 233 | ||
234 | /** | ||
235 | * We keep all prepared statements in a DLL. This is the tail. | ||
236 | */ | ||
235 | struct GNUNET_MysqlStatementHandle *stail; | 237 | struct GNUNET_MysqlStatementHandle *stail; |
236 | 238 | ||
237 | /** | 239 | /** |
@@ -250,79 +252,54 @@ struct Plugin | |||
250 | GNUNET_SCHEDULER_TaskIdentifier next_task; | 252 | GNUNET_SCHEDULER_TaskIdentifier next_task; |
251 | 253 | ||
252 | /** | 254 | /** |
253 | * Statements dealing with gn072 table | 255 | * Prepared statements. |
254 | */ | 256 | */ |
255 | #define SELECT_VALUE "SELECT value FROM gn072 WHERE vkey=?" | 257 | #define INSERT_ENTRY "INSERT INTO gn090 (repl,type,prio,anonLevel,expire,hash,vhash,value) VALUES (?,?,?,?,?,?,?,?)" |
256 | struct GNUNET_MysqlStatementHandle *select_value; | ||
257 | |||
258 | #define DELETE_VALUE "DELETE FROM gn072 WHERE vkey=?" | ||
259 | struct GNUNET_MysqlStatementHandle *delete_value; | ||
260 | |||
261 | #define INSERT_VALUE "INSERT INTO gn072 (value) VALUES (?)" | ||
262 | struct GNUNET_MysqlStatementHandle *insert_value; | ||
263 | |||
264 | /** | ||
265 | * Statements dealing with gn090 table | ||
266 | */ | ||
267 | #define INSERT_ENTRY "INSERT INTO gn090 (repl,type,prio,anonLevel,expire,hash,vhash,vkey) VALUES (?,?,?,?,?,?,?,?)" | ||
268 | struct GNUNET_MysqlStatementHandle *insert_entry; | 258 | struct GNUNET_MysqlStatementHandle *insert_entry; |
269 | 259 | ||
270 | #define DELETE_ENTRY_BY_VKEY "DELETE FROM gn090 WHERE vkey=?" | 260 | #define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?" |
271 | struct GNUNET_MysqlStatementHandle *delete_entry_by_vkey; | 261 | struct GNUNET_MysqlStatementHandle *delete_entry_by_uid; |
272 | |||
273 | #define SELECT_ENTRY_BY_HASH "SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX (hash_vkey) WHERE hash=? AND vkey > ? ORDER BY vkey ASC LIMIT 1 OFFSET ?" | ||
274 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash; | ||
275 | |||
276 | #define SELECT_ENTRY_BY_HASH_AND_VHASH "SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX (hash_vhash_vkey) WHERE hash=? AND vhash=? AND vkey > ? ORDER BY vkey ASC LIMIT 1 OFFSET ?" | ||
277 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_vhash; | ||
278 | 262 | ||
279 | #define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX (hash_vkey) WHERE hash=? AND vkey > ? AND type=? ORDER BY vkey ASC LIMIT 1 OFFSET ?" | 263 | #define COUNT_ENTRY_BY_HASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash) WHERE hash=?" |
280 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_type; | ||
281 | |||
282 | #define SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX (hash_vhash_vkey) WHERE hash=? AND vhash=? AND vkey > ? AND type=? ORDER BY vkey ASC LIMIT 1 OFFSET ?" | ||
283 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash_vhash_and_type; | ||
284 | |||
285 | #define COUNT_ENTRY_BY_HASH "SELECT count(*) FROM gn090 FORCE INDEX (hash) WHERE hash=?" | ||
286 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash; | 264 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash; |
265 | |||
266 | #define SELECT_ENTRY_BY_HASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_uid) WHERE hash=? ORDER BY uid LIMIT 1 OFFSET ?" | ||
267 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash; | ||
287 | 268 | ||
288 | #define COUNT_ENTRY_BY_HASH_AND_VHASH "SELECT count(*) FROM gn090 FORCE INDEX (hash_vhash_vkey) WHERE hash=? AND vhash=?" | 269 | #define COUNT_ENTRY_BY_HASH_AND_VHASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=?" |
289 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_vhash; | 270 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_vhash; |
290 | 271 | ||
291 | #define COUNT_ENTRY_BY_HASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (hash) WHERE hash=? AND type=?" | 272 | #define SELECT_ENTRY_BY_HASH_AND_VHASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? ORDER BY uid LIMIT 1 OFFSET ?" |
273 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_vhash; | ||
274 | |||
275 | #define COUNT_ENTRY_BY_HASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=?" | ||
292 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_type; | 276 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash_and_type; |
293 | 277 | ||
294 | #define COUNT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (hash_vhash) WHERE hash=? AND vhash=? AND type=?" | 278 | #define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=? ORDER BY uid LIMIT 1 OFFSET ?" |
279 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash_and_type; | ||
280 | |||
281 | #define COUNT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=?" | ||
295 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash_vhash_and_type; | 282 | struct GNUNET_MysqlStatementHandle *count_entry_by_hash_vhash_and_type; |
283 | |||
284 | #define SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=? ORDER BY uid ASC LIMIT 1 OFFSET ?" | ||
285 | struct GNUNET_MysqlStatementHandle *select_entry_by_hash_vhash_and_type; | ||
296 | 286 | ||
297 | #define UPDATE_ENTRY "UPDATE gn090 SET prio=prio+?,expire=IF(expire>=?,expire,?) WHERE vkey=?" | 287 | #define UPDATE_ENTRY "UPDATE gn090 FORCE INDEX (uid) SET prio=prio+?,expire=IF(expire>=?,expire,?) WHERE uid=? LIMIT 1" |
298 | struct GNUNET_MysqlStatementHandle *update_entry; | 288 | struct GNUNET_MysqlStatementHandle *update_entry; |
299 | 289 | ||
300 | #define SELECT_SIZE "SELECT SUM(BIT_LENGTH(value) DIV 8) FROM gn072" | 290 | #define SELECT_SIZE "SELECT SUM(BIT_LENGTH(value) DIV 8) FROM gn090" |
301 | struct GNUNET_MysqlStatementHandle *get_size; | 291 | struct GNUNET_MysqlStatementHandle *get_size; |
302 | 292 | ||
303 | /* warning, slighly crazy mysql statements ahead. Essentially, MySQL does not handle | 293 | #define SELECT_IT_NON_ANONYMOUS "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX(idx_anonLevel_uid) WHERE anonLevel=0 ORDER BY uid DESC LIMIT 1 OFFSET ?" |
304 | "OR" very well, so we need to use UNION instead. And UNION does not | ||
305 | automatically apply a LIMIT on the outermost clause, so we need to | ||
306 | repeat ourselves quite a bit. All hail the performance gods (and thanks | ||
307 | to #mysql on freenode) */ | ||
308 | #define SELECT_IT_NON_ANONYMOUS "(SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX(prio) WHERE (prio = ? AND vkey < ?)"\ | ||
309 | " AND anonLevel=0 ORDER BY prio DESC,vkey DESC LIMIT 1) "\ | ||
310 | "UNION "\ | ||
311 | "(SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX(prio) WHERE (prio < ? AND vkey != ?)"\ | ||
312 | " AND anonLevel=0 ORDER BY prio DESC,vkey DESC LIMIT 1) "\ | ||
313 | "ORDER BY prio DESC,vkey DESC LIMIT 1" | ||
314 | struct GNUNET_MysqlStatementHandle *zero_iter; | 294 | struct GNUNET_MysqlStatementHandle *zero_iter; |
315 | 295 | ||
316 | #define SELECT_IT_EXPIRATION "(SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX(expire) WHERE (expire < ?) "\ | 296 | #define SELECT_IT_EXPIRATION "(SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX(idx_expire_prio) WHERE expire < ? ORDER BY prio ASC LIMIT 1) "\ |
317 | "ORDER BY prio ASC LIMIT 1) "\ | ||
318 | "UNION "\ | 297 | "UNION "\ |
319 | "(SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX(prio) "\ | 298 | "(SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX(idx_prio) ORDER BY prio ASC LIMIT 1) "\ |
320 | "ORDER BY prio ASC LIMIT 1) ORDER BY expire ASC LIMIT 1" | 299 | "ORDER BY expire ASC LIMIT 1" |
321 | struct GNUNET_MysqlStatementHandle *select_expiration; | 300 | struct GNUNET_MysqlStatementHandle *select_expiration; |
322 | 301 | ||
323 | #define SELECT_IT_REPLICATION "SELECT type,prio,anonLevel,expire,hash,vkey FROM gn090 FORCE INDEX(expire) "\ | 302 | #define SELECT_IT_REPLICATION "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX(idx_repl) ORDER BY repl DESC,RAND() LIMIT 1" |
324 | "WHERE expire > ?"\ | ||
325 | " ORDER BY repl DESC,RAND() LIMIT 1" | ||
326 | struct GNUNET_MysqlStatementHandle *select_replication; | 303 | struct GNUNET_MysqlStatementHandle *select_replication; |
327 | 304 | ||
328 | }; | 305 | }; |
@@ -837,114 +814,33 @@ prepared_statement_run (struct Plugin *plugin, | |||
837 | 814 | ||
838 | 815 | ||
839 | /** | 816 | /** |
840 | * Delete an value from the gn072 table. | ||
841 | * | ||
842 | * @param plugin plugin context | ||
843 | * @param vkey vkey identifying the value to delete | ||
844 | * @return GNUNET_OK on success, GNUNET_NO if no such value exists, GNUNET_SYSERR on error | ||
845 | */ | ||
846 | static int | ||
847 | do_delete_value (struct Plugin *plugin, | ||
848 | unsigned long long vkey) | ||
849 | { | ||
850 | int ret; | ||
851 | |||
852 | #if DEBUG_MYSQL | ||
853 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
854 | "Deleting value %llu from gn072 table\n", | ||
855 | vkey); | ||
856 | #endif | ||
857 | ret = prepared_statement_run (plugin, | ||
858 | plugin->delete_value, | ||
859 | NULL, | ||
860 | MYSQL_TYPE_LONGLONG, | ||
861 | &vkey, GNUNET_YES, -1); | ||
862 | if (ret > 0) | ||
863 | { | ||
864 | ret = GNUNET_OK; | ||
865 | } | ||
866 | else | ||
867 | { | ||
868 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
869 | "Deleting value %llu from gn072 table failed\n", | ||
870 | vkey); | ||
871 | } | ||
872 | return ret; | ||
873 | } | ||
874 | |||
875 | /** | ||
876 | * Insert a value into the gn072 table. | ||
877 | * | ||
878 | * @param plugin plugin context | ||
879 | * @param value the value to insert | ||
880 | * @param size size of the value | ||
881 | * @param vkey vkey identifying the value henceforth (set) | ||
882 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
883 | */ | ||
884 | static int | ||
885 | do_insert_value (struct Plugin *plugin, | ||
886 | const void *value, unsigned int size, | ||
887 | unsigned long long *vkey) | ||
888 | { | ||
889 | unsigned long length = size; | ||
890 | int ret; | ||
891 | |||
892 | ret = prepared_statement_run (plugin, | ||
893 | plugin->insert_value, | ||
894 | vkey, | ||
895 | MYSQL_TYPE_BLOB, | ||
896 | value, length, &length, -1); | ||
897 | if (ret == GNUNET_OK) | ||
898 | { | ||
899 | #if DEBUG_MYSQL | ||
900 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
901 | "Inserted value number %llu with length %u into gn072 table\n", | ||
902 | *vkey, | ||
903 | size); | ||
904 | #endif | ||
905 | } | ||
906 | else | ||
907 | { | ||
908 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
909 | "Failed to insert %u byte value into gn072 table\n", | ||
910 | size); | ||
911 | } | ||
912 | return ret; | ||
913 | } | ||
914 | |||
915 | /** | ||
916 | * Delete an entry from the gn090 table. | 817 | * Delete an entry from the gn090 table. |
917 | * | 818 | * |
918 | * @param plugin plugin context | 819 | * @param plugin plugin context |
919 | * @param vkey vkey identifying the entry to delete | 820 | * @param uid unique ID of the entry to delete |
920 | * @return GNUNET_OK on success, GNUNET_NO if no such value exists, GNUNET_SYSERR on error | 821 | * @return GNUNET_OK on success, GNUNET_NO if no such value exists, GNUNET_SYSERR on error |
921 | */ | 822 | */ |
922 | static int | 823 | static int |
923 | do_delete_entry_by_vkey (struct Plugin *plugin, | 824 | do_delete_entry (struct Plugin *plugin, |
924 | unsigned long long vkey) | 825 | unsigned long long uid) |
925 | { | 826 | { |
926 | int ret; | 827 | int ret; |
927 | 828 | ||
928 | #if DEBUG_MYSQL | 829 | #if DEBUG_MYSQL |
929 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 830 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
930 | "Deleting value %llu from gn090 table\n", | 831 | "Deleting value %llu from gn090 table\n", |
931 | vkey); | 832 | uid); |
932 | #endif | 833 | #endif |
933 | ret = prepared_statement_run (plugin, | 834 | ret = prepared_statement_run (plugin, |
934 | plugin->delete_entry_by_vkey, | 835 | plugin->delete_entry_by_uid, |
935 | NULL, | 836 | NULL, |
936 | MYSQL_TYPE_LONGLONG, | 837 | MYSQL_TYPE_LONGLONG, uid, GNUNET_YES, |
937 | &vkey, GNUNET_YES, -1); | 838 | -1); |
938 | if (ret > 0) | 839 | if (ret > 0) |
939 | { | 840 | return GNUNET_OK; |
940 | ret = GNUNET_OK; | 841 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
941 | } | 842 | "Deleting value %llu from gn090 table failed\n", |
942 | else | 843 | uid); |
943 | { | ||
944 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
945 | "Deleting value %llu from gn090 table failed\n", | ||
946 | vkey); | ||
947 | } | ||
948 | return ret; | 844 | return ret; |
949 | } | 845 | } |
950 | 846 | ||
@@ -983,20 +879,20 @@ mysql_next_request_cont (void *next_cls, | |||
983 | unsigned int priority; | 879 | unsigned int priority; |
984 | unsigned int anonymity; | 880 | unsigned int anonymity; |
985 | unsigned long long exp; | 881 | unsigned long long exp; |
986 | unsigned long long vkey; | ||
987 | unsigned long hashSize; | 882 | unsigned long hashSize; |
883 | unsigned long size; | ||
884 | unsigned long long uid; | ||
885 | char value[GNUNET_DATASTORE_MAX_VALUE_SIZE]; | ||
988 | GNUNET_HashCode key; | 886 | GNUNET_HashCode key; |
989 | struct GNUNET_TIME_Absolute expiration; | 887 | struct GNUNET_TIME_Absolute expiration; |
990 | unsigned long length; | 888 | MYSQL_BIND *rbind = nrc->rbind; |
991 | MYSQL_BIND *rbind; /* size 7 */ | ||
992 | MYSQL_BIND dbind[1]; | ||
993 | char datum[GNUNET_SERVER_MAX_MESSAGE_SIZE]; | ||
994 | 889 | ||
995 | plugin = nrc->plugin; | 890 | plugin = nrc->plugin; |
996 | plugin->next_task = GNUNET_SCHEDULER_NO_TASK; | 891 | plugin->next_task = GNUNET_SCHEDULER_NO_TASK; |
997 | plugin->next_task_nc = NULL; | 892 | plugin->next_task_nc = NULL; |
998 | 893 | ||
999 | AGAIN: | 894 | if (GNUNET_YES == nrc->end_it) |
895 | goto END_SET; | ||
1000 | GNUNET_assert (nrc->plugin->next_task == GNUNET_SCHEDULER_NO_TASK); | 896 | GNUNET_assert (nrc->plugin->next_task == GNUNET_SCHEDULER_NO_TASK); |
1001 | nrc->now = GNUNET_TIME_absolute_get (); | 897 | nrc->now = GNUNET_TIME_absolute_get (); |
1002 | hashSize = sizeof (GNUNET_HashCode); | 898 | hashSize = sizeof (GNUNET_HashCode); |
@@ -1018,17 +914,19 @@ mysql_next_request_cont (void *next_cls, | |||
1018 | rbind[4].buffer = &key; | 914 | rbind[4].buffer = &key; |
1019 | rbind[4].buffer_length = hashSize; | 915 | rbind[4].buffer_length = hashSize; |
1020 | rbind[4].length = &hashSize; | 916 | rbind[4].length = &hashSize; |
1021 | rbind[5].buffer_type = MYSQL_TYPE_LONGLONG; | 917 | rbind[5].buffer_type = MYSQL_TYPE_BLOB; |
1022 | rbind[5].buffer = &vkey; | 918 | rbind[5].buffer = value; |
1023 | rbind[5].is_unsigned = GNUNET_YES; | 919 | rbind[5].buffer_length = size = sizeof (value); |
1024 | 920 | rbind[5].length = &size; | |
1025 | if ( (GNUNET_YES == nrc->end_it) || | 921 | rbind[6].buffer_type = MYSQL_TYPE_LONGLONG; |
1026 | (GNUNET_OK != nrc->prep (nrc->prep_cls, | 922 | rbind[6].buffer = &uid; |
1027 | nrc))) | 923 | rbind[6].is_unsigned = 1; |
924 | |||
925 | if (GNUNET_OK != nrc->prep (nrc->prep_cls, | ||
926 | nrc)) | ||
1028 | goto END_SET; | 927 | goto END_SET; |
1029 | nrc->last_vkey = vkey; | ||
1030 | nrc->last_prio = priority; | ||
1031 | GNUNET_assert (nrc->plugin->next_task == GNUNET_SCHEDULER_NO_TASK); | 928 | GNUNET_assert (nrc->plugin->next_task == GNUNET_SCHEDULER_NO_TASK); |
929 | GNUNET_assert (size <= sizeof(value)); | ||
1032 | if ( (rbind[4].buffer_length != sizeof (GNUNET_HashCode)) || | 930 | if ( (rbind[4].buffer_length != sizeof (GNUNET_HashCode)) || |
1033 | (hashSize != sizeof (GNUNET_HashCode)) ) | 931 | (hashSize != sizeof (GNUNET_HashCode)) ) |
1034 | { | 932 | { |
@@ -1037,63 +935,19 @@ mysql_next_request_cont (void *next_cls, | |||
1037 | } | 935 | } |
1038 | #if DEBUG_MYSQL | 936 | #if DEBUG_MYSQL |
1039 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 937 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1040 | "Found value %llu with prio %u, anon %u, expire %llu selecting from gn090 table\n", | 938 | "Found %u-byte value under key `%s' with prio %u, anon %u, expire %llu selecting from gn090 table\n", |
1041 | vkey, | 939 | (unsigned int) size, |
1042 | priority, | ||
1043 | anonymity, | ||
1044 | exp); | ||
1045 | #endif | ||
1046 | /* now do query on gn072 */ | ||
1047 | length = sizeof (datum); | ||
1048 | memset (dbind, 0, sizeof (dbind)); | ||
1049 | dbind[0].buffer_type = MYSQL_TYPE_BLOB; | ||
1050 | dbind[0].buffer_length = length; | ||
1051 | dbind[0].length = &length; | ||
1052 | dbind[0].buffer = datum; | ||
1053 | ret = prepared_statement_run_select (plugin, | ||
1054 | plugin->select_value, | ||
1055 | 1, | ||
1056 | dbind, | ||
1057 | &return_ok, | ||
1058 | NULL, | ||
1059 | MYSQL_TYPE_LONGLONG, | ||
1060 | &vkey, GNUNET_YES, -1); | ||
1061 | GNUNET_break (ret <= 1); /* should only have one rbind! */ | ||
1062 | if (ret > 0) | ||
1063 | ret = GNUNET_OK; | ||
1064 | if (ret != GNUNET_OK) | ||
1065 | { | ||
1066 | GNUNET_break (0); | ||
1067 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1068 | _("Failed to obtain value %llu from table `%s'\n"), | ||
1069 | vkey, | ||
1070 | "gn072"); | ||
1071 | goto AGAIN; | ||
1072 | } | ||
1073 | GNUNET_break (length <= sizeof(datum)); | ||
1074 | #if DEBUG_MYSQL | ||
1075 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1076 | "Calling iterator with value `%s' number %llu of size %u with type %u, priority %u, anonymity %u and expiration %llu\n", | ||
1077 | GNUNET_h2s (&key), | 940 | GNUNET_h2s (&key), |
1078 | vkey, | ||
1079 | length, | ||
1080 | type, | ||
1081 | priority, | 941 | priority, |
1082 | anonymity, | 942 | anonymity, |
1083 | exp); | 943 | exp); |
1084 | #endif | 944 | #endif |
1085 | GNUNET_assert (nrc->plugin->next_task == GNUNET_SCHEDULER_NO_TASK); | ||
1086 | expiration.abs_value = exp; | 945 | expiration.abs_value = exp; |
1087 | ret = nrc->dviter (nrc->dviter_cls, | 946 | ret = nrc->dviter (nrc->dviter_cls, nrc, |
1088 | nrc, | ||
1089 | &key, | 947 | &key, |
1090 | length, | 948 | size, value, |
1091 | datum, | 949 | type, priority, anonymity, expiration, |
1092 | type, | 950 | uid); |
1093 | priority, | ||
1094 | anonymity, | ||
1095 | expiration, | ||
1096 | vkey); | ||
1097 | if (ret == GNUNET_SYSERR) | 951 | if (ret == GNUNET_SYSERR) |
1098 | { | 952 | { |
1099 | nrc->end_it = GNUNET_YES; | 953 | nrc->end_it = GNUNET_YES; |
@@ -1101,11 +955,10 @@ mysql_next_request_cont (void *next_cls, | |||
1101 | } | 955 | } |
1102 | if (ret == GNUNET_NO) | 956 | if (ret == GNUNET_NO) |
1103 | { | 957 | { |
1104 | do_delete_value (plugin, vkey); | 958 | do_delete_entry (plugin, uid); |
1105 | do_delete_entry_by_vkey (plugin, vkey); | 959 | if (size != 0) |
1106 | if (length != 0) | ||
1107 | plugin->env->duc (plugin->env->cls, | 960 | plugin->env->duc (plugin->env->cls, |
1108 | - length); | 961 | - size); |
1109 | } | 962 | } |
1110 | return; | 963 | return; |
1111 | END_SET: | 964 | END_SET: |
@@ -1212,7 +1065,7 @@ mysql_plugin_put (void *cls, | |||
1212 | unsigned long long lexpiration = expiration.abs_value; | 1065 | unsigned long long lexpiration = expiration.abs_value; |
1213 | unsigned long hashSize; | 1066 | unsigned long hashSize; |
1214 | unsigned long hashSize2; | 1067 | unsigned long hashSize2; |
1215 | unsigned long long vkey; | 1068 | unsigned long lsize; |
1216 | GNUNET_HashCode vhash; | 1069 | GNUNET_HashCode vhash; |
1217 | 1070 | ||
1218 | if (size > MAX_DATUM_SIZE) | 1071 | if (size > MAX_DATUM_SIZE) |
@@ -1222,48 +1075,26 @@ mysql_plugin_put (void *cls, | |||
1222 | } | 1075 | } |
1223 | hashSize = sizeof (GNUNET_HashCode); | 1076 | hashSize = sizeof (GNUNET_HashCode); |
1224 | hashSize2 = sizeof (GNUNET_HashCode); | 1077 | hashSize2 = sizeof (GNUNET_HashCode); |
1078 | lsize = size; | ||
1225 | GNUNET_CRYPTO_hash (data, size, &vhash); | 1079 | GNUNET_CRYPTO_hash (data, size, &vhash); |
1226 | if (GNUNET_OK != do_insert_value (plugin, | ||
1227 | data, size, &vkey)) | ||
1228 | return GNUNET_SYSERR; | ||
1229 | if (GNUNET_OK != | 1080 | if (GNUNET_OK != |
1230 | prepared_statement_run (plugin, | 1081 | prepared_statement_run (plugin, |
1231 | plugin->insert_entry, | 1082 | plugin->insert_entry, |
1232 | NULL, | 1083 | NULL, |
1233 | MYSQL_TYPE_LONG, | 1084 | MYSQL_TYPE_LONG, &irepl, GNUNET_YES, |
1234 | &irepl, | 1085 | MYSQL_TYPE_LONG, &itype, GNUNET_YES, |
1235 | GNUNET_YES, | 1086 | MYSQL_TYPE_LONG, &ipriority, GNUNET_YES, |
1236 | MYSQL_TYPE_LONG, | 1087 | MYSQL_TYPE_LONG, &ianonymity, GNUNET_YES, |
1237 | &itype, | 1088 | MYSQL_TYPE_LONGLONG, &lexpiration, GNUNET_YES, |
1238 | GNUNET_YES, | 1089 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1239 | MYSQL_TYPE_LONG, | 1090 | MYSQL_TYPE_BLOB, &vhash, hashSize2, &hashSize2, |
1240 | &ipriority, | 1091 | MYSQL_TYPE_BLOB, data, lsize, &lsize, |
1241 | GNUNET_YES, | 1092 | -1)) |
1242 | MYSQL_TYPE_LONG, | 1093 | return GNUNET_SYSERR; |
1243 | &ianonymity, | ||
1244 | GNUNET_YES, | ||
1245 | MYSQL_TYPE_LONGLONG, | ||
1246 | &lexpiration, | ||
1247 | GNUNET_YES, | ||
1248 | MYSQL_TYPE_BLOB, | ||
1249 | key, | ||
1250 | hashSize, | ||
1251 | &hashSize, | ||
1252 | MYSQL_TYPE_BLOB, | ||
1253 | &vhash, | ||
1254 | hashSize2, | ||
1255 | &hashSize2, | ||
1256 | MYSQL_TYPE_LONGLONG, | ||
1257 | &vkey, GNUNET_YES, -1)) | ||
1258 | { | ||
1259 | do_delete_value (plugin, vkey); | ||
1260 | return GNUNET_SYSERR; | ||
1261 | } | ||
1262 | #if DEBUG_MYSQL | 1094 | #if DEBUG_MYSQL |
1263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1095 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1264 | "Inserted value `%s' number %llu with size %u into gn090 table\n", | 1096 | "Inserted value `%s' with size %u into gn090 table\n", |
1265 | GNUNET_h2s (key), | 1097 | GNUNET_h2s (key), |
1266 | vkey, | ||
1267 | (unsigned int) size); | 1098 | (unsigned int) size); |
1268 | #endif | 1099 | #endif |
1269 | if (size > 0) | 1100 | if (size > 0) |
@@ -1318,18 +1149,11 @@ mysql_plugin_update (void *cls, | |||
1318 | ret = prepared_statement_run (plugin, | 1149 | ret = prepared_statement_run (plugin, |
1319 | plugin->update_entry, | 1150 | plugin->update_entry, |
1320 | NULL, | 1151 | NULL, |
1321 | MYSQL_TYPE_LONG, | 1152 | MYSQL_TYPE_LONG, &delta, GNUNET_NO, |
1322 | &delta, | 1153 | MYSQL_TYPE_LONGLONG, &lexpire, GNUNET_YES, |
1323 | GNUNET_NO, | 1154 | MYSQL_TYPE_LONGLONG, &lexpire, GNUNET_YES, |
1324 | MYSQL_TYPE_LONGLONG, | 1155 | MYSQL_TYPE_LONGLONG, &vkey, GNUNET_YES, |
1325 | &lexpire, | 1156 | -1); |
1326 | GNUNET_YES, | ||
1327 | MYSQL_TYPE_LONGLONG, | ||
1328 | &lexpire, | ||
1329 | GNUNET_YES, | ||
1330 | MYSQL_TYPE_LONGLONG, | ||
1331 | &vkey, | ||
1332 | GNUNET_YES, -1); | ||
1333 | if (ret != GNUNET_OK) | 1157 | if (ret != GNUNET_OK) |
1334 | { | 1158 | { |
1335 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1159 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -1350,8 +1174,8 @@ struct GetContext | |||
1350 | unsigned long long expiration; | 1174 | unsigned long long expiration; |
1351 | unsigned long long vkey; | 1175 | unsigned long long vkey; |
1352 | unsigned long long total; | 1176 | unsigned long long total; |
1353 | int off; | 1177 | unsigned int off; |
1354 | int count; | 1178 | unsigned int count; |
1355 | int have_vhash; | 1179 | int have_vhash; |
1356 | }; | 1180 | }; |
1357 | 1181 | ||
@@ -1363,9 +1187,8 @@ get_statement_prepare (void *cls, | |||
1363 | struct GetContext *gc = cls; | 1187 | struct GetContext *gc = cls; |
1364 | struct Plugin *plugin; | 1188 | struct Plugin *plugin; |
1365 | int ret; | 1189 | int ret; |
1366 | unsigned int limit_off; | ||
1367 | unsigned long hashSize; | 1190 | unsigned long hashSize; |
1368 | 1191 | ||
1369 | if (NULL == nrc) | 1192 | if (NULL == nrc) |
1370 | { | 1193 | { |
1371 | GNUNET_free (gc); | 1194 | GNUNET_free (gc); |
@@ -1375,45 +1198,41 @@ get_statement_prepare (void *cls, | |||
1375 | return GNUNET_NO; | 1198 | return GNUNET_NO; |
1376 | plugin = nrc->plugin; | 1199 | plugin = nrc->plugin; |
1377 | hashSize = sizeof (GNUNET_HashCode); | 1200 | hashSize = sizeof (GNUNET_HashCode); |
1378 | if (gc->count + gc->off == gc->total) | 1201 | if (++gc->off >= gc->total) |
1379 | nrc->last_vkey = 0; /* back to start */ | 1202 | gc->off = 0; |
1380 | if (gc->count == 0) | ||
1381 | limit_off = gc->off; | ||
1382 | else | ||
1383 | limit_off = 0; | ||
1384 | #if DEBUG_MYSQL | 1203 | #if DEBUG_MYSQL |
1385 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1204 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1386 | "Obtaining result number %d/%lld at offset %d with lvc %llu for GET `%s'\n", | 1205 | "Obtaining result number %d/%lld at offset %u for GET `%s'\n", |
1387 | gc->count+1, | 1206 | gc->count+1, |
1388 | gc->total, | 1207 | gc->total, |
1389 | limit_off, | 1208 | gc->off, |
1390 | nrc->last_vkey, | ||
1391 | GNUNET_h2s (&gc->key)); | 1209 | GNUNET_h2s (&gc->key)); |
1392 | #endif | 1210 | #endif |
1393 | if (nrc->type != 0) | 1211 | if (nrc->type != 0) |
1394 | { | 1212 | { |
1395 | if (gc->have_vhash) | 1213 | if (gc->have_vhash) |
1396 | { | 1214 | { |
1397 | ret = | 1215 | ret = prepared_statement_run_select (plugin, |
1398 | prepared_statement_run_select | 1216 | plugin->select_entry_by_hash_vhash_and_type, |
1399 | (plugin, | 1217 | 7, nrc->rbind, |
1400 | plugin->select_entry_by_hash_vhash_and_type, 6, nrc->rbind, &return_ok, | 1218 | &return_ok, NULL, |
1401 | NULL, MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, | 1219 | MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, |
1402 | MYSQL_TYPE_BLOB, &gc->vhash, hashSize, &hashSize, | 1220 | MYSQL_TYPE_BLOB, &gc->vhash, hashSize, &hashSize, |
1403 | MYSQL_TYPE_LONGLONG, &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, | 1221 | MYSQL_TYPE_LONG, &nrc->type, GNUNET_YES, |
1404 | &nrc->type, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, GNUNET_YES, | 1222 | MYSQL_TYPE_LONG, &gc->off, GNUNET_YES, |
1405 | -1); | 1223 | -1); |
1406 | } | 1224 | } |
1407 | else | 1225 | else |
1408 | { | 1226 | { |
1409 | ret = | 1227 | ret = |
1410 | prepared_statement_run_select | 1228 | prepared_statement_run_select (plugin, |
1411 | (plugin, | 1229 | plugin->select_entry_by_hash_and_type, |
1412 | plugin->select_entry_by_hash_and_type, 6, nrc->rbind, &return_ok, NULL, | 1230 | 7, nrc->rbind, |
1413 | MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, | 1231 | &return_ok, NULL, |
1414 | MYSQL_TYPE_LONGLONG, &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, | 1232 | MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, |
1415 | &nrc->type, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, GNUNET_YES, | 1233 | MYSQL_TYPE_LONG, &nrc->type, GNUNET_YES, |
1416 | -1); | 1234 | MYSQL_TYPE_LONG, &gc->off, GNUNET_YES, |
1235 | -1); | ||
1417 | } | 1236 | } |
1418 | } | 1237 | } |
1419 | else | 1238 | else |
@@ -1421,23 +1240,25 @@ get_statement_prepare (void *cls, | |||
1421 | if (gc->have_vhash) | 1240 | if (gc->have_vhash) |
1422 | { | 1241 | { |
1423 | ret = | 1242 | ret = |
1424 | prepared_statement_run_select | 1243 | prepared_statement_run_select (plugin, |
1425 | (plugin, | 1244 | plugin->select_entry_by_hash_and_vhash, |
1426 | plugin->select_entry_by_hash_and_vhash, 6, nrc->rbind, &return_ok, NULL, | 1245 | 7, nrc->rbind, |
1427 | MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, MYSQL_TYPE_BLOB, | 1246 | &return_ok, NULL, |
1428 | &gc->vhash, hashSize, &hashSize, MYSQL_TYPE_LONGLONG, | 1247 | MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, |
1429 | &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, &limit_off, | 1248 | MYSQL_TYPE_BLOB, &gc->vhash, hashSize, &hashSize, |
1430 | GNUNET_YES, -1); | 1249 | MYSQL_TYPE_LONG, &gc->off, GNUNET_YES, |
1250 | -1); | ||
1431 | } | 1251 | } |
1432 | else | 1252 | else |
1433 | { | 1253 | { |
1434 | ret = | 1254 | ret = |
1435 | prepared_statement_run_select | 1255 | prepared_statement_run_select (plugin, |
1436 | (plugin, | 1256 | plugin->select_entry_by_hash, |
1437 | plugin->select_entry_by_hash, 6, nrc->rbind, &return_ok, NULL, | 1257 | 7, nrc->rbind, |
1438 | MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, | 1258 | &return_ok, NULL, |
1439 | MYSQL_TYPE_LONGLONG, &nrc->last_vkey, GNUNET_YES, MYSQL_TYPE_LONG, | 1259 | MYSQL_TYPE_BLOB, &gc->key, hashSize, &hashSize, |
1440 | &limit_off, GNUNET_YES, -1); | 1260 | MYSQL_TYPE_LONG, &gc->off, GNUNET_YES, |
1261 | -1); | ||
1441 | } | 1262 | } |
1442 | } | 1263 | } |
1443 | gc->count++; | 1264 | gc->count++; |
@@ -1446,8 +1267,7 @@ get_statement_prepare (void *cls, | |||
1446 | 1267 | ||
1447 | 1268 | ||
1448 | /** | 1269 | /** |
1449 | * Iterate over the results for a particular key | 1270 | * Iterate over the results for a particular key in the datastore. |
1450 | * in the datastore. | ||
1451 | * | 1271 | * |
1452 | * @param cls closure | 1272 | * @param cls closure |
1453 | * @param key maybe NULL (to match all entries) | 1273 | * @param key maybe NULL (to match all entries) |
@@ -1457,7 +1277,7 @@ get_statement_prepare (void *cls, | |||
1457 | * betwen key and vhash, but for other blocks | 1277 | * betwen key and vhash, but for other blocks |
1458 | * there may be! | 1278 | * there may be! |
1459 | * @param type entries of which type are relevant? | 1279 | * @param type entries of which type are relevant? |
1460 | * Use 0 for any type. | 1280 | * Use 0 for any type. |
1461 | * @param iter function to call on each matching value; | 1281 | * @param iter function to call on each matching value; |
1462 | * will be called once with a NULL value at the end | 1282 | * will be called once with a NULL value at the end |
1463 | * @param iter_cls closure for iter | 1283 | * @param iter_cls closure for iter |
@@ -1492,22 +1312,25 @@ mysql_plugin_get (void *cls, | |||
1492 | if (vhash != NULL) | 1312 | if (vhash != NULL) |
1493 | { | 1313 | { |
1494 | ret = | 1314 | ret = |
1495 | prepared_statement_run_select | 1315 | prepared_statement_run_select (plugin, |
1496 | (plugin, | 1316 | plugin->count_entry_by_hash_vhash_and_type, |
1497 | plugin->count_entry_by_hash_vhash_and_type, 1, cbind, &return_ok, NULL, | 1317 | 1, cbind, |
1498 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, | 1318 | &return_ok, NULL, |
1499 | vhash, hashSize, &hashSize, MYSQL_TYPE_LONG, &itype, GNUNET_YES, | 1319 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1500 | -1); | 1320 | MYSQL_TYPE_BLOB, vhash, hashSize, &hashSize, |
1321 | MYSQL_TYPE_LONG, &itype, GNUNET_YES, | ||
1322 | -1); | ||
1501 | } | 1323 | } |
1502 | else | 1324 | else |
1503 | { | 1325 | { |
1504 | ret = | 1326 | ret = |
1505 | prepared_statement_run_select | 1327 | prepared_statement_run_select (plugin, |
1506 | (plugin, | 1328 | plugin->count_entry_by_hash_and_type, |
1507 | plugin->count_entry_by_hash_and_type, 1, cbind, &return_ok, NULL, | 1329 | 1, cbind, |
1508 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_LONG, | 1330 | &return_ok, NULL, |
1509 | &itype, GNUNET_YES, -1); | 1331 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1510 | 1332 | MYSQL_TYPE_LONG, &itype, GNUNET_YES, | |
1333 | -1); | ||
1511 | } | 1334 | } |
1512 | } | 1335 | } |
1513 | else | 1336 | else |
@@ -1515,11 +1338,13 @@ mysql_plugin_get (void *cls, | |||
1515 | if (vhash != NULL) | 1338 | if (vhash != NULL) |
1516 | { | 1339 | { |
1517 | ret = | 1340 | ret = |
1518 | prepared_statement_run_select | 1341 | prepared_statement_run_select (plugin, |
1519 | (plugin, | 1342 | plugin->count_entry_by_hash_and_vhash, |
1520 | plugin->count_entry_by_hash_and_vhash, 1, cbind, &return_ok, NULL, | 1343 | 1, cbind, |
1521 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, MYSQL_TYPE_BLOB, | 1344 | &return_ok, NULL, |
1522 | vhash, hashSize, &hashSize, -1); | 1345 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1346 | MYSQL_TYPE_BLOB, vhash, hashSize, &hashSize, | ||
1347 | -1); | ||
1523 | 1348 | ||
1524 | } | 1349 | } |
1525 | else | 1350 | else |
@@ -1527,10 +1352,10 @@ mysql_plugin_get (void *cls, | |||
1527 | ret = | 1352 | ret = |
1528 | prepared_statement_run_select (plugin, | 1353 | prepared_statement_run_select (plugin, |
1529 | plugin->count_entry_by_hash, | 1354 | plugin->count_entry_by_hash, |
1530 | 1, cbind, &return_ok, | 1355 | 1, cbind, |
1531 | NULL, MYSQL_TYPE_BLOB, | 1356 | &return_ok, NULL, |
1532 | key, hashSize, | 1357 | MYSQL_TYPE_BLOB, key, hashSize, &hashSize, |
1533 | &hashSize, -1); | 1358 | -1); |
1534 | } | 1359 | } |
1535 | } | 1360 | } |
1536 | if ((ret != GNUNET_OK) || (0 >= total)) | 1361 | if ((ret != GNUNET_OK) || (0 >= total)) |
@@ -1564,7 +1389,6 @@ mysql_plugin_get (void *cls, | |||
1564 | nrc->dviter_cls = iter_cls; | 1389 | nrc->dviter_cls = iter_cls; |
1565 | nrc->prep = &get_statement_prepare; | 1390 | nrc->prep = &get_statement_prepare; |
1566 | nrc->prep_cls = gc; | 1391 | nrc->prep_cls = gc; |
1567 | nrc->last_vkey = 0; | ||
1568 | mysql_plugin_next_request (nrc, GNUNET_NO); | 1392 | mysql_plugin_next_request (nrc, GNUNET_NO); |
1569 | } | 1393 | } |
1570 | 1394 | ||
@@ -1581,29 +1405,19 @@ iterator_zero_prepare (void *cls, | |||
1581 | struct NextRequestClosure *nrc) | 1405 | struct NextRequestClosure *nrc) |
1582 | { | 1406 | { |
1583 | struct Plugin *plugin; | 1407 | struct Plugin *plugin; |
1408 | int ret; | ||
1584 | 1409 | ||
1585 | if (nrc == NULL) | 1410 | if (nrc == NULL) |
1586 | return GNUNET_NO; | 1411 | return GNUNET_NO; |
1587 | plugin = nrc->plugin; | 1412 | plugin = nrc->plugin; |
1588 | return prepared_statement_run_select (plugin, | 1413 | ret = prepared_statement_run_select (plugin, |
1589 | plugin->zero_iter, | 1414 | plugin->zero_iter, |
1590 | 6, | 1415 | 7, nrc->rbind, |
1591 | nrc->rbind, | 1416 | &return_ok, NULL, |
1592 | &return_ok, | 1417 | MYSQL_TYPE_LONG, &nrc->count, GNUNET_YES, |
1593 | NULL, | 1418 | -1); |
1594 | MYSQL_TYPE_LONGLONG, | 1419 | nrc->count++; |
1595 | &nrc->now.abs_value, | 1420 | return ret; |
1596 | GNUNET_YES, | ||
1597 | MYSQL_TYPE_LONGLONG, | ||
1598 | &nrc->last_vkey, | ||
1599 | GNUNET_YES, | ||
1600 | MYSQL_TYPE_LONGLONG, | ||
1601 | &nrc->last_prio, | ||
1602 | GNUNET_YES, | ||
1603 | MYSQL_TYPE_LONGLONG, | ||
1604 | &nrc->last_vkey, | ||
1605 | GNUNET_YES, | ||
1606 | -1); | ||
1607 | } | 1421 | } |
1608 | 1422 | ||
1609 | 1423 | ||
@@ -1633,8 +1447,6 @@ mysql_plugin_iter_zero_anonymity (void *cls, | |||
1633 | nrc->dviter = iter; | 1447 | nrc->dviter = iter; |
1634 | nrc->dviter_cls = iter_cls; | 1448 | nrc->dviter_cls = iter_cls; |
1635 | nrc->prep = &iterator_zero_prepare; | 1449 | nrc->prep = &iterator_zero_prepare; |
1636 | nrc->last_vkey = INT64_MAX; /* MySQL only supports 63 bits, hence signed */ | ||
1637 | nrc->last_prio = INT32_MAX; /* similar issue... */ | ||
1638 | mysql_plugin_next_request (nrc, GNUNET_NO); | 1450 | mysql_plugin_next_request (nrc, GNUNET_NO); |
1639 | } | 1451 | } |
1640 | 1452 | ||
@@ -1650,16 +1462,15 @@ replication_prepare (void *cls, | |||
1650 | struct NextRequestClosure *nrc) | 1462 | struct NextRequestClosure *nrc) |
1651 | { | 1463 | { |
1652 | struct Plugin *plugin = cls; | 1464 | struct Plugin *plugin = cls; |
1653 | long long nt; | 1465 | unsigned long long nt; |
1654 | 1466 | ||
1655 | nt = (long long) nrc->now.abs_value; | 1467 | nt = (unsigned long long) nrc->now.abs_value; |
1656 | return prepared_statement_run_select | 1468 | return prepared_statement_run_select (plugin, |
1657 | (plugin, | 1469 | plugin->select_replication, |
1658 | plugin->select_replication, | 1470 | 6, nrc->rbind, |
1659 | 6, nrc->rbind, | 1471 | &return_ok, NULL, |
1660 | &return_ok, NULL, | 1472 | MYSQL_TYPE_LONGLONG, &nt, GNUNET_YES, |
1661 | MYSQL_TYPE_LONGLONG, &nt, GNUNET_YES, | 1473 | -1); |
1662 | -1); | ||
1663 | } | 1474 | } |
1664 | 1475 | ||
1665 | 1476 | ||
@@ -1797,24 +1608,21 @@ libgnunet_plugin_datastore_mysql_init (void *cls) | |||
1797 | " expire BIGINT UNSIGNED NOT NULL DEFAULT 0," | 1608 | " expire BIGINT UNSIGNED NOT NULL DEFAULT 0," |
1798 | " hash BINARY(64) NOT NULL DEFAULT ''," | 1609 | " hash BINARY(64) NOT NULL DEFAULT ''," |
1799 | " vhash BINARY(64) NOT NULL DEFAULT ''," | 1610 | " vhash BINARY(64) NOT NULL DEFAULT ''," |
1800 | " vkey BIGINT UNSIGNED NOT NULL DEFAULT 0," | 1611 | " value BLOB NOT NULL DEFAULT ''" |
1801 | " INDEX hash (hash(64))," | 1612 | " uid BIGINT NOT NULL AUTO_INCREMENT" |
1802 | " INDEX hash_vhash_vkey (hash(64),vhash(64),vkey)," | 1613 | " PRIMARY KEY (uid)" |
1803 | " INDEX hash_vkey (hash(64),vkey)," | 1614 | " INDEX idx_hash (hash(64))," |
1804 | " INDEX vkey (vkey)," | 1615 | " INDEX idx_hash_uid (hash(64),uid)," |
1805 | " INDEX prio (prio,vkey)," | 1616 | " INDEX idx_hash_vhash (hash(64),vhash(64))," |
1806 | " INDEX expire (expire,vkey,type)," | 1617 | " INDEX idx_hash_type_uid (hash(64),type,uid)," |
1807 | " INDEX anonLevel (anonLevel,prio,vkey,type)" | 1618 | " INDEX idx_prio (prio)," |
1619 | " INDEX idx_repl (repl)," | ||
1620 | " INDEX idx_expire_prio (expire,prio)," | ||
1621 | " INDEX idx_anonLevel_uid (anonLevel,uid)" | ||
1808 | ") ENGINE=InnoDB") || | 1622 | ") ENGINE=InnoDB") || |
1809 | MRUNS ("CREATE TABLE IF NOT EXISTS gn072 (" | ||
1810 | " vkey BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY," | ||
1811 | " value BLOB NOT NULL DEFAULT '') ENGINE=MyISAM") || | ||
1812 | MRUNS ("SET AUTOCOMMIT = 1") || | 1623 | MRUNS ("SET AUTOCOMMIT = 1") || |
1813 | PINIT (plugin->select_value, SELECT_VALUE) || | ||
1814 | PINIT (plugin->delete_value, DELETE_VALUE) || | ||
1815 | PINIT (plugin->insert_value, INSERT_VALUE) || | ||
1816 | PINIT (plugin->insert_entry, INSERT_ENTRY) || | 1624 | PINIT (plugin->insert_entry, INSERT_ENTRY) || |
1817 | PINIT (plugin->delete_entry_by_vkey, DELETE_ENTRY_BY_VKEY) || | 1625 | PINIT (plugin->delete_entry_by_uid, DELETE_ENTRY_BY_UID) || |
1818 | PINIT (plugin->select_entry_by_hash, SELECT_ENTRY_BY_HASH) || | 1626 | PINIT (plugin->select_entry_by_hash, SELECT_ENTRY_BY_HASH) || |
1819 | PINIT (plugin->select_entry_by_hash_and_vhash, SELECT_ENTRY_BY_HASH_AND_VHASH) | 1627 | PINIT (plugin->select_entry_by_hash_and_vhash, SELECT_ENTRY_BY_HASH_AND_VHASH) |
1820 | || PINIT (plugin->select_entry_by_hash_and_type, SELECT_ENTRY_BY_HASH_AND_TYPE) | 1628 | || PINIT (plugin->select_entry_by_hash_and_type, SELECT_ENTRY_BY_HASH_AND_TYPE) |
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c index fd10a38cb..6e77ec364 100644 --- a/src/datastore/plugin_datastore_sqlite.c +++ b/src/datastore/plugin_datastore_sqlite.c | |||
@@ -181,7 +181,9 @@ create_indices (sqlite3 * dbh) | |||
181 | NULL); | 181 | NULL); |
182 | sqlite3_exec (dbh, "CREATE INDEX idx_comb ON gn090 (anonLevel ASC,expire ASC,prio,type,hash)", | 182 | sqlite3_exec (dbh, "CREATE INDEX idx_comb ON gn090 (anonLevel ASC,expire ASC,prio,type,hash)", |
183 | NULL, NULL, NULL); | 183 | NULL, NULL, NULL); |
184 | sqlite3_exec (dbh, "CREATE INDEX expire ON gn090 (expire)", | 184 | sqlite3_exec (dbh, "CREATE INDEX idx_expire ON gn090 (expire)", |
185 | NULL, NULL, NULL); | ||
186 | sqlite3_exec (dbh, "CREATE INDEX idx_repl ON gn090 (repl)", | ||
185 | NULL, NULL, NULL); | 187 | NULL, NULL, NULL); |
186 | } | 188 | } |
187 | 189 | ||
@@ -309,24 +311,6 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
309 | sqlite3_finalize (stmt); | 311 | sqlite3_finalize (stmt); |
310 | create_indices (plugin->dbh); | 312 | create_indices (plugin->dbh); |
311 | 313 | ||
312 | CHECK (SQLITE_OK == | ||
313 | sq_prepare (plugin->dbh, | ||
314 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn071'", | ||
315 | &stmt)); | ||
316 | if ( (sqlite3_step (stmt) == SQLITE_DONE) && | ||
317 | (sqlite3_exec (plugin->dbh, | ||
318 | "CREATE TABLE gn071 (" | ||
319 | " key TEXT NOT NULL DEFAULT ''," | ||
320 | " value INTEGER NOT NULL DEFAULT 0)", NULL, NULL, | ||
321 | NULL) != SQLITE_OK) ) | ||
322 | { | ||
323 | LOG_SQLITE (plugin, NULL, | ||
324 | GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec"); | ||
325 | sqlite3_finalize (stmt); | ||
326 | return GNUNET_SYSERR; | ||
327 | } | ||
328 | sqlite3_finalize (stmt); | ||
329 | |||
330 | if ((sq_prepare (plugin->dbh, | 314 | if ((sq_prepare (plugin->dbh, |
331 | "UPDATE gn090 SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?", | 315 | "UPDATE gn090 SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?", |
332 | &plugin->updPrio) != SQLITE_OK) || | 316 | &plugin->updPrio) != SQLITE_OK) || |
@@ -334,7 +318,7 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
334 | "UPDATE gn090 SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?", | 318 | "UPDATE gn090 SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?", |
335 | &plugin->updRepl) != SQLITE_OK) || | 319 | &plugin->updRepl) != SQLITE_OK) || |
336 | (sq_prepare (plugin->dbh, | 320 | (sq_prepare (plugin->dbh, |
337 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE expire > ?" | 321 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090" |
338 | " ORDER BY repl DESC, Random() LIMIT 1", | 322 | " ORDER BY repl DESC, Random() LIMIT 1", |
339 | &plugin->selRepl) != SQLITE_OK) || | 323 | &plugin->selRepl) != SQLITE_OK) || |
340 | (sq_prepare (plugin->dbh, | 324 | (sq_prepare (plugin->dbh, |
@@ -1419,7 +1403,95 @@ execute_get (struct Plugin *plugin, | |||
1419 | 1403 | ||
1420 | 1404 | ||
1421 | /** | 1405 | /** |
1422 | * Get a random item for replication. Returns a single, not expired, random item | 1406 | * Context for 'repl_iter' function. |
1407 | */ | ||
1408 | struct ReplCtx | ||
1409 | { | ||
1410 | |||
1411 | /** | ||
1412 | * Plugin handle. | ||
1413 | */ | ||
1414 | struct Plugin *plugin; | ||
1415 | |||
1416 | /** | ||
1417 | * Function to call for the result (or the NULL). | ||
1418 | */ | ||
1419 | PluginIterator iter; | ||
1420 | |||
1421 | /** | ||
1422 | * Closure for iter. | ||
1423 | */ | ||
1424 | void *iter_cls; | ||
1425 | }; | ||
1426 | |||
1427 | |||
1428 | /** | ||
1429 | * Wrapper for the iterator for 'sqlite_plugin_replication_get'. | ||
1430 | * Decrements the replication counter and calls the original | ||
1431 | * iterator. | ||
1432 | * | ||
1433 | * @param cls closure | ||
1434 | * @param next_cls closure to pass to the "next" function. | ||
1435 | * @param key key for the content | ||
1436 | * @param size number of bytes in data | ||
1437 | * @param data content stored | ||
1438 | * @param type type of the content | ||
1439 | * @param priority priority of the content | ||
1440 | * @param anonymity anonymity-level for the content | ||
1441 | * @param expiration expiration time for the content | ||
1442 | * @param uid unique identifier for the datum; | ||
1443 | * maybe 0 if no unique identifier is available | ||
1444 | * | ||
1445 | * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue | ||
1446 | * (continue on call to "next", of course), | ||
1447 | * GNUNET_NO to delete the item and continue (if supported) | ||
1448 | */ | ||
1449 | static int | ||
1450 | repl_iter (void *cls, | ||
1451 | void *next_cls, | ||
1452 | const GNUNET_HashCode *key, | ||
1453 | uint32_t size, | ||
1454 | const void *data, | ||
1455 | enum GNUNET_BLOCK_Type type, | ||
1456 | uint32_t priority, | ||
1457 | uint32_t anonymity, | ||
1458 | struct GNUNET_TIME_Absolute expiration, | ||
1459 | uint64_t uid) | ||
1460 | { | ||
1461 | struct ReplCtx *rc = cls; | ||
1462 | struct Plugin *plugin = rc->plugin; | ||
1463 | int ret; | ||
1464 | |||
1465 | ret = rc->iter (rc->iter_cls, | ||
1466 | next_cls, key, | ||
1467 | size, data, | ||
1468 | type, priority, anonymity, expiration, | ||
1469 | uid); | ||
1470 | if (NULL != key) | ||
1471 | { | ||
1472 | sqlite3_bind_int64 (plugin->updRepl, 1, uid); | ||
1473 | if (SQLITE_DONE != sqlite3_step (plugin->updRepl)) | ||
1474 | { | ||
1475 | LOG_SQLITE (plugin, NULL, | ||
1476 | GNUNET_ERROR_TYPE_ERROR | | ||
1477 | GNUNET_ERROR_TYPE_BULK, "sqlite3_step"); | ||
1478 | if (SQLITE_OK != sqlite3_reset (plugin->updRepl)) | ||
1479 | LOG_SQLITE (plugin, NULL, | ||
1480 | GNUNET_ERROR_TYPE_ERROR | | ||
1481 | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | ||
1482 | return GNUNET_SYSERR; | ||
1483 | } | ||
1484 | if (SQLITE_OK != sqlite3_reset (plugin->delRow)) | ||
1485 | LOG_SQLITE (plugin, NULL, | ||
1486 | GNUNET_ERROR_TYPE_ERROR | | ||
1487 | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | ||
1488 | } | ||
1489 | return ret; | ||
1490 | } | ||
1491 | |||
1492 | |||
1493 | /** | ||
1494 | * Get a random item for replication. Returns a single random item | ||
1423 | * from those with the highest replication counters. The item's | 1495 | * from those with the highest replication counters. The item's |
1424 | * replication counter is decremented by one IF it was positive before. | 1496 | * replication counter is decremented by one IF it was positive before. |
1425 | * Call 'iter' with all values ZERO or NULL if the datastore is empty. | 1497 | * Call 'iter' with all values ZERO or NULL if the datastore is empty. |
@@ -1433,28 +1505,17 @@ sqlite_plugin_replication_get (void *cls, | |||
1433 | PluginIterator iter, void *iter_cls) | 1505 | PluginIterator iter, void *iter_cls) |
1434 | { | 1506 | { |
1435 | struct Plugin *plugin = cls; | 1507 | struct Plugin *plugin = cls; |
1436 | sqlite3_stmt *stmt; | 1508 | struct ReplCtx rc; |
1437 | struct GNUNET_TIME_Absolute now; | ||
1438 | 1509 | ||
1439 | #if DEBUG_SQLITE | 1510 | #if DEBUG_SQLITE |
1440 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1511 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1441 | "sqlite", | 1512 | "sqlite", |
1442 | "Getting random block based on replication order.\n"); | 1513 | "Getting random block based on replication order.\n"); |
1443 | #endif | 1514 | #endif |
1444 | stmt = plugin->selRepl; | 1515 | rc.plugin = plugin; |
1445 | now = GNUNET_TIME_absolute_get (); | 1516 | rc.iter = iter; |
1446 | if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, now.abs_value)) | 1517 | rc.iter_cls = iter_cls; |
1447 | { | 1518 | execute_get (plugin, plugin->selRepl, &repl_iter, &rc); |
1448 | LOG_SQLITE (plugin, NULL, | ||
1449 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind_XXXX"); | ||
1450 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1451 | LOG_SQLITE (plugin, NULL, | ||
1452 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | ||
1453 | iter (iter_cls, NULL, NULL, 0, NULL, 0, 0, 0, | ||
1454 | GNUNET_TIME_UNIT_ZERO_ABS, 0); | ||
1455 | return; | ||
1456 | } | ||
1457 | execute_get (plugin, stmt, iter, iter_cls); | ||
1458 | } | 1519 | } |
1459 | 1520 | ||
1460 | 1521 | ||