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