diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-06-04 16:03:17 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-06-04 16:03:17 +0000 |
commit | f286cd0b87731774b9448a0cdc82f7c8682c4efe (patch) | |
tree | d84ace0bf67dd4f8a99888548f6ab635206eab4f /src/peerstore/plugin_peerstore_sqlite.c | |
parent | 7d18e9d89d2c920f9139bec7f55f01b00b5fd81a (diff) | |
download | gnunet-f286cd0b87731774b9448a0cdc82f7c8682c4efe.tar.gz gnunet-f286cd0b87731774b9448a0cdc82f7c8682c4efe.zip |
peerstore: added 'replace' option and other fixes
Diffstat (limited to 'src/peerstore/plugin_peerstore_sqlite.c')
-rw-r--r-- | src/peerstore/plugin_peerstore_sqlite.c | 85 |
1 files changed, 79 insertions, 6 deletions
diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c index 8705ce188..38e72df51 100644 --- a/src/peerstore/plugin_peerstore_sqlite.c +++ b/src/peerstore/plugin_peerstore_sqlite.c | |||
@@ -100,13 +100,58 @@ struct Plugin | |||
100 | sqlite3_stmt *select_peerstoredata_by_all; | 100 | sqlite3_stmt *select_peerstoredata_by_all; |
101 | 101 | ||
102 | /** | 102 | /** |
103 | * Precompiled SQL for deleting expired records from peerstoredata | 103 | * Precompiled SQL for deleting expired |
104 | * records from peerstoredata | ||
104 | */ | 105 | */ |
105 | sqlite3_stmt *expire_peerstoredata; | 106 | sqlite3_stmt *expire_peerstoredata; |
106 | 107 | ||
108 | /** | ||
109 | * Precompiled SQL for deleting records | ||
110 | * with given key | ||
111 | */ | ||
112 | sqlite3_stmt *delete_peerstoredata; | ||
113 | |||
107 | }; | 114 | }; |
108 | 115 | ||
109 | /** | 116 | /** |
117 | * Delete records with the given key | ||
118 | * | ||
119 | * @param cls closure (internal context for the plugin) | ||
120 | * @param sub_system name of sub system | ||
121 | * @param peer Peer identity (can be NULL) | ||
122 | * @param key entry key string (can be NULL) | ||
123 | * @return number of deleted records | ||
124 | */ | ||
125 | static int | ||
126 | peerstore_sqlite_delete_records(void *cls, | ||
127 | const char *sub_system, | ||
128 | const struct GNUNET_PeerIdentity *peer, | ||
129 | const char *key) | ||
130 | { | ||
131 | struct Plugin *plugin = cls; | ||
132 | sqlite3_stmt *stmt = plugin->delete_peerstoredata; | ||
133 | |||
134 | if((SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)) | ||
135 | || (SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)) | ||
136 | || (SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC))) | ||
137 | { | ||
138 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind"); | ||
139 | } | ||
140 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
141 | { | ||
142 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
143 | "sqlite3_step"); | ||
144 | } | ||
145 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
146 | { | ||
147 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
148 | "sqlite3_reset"); | ||
149 | return 0; | ||
150 | } | ||
151 | return sqlite3_changes(plugin->dbh); | ||
152 | } | ||
153 | |||
154 | /** | ||
110 | * Delete expired records (expiry < now) | 155 | * Delete expired records (expiry < now) |
111 | * | 156 | * |
112 | * @param cls closure (internal context for the plugin) | 157 | * @param cls closure (internal context for the plugin) |
@@ -120,7 +165,7 @@ peerstore_sqlite_expire_records(void *cls, | |||
120 | struct Plugin *plugin = cls; | 165 | struct Plugin *plugin = cls; |
121 | sqlite3_stmt *stmt = plugin->expire_peerstoredata; | 166 | sqlite3_stmt *stmt = plugin->expire_peerstoredata; |
122 | 167 | ||
123 | if(SQLITE_OK != sqlite3_bind_int64(stmt, 1, (sqlite3_int64)now.abs_value_us)) | 168 | if(SQLITE_OK != sqlite3_bind_int64(stmt, 1, (sqlite3_uint64)now.abs_value_us)) |
124 | { | 169 | { |
125 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind"); | 170 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "sqlite3_bind"); |
126 | } | 171 | } |
@@ -254,16 +299,21 @@ peerstore_sqlite_store_record(void *cls, | |||
254 | const char *key, | 299 | const char *key, |
255 | const void *value, | 300 | const void *value, |
256 | size_t size, | 301 | size_t size, |
257 | struct GNUNET_TIME_Absolute expiry) | 302 | struct GNUNET_TIME_Absolute expiry, |
303 | enum GNUNET_PEERSTORE_StoreOption options) | ||
258 | { | 304 | { |
259 | struct Plugin *plugin = cls; | 305 | struct Plugin *plugin = cls; |
260 | sqlite3_stmt *stmt = plugin->insert_peerstoredata; | 306 | sqlite3_stmt *stmt = plugin->insert_peerstoredata; |
261 | 307 | ||
308 | if(GNUNET_PEERSTORE_STOREOPTION_REPLACE == options) | ||
309 | { | ||
310 | peerstore_sqlite_delete_records(cls, sub_system, peer, key); | ||
311 | } | ||
262 | if(SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC) | 312 | if(SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC) |
263 | || SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC) | 313 | || SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC) |
264 | || SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC) | 314 | || SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC) |
265 | || SQLITE_OK != sqlite3_bind_blob(stmt, 4, value, size, SQLITE_STATIC) | 315 | || SQLITE_OK != sqlite3_bind_blob(stmt, 4, value, size, SQLITE_STATIC) |
266 | || SQLITE_OK != sqlite3_bind_int64(stmt, 5, (sqlite3_int64)expiry.abs_value_us)) | 316 | || SQLITE_OK != sqlite3_bind_int64(stmt, 5, (sqlite3_uint64)expiry.abs_value_us)) |
267 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 317 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
268 | "sqlite3_bind"); | 318 | "sqlite3_bind"); |
269 | else if (SQLITE_DONE != sqlite3_step (stmt)) | 319 | else if (SQLITE_DONE != sqlite3_step (stmt)) |
@@ -330,6 +380,21 @@ sql_prepare (sqlite3 *dbh, const char *sql, sqlite3_stmt **stmt) | |||
330 | } | 380 | } |
331 | 381 | ||
332 | /** | 382 | /** |
383 | * sqlite3 custom function for comparison of uint64_t values | ||
384 | * since it is not supported by default | ||
385 | */ | ||
386 | void sqlite3_lessthan(sqlite3_context* ctx, int dummy, | ||
387 | sqlite3_value** values) | ||
388 | { | ||
389 | uint64_t v1; | ||
390 | uint64_t v2; | ||
391 | |||
392 | v1 = (uint64_t)sqlite3_value_int64(values[0]); | ||
393 | v2 = (uint64_t)sqlite3_value_int64(values[1]); | ||
394 | sqlite3_result_int(ctx, v1 < v2); | ||
395 | } | ||
396 | |||
397 | /** | ||
333 | * Initialize the database connections and associated | 398 | * Initialize the database connections and associated |
334 | * data structures (create tables and indices | 399 | * data structures (create tables and indices |
335 | * as needed as well). | 400 | * as needed as well). |
@@ -389,9 +454,11 @@ database_setup (struct Plugin *plugin) | |||
389 | " peer_id BLOB NOT NULL,\n" | 454 | " peer_id BLOB NOT NULL,\n" |
390 | " key TEXT NOT NULL,\n" | 455 | " key TEXT NOT NULL,\n" |
391 | " value BLOB NULL,\n" | 456 | " value BLOB NULL,\n" |
392 | " expiry INTEGER NOT NULL" | 457 | " expiry sqlite3_uint64 NOT NULL" |
393 | ");"); | 458 | ");"); |
394 | 459 | ||
460 | sqlite3_create_function(plugin->dbh, "UINT64_LT", 2, SQLITE_UTF8, NULL, &sqlite3_lessthan, NULL, NULL); | ||
461 | |||
395 | /* Prepare statements */ | 462 | /* Prepare statements */ |
396 | 463 | ||
397 | sql_prepare (plugin->dbh, | 464 | sql_prepare (plugin->dbh, |
@@ -419,8 +486,14 @@ database_setup (struct Plugin *plugin) | |||
419 | &plugin->select_peerstoredata_by_all); | 486 | &plugin->select_peerstoredata_by_all); |
420 | sql_prepare(plugin->dbh, | 487 | sql_prepare(plugin->dbh, |
421 | "DELETE FROM peerstoredata" | 488 | "DELETE FROM peerstoredata" |
422 | " WHERE expiry < ?", | 489 | " WHERE UINT64_LT(expiry, ?)", |
423 | &plugin->expire_peerstoredata); | 490 | &plugin->expire_peerstoredata); |
491 | sql_prepare(plugin->dbh, | ||
492 | "DELETE FROM peerstoredata" | ||
493 | " WHERE sub_system = ?" | ||
494 | " AND peer_id = ?" | ||
495 | " AND key = ?", | ||
496 | &plugin->delete_peerstoredata); | ||
424 | 497 | ||
425 | return GNUNET_OK; | 498 | return GNUNET_OK; |
426 | } | 499 | } |