aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore/plugin_peerstore_sqlite.c
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-06-04 16:03:17 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-06-04 16:03:17 +0000
commitf286cd0b87731774b9448a0cdc82f7c8682c4efe (patch)
treed84ace0bf67dd4f8a99888548f6ab635206eab4f /src/peerstore/plugin_peerstore_sqlite.c
parent7d18e9d89d2c920f9139bec7f55f01b00b5fd81a (diff)
downloadgnunet-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.c85
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 */
125static int
126peerstore_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 */
386void 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}