diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-05-12 17:01:59 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-05-12 17:01:59 +0000 |
commit | d743a7e758a4fd96f5997a2b6d0f2ce4d62e13cf (patch) | |
tree | 1c5c537eecbe2b71b661a442da4729e8bc605ccd /src/peerstore/plugin_peerstore_sqlite.c | |
parent | ac2be7dde06b71347d87ed491eb38d64a9163ad8 (diff) | |
download | gnunet-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.c | 142 |
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 | */ | ||
113 | static int | ||
114 | get_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 | */ | ||
160 | static int | ||
161 | peerstore_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 | } |