diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-04-03 16:30:06 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-04-03 16:30:06 +0000 |
commit | 9f871785d57da57ba128ac2279fda1db1d9b8bfb (patch) | |
tree | a666045b38f3fc7b34792f32d796e12430b0b498 /src/datastore | |
parent | d2f2c8800aa6ea07a024c5511a1b1d23ad356090 (diff) | |
download | gnunet-9f871785d57da57ba128ac2279fda1db1d9b8bfb.tar.gz gnunet-9f871785d57da57ba128ac2279fda1db1d9b8bfb.zip |
first hack at implementing new replication select code
Diffstat (limited to 'src/datastore')
-rw-r--r-- | src/datastore/plugin_datastore_sqlite.c | 185 |
1 files changed, 144 insertions, 41 deletions
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c index 260bd54cc..b8661f46d 100644 --- a/src/datastore/plugin_datastore_sqlite.c +++ b/src/datastore/plugin_datastore_sqlite.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2009, 2011 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -39,37 +39,43 @@ | |||
39 | #define LOG_SQLITE(db, msg, level, cmd) do { GNUNET_log_from (level, "sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); if (msg != NULL) GNUNET_asprintf(msg, _("`%s' failed at %s:%u with error: %s"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0) | 39 | #define LOG_SQLITE(db, msg, level, cmd) do { GNUNET_log_from (level, "sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); if (msg != NULL) GNUNET_asprintf(msg, _("`%s' failed at %s:%u with error: %s"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0) |
40 | 40 | ||
41 | #define SELECT_IT_LOW_PRIORITY_1 \ | 41 | #define SELECT_IT_LOW_PRIORITY_1 \ |
42 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (prio = ? AND hash > ?) "\ | 42 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (prio = ? AND hash > ?) "\ |
43 | "ORDER BY hash ASC LIMIT 1" | 43 | "ORDER BY hash ASC LIMIT 1" |
44 | 44 | ||
45 | #define SELECT_IT_LOW_PRIORITY_2 \ | 45 | #define SELECT_IT_LOW_PRIORITY_2 \ |
46 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (prio > ?) "\ | 46 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (prio > ?) "\ |
47 | "ORDER BY prio ASC, hash ASC LIMIT 1" | 47 | "ORDER BY prio ASC, hash ASC LIMIT 1" |
48 | 48 | ||
49 | #define SELECT_IT_NON_ANONYMOUS_1 \ | 49 | #define SELECT_IT_NON_ANONYMOUS_1 \ |
50 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (prio = ? AND hash < ? AND anonLevel = 0 AND expire > %llu) "\ | 50 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (prio = ? AND hash < ? AND anonLevel = 0 AND expire > %llu) "\ |
51 | " ORDER BY hash DESC LIMIT 1" | 51 | " ORDER BY hash DESC LIMIT 1" |
52 | 52 | ||
53 | #define SELECT_IT_NON_ANONYMOUS_2 \ | 53 | #define SELECT_IT_NON_ANONYMOUS_2 \ |
54 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (prio < ? AND anonLevel = 0 AND expire > %llu)"\ | 54 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (prio < ? AND anonLevel = 0 AND expire > %llu)"\ |
55 | " ORDER BY prio DESC, hash DESC LIMIT 1" | 55 | " ORDER BY prio DESC, hash DESC LIMIT 1" |
56 | 56 | ||
57 | #define SELECT_IT_EXPIRATION_TIME_1 \ | 57 | #define SELECT_IT_EXPIRATION_TIME_1 \ |
58 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (expire = ? AND hash > ?) "\ | 58 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (expire = ? AND hash > ?) "\ |
59 | " ORDER BY hash ASC LIMIT 1" | 59 | " ORDER BY hash ASC LIMIT 1" |
60 | 60 | ||
61 | #define SELECT_IT_EXPIRATION_TIME_2 \ | 61 | #define SELECT_IT_EXPIRATION_TIME_2 \ |
62 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (expire > ?) "\ | 62 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (expire > ?) "\ |
63 | " ORDER BY expire ASC, hash ASC LIMIT 1" | 63 | " ORDER BY expire ASC, hash ASC LIMIT 1" |
64 | 64 | ||
65 | #define SELECT_IT_MIGRATION_ORDER_1 \ | 65 | #define SELECT_IT_MIGRATION_ORDER_1 \ |
66 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (expire = ? AND hash < ?) "\ | 66 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (expire = ? AND hash < ?) "\ |
67 | " ORDER BY hash DESC LIMIT 1" | 67 | " ORDER BY hash DESC LIMIT 1" |
68 | 68 | ||
69 | #define SELECT_IT_MIGRATION_ORDER_2 \ | 69 | #define SELECT_IT_MIGRATION_ORDER_2 \ |
70 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080 WHERE (expire < ? AND expire > %llu) "\ | 70 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (expire < ? AND expire > %llu) "\ |
71 | " ORDER BY expire DESC, hash DESC LIMIT 1" | 71 | " ORDER BY expire DESC, hash DESC LIMIT 1" |
72 | 72 | ||
73 | |||
74 | #define SELECT_IT_REPLICATION_ORDER \ | ||
75 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090 WHERE (expire > ?) "\ | ||
76 | " ORDER BY repl DESC, Random() LIMIT 1" | ||
77 | |||
78 | |||
73 | /** | 79 | /** |
74 | * After how many ms "busy" should a DB operation fail for good? | 80 | * After how many ms "busy" should a DB operation fail for good? |
75 | * A low value makes sure that we are more responsive to requests | 81 | * A low value makes sure that we are more responsive to requests |
@@ -115,6 +121,16 @@ struct Plugin | |||
115 | sqlite3_stmt *updPrio; | 121 | sqlite3_stmt *updPrio; |
116 | 122 | ||
117 | /** | 123 | /** |
124 | * Precompiled SQL for replication decrement. | ||
125 | */ | ||
126 | sqlite3_stmt *updRepl; | ||
127 | |||
128 | /** | ||
129 | * Precompiled SQL for replication decrement. | ||
130 | */ | ||
131 | sqlite3_stmt *selRepl; | ||
132 | |||
133 | /** | ||
118 | * Precompiled SQL for insertion. | 134 | * Precompiled SQL for insertion. |
119 | */ | 135 | */ |
120 | sqlite3_stmt *insertContent; | 136 | sqlite3_stmt *insertContent; |
@@ -173,19 +189,21 @@ create_indices (sqlite3 * dbh) | |||
173 | { | 189 | { |
174 | /* create indices */ | 190 | /* create indices */ |
175 | sqlite3_exec (dbh, | 191 | sqlite3_exec (dbh, |
176 | "CREATE INDEX idx_hash ON gn080 (hash)", NULL, NULL, NULL); | 192 | "CREATE INDEX idx_hash ON gn090 (hash)", NULL, NULL, NULL); |
177 | sqlite3_exec (dbh, | 193 | sqlite3_exec (dbh, |
178 | "CREATE INDEX idx_hash_vhash ON gn080 (hash,vhash)", NULL, | 194 | "CREATE INDEX idx_hash_vhash ON gn090 (hash,vhash)", NULL, |
179 | NULL, NULL); | 195 | NULL, NULL); |
180 | sqlite3_exec (dbh, "CREATE INDEX idx_prio ON gn080 (prio)", NULL, NULL, | 196 | sqlite3_exec (dbh, "CREATE INDEX idx_prio ON gn090 (prio)", NULL, NULL, |
181 | NULL); | 197 | NULL); |
182 | sqlite3_exec (dbh, "CREATE INDEX idx_expire ON gn080 (expire)", NULL, NULL, | 198 | sqlite3_exec (dbh, "CREATE INDEX idx_expire ON gn090 (expire)", NULL, NULL, |
183 | NULL); | 199 | NULL); |
184 | sqlite3_exec (dbh, "CREATE INDEX idx_comb3 ON gn080 (prio,anonLevel)", NULL, | 200 | sqlite3_exec (dbh, "CREATE INDEX idx_comb3 ON gn090 (prio,anonLevel)", NULL, |
185 | NULL, NULL); | 201 | NULL, NULL); |
186 | sqlite3_exec (dbh, "CREATE INDEX idx_comb4 ON gn080 (prio,hash,anonLevel)", | 202 | sqlite3_exec (dbh, "CREATE INDEX idx_comb4 ON gn090 (prio,hash,anonLevel)", |
187 | NULL, NULL, NULL); | 203 | NULL, NULL, NULL); |
188 | sqlite3_exec (dbh, "CREATE INDEX idx_comb7 ON gn080 (expire,hash)", NULL, | 204 | sqlite3_exec (dbh, "CREATE INDEX idx_comb7 ON gn090 (expire,hash)", NULL, |
205 | NULL, NULL); | ||
206 | sqlite3_exec (dbh, "CREATE INDEX idx_comb8 ON gn090 (expire)", NULL, | ||
189 | NULL, NULL); | 207 | NULL, NULL); |
190 | } | 208 | } |
191 | 209 | ||
@@ -286,12 +304,12 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
286 | /* We have to do it here, because otherwise precompiling SQL might fail */ | 304 | /* We have to do it here, because otherwise precompiling SQL might fail */ |
287 | CHECK (SQLITE_OK == | 305 | CHECK (SQLITE_OK == |
288 | sq_prepare (plugin->dbh, | 306 | sq_prepare (plugin->dbh, |
289 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn080'", | 307 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn090'", |
290 | &stmt)); | 308 | &stmt)); |
291 | if ( (sqlite3_step (stmt) == SQLITE_DONE) && | 309 | if ( (sqlite3_step (stmt) == SQLITE_DONE) && |
292 | (sqlite3_exec (plugin->dbh, | 310 | (sqlite3_exec (plugin->dbh, |
293 | "CREATE TABLE gn080 (" | 311 | "CREATE TABLE gn090 (" |
294 | " size INT4 NOT NULL DEFAULT 0," | 312 | " repl INT4 NOT NULL DEFAULT 0," |
295 | " type INT4 NOT NULL DEFAULT 0," | 313 | " type INT4 NOT NULL DEFAULT 0," |
296 | " prio INT4 NOT NULL DEFAULT 0," | 314 | " prio INT4 NOT NULL DEFAULT 0," |
297 | " anonLevel INT4 NOT NULL DEFAULT 0," | 315 | " anonLevel INT4 NOT NULL DEFAULT 0," |
@@ -329,16 +347,23 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
329 | sqlite3_finalize (stmt); | 347 | sqlite3_finalize (stmt); |
330 | 348 | ||
331 | if ((sq_prepare (plugin->dbh, | 349 | if ((sq_prepare (plugin->dbh, |
332 | "UPDATE gn080 SET prio = prio + ?, expire = MAX(expire,?) WHERE " | 350 | "UPDATE gn090 SET prio = prio + ?, expire = MAX(expire,?) WHERE " |
333 | "_ROWID_ = ?", | 351 | "_ROWID_ = ?", |
334 | &plugin->updPrio) != SQLITE_OK) || | 352 | &plugin->updPrio) != SQLITE_OK) || |
335 | (sq_prepare (plugin->dbh, | 353 | (sq_prepare (plugin->dbh, |
336 | "INSERT INTO gn080 (size, type, prio, " | 354 | "UPDATE gn090 SET repl = MAX (0, repl - 1) WHERE " |
355 | "_ROWID_ = ?", | ||
356 | &plugin->updRepl) != SQLITE_OK) || | ||
357 | (sq_prepare (plugin->dbh, | ||
358 | SELECT_IT_REPLICATION_ORDER, | ||
359 | &plugin->selRepl) != SQLITE_OK) || | ||
360 | (sq_prepare (plugin->dbh, | ||
361 | "INSERT INTO gn090 (repl, type, prio, " | ||
337 | "anonLevel, expire, hash, vhash, value) VALUES " | 362 | "anonLevel, expire, hash, vhash, value) VALUES " |
338 | "(?, ?, ?, ?, ?, ?, ?, ?)", | 363 | "(?, ?, ?, ?, ?, ?, ?, ?)", |
339 | &plugin->insertContent) != SQLITE_OK) || | 364 | &plugin->insertContent) != SQLITE_OK) || |
340 | (sq_prepare (plugin->dbh, | 365 | (sq_prepare (plugin->dbh, |
341 | "DELETE FROM gn080 WHERE _ROWID_ = ?", | 366 | "DELETE FROM gn090 WHERE _ROWID_ = ?", |
342 | &plugin->delRow) != SQLITE_OK)) | 367 | &plugin->delRow) != SQLITE_OK)) |
343 | { | 368 | { |
344 | LOG_SQLITE (plugin, NULL, | 369 | LOG_SQLITE (plugin, NULL, |
@@ -367,6 +392,10 @@ database_shutdown (struct Plugin *plugin) | |||
367 | sqlite3_finalize (plugin->delRow); | 392 | sqlite3_finalize (plugin->delRow); |
368 | if (plugin->updPrio != NULL) | 393 | if (plugin->updPrio != NULL) |
369 | sqlite3_finalize (plugin->updPrio); | 394 | sqlite3_finalize (plugin->updPrio); |
395 | if (plugin->updRepl != NULL) | ||
396 | sqlite3_finalize (plugin->updRepl); | ||
397 | if (plugin->selRepl != NULL) | ||
398 | sqlite3_finalize (plugin->selRepl); | ||
370 | if (plugin->insertContent != NULL) | 399 | if (plugin->insertContent != NULL) |
371 | sqlite3_finalize (plugin->insertContent); | 400 | sqlite3_finalize (plugin->insertContent); |
372 | result = sqlite3_close(plugin->dbh); | 401 | result = sqlite3_close(plugin->dbh); |
@@ -415,7 +444,6 @@ static int | |||
415 | delete_by_rowid (struct Plugin* plugin, | 444 | delete_by_rowid (struct Plugin* plugin, |
416 | unsigned long long rid) | 445 | unsigned long long rid) |
417 | { | 446 | { |
418 | |||
419 | sqlite3_bind_int64 (plugin->delRow, 1, rid); | 447 | sqlite3_bind_int64 (plugin->delRow, 1, rid); |
420 | if (SQLITE_DONE != sqlite3_step (plugin->delRow)) | 448 | if (SQLITE_DONE != sqlite3_step (plugin->delRow)) |
421 | { | 449 | { |
@@ -564,11 +592,11 @@ sqlite_next_request_cont (void *cls, | |||
564 | return; | 592 | return; |
565 | } | 593 | } |
566 | 594 | ||
567 | rowid = sqlite3_column_int64 (nc->stmt, 7); | 595 | rowid = sqlite3_column_int64 (nc->stmt, 6); |
568 | nc->last_rowid = rowid; | 596 | nc->last_rowid = rowid; |
569 | type = sqlite3_column_int (nc->stmt, 1); | 597 | type = sqlite3_column_int (nc->stmt, 0); |
570 | size = sqlite3_column_bytes (nc->stmt, 6); | 598 | size = sqlite3_column_bytes (nc->stmt, 5); |
571 | if (sqlite3_column_bytes (nc->stmt, 5) != sizeof (GNUNET_HashCode)) | 599 | if (sqlite3_column_bytes (nc->stmt, 4) != sizeof (GNUNET_HashCode)) |
572 | { | 600 | { |
573 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 601 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
574 | "sqlite", | 602 | "sqlite", |
@@ -579,7 +607,7 @@ sqlite_next_request_cont (void *cls, | |||
579 | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | 607 | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); |
580 | if (sq_prepare | 608 | if (sq_prepare |
581 | (nc->plugin->dbh, | 609 | (nc->plugin->dbh, |
582 | "DELETE FROM gn080 WHERE NOT LENGTH(hash) = ?", | 610 | "DELETE FROM gn090 WHERE NOT LENGTH(hash) = ?", |
583 | &stmtd) != SQLITE_OK) | 611 | &stmtd) != SQLITE_OK) |
584 | { | 612 | { |
585 | LOG_SQLITE (nc->plugin, NULL, | 613 | LOG_SQLITE (nc->plugin, NULL, |
@@ -604,14 +632,14 @@ sqlite_next_request_cont (void *cls, | |||
604 | goto END; | 632 | goto END; |
605 | } | 633 | } |
606 | 634 | ||
607 | priority = sqlite3_column_int (nc->stmt, 2); | 635 | priority = sqlite3_column_int (nc->stmt, 1); |
608 | anonymity = sqlite3_column_int (nc->stmt, 3); | 636 | anonymity = sqlite3_column_int (nc->stmt, 2); |
609 | expiration.abs_value = sqlite3_column_int64 (nc->stmt, 4); | 637 | expiration.abs_value = sqlite3_column_int64 (nc->stmt, 3); |
610 | key = sqlite3_column_blob (nc->stmt, 5); | 638 | key = sqlite3_column_blob (nc->stmt, 4); |
611 | nc->lastPriority = priority; | 639 | nc->lastPriority = priority; |
612 | nc->lastExpiration = expiration; | 640 | nc->lastExpiration = expiration; |
613 | memcpy (&nc->lastKey, key, sizeof(GNUNET_HashCode)); | 641 | memcpy (&nc->lastKey, key, sizeof(GNUNET_HashCode)); |
614 | data = sqlite3_column_blob (nc->stmt, 6); | 642 | data = sqlite3_column_blob (nc->stmt, 5); |
615 | nc->count++; | 643 | nc->count++; |
616 | ret = nc->iter (nc->iter_cls, | 644 | ret = nc->iter (nc->iter_cls, |
617 | nc, | 645 | nc, |
@@ -678,7 +706,6 @@ sqlite_next_request (void *next_cls, | |||
678 | } | 706 | } |
679 | 707 | ||
680 | 708 | ||
681 | |||
682 | /** | 709 | /** |
683 | * Store an item in the datastore. | 710 | * Store an item in the datastore. |
684 | * | 711 | * |
@@ -723,7 +750,7 @@ sqlite_plugin_put (void *cls, | |||
723 | #endif | 750 | #endif |
724 | GNUNET_CRYPTO_hash (data, size, &vhash); | 751 | GNUNET_CRYPTO_hash (data, size, &vhash); |
725 | stmt = plugin->insertContent; | 752 | stmt = plugin->insertContent; |
726 | if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, size)) || | 753 | if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, replication)) || |
727 | (SQLITE_OK != sqlite3_bind_int (stmt, 2, type)) || | 754 | (SQLITE_OK != sqlite3_bind_int (stmt, 2, type)) || |
728 | (SQLITE_OK != sqlite3_bind_int (stmt, 3, priority)) || | 755 | (SQLITE_OK != sqlite3_bind_int (stmt, 3, priority)) || |
729 | (SQLITE_OK != sqlite3_bind_int (stmt, 4, anonymity)) || | 756 | (SQLITE_OK != sqlite3_bind_int (stmt, 4, anonymity)) || |
@@ -1282,7 +1309,7 @@ sqlite_plugin_iter_all_now (void *cls, | |||
1282 | sqlite3_stmt *stmt; | 1309 | sqlite3_stmt *stmt; |
1283 | 1310 | ||
1284 | if (sq_prepare (plugin->dbh, | 1311 | if (sq_prepare (plugin->dbh, |
1285 | "SELECT size,type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn080", | 1312 | "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ FROM gn090", |
1286 | &stmt) != SQLITE_OK) | 1313 | &stmt) != SQLITE_OK) |
1287 | { | 1314 | { |
1288 | LOG_SQLITE (plugin, NULL, | 1315 | LOG_SQLITE (plugin, NULL, |
@@ -1443,7 +1470,7 @@ sqlite_plugin_get (void *cls, | |||
1443 | return; | 1470 | return; |
1444 | } | 1471 | } |
1445 | GNUNET_snprintf (scratch, sizeof (scratch), | 1472 | GNUNET_snprintf (scratch, sizeof (scratch), |
1446 | "SELECT count(*) FROM gn080 WHERE hash=:1%s%s", | 1473 | "SELECT count(*) FROM gn090 WHERE hash=:1%s%s", |
1447 | vhash == NULL ? "" : " AND vhash=:2", | 1474 | vhash == NULL ? "" : " AND vhash=:2", |
1448 | type == 0 ? "" : (vhash == | 1475 | type == 0 ? "" : (vhash == |
1449 | NULL) ? " AND type=:2" : " AND type=:3"); | 1476 | NULL) ? " AND type=:2" : " AND type=:3"); |
@@ -1495,8 +1522,8 @@ sqlite_plugin_get (void *cls, | |||
1495 | } | 1522 | } |
1496 | 1523 | ||
1497 | GNUNET_snprintf (scratch, sizeof (scratch), | 1524 | GNUNET_snprintf (scratch, sizeof (scratch), |
1498 | "SELECT size, type, prio, anonLevel, expire, hash, value, _ROWID_ " | 1525 | "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ " |
1499 | "FROM gn080 WHERE hash=:1%s%s AND _ROWID_ >= :%d " | 1526 | "FROM gn090 WHERE hash=:1%s%s AND _ROWID_ >= :%d " |
1500 | "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET :d", | 1527 | "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET :d", |
1501 | vhash == NULL ? "" : " AND vhash=:2", | 1528 | vhash == NULL ? "" : " AND vhash=:2", |
1502 | type == 0 ? "" : (vhash == | 1529 | type == 0 ? "" : (vhash == |
@@ -1547,8 +1574,84 @@ static void | |||
1547 | sqlite_plugin_replication_get (void *cls, | 1574 | sqlite_plugin_replication_get (void *cls, |
1548 | PluginIterator iter, void *iter_cls) | 1575 | PluginIterator iter, void *iter_cls) |
1549 | { | 1576 | { |
1550 | /* FIXME: not implemented! */ | 1577 | struct Plugin *plugin = cls; |
1551 | iter (iter_cls, NULL, NULL, 0, NULL, 0, 0, 0, | 1578 | int n; |
1579 | sqlite3_stmt *stmt; | ||
1580 | struct GNUNET_TIME_Absolute expiration; | ||
1581 | unsigned long long rowid; | ||
1582 | |||
1583 | #if DEBUG_SQLITE | ||
1584 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1585 | "sqlite", | ||
1586 | "Getting random block based on replication order.\n"); | ||
1587 | #endif | ||
1588 | stmt = plugin->selRepl; | ||
1589 | if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, expiration.abs_value)) | ||
1590 | { | ||
1591 | LOG_SQLITE (plugin, NULL, | ||
1592 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind_XXXX"); | ||
1593 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1594 | LOG_SQLITE (plugin, NULL, | ||
1595 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | ||
1596 | iter (iter_cls, NULL, NULL, 0, NULL, 0, 0, 0, | ||
1597 | GNUNET_TIME_UNIT_ZERO_ABS, 0); | ||
1598 | return; | ||
1599 | } | ||
1600 | n = sqlite3_step (stmt); | ||
1601 | switch (n) | ||
1602 | { | ||
1603 | case SQLITE_ROW: | ||
1604 | rowid = sqlite3_column_int64 (stmt, 6); | ||
1605 | if (sqlite3_column_bytes (stmt, 4) != sizeof (GNUNET_HashCode)) | ||
1606 | { | ||
1607 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
1608 | "sqlite", | ||
1609 | _("Invalid data in database. Trying to fix (by deletion).\n")); | ||
1610 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1611 | LOG_SQLITE (plugin, NULL, | ||
1612 | GNUNET_ERROR_TYPE_ERROR | | ||
1613 | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | ||
1614 | delete_by_rowid (plugin, rowid); | ||
1615 | break; | ||
1616 | } | ||
1617 | expiration.abs_value = sqlite3_column_int64 (stmt, 3); | ||
1618 | (void) iter (iter_cls, | ||
1619 | NULL, | ||
1620 | sqlite3_column_blob (stmt, 4) /* key */, | ||
1621 | sqlite3_column_bytes (stmt, 5) /* size of data */, | ||
1622 | sqlite3_column_blob (stmt, 5) /* data */, | ||
1623 | sqlite3_column_int (stmt, 0) /* type */, | ||
1624 | sqlite3_column_int (stmt, 1) /* priority */, | ||
1625 | sqlite3_column_int (stmt, 2) /* anonymity */, | ||
1626 | expiration, | ||
1627 | rowid); | ||
1628 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1629 | LOG_SQLITE (plugin, NULL, | ||
1630 | GNUNET_ERROR_TYPE_ERROR | | ||
1631 | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | ||
1632 | return; | ||
1633 | case SQLITE_DONE: | ||
1634 | /* database must be empty */ | ||
1635 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1636 | LOG_SQLITE (plugin, NULL, | ||
1637 | GNUNET_ERROR_TYPE_ERROR | | ||
1638 | GNUNET_ERROR_TYPE_BULK, "sqlite3_reset"); | ||
1639 | break; | ||
1640 | case SQLITE_BUSY: | ||
1641 | case SQLITE_ERROR: | ||
1642 | case SQLITE_MISUSE: | ||
1643 | default: | ||
1644 | LOG_SQLITE (plugin, NULL, | ||
1645 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1646 | "sqlite3_step"); | ||
1647 | (void) sqlite3_reset (stmt); | ||
1648 | GNUNET_break (0); | ||
1649 | database_shutdown (plugin); | ||
1650 | database_setup (plugin->env->cfg, | ||
1651 | plugin); | ||
1652 | break; | ||
1653 | } | ||
1654 | iter (iter_cls, NULL, NULL, 0, NULL, 0, 0, 0, | ||
1552 | GNUNET_TIME_UNIT_ZERO_ABS, 0); | 1655 | GNUNET_TIME_UNIT_ZERO_ABS, 0); |
1553 | } | 1656 | } |
1554 | 1657 | ||