summaryrefslogtreecommitdiff
path: root/src/namestore/plugin_namestore_sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r--src/namestore/plugin_namestore_sqlite.c871
1 files changed, 443 insertions, 428 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index ba031217d..fbf30567b 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -50,15 +50,23 @@
50 * a failure of the command 'cmd' on file 'filename' 50 * a failure of the command 'cmd' on file 'filename'
51 * with the message given by strerror(errno). 51 * with the message given by strerror(errno).
52 */ 52 */
53#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from(level, "namestore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while (0) 53#define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, \
54 "namestore-sqlite", _ ( \
55 "`%s' failed at %s:%d with error: %s\n"), \
56 cmd, \
57 __FILE__, __LINE__, \
58 sqlite3_errmsg ( \
59 db->dbh)); \
60} while (0)
54 61
55#define LOG(kind, ...) GNUNET_log_from(kind, "namestore-sqlite", __VA_ARGS__) 62#define LOG(kind, ...) GNUNET_log_from (kind, "namestore-sqlite", __VA_ARGS__)
56 63
57 64
58/** 65/**
59 * Context for all functions in this plugin. 66 * Context for all functions in this plugin.
60 */ 67 */
61struct Plugin { 68struct Plugin
69{
62 const struct GNUNET_CONFIGURATION_Handle *cfg; 70 const struct GNUNET_CONFIGURATION_Handle *cfg;
63 71
64 /** 72 /**
@@ -112,123 +120,124 @@ struct Plugin {
112 * @return #GNUNET_OK on success 120 * @return #GNUNET_OK on success
113 */ 121 */
114static int 122static int
115database_setup(struct Plugin *plugin) 123database_setup (struct Plugin *plugin)
116{ 124{
117 char *sqlite_filename; 125 char *sqlite_filename;
118 struct GNUNET_SQ_ExecuteStatement es[] = { 126 struct GNUNET_SQ_ExecuteStatement es[] = {
119 GNUNET_SQ_make_try_execute("PRAGMA temp_store=MEMORY"), 127 GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
120 GNUNET_SQ_make_try_execute("PRAGMA synchronous=NORMAL"), 128 GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
121 GNUNET_SQ_make_try_execute("PRAGMA legacy_file_format=OFF"), 129 GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
122 GNUNET_SQ_make_try_execute("PRAGMA auto_vacuum=INCREMENTAL"), 130 GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
123 GNUNET_SQ_make_try_execute("PRAGMA encoding=\"UTF-8\""), 131 GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
124 GNUNET_SQ_make_try_execute("PRAGMA locking_mode=EXCLUSIVE"), 132 GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"),
125 GNUNET_SQ_make_try_execute("PRAGMA journal_mode=WAL"), 133 GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
126 GNUNET_SQ_make_try_execute("PRAGMA page_size=4092"), 134 GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
127 GNUNET_SQ_make_execute("CREATE TABLE IF NOT EXISTS ns098records (" 135 GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
128 " uid INTEGER PRIMARY KEY," 136 " uid INTEGER PRIMARY KEY,"
129 " zone_private_key BLOB NOT NULL," 137 " zone_private_key BLOB NOT NULL,"
130 " pkey BLOB," 138 " pkey BLOB,"
131 " rvalue INT8 NOT NULL," 139 " rvalue INT8 NOT NULL,"
132 " record_count INT NOT NULL," 140 " record_count INT NOT NULL,"
133 " record_data BLOB NOT NULL," 141 " record_data BLOB NOT NULL,"
134 " label TEXT NOT NULL" 142 " label TEXT NOT NULL"
135 ")"), 143 ")"),
136 GNUNET_SQ_make_try_execute("CREATE INDEX IF NOT EXISTS ir_pkey_reverse " 144 GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse "
137 "ON ns098records (zone_private_key,pkey)"), 145 "ON ns098records (zone_private_key,pkey)"),
138 GNUNET_SQ_make_try_execute("CREATE INDEX IF NOT EXISTS ir_pkey_iter " 146 GNUNET_SQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter "
139 "ON ns098records (zone_private_key,uid)"), 147 "ON ns098records (zone_private_key,uid)"),
140 GNUNET_SQ_EXECUTE_STATEMENT_END 148 GNUNET_SQ_EXECUTE_STATEMENT_END
141 }; 149 };
142 struct GNUNET_SQ_PrepareStatement ps[] = { 150 struct GNUNET_SQ_PrepareStatement ps[] = {
143 GNUNET_SQ_make_prepare("INSERT INTO ns098records " 151 GNUNET_SQ_make_prepare ("INSERT INTO ns098records "
144 "(zone_private_key,pkey,rvalue,record_count,record_data,label)" 152 "(zone_private_key,pkey,rvalue,record_count,record_data,label)"
145 " VALUES (?, ?, ?, ?, ?, ?)", 153 " VALUES (?, ?, ?, ?, ?, ?)",
146 &plugin->store_records), 154 &plugin->store_records),
147 GNUNET_SQ_make_prepare("DELETE FROM ns098records " 155 GNUNET_SQ_make_prepare ("DELETE FROM ns098records "
148 "WHERE zone_private_key=? AND label=?", 156 "WHERE zone_private_key=? AND label=?",
149 &plugin->delete_records), 157 &plugin->delete_records),
150 GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label" 158 GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
151 " FROM ns098records" 159 " FROM ns098records"
152 " WHERE zone_private_key=? AND pkey=?", 160 " WHERE zone_private_key=? AND pkey=?",
153 &plugin->zone_to_name), 161 &plugin->zone_to_name),
154 GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label" 162 GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
155 " FROM ns098records" 163 " FROM ns098records"
156 " WHERE zone_private_key=? AND uid > ?" 164 " WHERE zone_private_key=? AND uid > ?"
157 " ORDER BY uid ASC" 165 " ORDER BY uid ASC"
158 " LIMIT ?", 166 " LIMIT ?",
159 &plugin->iterate_zone), 167 &plugin->iterate_zone),
160 GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label,zone_private_key" 168 GNUNET_SQ_make_prepare (
161 " FROM ns098records" 169 "SELECT uid,record_count,record_data,label,zone_private_key"
162 " WHERE uid > ?" 170 " FROM ns098records"
163 " ORDER BY uid ASC" 171 " WHERE uid > ?"
164 " LIMIT ?", 172 " ORDER BY uid ASC"
165 &plugin->iterate_all_zones), 173 " LIMIT ?",
166 GNUNET_SQ_make_prepare("SELECT uid,record_count,record_data,label" 174 &plugin->iterate_all_zones),
167 " FROM ns098records" 175 GNUNET_SQ_make_prepare ("SELECT uid,record_count,record_data,label"
168 " WHERE zone_private_key=? AND label=?", 176 " FROM ns098records"
169 &plugin->lookup_label), 177 " WHERE zone_private_key=? AND label=?",
178 &plugin->lookup_label),
170 GNUNET_SQ_PREPARE_END 179 GNUNET_SQ_PREPARE_END
171 }; 180 };
172 181
173 if (GNUNET_OK != 182 if (GNUNET_OK !=
174 GNUNET_CONFIGURATION_get_value_filename(plugin->cfg, 183 GNUNET_CONFIGURATION_get_value_filename (plugin->cfg,
175 "namestore-sqlite", 184 "namestore-sqlite",
176 "FILENAME", 185 "FILENAME",
177 &sqlite_filename)) 186 &sqlite_filename))
178 { 187 {
179 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, 188 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
180 "namestore-sqlite", 189 "namestore-sqlite",
181 "FILENAME"); 190 "FILENAME");
182 return GNUNET_SYSERR; 191 return GNUNET_SYSERR;
183 } 192 }
184 if (GNUNET_OK != 193 if (GNUNET_OK !=
185 GNUNET_DISK_file_test(sqlite_filename)) 194 GNUNET_DISK_file_test (sqlite_filename))
195 {
196 if (GNUNET_OK !=
197 GNUNET_DISK_directory_create_for_file (sqlite_filename))
186 { 198 {
187 if (GNUNET_OK != 199 GNUNET_break (0);
188 GNUNET_DISK_directory_create_for_file(sqlite_filename)) 200 GNUNET_free (sqlite_filename);
189 { 201 return GNUNET_SYSERR;
190 GNUNET_break(0);
191 GNUNET_free(sqlite_filename);
192 return GNUNET_SYSERR;
193 }
194 } 202 }
203 }
195 /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */ 204 /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */
196 plugin->fn = sqlite_filename; 205 plugin->fn = sqlite_filename;
197 206
198 /* Open database and precompile statements */ 207 /* Open database and precompile statements */
199 if (SQLITE_OK != 208 if (SQLITE_OK !=
200 sqlite3_open(plugin->fn, 209 sqlite3_open (plugin->fn,
201 &plugin->dbh)) 210 &plugin->dbh))
202 { 211 {
203 LOG(GNUNET_ERROR_TYPE_ERROR, 212 LOG (GNUNET_ERROR_TYPE_ERROR,
204 _("Unable to initialize SQLite: %s.\n"), 213 _ ("Unable to initialize SQLite: %s.\n"),
205 sqlite3_errmsg(plugin->dbh)); 214 sqlite3_errmsg (plugin->dbh));
206 return GNUNET_SYSERR; 215 return GNUNET_SYSERR;
207 } 216 }
208 GNUNET_break(SQLITE_OK == 217 GNUNET_break (SQLITE_OK ==
209 sqlite3_busy_timeout(plugin->dbh, 218 sqlite3_busy_timeout (plugin->dbh,
210 BUSY_TIMEOUT_MS)); 219 BUSY_TIMEOUT_MS));
211 if (GNUNET_OK != 220 if (GNUNET_OK !=
212 GNUNET_SQ_exec_statements(plugin->dbh, 221 GNUNET_SQ_exec_statements (plugin->dbh,
213 es)) 222 es))
214 { 223 {
215 GNUNET_break(0); 224 GNUNET_break (0);
216 LOG(GNUNET_ERROR_TYPE_ERROR, 225 LOG (GNUNET_ERROR_TYPE_ERROR,
217 _("Failed to setup database at `%s'\n"), 226 _ ("Failed to setup database at `%s'\n"),
218 plugin->fn); 227 plugin->fn);
219 return GNUNET_SYSERR; 228 return GNUNET_SYSERR;
220 } 229 }
221 230
222 if (GNUNET_OK != 231 if (GNUNET_OK !=
223 GNUNET_SQ_prepare(plugin->dbh, 232 GNUNET_SQ_prepare (plugin->dbh,
224 ps)) 233 ps))
225 { 234 {
226 GNUNET_break(0); 235 GNUNET_break (0);
227 LOG(GNUNET_ERROR_TYPE_ERROR, 236 LOG (GNUNET_ERROR_TYPE_ERROR,
228 _("Failed to setup database at `%s'\n"), 237 _ ("Failed to setup database at `%s'\n"),
229 plugin->fn); 238 plugin->fn);
230 return GNUNET_SYSERR; 239 return GNUNET_SYSERR;
231 } 240 }
232 return GNUNET_OK; 241 return GNUNET_OK;
233} 242}
234 243
@@ -239,54 +248,55 @@ database_setup(struct Plugin *plugin)
239 * @param plugin the plugin context (state for this module) 248 * @param plugin the plugin context (state for this module)
240 */ 249 */
241static void 250static void
242database_shutdown(struct Plugin *plugin) 251database_shutdown (struct Plugin *plugin)
243{ 252{
244 int result; 253 int result;
245 sqlite3_stmt *stmt; 254 sqlite3_stmt *stmt;
246 255
247 if (NULL != plugin->store_records) 256 if (NULL != plugin->store_records)
248 sqlite3_finalize(plugin->store_records); 257 sqlite3_finalize (plugin->store_records);
249 if (NULL != plugin->delete_records) 258 if (NULL != plugin->delete_records)
250 sqlite3_finalize(plugin->delete_records); 259 sqlite3_finalize (plugin->delete_records);
251 if (NULL != plugin->iterate_zone) 260 if (NULL != plugin->iterate_zone)
252 sqlite3_finalize(plugin->iterate_zone); 261 sqlite3_finalize (plugin->iterate_zone);
253 if (NULL != plugin->iterate_all_zones) 262 if (NULL != plugin->iterate_all_zones)
254 sqlite3_finalize(plugin->iterate_all_zones); 263 sqlite3_finalize (plugin->iterate_all_zones);
255 if (NULL != plugin->zone_to_name) 264 if (NULL != plugin->zone_to_name)
256 sqlite3_finalize(plugin->zone_to_name); 265 sqlite3_finalize (plugin->zone_to_name);
257 if (NULL != plugin->lookup_label) 266 if (NULL != plugin->lookup_label)
258 sqlite3_finalize(plugin->lookup_label); 267 sqlite3_finalize (plugin->lookup_label);
259 result = sqlite3_close(plugin->dbh); 268 result = sqlite3_close (plugin->dbh);
260 if (result == SQLITE_BUSY) 269 if (result == SQLITE_BUSY)
270 {
271 LOG (GNUNET_ERROR_TYPE_WARNING,
272 _ (
273 "Tried to close sqlite without finalizing all prepared statements.\n"));
274 stmt = sqlite3_next_stmt (plugin->dbh,
275 NULL);
276 while (NULL != stmt)
261 { 277 {
262 LOG(GNUNET_ERROR_TYPE_WARNING, 278 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
263 _("Tried to close sqlite without finalizing all prepared statements.\n")); 279 "sqlite",
264 stmt = sqlite3_next_stmt(plugin->dbh, 280 "Closing statement %p\n",
265 NULL); 281 stmt);
266 while (NULL != stmt) 282 result = sqlite3_finalize (stmt);
267 { 283 if (result != SQLITE_OK)
268 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, 284 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
269 "sqlite", 285 "sqlite",
270 "Closing statement %p\n", 286 "Failed to close statement %p: %d\n",
271 stmt); 287 stmt,
272 result = sqlite3_finalize(stmt); 288 result);
273 if (result != SQLITE_OK) 289 stmt = sqlite3_next_stmt (plugin->dbh,
274 GNUNET_log_from(GNUNET_ERROR_TYPE_WARNING, 290 NULL);
275 "sqlite",
276 "Failed to close statement %p: %d\n",
277 stmt,
278 result);
279 stmt = sqlite3_next_stmt(plugin->dbh,
280 NULL);
281 }
282 result = sqlite3_close(plugin->dbh);
283 } 291 }
292 result = sqlite3_close (plugin->dbh);
293 }
284 if (SQLITE_OK != result) 294 if (SQLITE_OK != result)
285 LOG_SQLITE(plugin, 295 LOG_SQLITE (plugin,
286 GNUNET_ERROR_TYPE_ERROR, 296 GNUNET_ERROR_TYPE_ERROR,
287 "sqlite3_close"); 297 "sqlite3_close");
288 298
289 GNUNET_free_non_null(plugin->fn); 299 GNUNET_free_non_null (plugin->fn);
290} 300}
291 301
292 302
@@ -302,11 +312,12 @@ database_shutdown(struct Plugin *plugin)
302 * @return #GNUNET_OK on success, else #GNUNET_SYSERR 312 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
303 */ 313 */
304static int 314static int
305namestore_sqlite_store_records(void *cls, 315namestore_sqlite_store_records (void *cls,
306 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, 316 const struct
307 const char *label, 317 GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
308 unsigned int rd_count, 318 const char *label,
309 const struct GNUNET_GNSRECORD_Data *rd) 319 unsigned int rd_count,
320 const struct GNUNET_GNSRECORD_Data *rd)
310{ 321{
311 struct Plugin *plugin = cls; 322 struct Plugin *plugin = cls;
312 int n; 323 int n;
@@ -314,122 +325,122 @@ namestore_sqlite_store_records(void *cls,
314 uint64_t rvalue; 325 uint64_t rvalue;
315 ssize_t data_size; 326 ssize_t data_size;
316 327
317 memset(&pkey, 328 memset (&pkey,
318 0, 329 0,
319 sizeof(pkey)); 330 sizeof(pkey));
320 for (unsigned int i = 0; i < rd_count; i++) 331 for (unsigned int i = 0; i < rd_count; i++)
321 if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type) 332 if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type)
322 {
323 GNUNET_break(sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) ==
324 rd[i].data_size);
325 GNUNET_memcpy(&pkey,
326 rd[i].data,
327 rd[i].data_size);
328 break;
329 }
330 rvalue = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK,
331 UINT64_MAX);
332 data_size = GNUNET_GNSRECORD_records_get_size(rd_count,
333 rd);
334 if (data_size < 0)
335 { 333 {
336 GNUNET_break(0); 334 GNUNET_break (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) ==
337 return GNUNET_SYSERR; 335 rd[i].data_size);
336 GNUNET_memcpy (&pkey,
337 rd[i].data,
338 rd[i].data_size);
339 break;
338 } 340 }
341 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
342 UINT64_MAX);
343 data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
344 rd);
345 if (data_size < 0)
346 {
347 GNUNET_break (0);
348 return GNUNET_SYSERR;
349 }
339 if (data_size > 64 * 65536) 350 if (data_size > 64 * 65536)
340 { 351 {
341 GNUNET_break(0); 352 GNUNET_break (0);
342 return GNUNET_SYSERR; 353 return GNUNET_SYSERR;
343 } 354 }
344 { 355 {
345 /* First delete 'old' records */ 356 /* First delete 'old' records */
346 char data[data_size]; 357 char data[data_size];
347 struct GNUNET_SQ_QueryParam dparams[] = { 358 struct GNUNET_SQ_QueryParam dparams[] = {
348 GNUNET_SQ_query_param_auto_from_type(zone_key), 359 GNUNET_SQ_query_param_auto_from_type (zone_key),
349 GNUNET_SQ_query_param_string(label), 360 GNUNET_SQ_query_param_string (label),
350 GNUNET_SQ_query_param_end 361 GNUNET_SQ_query_param_end
351 }; 362 };
352 ssize_t ret; 363 ssize_t ret;
353 364
354 ret = GNUNET_GNSRECORD_records_serialize(rd_count, 365 ret = GNUNET_GNSRECORD_records_serialize (rd_count,
355 rd, 366 rd,
356 data_size, 367 data_size,
357 data); 368 data);
358 if ((ret < 0) || 369 if ((ret < 0) ||
359 (data_size != ret)) 370 (data_size != ret))
360 { 371 {
361 GNUNET_break(0); 372 GNUNET_break (0);
362 return GNUNET_SYSERR; 373 return GNUNET_SYSERR;
363 } 374 }
364 if (GNUNET_OK != 375 if (GNUNET_OK !=
365 GNUNET_SQ_bind(plugin->delete_records, 376 GNUNET_SQ_bind (plugin->delete_records,
366 dparams)) 377 dparams))
367 { 378 {
368 LOG_SQLITE(plugin, 379 LOG_SQLITE (plugin,
369 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 380 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
370 "sqlite3_bind_XXXX"); 381 "sqlite3_bind_XXXX");
371 GNUNET_SQ_reset(plugin->dbh, 382 GNUNET_SQ_reset (plugin->dbh,
372 plugin->delete_records); 383 plugin->delete_records);
373 return GNUNET_SYSERR; 384 return GNUNET_SYSERR;
374 } 385 }
375 n = sqlite3_step(plugin->delete_records); 386 n = sqlite3_step (plugin->delete_records);
376 GNUNET_SQ_reset(plugin->dbh, 387 GNUNET_SQ_reset (plugin->dbh,
377 plugin->delete_records); 388 plugin->delete_records);
378 389
379 if (0 != rd_count) 390 if (0 != rd_count)
380 { 391 {
381 uint32_t rd_count32 = (uint32_t)rd_count; 392 uint32_t rd_count32 = (uint32_t) rd_count;
382 struct GNUNET_SQ_QueryParam sparams[] = { 393 struct GNUNET_SQ_QueryParam sparams[] = {
383 GNUNET_SQ_query_param_auto_from_type(zone_key), 394 GNUNET_SQ_query_param_auto_from_type (zone_key),
384 GNUNET_SQ_query_param_auto_from_type(&pkey), 395 GNUNET_SQ_query_param_auto_from_type (&pkey),
385 GNUNET_SQ_query_param_uint64(&rvalue), 396 GNUNET_SQ_query_param_uint64 (&rvalue),
386 GNUNET_SQ_query_param_uint32(&rd_count32), 397 GNUNET_SQ_query_param_uint32 (&rd_count32),
387 GNUNET_SQ_query_param_fixed_size(data, data_size), 398 GNUNET_SQ_query_param_fixed_size (data, data_size),
388 GNUNET_SQ_query_param_string(label), 399 GNUNET_SQ_query_param_string (label),
389 GNUNET_SQ_query_param_end 400 GNUNET_SQ_query_param_end
390 }; 401 };
391 402
392 if (GNUNET_OK != 403 if (GNUNET_OK !=
393 GNUNET_SQ_bind(plugin->store_records, 404 GNUNET_SQ_bind (plugin->store_records,
394 sparams)) 405 sparams))
395 { 406 {
396 LOG_SQLITE(plugin, 407 LOG_SQLITE (plugin,
397 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 408 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
398 "sqlite3_bind_XXXX"); 409 "sqlite3_bind_XXXX");
399 GNUNET_SQ_reset(plugin->dbh, 410 GNUNET_SQ_reset (plugin->dbh,
400 plugin->store_records); 411 plugin->store_records);
401 return GNUNET_SYSERR; 412 return GNUNET_SYSERR;
402 }
403 n = sqlite3_step(plugin->store_records);
404 GNUNET_SQ_reset(plugin->dbh,
405 plugin->store_records);
406 } 413 }
414 n = sqlite3_step (plugin->store_records);
415 GNUNET_SQ_reset (plugin->dbh,
416 plugin->store_records);
417 }
407 } 418 }
408 switch (n) 419 switch (n)
409 { 420 {
410 case SQLITE_DONE: 421 case SQLITE_DONE:
411 if (0 != rd_count) 422 if (0 != rd_count)
412 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, 423 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
413 "sqlite", 424 "sqlite",
414 "Record stored\n"); 425 "Record stored\n");
415 else 426 else
416 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, 427 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
417 "sqlite", 428 "sqlite",
418 "Record deleted\n"); 429 "Record deleted\n");
419 return GNUNET_OK; 430 return GNUNET_OK;
420 431
421 case SQLITE_BUSY: 432 case SQLITE_BUSY:
422 LOG_SQLITE(plugin, 433 LOG_SQLITE (plugin,
423 GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, 434 GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
424 "sqlite3_step"); 435 "sqlite3_step");
425 return GNUNET_NO; 436 return GNUNET_NO;
426 437
427 default: 438 default:
428 LOG_SQLITE(plugin, 439 LOG_SQLITE (plugin,
429 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 440 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
430 "sqlite3_step"); 441 "sqlite3_step");
431 return GNUNET_SYSERR; 442 return GNUNET_SYSERR;
432 } 443 }
433} 444}
434 445
435 446
@@ -447,108 +458,109 @@ namestore_sqlite_store_records(void *cls,
447 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 458 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
448 */ 459 */
449static int 460static int
450get_records_and_call_iterator(struct Plugin *plugin, 461get_records_and_call_iterator (struct Plugin *plugin,
451 sqlite3_stmt *stmt, 462 sqlite3_stmt *stmt,
452 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, 463 const struct
453 uint64_t limit, 464 GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
454 GNUNET_NAMESTORE_RecordIterator iter, 465 uint64_t limit,
455 void *iter_cls) 466 GNUNET_NAMESTORE_RecordIterator iter,
467 void *iter_cls)
456{ 468{
457 int ret; 469 int ret;
458 int sret; 470 int sret;
459 471
460 ret = GNUNET_OK; 472 ret = GNUNET_OK;
461 for (uint64_t i = 0; i < limit; i++) 473 for (uint64_t i = 0; i < limit; i++)
474 {
475 sret = sqlite3_step (stmt);
476
477 if (SQLITE_DONE == sret)
462 { 478 {
463 sret = sqlite3_step(stmt); 479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
480 "Iteration done (no results)\n");
481 ret = GNUNET_NO;
482 break;
483 }
484 if (SQLITE_ROW != sret)
485 {
486 LOG_SQLITE (plugin,
487 GNUNET_ERROR_TYPE_ERROR,
488 "sqlite_step");
489 ret = GNUNET_SYSERR;
490 break;
491 }
464 492
465 if (SQLITE_DONE == sret) 493 {
466 { 494 uint64_t seq;
467 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 495 uint32_t record_count;
468 "Iteration done (no results)\n"); 496 size_t data_size;
469 ret = GNUNET_NO; 497 void *data;
470 break; 498 char *label;
471 } 499 struct GNUNET_CRYPTO_EcdsaPrivateKey zk;
472 if (SQLITE_ROW != sret) 500 struct GNUNET_SQ_ResultSpec rs[] = {
501 GNUNET_SQ_result_spec_uint64 (&seq),
502 GNUNET_SQ_result_spec_uint32 (&record_count),
503 GNUNET_SQ_result_spec_variable_size (&data,
504 &data_size),
505 GNUNET_SQ_result_spec_string (&label),
506 GNUNET_SQ_result_spec_end
507 };
508 struct GNUNET_SQ_ResultSpec rsx[] = {
509 GNUNET_SQ_result_spec_uint64 (&seq),
510 GNUNET_SQ_result_spec_uint32 (&record_count),
511 GNUNET_SQ_result_spec_variable_size (&data,
512 &data_size),
513 GNUNET_SQ_result_spec_string (&label),
514 GNUNET_SQ_result_spec_auto_from_type (&zk),
515 GNUNET_SQ_result_spec_end
516 };
517
518 ret = GNUNET_SQ_extract_result (stmt,
519 (NULL == zone_key)
520 ? rsx
521 : rs);
522 if ((GNUNET_OK != ret) ||
523 (record_count > 64 * 1024))
524 {
525 /* sanity check, don't stack allocate far too much just
526 because database might contain a large value here */
527 GNUNET_break (0);
528 ret = GNUNET_SYSERR;
529 break;
530 }
531 else
532 {
533 struct GNUNET_GNSRECORD_Data rd[record_count];
534
535 GNUNET_assert (0 != seq);
536 if (GNUNET_OK !=
537 GNUNET_GNSRECORD_records_deserialize (data_size,
538 data,
539 record_count,
540 rd))
473 { 541 {
474 LOG_SQLITE(plugin, 542 GNUNET_break (0);
475 GNUNET_ERROR_TYPE_ERROR,
476 "sqlite_step");
477 ret = GNUNET_SYSERR; 543 ret = GNUNET_SYSERR;
478 break; 544 break;
479 } 545 }
480
481 {
482 uint64_t seq;
483 uint32_t record_count;
484 size_t data_size;
485 void *data;
486 char *label;
487 struct GNUNET_CRYPTO_EcdsaPrivateKey zk;
488 struct GNUNET_SQ_ResultSpec rs[] = {
489 GNUNET_SQ_result_spec_uint64(&seq),
490 GNUNET_SQ_result_spec_uint32(&record_count),
491 GNUNET_SQ_result_spec_variable_size(&data,
492 &data_size),
493 GNUNET_SQ_result_spec_string(&label),
494 GNUNET_SQ_result_spec_end
495 };
496 struct GNUNET_SQ_ResultSpec rsx[] = {
497 GNUNET_SQ_result_spec_uint64(&seq),
498 GNUNET_SQ_result_spec_uint32(&record_count),
499 GNUNET_SQ_result_spec_variable_size(&data,
500 &data_size),
501 GNUNET_SQ_result_spec_string(&label),
502 GNUNET_SQ_result_spec_auto_from_type(&zk),
503 GNUNET_SQ_result_spec_end
504 };
505
506 ret = GNUNET_SQ_extract_result(stmt,
507 (NULL == zone_key)
508 ? rsx
509 : rs);
510 if ((GNUNET_OK != ret) ||
511 (record_count > 64 * 1024))
512 {
513 /* sanity check, don't stack allocate far too much just
514 because database might contain a large value here */
515 GNUNET_break(0);
516 ret = GNUNET_SYSERR;
517 break;
518 }
519 else 546 else
520 { 547 {
521 struct GNUNET_GNSRECORD_Data rd[record_count]; 548 if (NULL != zone_key)
522 549 zk = *zone_key;
523 GNUNET_assert(0 != seq); 550 if (NULL != iter)
524 if (GNUNET_OK != 551 iter (iter_cls,
525 GNUNET_GNSRECORD_records_deserialize(data_size, 552 seq,
526 data, 553 &zk,
527 record_count, 554 label,
528 rd)) 555 record_count,
529 { 556 rd);
530 GNUNET_break(0); 557 }
531 ret = GNUNET_SYSERR;
532 break;
533 }
534 else
535 {
536 if (NULL != zone_key)
537 zk = *zone_key;
538 if (NULL != iter)
539 iter(iter_cls,
540 seq,
541 &zk,
542 label,
543 record_count,
544 rd);
545 }
546 }
547 GNUNET_SQ_cleanup_result(rs);
548 } 558 }
559 GNUNET_SQ_cleanup_result (rs);
549 } 560 }
550 GNUNET_SQ_reset(plugin->dbh, 561 }
551 stmt); 562 GNUNET_SQ_reset (plugin->dbh,
563 stmt);
552 return ret; 564 return ret;
553} 565}
554 566
@@ -564,40 +576,41 @@ get_records_and_call_iterator(struct Plugin *plugin,
564 * @return #GNUNET_OK on success, #GNUNET_NO for no results, else #GNUNET_SYSERR 576 * @return #GNUNET_OK on success, #GNUNET_NO for no results, else #GNUNET_SYSERR
565 */ 577 */
566static int 578static int
567namestore_sqlite_lookup_records(void *cls, 579namestore_sqlite_lookup_records (void *cls,
568 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, 580 const struct
569 const char *label, 581 GNUNET_CRYPTO_EcdsaPrivateKey *zone,
570 GNUNET_NAMESTORE_RecordIterator iter, 582 const char *label,
571 void *iter_cls) 583 GNUNET_NAMESTORE_RecordIterator iter,
584 void *iter_cls)
572{ 585{
573 struct Plugin *plugin = cls; 586 struct Plugin *plugin = cls;
574 struct GNUNET_SQ_QueryParam params[] = { 587 struct GNUNET_SQ_QueryParam params[] = {
575 GNUNET_SQ_query_param_auto_from_type(zone), 588 GNUNET_SQ_query_param_auto_from_type (zone),
576 GNUNET_SQ_query_param_string(label), 589 GNUNET_SQ_query_param_string (label),
577 GNUNET_SQ_query_param_end 590 GNUNET_SQ_query_param_end
578 }; 591 };
579 592
580 if (NULL == zone) 593 if (NULL == zone)
581 { 594 {
582 GNUNET_break(0); 595 GNUNET_break (0);
583 return GNUNET_SYSERR; 596 return GNUNET_SYSERR;
584 } 597 }
585 if (GNUNET_OK != 598 if (GNUNET_OK !=
586 GNUNET_SQ_bind(plugin->lookup_label, 599 GNUNET_SQ_bind (plugin->lookup_label,
587 params)) 600 params))
588 { 601 {
589 LOG_SQLITE(plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 602 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
590 "sqlite3_bind_XXXX"); 603 "sqlite3_bind_XXXX");
591 GNUNET_SQ_reset(plugin->dbh, 604 GNUNET_SQ_reset (plugin->dbh,
592 plugin->lookup_label); 605 plugin->lookup_label);
593 return GNUNET_SYSERR; 606 return GNUNET_SYSERR;
594 } 607 }
595 return get_records_and_call_iterator(plugin, 608 return get_records_and_call_iterator (plugin,
596 plugin->lookup_label, 609 plugin->lookup_label,
597 zone, 610 zone,
598 1, 611 1,
599 iter, 612 iter,
600 iter_cls); 613 iter_cls);
601} 614}
602 615
603 616
@@ -614,57 +627,58 @@ namestore_sqlite_lookup_records(void *cls,
614 * @return #GNUNET_OK on success, #GNUNET_NO if there were no more results, #GNUNET_SYSERR on error 627 * @return #GNUNET_OK on success, #GNUNET_NO if there were no more results, #GNUNET_SYSERR on error
615 */ 628 */
616static int 629static int
617namestore_sqlite_iterate_records(void *cls, 630namestore_sqlite_iterate_records (void *cls,
618 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, 631 const struct
619 uint64_t serial, 632 GNUNET_CRYPTO_EcdsaPrivateKey *zone,
620 uint64_t limit, 633 uint64_t serial,
621 GNUNET_NAMESTORE_RecordIterator iter, 634 uint64_t limit,
622 void *iter_cls) 635 GNUNET_NAMESTORE_RecordIterator iter,
636 void *iter_cls)
623{ 637{
624 struct Plugin *plugin = cls; 638 struct Plugin *plugin = cls;
625 sqlite3_stmt *stmt; 639 sqlite3_stmt *stmt;
626 int err; 640 int err;
627 641
628 if (NULL == zone) 642 if (NULL == zone)
629 { 643 {
630 struct GNUNET_SQ_QueryParam params[] = { 644 struct GNUNET_SQ_QueryParam params[] = {
631 GNUNET_SQ_query_param_uint64(&serial), 645 GNUNET_SQ_query_param_uint64 (&serial),
632 GNUNET_SQ_query_param_uint64(&limit), 646 GNUNET_SQ_query_param_uint64 (&limit),
633 GNUNET_SQ_query_param_end 647 GNUNET_SQ_query_param_end
634 }; 648 };
635 649
636 stmt = plugin->iterate_all_zones; 650 stmt = plugin->iterate_all_zones;
637 err = GNUNET_SQ_bind(stmt, 651 err = GNUNET_SQ_bind (stmt,
638 params); 652 params);
639 } 653 }
640 else 654 else
641 { 655 {
642 struct GNUNET_SQ_QueryParam params[] = { 656 struct GNUNET_SQ_QueryParam params[] = {
643 GNUNET_SQ_query_param_auto_from_type(zone), 657 GNUNET_SQ_query_param_auto_from_type (zone),
644 GNUNET_SQ_query_param_uint64(&serial), 658 GNUNET_SQ_query_param_uint64 (&serial),
645 GNUNET_SQ_query_param_uint64(&limit), 659 GNUNET_SQ_query_param_uint64 (&limit),
646 GNUNET_SQ_query_param_end 660 GNUNET_SQ_query_param_end
647 }; 661 };
648 662
649 stmt = plugin->iterate_zone; 663 stmt = plugin->iterate_zone;
650 err = GNUNET_SQ_bind(stmt, 664 err = GNUNET_SQ_bind (stmt,
651 params); 665 params);
652 } 666 }
653 if (GNUNET_OK != err) 667 if (GNUNET_OK != err)
654 { 668 {
655 LOG_SQLITE(plugin, 669 LOG_SQLITE (plugin,
656 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 670 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
657 "sqlite3_bind_XXXX"); 671 "sqlite3_bind_XXXX");
658 GNUNET_SQ_reset(plugin->dbh, 672 GNUNET_SQ_reset (plugin->dbh,
659 stmt); 673 stmt);
660 return GNUNET_SYSERR; 674 return GNUNET_SYSERR;
661 } 675 }
662 return get_records_and_call_iterator(plugin, 676 return get_records_and_call_iterator (plugin,
663 stmt, 677 stmt,
664 zone, 678 zone,
665 limit, 679 limit,
666 iter, 680 iter,
667 iter_cls); 681 iter_cls);
668} 682}
669 683
670 684
@@ -680,39 +694,40 @@ namestore_sqlite_iterate_records(void *cls,
680 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 694 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
681 */ 695 */
682static int 696static int
683namestore_sqlite_zone_to_name(void *cls, 697namestore_sqlite_zone_to_name (void *cls,
684 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, 698 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
685 const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, 699 const struct
686 GNUNET_NAMESTORE_RecordIterator iter, 700 GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
687 void *iter_cls) 701 GNUNET_NAMESTORE_RecordIterator iter,
702 void *iter_cls)
688{ 703{
689 struct Plugin *plugin = cls; 704 struct Plugin *plugin = cls;
690 struct GNUNET_SQ_QueryParam params[] = { 705 struct GNUNET_SQ_QueryParam params[] = {
691 GNUNET_SQ_query_param_auto_from_type(zone), 706 GNUNET_SQ_query_param_auto_from_type (zone),
692 GNUNET_SQ_query_param_auto_from_type(value_zone), 707 GNUNET_SQ_query_param_auto_from_type (value_zone),
693 GNUNET_SQ_query_param_end 708 GNUNET_SQ_query_param_end
694 }; 709 };
695 710
696 if (GNUNET_OK != 711 if (GNUNET_OK !=
697 GNUNET_SQ_bind(plugin->zone_to_name, 712 GNUNET_SQ_bind (plugin->zone_to_name,
698 params)) 713 params))
699 { 714 {
700 LOG_SQLITE(plugin, 715 LOG_SQLITE (plugin,
701 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 716 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
702 "sqlite3_bind_XXXX"); 717 "sqlite3_bind_XXXX");
703 GNUNET_SQ_reset(plugin->dbh, 718 GNUNET_SQ_reset (plugin->dbh,
704 plugin->zone_to_name); 719 plugin->zone_to_name);
705 return GNUNET_SYSERR; 720 return GNUNET_SYSERR;
706 } 721 }
707 LOG(GNUNET_ERROR_TYPE_DEBUG, 722 LOG (GNUNET_ERROR_TYPE_DEBUG,
708 "Performing reverse lookup for `%s'\n", 723 "Performing reverse lookup for `%s'\n",
709 GNUNET_GNSRECORD_z2s(value_zone)); 724 GNUNET_GNSRECORD_z2s (value_zone));
710 return get_records_and_call_iterator(plugin, 725 return get_records_and_call_iterator (plugin,
711 plugin->zone_to_name, 726 plugin->zone_to_name,
712 zone, 727 zone,
713 1, 728 1,
714 iter, 729 iter,
715 iter_cls); 730 iter_cls);
716} 731}
717 732
718 733
@@ -723,7 +738,7 @@ namestore_sqlite_zone_to_name(void *cls,
723 * @return NULL on error, otherwise the plugin context 738 * @return NULL on error, otherwise the plugin context
724 */ 739 */
725void * 740void *
726libgnunet_plugin_namestore_sqlite_init(void *cls) 741libgnunet_plugin_namestore_sqlite_init (void *cls)
727{ 742{
728 static struct Plugin plugin; 743 static struct Plugin plugin;
729 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 744 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -731,23 +746,23 @@ libgnunet_plugin_namestore_sqlite_init(void *cls)
731 746
732 if (NULL != plugin.cfg) 747 if (NULL != plugin.cfg)
733 return NULL; /* can only initialize once! */ 748 return NULL; /* can only initialize once! */
734 memset(&plugin, 749 memset (&plugin,
735 0, 750 0,
736 sizeof(struct Plugin)); 751 sizeof(struct Plugin));
737 plugin.cfg = cfg; 752 plugin.cfg = cfg;
738 if (GNUNET_OK != database_setup(&plugin)) 753 if (GNUNET_OK != database_setup (&plugin))
739 { 754 {
740 database_shutdown(&plugin); 755 database_shutdown (&plugin);
741 return NULL; 756 return NULL;
742 } 757 }
743 api = GNUNET_new(struct GNUNET_NAMESTORE_PluginFunctions); 758 api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
744 api->cls = &plugin; 759 api->cls = &plugin;
745 api->store_records = &namestore_sqlite_store_records; 760 api->store_records = &namestore_sqlite_store_records;
746 api->iterate_records = &namestore_sqlite_iterate_records; 761 api->iterate_records = &namestore_sqlite_iterate_records;
747 api->zone_to_name = &namestore_sqlite_zone_to_name; 762 api->zone_to_name = &namestore_sqlite_zone_to_name;
748 api->lookup_records = &namestore_sqlite_lookup_records; 763 api->lookup_records = &namestore_sqlite_lookup_records;
749 LOG(GNUNET_ERROR_TYPE_INFO, 764 LOG (GNUNET_ERROR_TYPE_INFO,
750 _("Sqlite database running\n")); 765 _ ("Sqlite database running\n"));
751 return api; 766 return api;
752} 767}
753 768
@@ -759,16 +774,16 @@ libgnunet_plugin_namestore_sqlite_init(void *cls)
759 * @return always NULL 774 * @return always NULL
760 */ 775 */
761void * 776void *
762libgnunet_plugin_namestore_sqlite_done(void *cls) 777libgnunet_plugin_namestore_sqlite_done (void *cls)
763{ 778{
764 struct GNUNET_NAMESTORE_PluginFunctions *api = cls; 779 struct GNUNET_NAMESTORE_PluginFunctions *api = cls;
765 struct Plugin *plugin = api->cls; 780 struct Plugin *plugin = api->cls;
766 781
767 database_shutdown(plugin); 782 database_shutdown (plugin);
768 plugin->cfg = NULL; 783 plugin->cfg = NULL;
769 GNUNET_free(api); 784 GNUNET_free (api);
770 LOG(GNUNET_ERROR_TYPE_DEBUG, 785 LOG (GNUNET_ERROR_TYPE_DEBUG,
771 "sqlite plugin is finished\n"); 786 "sqlite plugin is finished\n");
772 return NULL; 787 return NULL;
773} 788}
774 789