aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore/plugin_peerstore_sqlite.c
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-05-12 17:01:59 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-05-12 17:01:59 +0000
commitd743a7e758a4fd96f5997a2b6d0f2ce4d62e13cf (patch)
tree1c5c537eecbe2b71b661a442da4729e8bc605ccd /src/peerstore/plugin_peerstore_sqlite.c
parentac2be7dde06b71347d87ed491eb38d64a9163ad8 (diff)
downloadgnunet-d743a7e758a4fd96f5997a2b6d0f2ce4d62e13cf.tar.gz
gnunet-d743a7e758a4fd96f5997a2b6d0f2ce4d62e13cf.zip
towards PEERSTORE iterate
Diffstat (limited to 'src/peerstore/plugin_peerstore_sqlite.c')
-rw-r--r--src/peerstore/plugin_peerstore_sqlite.c142
1 files changed, 138 insertions, 4 deletions
diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c
index e967e2177..4598bbf24 100644
--- a/src/peerstore/plugin_peerstore_sqlite.c
+++ b/src/peerstore/plugin_peerstore_sqlite.c
@@ -77,9 +77,130 @@ struct Plugin
77 */ 77 */
78 sqlite3_stmt *insert_peerstoredata; 78 sqlite3_stmt *insert_peerstoredata;
79 79
80 /**
81 * Precompiled SQL for selecting from peerstoredata
82 */
83 sqlite3_stmt *select_peerstoredata;
84
85 /**
86 * Precompiled SQL for selecting from peerstoredata
87 */
88 sqlite3_stmt *select_peerstoredata_by_pid;
89
90 /**
91 * Precompiled SQL for selecting from peerstoredata
92 */
93 sqlite3_stmt *select_peerstoredata_by_ss;
94
95 /**
96 * Precompiled SQL for selecting from peerstoredata
97 */
98 sqlite3_stmt *select_peerstoredata_by_both;
99
80}; 100};
81 101
82/** 102/**
103 * The given 'sqlite' statement has been prepared to be run.
104 * It will return a record which should be given to the iterator.
105 * Runs the statement and parses the returned record.
106 *
107 * @param plugin plugin context
108 * @param stmt to run (and then clean up)
109 * @param iter iterator to call with the result
110 * @param iter_cls closure for @a iter
111 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
112 */
113static int
114get_record_and_call_iterator (struct Plugin *plugin,
115 sqlite3_stmt *stmt,
116 GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls)
117{
118 int ret;
119 int sret;
120 struct GNUNET_PeerIdentity *pid;
121 char *sub_system;
122 void *value;
123 size_t value_size;
124
125 ret = GNUNET_NO;
126 if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
127 {
128 pid = sqlite3_column_blob(stmt, 0);
129 sub_system = sqlite3_column_text(stmt, 1);
130 value = sqlite3_column_blob(stmt, 2);
131 value_size = sqlite3_column_bytes(stmt, 2);
132 if (NULL != iter)
133 iter (iter_cls, pid, sub_system, value, value_size);
134 ret = GNUNET_YES;
135 }
136 else
137 {
138 if (SQLITE_DONE != sret)
139 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
140 }
141 if (SQLITE_OK != sqlite3_reset (stmt))
142 LOG_SQLITE (plugin,
143 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
144 "sqlite3_reset");
145 return ret;
146
147}
148
149/**
150 * Iterate over the records given an optional peer id
151 * and/or sub system.
152 *
153 * @param cls closure (internal context for the plugin)
154 * @param peer Peer identity (can be NULL)
155 * @param sub_system name of sub system (can be NULL)
156 * @param iter function to call with the result
157 * @param iter_cls closure for @a iter
158 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
159 */
160static int
161peerstore_sqlite_iterate_records (void *cls,
162 const struct GNUNET_PeerIdentity *peer,
163 const char *sub_system,
164 GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls)
165{
166 struct Plugin *plugin = cls;
167 sqlite3_stmt *stmt;
168 int err;
169
170 if(NULL == sub_system && NULL == peer)
171 stmt = plugin->select_peerstoredata;
172 else if(NULL == sub_system)
173 {
174 stmt = plugin->select_peerstoredata_by_pid;
175 err = (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC));
176 }
177 else if(NULL == peer)
178 {
179 stmt = plugin->select_peerstoredata_by_ss;
180 err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC));
181 }
182 else
183 {
184 stmt = plugin->select_peerstoredata_by_both;
185 err =
186 (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC))
187 || (SQLITE_OK != sqlite3_bind_text(stmt, 2, sub_system, strlen(sub_system) + 1, SQLITE_STATIC));
188 }
189
190 if (err)
191 {
192 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
193 "sqlite3_bind_XXXX");
194 if (SQLITE_OK != sqlite3_reset (stmt))
195 LOG_SQLITE (plugin,
196 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
197 "sqlite3_reset");
198 return GNUNET_SYSERR;
199 }
200 return get_record_and_call_iterator (plugin, stmt, iter, iter_cls);
201}
202
203/**
83 * Store a record in the peerstore. 204 * Store a record in the peerstore.
84 * Key is the combination of sub system and peer identity. 205 * Key is the combination of sub system and peer identity.
85 * One key can store multiple values. 206 * One key can store multiple values.
@@ -103,8 +224,8 @@ peerstore_sqlite_store_record (void *cls,
103 224
104 //FIXME: check if value exists with the same key first 225 //FIXME: check if value exists with the same key first
105 226
106 if(SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC) 227 if(SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)
107 || SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC) 228 || SQLITE_OK != sqlite3_bind_text(stmt, 2, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)
108 || SQLITE_OK != sqlite3_bind_blob(stmt, 3, value, size, SQLITE_STATIC)) 229 || SQLITE_OK != sqlite3_bind_blob(stmt, 3, value, size, SQLITE_STATIC))
109 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 230 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
110 "sqlite3_bind"); 231 "sqlite3_bind");
@@ -235,8 +356,20 @@ database_setup (struct Plugin *plugin)
235 /* Prepare statements */ 356 /* Prepare statements */
236 357
237 sql_prepare (plugin->dbh, 358 sql_prepare (plugin->dbh,
238 "INSERT INTO peerstoredata (peer_id, sub_system, value) VALUES (?,?,?);", 359 "INSERT INTO peerstoredata (peer_id, sub_system, value) VALUES (?,?,?);",
239 &plugin->insert_peerstoredata); 360 &plugin->insert_peerstoredata);
361 sql_prepare(plugin->dbh,
362 "SELECT peer_id, sub_system, value FROM peerstoredata",
363 &plugin->select_peerstoredata);
364 sql_prepare(plugin->dbh,
365 "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ?",
366 &plugin->select_peerstoredata_by_pid);
367 sql_prepare(plugin->dbh,
368 "SELECT peer_id, sub_system, value FROM peerstoredata WHERE sub_system = ?",
369 &plugin->select_peerstoredata_by_ss);
370 sql_prepare(plugin->dbh,
371 "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ? AND sub_system = ?",
372 &plugin->select_peerstoredata_by_both);
240 373
241 return GNUNET_OK; 374 return GNUNET_OK;
242} 375}
@@ -289,6 +422,7 @@ libgnunet_plugin_peerstore_sqlite_init (void *cls)
289 api = GNUNET_new (struct GNUNET_PEERSTORE_PluginFunctions); 422 api = GNUNET_new (struct GNUNET_PEERSTORE_PluginFunctions);
290 api->cls = &plugin; 423 api->cls = &plugin;
291 api->store_record = &peerstore_sqlite_store_record; 424 api->store_record = &peerstore_sqlite_store_record;
425 api->iterate_records = &peerstore_sqlite_iterate_records;
292 LOG(GNUNET_ERROR_TYPE_DEBUG, "Sqlite plugin is running\n"); 426 LOG(GNUNET_ERROR_TYPE_DEBUG, "Sqlite plugin is running\n");
293 return api; 427 return api;
294} 428}