aboutsummaryrefslogtreecommitdiff
path: root/src/datacache
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-09-06 22:46:29 +0000
committerng0 <ng0@n0.is>2019-09-06 22:46:29 +0000
commit6e599264ad13e8fc105493d74d7c11d46f8739ed (patch)
tree169bef1ecbade5a659831fb169f3ae6943af127f /src/datacache
parent4f13bc15113021ebf71d5d81e99bc29f8a07fc9c (diff)
downloadgnunet-6e599264ad13e8fc105493d74d7c11d46f8739ed.tar.gz
gnunet-6e599264ad13e8fc105493d74d7c11d46f8739ed.zip
first step to remove plibc
Diffstat (limited to 'src/datacache')
-rw-r--r--src/datacache/datacache.c126
-rw-r--r--src/datacache/perf_datacache.c16
-rw-r--r--src/datacache/plugin_datacache_sqlite.c504
-rw-r--r--src/datacache/test_datacache.c4
-rw-r--r--src/datacache/test_datacache_quota.c12
5 files changed, 271 insertions, 391 deletions
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c
index 7dcd54fcf..57e0b0bb7 100644
--- a/src/datacache/datacache.c
+++ b/src/datacache/datacache.c
@@ -29,9 +29,10 @@
29#include "gnunet_datacache_plugin.h" 29#include "gnunet_datacache_plugin.h"
30 30
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "datacache", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "datacache", __VA_ARGS__)
33 33
34#define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache", op, fn) 34#define LOG_STRERROR_FILE(kind, op, fn) \
35 GNUNET_log_from_strerror_file (kind, "datacache", op, fn)
35 36
36/** 37/**
37 * Internal state of the datacache library. 38 * Internal state of the datacache library.
@@ -89,7 +90,6 @@ struct GNUNET_DATACACHE_Handle
89 * How much space is in use right now? 90 * How much space is in use right now?
90 */ 91 */
91 unsigned long long utilization; 92 unsigned long long utilization;
92
93}; 93};
94 94
95 95
@@ -102,9 +102,7 @@ struct GNUNET_DATACACHE_Handle
102 * @param size number of bytes that were made available 102 * @param size number of bytes that were made available
103 */ 103 */
104static void 104static void
105env_delete_notify (void *cls, 105env_delete_notify (void *cls, const struct GNUNET_HashCode *key, size_t size)
106 const struct GNUNET_HashCode *key,
107 size_t size)
108{ 106{
109 struct GNUNET_DATACACHE_Handle *h = cls; 107 struct GNUNET_DATACACHE_Handle *h = cls;
110 108
@@ -113,11 +111,10 @@ env_delete_notify (void *cls,
113 GNUNET_h2s (key)); 111 GNUNET_h2s (key));
114 GNUNET_assert (h->utilization >= size); 112 GNUNET_assert (h->utilization >= size);
115 h->utilization -= size; 113 h->utilization -= size;
116 GNUNET_CONTAINER_bloomfilter_remove (h->filter, 114 GNUNET_CONTAINER_bloomfilter_remove (h->filter, key);
117 key);
118 GNUNET_STATISTICS_update (h->stats, 115 GNUNET_STATISTICS_update (h->stats,
119 gettext_noop ("# bytes stored"), 116 gettext_noop ("# bytes stored"),
120 - (long long) size, 117 -(long long) size,
121 GNUNET_NO); 118 GNUNET_NO);
122 GNUNET_STATISTICS_update (h->stats, 119 GNUNET_STATISTICS_update (h->stats,
123 gettext_noop ("# items stored"), 120 gettext_noop ("# items stored"),
@@ -144,54 +141,42 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
144 char *name; 141 char *name;
145 142
146 if (GNUNET_OK != 143 if (GNUNET_OK !=
147 GNUNET_CONFIGURATION_get_value_size (cfg, 144 GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", &quota))
148 section,
149 "QUOTA",
150 &quota))
151 { 145 {
152 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 146 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "QUOTA");
153 section,
154 "QUOTA");
155 return NULL; 147 return NULL;
156 } 148 }
157 if (GNUNET_OK != 149 if (GNUNET_OK !=
158 GNUNET_CONFIGURATION_get_value_string (cfg, 150 GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name))
159 section,
160 "DATABASE",
161 &name))
162 { 151 {
163 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 152 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "DATABASE");
164 section,
165 "DATABASE");
166 return NULL; 153 return NULL;
167 } 154 }
168 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ 155 bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */
169 156
170 ret = GNUNET_new (struct GNUNET_DATACACHE_Handle); 157 ret = GNUNET_new (struct GNUNET_DATACACHE_Handle);
171 158
172 if (GNUNET_YES != 159 if (GNUNET_YES !=
173 GNUNET_CONFIGURATION_get_value_yesno (cfg, 160 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF"))
174 section,
175 "DISABLE_BF"))
176 { 161 {
177 if (GNUNET_YES != 162 if (GNUNET_YES !=
178 GNUNET_CONFIGURATION_get_value_yesno (cfg, 163 GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF_RC"))
179 section,
180 "DISABLE_BF_RC"))
181 { 164 {
182 ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom"); 165 ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom");
183 } 166 }
184 if (NULL != ret->bloom_name) 167 if (NULL != ret->bloom_name)
185 { 168 {
186 ret->filter = GNUNET_CONTAINER_bloomfilter_load (ret->bloom_name, 169 ret->filter = GNUNET_CONTAINER_bloomfilter_load (
187 quota / 1024, /* 8 bit per entry in DB, expect 1k entries */ 170 ret->bloom_name,
188 5); 171 quota / 1024, /* 8 bit per entry in DB, expect 1k entries */
172 5);
189 } 173 }
190 if (NULL == ret->filter) 174 if (NULL == ret->filter)
191 { 175 {
192 ret->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, 176 ret->filter =
193 bf_size, 177 GNUNET_CONTAINER_bloomfilter_init (NULL,
194 5); /* approx. 3% false positives at max use */ 178 bf_size,
179 5); /* approx. 3% false positives at max use */
195 } 180 }
196 } 181 }
197 ret->stats = GNUNET_STATISTICS_create ("datacache", cfg); 182 ret->stats = GNUNET_STATISTICS_create ("datacache", cfg);
@@ -202,19 +187,15 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
202 ret->env.cls = ret; 187 ret->env.cls = ret;
203 ret->env.delete_notify = &env_delete_notify; 188 ret->env.delete_notify = &env_delete_notify;
204 ret->env.quota = quota; 189 ret->env.quota = quota;
205 LOG (GNUNET_ERROR_TYPE_INFO, 190 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Loading `%s' datacache plugin\n"), name);
206 _("Loading `%s' datacache plugin\n"), 191 GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name);
207 name);
208 GNUNET_asprintf (&libname,
209 "libgnunet_plugin_datacache_%s",
210 name);
211 ret->short_name = name; 192 ret->short_name = name;
212 ret->lib_name = libname; 193 ret->lib_name = libname;
213 ret->api = GNUNET_PLUGIN_load (libname, &ret->env); 194 ret->api = GNUNET_PLUGIN_load (libname, &ret->env);
214 if (ret->api == NULL) 195 if (ret->api == NULL)
215 { 196 {
216 LOG (GNUNET_ERROR_TYPE_ERROR, 197 LOG (GNUNET_ERROR_TYPE_ERROR,
217 _("Failed to load datacache plugin for `%s'\n"), 198 _ ("Failed to load datacache plugin for `%s'\n"),
218 name); 199 name);
219 GNUNET_DATACACHE_destroy (ret); 200 GNUNET_DATACACHE_destroy (ret);
220 return NULL; 201 return NULL;
@@ -234,23 +215,20 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
234 if (NULL != h->filter) 215 if (NULL != h->filter)
235 GNUNET_CONTAINER_bloomfilter_free (h->filter); 216 GNUNET_CONTAINER_bloomfilter_free (h->filter);
236 if (NULL != h->api) 217 if (NULL != h->api)
237 GNUNET_break (NULL == 218 GNUNET_break (NULL == GNUNET_PLUGIN_unload (h->lib_name, h->api));
238 GNUNET_PLUGIN_unload (h->lib_name,
239 h->api));
240 GNUNET_free (h->lib_name); 219 GNUNET_free (h->lib_name);
241 GNUNET_free (h->short_name); 220 GNUNET_free (h->short_name);
242 GNUNET_free (h->section); 221 GNUNET_free (h->section);
243 if (NULL != h->bloom_name) 222 if (NULL != h->bloom_name)
244 { 223 {
245 if (0 != UNLINK (h->bloom_name)) 224 if (0 != unlink (h->bloom_name))
246 GNUNET_log_from_strerror_file (GNUNET_ERROR_TYPE_WARNING, 225 GNUNET_log_from_strerror_file (GNUNET_ERROR_TYPE_WARNING,
247 "datacache", 226 "datacache",
248 "unlink", 227 "unlink",
249 h->bloom_name); 228 h->bloom_name);
250 GNUNET_free (h->bloom_name); 229 GNUNET_free (h->bloom_name);
251 } 230 }
252 GNUNET_STATISTICS_destroy (h->stats, 231 GNUNET_STATISTICS_destroy (h->stats, GNUNET_NO);
253 GNUNET_NO);
254 GNUNET_free (h); 232 GNUNET_free (h);
255} 233}
256 234
@@ -277,19 +255,19 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
277 const char *data, 255 const char *data,
278 enum GNUNET_BLOCK_Type type, 256 enum GNUNET_BLOCK_Type type,
279 struct GNUNET_TIME_Absolute discard_time, 257 struct GNUNET_TIME_Absolute discard_time,
280 unsigned int path_info_len, 258 unsigned int path_info_len,
281 const struct GNUNET_PeerIdentity *path_info) 259 const struct GNUNET_PeerIdentity *path_info)
282{ 260{
283 ssize_t used; 261 ssize_t used;
284 262
285 used = h->api->put (h->api->cls, 263 used = h->api->put (h->api->cls,
286 key, 264 key,
287 xor_distance, 265 xor_distance,
288 data_size, 266 data_size,
289 data, 267 data,
290 type, 268 type,
291 discard_time, 269 discard_time,
292 path_info_len, 270 path_info_len,
293 path_info); 271 path_info);
294 if (-1 == used) 272 if (-1 == used)
295 { 273 {
@@ -305,8 +283,7 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
305 "Stored data under key `%s' in cache\n", 283 "Stored data under key `%s' in cache\n",
306 GNUNET_h2s (key)); 284 GNUNET_h2s (key));
307 if (NULL != h->filter) 285 if (NULL != h->filter)
308 GNUNET_CONTAINER_bloomfilter_add (h->filter, 286 GNUNET_CONTAINER_bloomfilter_add (h->filter, key);
309 key);
310 GNUNET_STATISTICS_update (h->stats, 287 GNUNET_STATISTICS_update (h->stats,
311 gettext_noop ("# bytes stored"), 288 gettext_noop ("# bytes stored"),
312 used, 289 used,
@@ -316,8 +293,7 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
316 1, 293 1,
317 GNUNET_NO); 294 GNUNET_NO);
318 while (h->utilization + used > h->env.quota) 295 while (h->utilization + used > h->env.quota)
319 GNUNET_assert (GNUNET_OK == 296 GNUNET_assert (GNUNET_OK == h->api->del (h->api->cls));
320 h->api->del (h->api->cls));
321 h->utilization += used; 297 h->utilization += used;
322 return GNUNET_OK; 298 return GNUNET_OK;
323} 299}
@@ -348,23 +324,20 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
348 LOG (GNUNET_ERROR_TYPE_DEBUG, 324 LOG (GNUNET_ERROR_TYPE_DEBUG,
349 "Processing request for key `%s'\n", 325 "Processing request for key `%s'\n",
350 GNUNET_h2s (key)); 326 GNUNET_h2s (key));
351 if ( (NULL != h->filter) && 327 if ((NULL != h->filter) &&
352 (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key)) ) 328 (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key)))
353 { 329 {
354 GNUNET_STATISTICS_update (h->stats, 330 GNUNET_STATISTICS_update (h->stats,
355 gettext_noop ("# requests filtered by bloom filter"), 331 gettext_noop (
332 "# requests filtered by bloom filter"),
356 1, 333 1,
357 GNUNET_NO); 334 GNUNET_NO);
358 LOG (GNUNET_ERROR_TYPE_DEBUG, 335 LOG (GNUNET_ERROR_TYPE_DEBUG,
359 "Bloomfilter filters request for key `%s'\n", 336 "Bloomfilter filters request for key `%s'\n",
360 GNUNET_h2s (key)); 337 GNUNET_h2s (key));
361 return 0; /* can not be present */ 338 return 0; /* can not be present */
362 } 339 }
363 return h->api->get (h->api->cls, 340 return h->api->get (h->api->cls, key, type, iter, iter_cls);
364 key,
365 type,
366 iter,
367 iter_cls);
368} 341}
369 342
370 343
@@ -382,14 +355,12 @@ GNUNET_DATACACHE_get_random (struct GNUNET_DATACACHE_Handle *h,
382 void *iter_cls) 355 void *iter_cls)
383{ 356{
384 GNUNET_STATISTICS_update (h->stats, 357 GNUNET_STATISTICS_update (h->stats,
385 gettext_noop ("# requests for random value received"), 358 gettext_noop (
359 "# requests for random value received"),
386 1, 360 1,
387 GNUNET_NO); 361 GNUNET_NO);
388 LOG (GNUNET_ERROR_TYPE_DEBUG, 362 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing request for random value\n");
389 "Processing request for random value\n"); 363 return h->api->get_random (h->api->cls, iter, iter_cls);
390 return h->api->get_random (h->api->cls,
391 iter,
392 iter_cls);
393} 364}
394 365
395 366
@@ -414,17 +385,14 @@ GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h,
414 void *iter_cls) 385 void *iter_cls)
415{ 386{
416 GNUNET_STATISTICS_update (h->stats, 387 GNUNET_STATISTICS_update (h->stats,
417 gettext_noop ("# proximity search requests received"), 388 gettext_noop (
389 "# proximity search requests received"),
418 1, 390 1,
419 GNUNET_NO); 391 GNUNET_NO);
420 LOG (GNUNET_ERROR_TYPE_DEBUG, 392 LOG (GNUNET_ERROR_TYPE_DEBUG,
421 "Processing proximity search at `%s'\n", 393 "Processing proximity search at `%s'\n",
422 GNUNET_h2s (key)); 394 GNUNET_h2s (key));
423 return h->api->get_closest (h->api->cls, 395 return h->api->get_closest (h->api->cls, key, num_results, iter, iter_cls);
424 key,
425 num_results,
426 iter,
427 iter_cls);
428} 396}
429 397
430 398
diff --git a/src/datacache/perf_datacache.c b/src/datacache/perf_datacache.c
index 4381171c5..1dfb46cf1 100644
--- a/src/datacache/perf_datacache.c
+++ b/src/datacache/perf_datacache.c
@@ -74,7 +74,7 @@ run (void *cls, char *const *args, const char *cfgfile,
74 74
75 if (h == NULL) 75 if (h == NULL)
76 { 76 {
77 FPRINTF (stderr, "%s", "Failed to initialize datacache. Database likely not setup, skipping test.\n"); 77 fprintf (stderr, "%s", "Failed to initialize datacache. Database likely not setup, skipping test.\n");
78 ok = 77; /* mark test as skipped */ 78 ok = 77; /* mark test as skipped */
79 return; 79 return;
80 } 80 }
@@ -84,7 +84,7 @@ run (void *cls, char *const *args, const char *cfgfile,
84 for (i = 0; i < ITERATIONS; i++) 84 for (i = 0; i < ITERATIONS; i++)
85 { 85 {
86 if (0 == i % (ITERATIONS / 80)) 86 if (0 == i % (ITERATIONS / 80))
87 FPRINTF (stderr, "%s", "."); 87 fprintf (stderr, "%s", ".");
88 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 88 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
89 ASSERT (GNUNET_OK == 89 ASSERT (GNUNET_OK ==
90 GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode), 90 GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
@@ -92,8 +92,8 @@ run (void *cls, char *const *args, const char *cfgfile,
92 0, NULL)); 92 0, NULL));
93 k = n; 93 k = n;
94 } 94 }
95 FPRINTF (stderr, "%s", "\n"); 95 fprintf (stderr, "%s", "\n");
96 FPRINTF (stdout, "Stored %u items in %s\n", ITERATIONS, 96 fprintf (stdout, "Stored %u items in %s\n", ITERATIONS,
97 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES)); 97 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES));
98 GNUNET_snprintf (gstr, sizeof (gstr), "DATACACHE-%s", plugin_name); 98 GNUNET_snprintf (gstr, sizeof (gstr), "DATACACHE-%s", plugin_name);
99 GAUGER (gstr, "Time to PUT item in datacache", 99 GAUGER (gstr, "Time to PUT item in datacache",
@@ -104,13 +104,13 @@ run (void *cls, char *const *args, const char *cfgfile,
104 for (i = 0; i < ITERATIONS; i++) 104 for (i = 0; i < ITERATIONS; i++)
105 { 105 {
106 if (0 == i % (ITERATIONS / 80)) 106 if (0 == i % (ITERATIONS / 80))
107 FPRINTF (stderr, "%s", "."); 107 fprintf (stderr, "%s", ".");
108 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 108 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
109 GNUNET_DATACACHE_get (h, &k, 1 + i % 16, &checkIt, &n); 109 GNUNET_DATACACHE_get (h, &k, 1 + i % 16, &checkIt, &n);
110 k = n; 110 k = n;
111 } 111 }
112 FPRINTF (stderr, "%s", "\n"); 112 fprintf (stderr, "%s", "\n");
113 FPRINTF (stdout, 113 fprintf (stdout,
114 "Found %u/%u items in %s (%u were deleted during storage processing)\n", 114 "Found %u/%u items in %s (%u were deleted during storage processing)\n",
115 found, ITERATIONS, 115 found, ITERATIONS,
116 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES), 116 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES),
@@ -152,7 +152,7 @@ main (int argc, char *argv[])
152 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, 152 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv,
153 "perf-datacache", "nohelp", options, &run, NULL); 153 "perf-datacache", "nohelp", options, &run, NULL);
154 if ( (0 != ok) && (77 != ok) ) 154 if ( (0 != ok) && (77 != ok) )
155 FPRINTF (stderr, "Missed some perfcases: %d\n", ok); 155 fprintf (stderr, "Missed some perfcases: %d\n", ok);
156 return ok; 156 return ok;
157} 157}
158 158
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index 07a72957a..0cf77d6e6 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -29,16 +29,17 @@
29#include "gnunet_sq_lib.h" 29#include "gnunet_sq_lib.h"
30#include <sqlite3.h> 30#include <sqlite3.h>
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "datacache-sqlite", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "datacache-sqlite", __VA_ARGS__)
33 33
34#define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn) 34#define LOG_STRERROR_FILE(kind, op, fn) \
35 GNUNET_log_from_strerror_file (kind, "datacache-sqlite", op, fn)
35 36
36 37
37/** 38/**
38 * How much overhead do we assume per entry in the 39 * How much overhead do we assume per entry in the
39 * datacache? 40 * datacache?
40 */ 41 */
41#define OVERHEAD (sizeof(struct GNUNET_HashCode) + 36) 42#define OVERHEAD (sizeof (struct GNUNET_HashCode) + 36)
42 43
43/** 44/**
44 * Context for all functions in this plugin. 45 * Context for all functions in this plugin.
@@ -115,7 +116,16 @@ struct Plugin
115 * @param level log level 116 * @param level log level
116 * @param cmd failed command 117 * @param cmd failed command
117 */ 118 */
118#define LOG_SQLITE(db, level, cmd) do { LOG (level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db)); } while(0) 119#define LOG_SQLITE(db, level, cmd) \
120 do \
121 { \
122 LOG (level, \
123 _ ("`%s' failed at %s:%d with error: %s\n"), \
124 cmd, \
125 __FILE__, \
126 __LINE__, \
127 sqlite3_errmsg (db)); \
128 } while (0)
119 129
120 130
121/** 131/**
@@ -124,7 +134,21 @@ struct Plugin
124 * @param db database handle 134 * @param db database handle
125 * @param cmd SQL command to execute 135 * @param cmd SQL command to execute
126 */ 136 */
127#define SQLITE3_EXEC(db, cmd) do { emsg = NULL; if (SQLITE_OK != sqlite3_exec(db, cmd, NULL, NULL, &emsg)) { LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, _("`%s' failed at %s:%d with error: %s\n"), "sqlite3_exec", __FILE__, __LINE__, emsg); sqlite3_free(emsg); } } while(0) 137#define SQLITE3_EXEC(db, cmd) \
138 do \
139 { \
140 emsg = NULL; \
141 if (SQLITE_OK != sqlite3_exec (db, cmd, NULL, NULL, &emsg)) \
142 { \
143 LOG (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, \
144 _ ("`%s' failed at %s:%d with error: %s\n"), \
145 "sqlite3_exec", \
146 __FILE__, \
147 __LINE__, \
148 emsg); \
149 sqlite3_free (emsg); \
150 } \
151 } while (0)
128 152
129 153
130/** 154/**
@@ -137,9 +161,9 @@ struct Plugin
137 */ 161 */
138static int 162static int
139sq_prepare (sqlite3 *dbh, 163sq_prepare (sqlite3 *dbh,
140 const char *zSql, /* SQL statement, UTF-8 encoded */ 164 const char *zSql, /* SQL statement, UTF-8 encoded */
141 sqlite3_stmt **ppStmt) 165 sqlite3_stmt **ppStmt)
142{ /* OUT: Statement handle */ 166{ /* OUT: Statement handle */
143 char *dummy; 167 char *dummy;
144 168
145 return sqlite3_prepare (dbh, 169 return sqlite3_prepare (dbh,
@@ -166,58 +190,53 @@ sq_prepare (sqlite3 *dbh,
166 */ 190 */
167static ssize_t 191static ssize_t
168sqlite_plugin_put (void *cls, 192sqlite_plugin_put (void *cls,
169 const struct GNUNET_HashCode *key, 193 const struct GNUNET_HashCode *key,
170 uint32_t xor_distance, 194 uint32_t xor_distance,
171 size_t size, 195 size_t size,
172 const char *data, 196 const char *data,
173 enum GNUNET_BLOCK_Type type, 197 enum GNUNET_BLOCK_Type type,
174 struct GNUNET_TIME_Absolute discard_time, 198 struct GNUNET_TIME_Absolute discard_time,
175 unsigned int path_info_len, 199 unsigned int path_info_len,
176 const struct GNUNET_PeerIdentity *path_info) 200 const struct GNUNET_PeerIdentity *path_info)
177{ 201{
178 struct Plugin *plugin = cls; 202 struct Plugin *plugin = cls;
179 uint32_t type32 = type; 203 uint32_t type32 = type;
180 struct GNUNET_SQ_QueryParam params[] = { 204 struct GNUNET_SQ_QueryParam params[] =
181 GNUNET_SQ_query_param_uint32 (&type32), 205 {GNUNET_SQ_query_param_uint32 (&type32),
182 GNUNET_SQ_query_param_absolute_time (&discard_time), 206 GNUNET_SQ_query_param_absolute_time (&discard_time),
183 GNUNET_SQ_query_param_auto_from_type (key), 207 GNUNET_SQ_query_param_auto_from_type (key),
184 GNUNET_SQ_query_param_uint32 (&xor_distance), 208 GNUNET_SQ_query_param_uint32 (&xor_distance),
185 GNUNET_SQ_query_param_fixed_size (data, size), 209 GNUNET_SQ_query_param_fixed_size (data, size),
186 GNUNET_SQ_query_param_fixed_size (path_info, 210 GNUNET_SQ_query_param_fixed_size (path_info,
187 path_info_len * sizeof (struct GNUNET_PeerIdentity)), 211 path_info_len *
188 GNUNET_SQ_query_param_end 212 sizeof (struct GNUNET_PeerIdentity)),
189 }; 213 GNUNET_SQ_query_param_end};
190 214
191 LOG (GNUNET_ERROR_TYPE_DEBUG, 215 LOG (GNUNET_ERROR_TYPE_DEBUG,
192 "Processing PUT of %u bytes with key `%s' and expiration %s\n", 216 "Processing PUT of %u bytes with key `%s' and expiration %s\n",
193 (unsigned int) size, 217 (unsigned int) size,
194 GNUNET_h2s (key), 218 GNUNET_h2s (key),
195 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (discard_time), 219 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (
220 discard_time),
196 GNUNET_YES)); 221 GNUNET_YES));
197 if (GNUNET_OK != 222 if (GNUNET_OK != GNUNET_SQ_bind (plugin->insert_stmt, params))
198 GNUNET_SQ_bind (plugin->insert_stmt,
199 params))
200 { 223 {
201 LOG_SQLITE (plugin->dbh, 224 LOG_SQLITE (plugin->dbh,
202 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 225 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
203 "sqlite3_bind_xxx"); 226 "sqlite3_bind_xxx");
204 GNUNET_SQ_reset (plugin->dbh, 227 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
205 plugin->insert_stmt);
206 return -1; 228 return -1;
207 } 229 }
208 if (SQLITE_DONE != 230 if (SQLITE_DONE != sqlite3_step (plugin->insert_stmt))
209 sqlite3_step (plugin->insert_stmt))
210 { 231 {
211 LOG_SQLITE (plugin->dbh, 232 LOG_SQLITE (plugin->dbh,
212 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 233 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
213 "sqlite3_step"); 234 "sqlite3_step");
214 GNUNET_SQ_reset (plugin->dbh, 235 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
215 plugin->insert_stmt);
216 return -1; 236 return -1;
217 } 237 }
218 plugin->num_items++; 238 plugin->num_items++;
219 GNUNET_SQ_reset (plugin->dbh, 239 GNUNET_SQ_reset (plugin->dbh, plugin->insert_stmt);
220 plugin->insert_stmt);
221 return size + OVERHEAD; 240 return size + OVERHEAD;
222} 241}
223 242
@@ -251,62 +270,50 @@ sqlite_plugin_get (void *cls,
251 unsigned int total; 270 unsigned int total;
252 size_t psize; 271 size_t psize;
253 struct GNUNET_PeerIdentity *path; 272 struct GNUNET_PeerIdentity *path;
254 struct GNUNET_SQ_QueryParam params_count[] = { 273 struct GNUNET_SQ_QueryParam params_count[] =
255 GNUNET_SQ_query_param_auto_from_type (key), 274 {GNUNET_SQ_query_param_auto_from_type (key),
256 GNUNET_SQ_query_param_uint32 (&type32), 275 GNUNET_SQ_query_param_uint32 (&type32),
257 GNUNET_SQ_query_param_absolute_time (&now), 276 GNUNET_SQ_query_param_absolute_time (&now),
258 GNUNET_SQ_query_param_end 277 GNUNET_SQ_query_param_end};
259 }; 278 struct GNUNET_SQ_QueryParam params_select[] =
260 struct GNUNET_SQ_QueryParam params_select[] = { 279 {GNUNET_SQ_query_param_auto_from_type (key),
261 GNUNET_SQ_query_param_auto_from_type (key), 280 GNUNET_SQ_query_param_uint32 (&type32),
262 GNUNET_SQ_query_param_uint32 (&type32), 281 GNUNET_SQ_query_param_absolute_time (&now),
263 GNUNET_SQ_query_param_absolute_time (&now), 282 GNUNET_SQ_query_param_uint32 (&off),
264 GNUNET_SQ_query_param_uint32 (&off), 283 GNUNET_SQ_query_param_end};
265 GNUNET_SQ_query_param_end 284 struct GNUNET_SQ_ResultSpec rs[] =
266 }; 285 {GNUNET_SQ_result_spec_variable_size (&dat, &size),
267 struct GNUNET_SQ_ResultSpec rs[] = { 286 GNUNET_SQ_result_spec_absolute_time (&exp),
268 GNUNET_SQ_result_spec_variable_size (&dat, 287 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
269 &size), 288 GNUNET_SQ_result_spec_end};
270 GNUNET_SQ_result_spec_absolute_time (&exp),
271 GNUNET_SQ_result_spec_variable_size ((void **) &path,
272 &psize),
273 GNUNET_SQ_result_spec_end
274 };
275 289
276 now = GNUNET_TIME_absolute_get (); 290 now = GNUNET_TIME_absolute_get ();
277 LOG (GNUNET_ERROR_TYPE_DEBUG, 291 LOG (GNUNET_ERROR_TYPE_DEBUG,
278 "Processing GET for key `%s'\n", 292 "Processing GET for key `%s'\n",
279 GNUNET_h2s (key)); 293 GNUNET_h2s (key));
280 294
281 if (GNUNET_OK != 295 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_count_stmt, params_count))
282 GNUNET_SQ_bind (plugin->get_count_stmt,
283 params_count))
284 { 296 {
285 LOG_SQLITE (plugin->dbh, 297 LOG_SQLITE (plugin->dbh,
286 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 298 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
287 "sqlite3_bind_xxx"); 299 "sqlite3_bind_xxx");
288 GNUNET_SQ_reset (plugin->dbh, 300 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
289 plugin->get_count_stmt);
290 return 0; 301 return 0;
291 } 302 }
292 if (SQLITE_ROW != 303 if (SQLITE_ROW != sqlite3_step (plugin->get_count_stmt))
293 sqlite3_step (plugin->get_count_stmt))
294 { 304 {
295 LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 305 LOG_SQLITE (plugin->dbh,
306 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
296 "sqlite_step"); 307 "sqlite_step");
297 GNUNET_SQ_reset (plugin->dbh, 308 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
298 plugin->get_count_stmt);
299 LOG (GNUNET_ERROR_TYPE_DEBUG, 309 LOG (GNUNET_ERROR_TYPE_DEBUG,
300 "No content found when processing GET for key `%s'\n", 310 "No content found when processing GET for key `%s'\n",
301 GNUNET_h2s (key)); 311 GNUNET_h2s (key));
302 return 0; 312 return 0;
303 } 313 }
304 total = sqlite3_column_int (plugin->get_count_stmt, 314 total = sqlite3_column_int (plugin->get_count_stmt, 0);
305 0); 315 GNUNET_SQ_reset (plugin->dbh, plugin->get_count_stmt);
306 GNUNET_SQ_reset (plugin->dbh, 316 if ((0 == total) || (NULL == iter))
307 plugin->get_count_stmt);
308 if ( (0 == total) ||
309 (NULL == iter) )
310 { 317 {
311 if (0 == total) 318 if (0 == total)
312 LOG (GNUNET_ERROR_TYPE_DEBUG, 319 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -316,32 +323,24 @@ sqlite_plugin_get (void *cls,
316 } 323 }
317 324
318 cnt = 0; 325 cnt = 0;
319 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 326 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
320 total);
321 while (cnt < total) 327 while (cnt < total)
322 { 328 {
323 off = (off + 1) % total; 329 off = (off + 1) % total;
324 if (GNUNET_OK != 330 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_stmt, params_select))
325 GNUNET_SQ_bind (plugin->get_stmt,
326 params_select))
327 { 331 {
328 LOG_SQLITE (plugin->dbh, 332 LOG_SQLITE (plugin->dbh,
329 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 333 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
330 "sqlite3_bind_xxx"); 334 "sqlite3_bind_xxx");
331 GNUNET_SQ_reset (plugin->dbh, 335 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
332 plugin->get_stmt);
333 return cnt; 336 return cnt;
334 } 337 }
335 if (SQLITE_ROW != 338 if (SQLITE_ROW != sqlite3_step (plugin->get_stmt))
336 sqlite3_step (plugin->get_stmt))
337 break; 339 break;
338 if (GNUNET_OK != 340 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_stmt, rs))
339 GNUNET_SQ_extract_result (plugin->get_stmt,
340 rs))
341 { 341 {
342 GNUNET_break (0); 342 GNUNET_break (0);
343 GNUNET_SQ_reset (plugin->dbh, 343 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
344 plugin->get_stmt);
345 break; 344 break;
346 } 345 }
347 if (0 != psize % sizeof (struct GNUNET_PeerIdentity)) 346 if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
@@ -356,26 +355,16 @@ sqlite_plugin_get (void *cls,
356 "Found %u-byte result when processing GET for key `%s'\n", 355 "Found %u-byte result when processing GET for key `%s'\n",
357 (unsigned int) size, 356 (unsigned int) size,
358 GNUNET_h2s (key)); 357 GNUNET_h2s (key));
359 if (GNUNET_OK != iter (iter_cls, 358 if (GNUNET_OK != iter (iter_cls, key, size, dat, type, exp, psize, path))
360 key,
361 size,
362 dat,
363 type,
364 exp,
365 psize,
366 path))
367 { 359 {
368 GNUNET_SQ_cleanup_result (rs); 360 GNUNET_SQ_cleanup_result (rs);
369 GNUNET_SQ_reset (plugin->dbh, 361 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
370 plugin->get_stmt);
371 break; 362 break;
372 } 363 }
373 GNUNET_SQ_cleanup_result (rs); 364 GNUNET_SQ_cleanup_result (rs);
374 GNUNET_SQ_reset (plugin->dbh, 365 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
375 plugin->get_stmt);
376 } 366 }
377 GNUNET_SQ_reset (plugin->dbh, 367 GNUNET_SQ_reset (plugin->dbh, plugin->get_stmt);
378 plugin->get_stmt);
379 return cnt; 368 return cnt;
380} 369}
381 370
@@ -396,94 +385,66 @@ sqlite_plugin_del (void *cls)
396 size_t dsize; 385 size_t dsize;
397 struct GNUNET_HashCode hc; 386 struct GNUNET_HashCode hc;
398 struct GNUNET_TIME_Absolute now; 387 struct GNUNET_TIME_Absolute now;
399 struct GNUNET_SQ_ResultSpec rs[] = { 388 struct GNUNET_SQ_ResultSpec rs[] =
400 GNUNET_SQ_result_spec_uint64 (&rowid), 389 {GNUNET_SQ_result_spec_uint64 (&rowid),
401 GNUNET_SQ_result_spec_auto_from_type (&hc), 390 GNUNET_SQ_result_spec_auto_from_type (&hc),
402 GNUNET_SQ_result_spec_variable_size ((void **) &data, 391 GNUNET_SQ_result_spec_variable_size ((void **) &data, &dsize),
403 &dsize), 392 GNUNET_SQ_result_spec_end};
404 GNUNET_SQ_result_spec_end 393 struct GNUNET_SQ_QueryParam params[] = {GNUNET_SQ_query_param_uint64 (&rowid),
405 }; 394 GNUNET_SQ_query_param_end};
406 struct GNUNET_SQ_QueryParam params[] = { 395 struct GNUNET_SQ_QueryParam time_params[] =
407 GNUNET_SQ_query_param_uint64 (&rowid), 396 {GNUNET_SQ_query_param_absolute_time (&now), GNUNET_SQ_query_param_end};
408 GNUNET_SQ_query_param_end 397
409 }; 398 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing DEL\n");
410 struct GNUNET_SQ_QueryParam time_params[] = {
411 GNUNET_SQ_query_param_absolute_time (&now),
412 GNUNET_SQ_query_param_end
413 };
414
415 LOG (GNUNET_ERROR_TYPE_DEBUG,
416 "Processing DEL\n");
417 now = GNUNET_TIME_absolute_get (); 399 now = GNUNET_TIME_absolute_get ();
418 if (GNUNET_OK != 400 if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_expired_stmt, time_params))
419 GNUNET_SQ_bind (plugin->del_expired_stmt,
420 time_params))
421 { 401 {
422 LOG_SQLITE (plugin->dbh, 402 LOG_SQLITE (plugin->dbh,
423 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 403 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
424 "sqlite3_bind"); 404 "sqlite3_bind");
425 GNUNET_SQ_reset (plugin->dbh, 405 GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt);
426 plugin->del_expired_stmt);
427 return GNUNET_SYSERR; 406 return GNUNET_SYSERR;
428 } 407 }
429 if ( (SQLITE_ROW != 408 if ((SQLITE_ROW != sqlite3_step (plugin->del_expired_stmt)) ||
430 sqlite3_step (plugin->del_expired_stmt)) || 409 (GNUNET_OK != GNUNET_SQ_extract_result (plugin->del_expired_stmt, rs)))
431 (GNUNET_OK !=
432 GNUNET_SQ_extract_result (plugin->del_expired_stmt,
433 rs)) )
434 { 410 {
435 GNUNET_SQ_reset (plugin->dbh, 411 GNUNET_SQ_reset (plugin->dbh, plugin->del_expired_stmt);
436 plugin->del_expired_stmt); 412 if (SQLITE_ROW != sqlite3_step (plugin->del_select_stmt))
437 if (SQLITE_ROW !=
438 sqlite3_step (plugin->del_select_stmt))
439 { 413 {
440 LOG_SQLITE (plugin->dbh, 414 LOG_SQLITE (plugin->dbh,
441 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 415 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
442 "sqlite3_step"); 416 "sqlite3_step");
443 GNUNET_SQ_reset (plugin->dbh, 417 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
444 plugin->del_select_stmt);
445 return GNUNET_SYSERR; 418 return GNUNET_SYSERR;
446 } 419 }
447 if (GNUNET_OK != 420 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->del_select_stmt, rs))
448 GNUNET_SQ_extract_result (plugin->del_select_stmt,
449 rs))
450 { 421 {
451 GNUNET_SQ_reset (plugin->dbh, 422 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
452 plugin->del_select_stmt);
453 GNUNET_break (0); 423 GNUNET_break (0);
454 return GNUNET_SYSERR; 424 return GNUNET_SYSERR;
455 } 425 }
456 } 426 }
457 GNUNET_SQ_cleanup_result (rs); 427 GNUNET_SQ_cleanup_result (rs);
458 GNUNET_SQ_reset (plugin->dbh, 428 GNUNET_SQ_reset (plugin->dbh, plugin->del_select_stmt);
459 plugin->del_select_stmt); 429 if (GNUNET_OK != GNUNET_SQ_bind (plugin->del_stmt, params))
460 if (GNUNET_OK !=
461 GNUNET_SQ_bind (plugin->del_stmt,
462 params))
463 { 430 {
464 LOG_SQLITE (plugin->dbh, 431 LOG_SQLITE (plugin->dbh,
465 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 432 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
466 "sqlite3_bind"); 433 "sqlite3_bind");
467 GNUNET_SQ_reset (plugin->dbh, 434 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
468 plugin->del_stmt);
469 return GNUNET_SYSERR; 435 return GNUNET_SYSERR;
470 } 436 }
471 if (SQLITE_DONE != 437 if (SQLITE_DONE != sqlite3_step (plugin->del_stmt))
472 sqlite3_step (plugin->del_stmt))
473 { 438 {
474 LOG_SQLITE (plugin->dbh, 439 LOG_SQLITE (plugin->dbh,
475 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 440 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
476 "sqlite3_step"); 441 "sqlite3_step");
477 GNUNET_SQ_reset (plugin->dbh, 442 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
478 plugin->del_stmt);
479 return GNUNET_SYSERR; 443 return GNUNET_SYSERR;
480 } 444 }
481 plugin->num_items--; 445 plugin->num_items--;
482 plugin->env->delete_notify (plugin->env->cls, 446 plugin->env->delete_notify (plugin->env->cls, &hc, dsize + OVERHEAD);
483 &hc, 447 GNUNET_SQ_reset (plugin->dbh, plugin->del_stmt);
484 dsize + OVERHEAD);
485 GNUNET_SQ_reset (plugin->dbh,
486 plugin->del_stmt);
487 return GNUNET_OK; 448 return GNUNET_OK;
488} 449}
489 450
@@ -510,48 +471,36 @@ sqlite_plugin_get_random (void *cls,
510 uint32_t type; 471 uint32_t type;
511 struct GNUNET_PeerIdentity *path; 472 struct GNUNET_PeerIdentity *path;
512 struct GNUNET_HashCode key; 473 struct GNUNET_HashCode key;
513 struct GNUNET_SQ_QueryParam params[] = { 474 struct GNUNET_SQ_QueryParam params[] = {GNUNET_SQ_query_param_uint32 (&off),
514 GNUNET_SQ_query_param_uint32 (&off), 475 GNUNET_SQ_query_param_end};
515 GNUNET_SQ_query_param_end 476 struct GNUNET_SQ_ResultSpec rs[] =
516 }; 477 {GNUNET_SQ_result_spec_variable_size (&dat, &size),
517 struct GNUNET_SQ_ResultSpec rs[] = { 478 GNUNET_SQ_result_spec_absolute_time (&exp),
518 GNUNET_SQ_result_spec_variable_size (&dat, 479 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
519 &size), 480 GNUNET_SQ_result_spec_auto_from_type (&key),
520 GNUNET_SQ_result_spec_absolute_time (&exp), 481 GNUNET_SQ_result_spec_uint32 (&type),
521 GNUNET_SQ_result_spec_variable_size ((void **) &path, 482 GNUNET_SQ_result_spec_end};
522 &psize),
523 GNUNET_SQ_result_spec_auto_from_type (&key),
524 GNUNET_SQ_result_spec_uint32 (&type),
525 GNUNET_SQ_result_spec_end
526 };
527 483
528 if (0 == plugin->num_items) 484 if (0 == plugin->num_items)
529 return 0; 485 return 0;
530 if (NULL == iter) 486 if (NULL == iter)
531 return 1; 487 return 1;
532 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 488 off =
533 plugin->num_items); 489 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, plugin->num_items);
534 if (GNUNET_OK != 490 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_random_stmt, params))
535 GNUNET_SQ_bind (plugin->get_random_stmt,
536 params))
537 { 491 {
538 return 0; 492 return 0;
539 } 493 }
540 if (SQLITE_ROW != 494 if (SQLITE_ROW != sqlite3_step (plugin->get_random_stmt))
541 sqlite3_step (plugin->get_random_stmt))
542 { 495 {
543 GNUNET_break (0); 496 GNUNET_break (0);
544 GNUNET_SQ_reset (plugin->dbh, 497 GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
545 plugin->get_random_stmt);
546 return 0; 498 return 0;
547 } 499 }
548 if (GNUNET_OK != 500 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_random_stmt, rs))
549 GNUNET_SQ_extract_result (plugin->get_random_stmt,
550 rs))
551 { 501 {
552 GNUNET_break (0); 502 GNUNET_break (0);
553 GNUNET_SQ_reset (plugin->dbh, 503 GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
554 plugin->get_random_stmt);
555 return 0; 504 return 0;
556 } 505 }
557 if (0 != psize % sizeof (struct GNUNET_PeerIdentity)) 506 if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
@@ -574,8 +523,7 @@ sqlite_plugin_get_random (void *cls,
574 psize, 523 psize,
575 path); 524 path);
576 GNUNET_SQ_cleanup_result (rs); 525 GNUNET_SQ_cleanup_result (rs);
577 GNUNET_SQ_reset (plugin->dbh, 526 GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt);
578 plugin->get_random_stmt);
579 return 1; 527 return 1;
580} 528}
581 529
@@ -611,45 +559,35 @@ sqlite_plugin_get_closest (void *cls,
611 uint32_t type; 559 uint32_t type;
612 struct GNUNET_HashCode hc; 560 struct GNUNET_HashCode hc;
613 struct GNUNET_PeerIdentity *path; 561 struct GNUNET_PeerIdentity *path;
614 struct GNUNET_SQ_QueryParam params[] = { 562 struct GNUNET_SQ_QueryParam params[] =
615 GNUNET_SQ_query_param_auto_from_type (key), 563 {GNUNET_SQ_query_param_auto_from_type (key),
616 GNUNET_SQ_query_param_absolute_time (&now), 564 GNUNET_SQ_query_param_absolute_time (&now),
617 GNUNET_SQ_query_param_uint32 (&num_results32), 565 GNUNET_SQ_query_param_uint32 (&num_results32),
618 GNUNET_SQ_query_param_end 566 GNUNET_SQ_query_param_end};
619 }; 567 struct GNUNET_SQ_ResultSpec rs[] =
620 struct GNUNET_SQ_ResultSpec rs[] = { 568 {GNUNET_SQ_result_spec_variable_size (&dat, &size),
621 GNUNET_SQ_result_spec_variable_size (&dat, 569 GNUNET_SQ_result_spec_absolute_time (&exp),
622 &size), 570 GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize),
623 GNUNET_SQ_result_spec_absolute_time (&exp), 571 GNUNET_SQ_result_spec_uint32 (&type),
624 GNUNET_SQ_result_spec_variable_size ((void **) &path, 572 GNUNET_SQ_result_spec_auto_from_type (&hc),
625 &psize), 573 GNUNET_SQ_result_spec_end};
626 GNUNET_SQ_result_spec_uint32 (&type),
627 GNUNET_SQ_result_spec_auto_from_type (&hc),
628 GNUNET_SQ_result_spec_end
629 };
630 574
631 now = GNUNET_TIME_absolute_get (); 575 now = GNUNET_TIME_absolute_get ();
632 LOG (GNUNET_ERROR_TYPE_DEBUG, 576 LOG (GNUNET_ERROR_TYPE_DEBUG,
633 "Processing GET_CLOSEST for key `%s'\n", 577 "Processing GET_CLOSEST for key `%s'\n",
634 GNUNET_h2s (key)); 578 GNUNET_h2s (key));
635 if (GNUNET_OK != 579 if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_closest_stmt, params))
636 GNUNET_SQ_bind (plugin->get_closest_stmt,
637 params))
638 { 580 {
639 LOG_SQLITE (plugin->dbh, 581 LOG_SQLITE (plugin->dbh,
640 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 582 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
641 "sqlite3_bind_xxx"); 583 "sqlite3_bind_xxx");
642 GNUNET_SQ_reset (plugin->dbh, 584 GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt);
643 plugin->get_closest_stmt);
644 return 0; 585 return 0;
645 } 586 }
646 cnt = 0; 587 cnt = 0;
647 while (SQLITE_ROW == 588 while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt))
648 sqlite3_step (plugin->get_closest_stmt))
649 { 589 {
650 if (GNUNET_OK != 590 if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_closest_stmt, rs))
651 GNUNET_SQ_extract_result (plugin->get_closest_stmt,
652 rs))
653 { 591 {
654 GNUNET_break (0); 592 GNUNET_break (0);
655 break; 593 break;
@@ -666,22 +604,14 @@ sqlite_plugin_get_closest (void *cls,
666 "Found %u-byte result at %s when processing GET_CLOSE\n", 604 "Found %u-byte result at %s when processing GET_CLOSE\n",
667 (unsigned int) size, 605 (unsigned int) size,
668 GNUNET_h2s (&hc)); 606 GNUNET_h2s (&hc));
669 if (GNUNET_OK != iter (iter_cls, 607 if (GNUNET_OK != iter (iter_cls, &hc, size, dat, type, exp, psize, path))
670 &hc,
671 size,
672 dat,
673 type,
674 exp,
675 psize,
676 path))
677 { 608 {
678 GNUNET_SQ_cleanup_result (rs); 609 GNUNET_SQ_cleanup_result (rs);
679 break; 610 break;
680 } 611 }
681 GNUNET_SQ_cleanup_result (rs); 612 GNUNET_SQ_cleanup_result (rs);
682 } 613 }
683 GNUNET_SQ_reset (plugin->dbh, 614 GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt);
684 plugin->get_closest_stmt);
685 return cnt; 615 return cnt;
686} 616}
687 617
@@ -703,10 +633,9 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
703 sqlite3 *dbh; 633 sqlite3 *dbh;
704 char *emsg; 634 char *emsg;
705 635
706 if (GNUNET_YES == 636 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
707 GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 637 "datacache-sqlite",
708 "datacache-sqlite", 638 "IN_MEMORY"))
709 "IN_MEMORY"))
710 { 639 {
711 if (SQLITE_OK != sqlite3_open (":memory:", &dbh)) 640 if (SQLITE_OK != sqlite3_open (":memory:", &dbh))
712 return NULL; 641 return NULL;
@@ -716,10 +645,10 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
716 { 645 {
717 fn = GNUNET_DISK_mktemp ("gnunet-datacache"); 646 fn = GNUNET_DISK_mktemp ("gnunet-datacache");
718 if (fn == NULL) 647 if (fn == NULL)
719 { 648 {
720 GNUNET_break (0); 649 GNUNET_break (0);
721 return NULL; 650 return NULL;
722 } 651 }
723 /* fn should be UTF-8-encoded. If it isn't, it's a bug. */ 652 /* fn should be UTF-8-encoded. If it isn't, it's a bug. */
724 fn_utf8 = GNUNET_strdup (fn); 653 fn_utf8 = GNUNET_strdup (fn);
725 if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh)) 654 if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh))
@@ -736,10 +665,9 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
736 SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF"); 665 SQLITE3_EXEC (dbh, "PRAGMA journal_mode=OFF");
737 SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF"); 666 SQLITE3_EXEC (dbh, "PRAGMA synchronous=OFF");
738 SQLITE3_EXEC (dbh, "PRAGMA page_size=4092"); 667 SQLITE3_EXEC (dbh, "PRAGMA page_size=4092");
739 if (GNUNET_YES == 668 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
740 GNUNET_CONFIGURATION_get_value_yesno (env->cfg, 669 "datacache-sqlite",
741 "datacache-sqlite", 670 "IN_MEMORY"))
742 "IN_MEMORY"))
743 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3"); 671 SQLITE3_EXEC (dbh, "PRAGMA sqlite_temp_store=3");
744 672
745 SQLITE3_EXEC (dbh, 673 SQLITE3_EXEC (dbh,
@@ -749,7 +677,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
749 " key BLOB NOT NULL DEFAULT ''," 677 " key BLOB NOT NULL DEFAULT '',"
750 " prox INTEGER NOT NULL," 678 " prox INTEGER NOT NULL,"
751 " value BLOB NOT NULL," 679 " value BLOB NOT NULL,"
752 " path BLOB DEFAULT '')"); 680 " path BLOB DEFAULT '')");
753 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)"); 681 SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds091 (key,type,expire)");
754 SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)"); 682 SQLITE3_EXEC (dbh, "CREATE INDEX idx_prox_expire ON ds091 (prox,expire)");
755 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)"); 683 SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire_only ON ds091 (expire)");
@@ -758,53 +686,46 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
758 plugin->dbh = dbh; 686 plugin->dbh = dbh;
759 plugin->fn = fn_utf8; 687 plugin->fn = fn_utf8;
760 688
761 if ( (SQLITE_OK != 689 if ((SQLITE_OK !=
762 sq_prepare (plugin->dbh, 690 sq_prepare (plugin->dbh,
763 "INSERT INTO ds091 (type, expire, key, prox, value, path) " 691 "INSERT INTO ds091 (type, expire, key, prox, value, path) "
764 "VALUES (?, ?, ?, ?, ?, ?)", 692 "VALUES (?, ?, ?, ?, ?, ?)",
765 &plugin->insert_stmt)) || 693 &plugin->insert_stmt)) ||
766 (SQLITE_OK != 694 (SQLITE_OK != sq_prepare (plugin->dbh,
767 sq_prepare (plugin->dbh, 695 "SELECT count(*) FROM ds091 "
768 "SELECT count(*) FROM ds091 " 696 "WHERE key=? AND type=? AND expire >= ?",
769 "WHERE key=? AND type=? AND expire >= ?", 697 &plugin->get_count_stmt)) ||
770 &plugin->get_count_stmt)) || 698 (SQLITE_OK !=
771 (SQLITE_OK != 699 sq_prepare (plugin->dbh,
772 sq_prepare (plugin->dbh, 700 "SELECT value,expire,path FROM ds091"
773 "SELECT value,expire,path FROM ds091" 701 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?",
774 " WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?", 702 &plugin->get_stmt)) ||
775 &plugin->get_stmt)) || 703 (SQLITE_OK != sq_prepare (plugin->dbh,
776 (SQLITE_OK != 704 "SELECT _ROWID_,key,value FROM ds091"
777 sq_prepare (plugin->dbh, 705 " WHERE expire < ?"
778 "SELECT _ROWID_,key,value FROM ds091" 706 " ORDER BY expire ASC LIMIT 1",
779 " WHERE expire < ?" 707 &plugin->del_expired_stmt)) ||
780 " ORDER BY expire ASC LIMIT 1", 708 (SQLITE_OK != sq_prepare (plugin->dbh,
781 &plugin->del_expired_stmt)) || 709 "SELECT _ROWID_,key,value FROM ds091"
782 (SQLITE_OK != 710 " ORDER BY prox ASC, expire ASC LIMIT 1",
783 sq_prepare (plugin->dbh, 711 &plugin->del_select_stmt)) ||
784 "SELECT _ROWID_,key,value FROM ds091" 712 (SQLITE_OK != sq_prepare (plugin->dbh,
785 " ORDER BY prox ASC, expire ASC LIMIT 1", 713 "DELETE FROM ds091 WHERE _ROWID_=?",
786 &plugin->del_select_stmt)) || 714 &plugin->del_stmt)) ||
787 (SQLITE_OK != 715 (SQLITE_OK != sq_prepare (plugin->dbh,
788 sq_prepare (plugin->dbh, 716 "SELECT value,expire,path,key,type FROM ds091 "
789 "DELETE FROM ds091 WHERE _ROWID_=?", 717 "ORDER BY key LIMIT 1 OFFSET ?",
790 &plugin->del_stmt)) || 718 &plugin->get_random_stmt)) ||
791 (SQLITE_OK != 719 (SQLITE_OK !=
792 sq_prepare (plugin->dbh, 720 sq_prepare (plugin->dbh,
793 "SELECT value,expire,path,key,type FROM ds091 " 721 "SELECT value,expire,path,type,key FROM ds091 "
794 "ORDER BY key LIMIT 1 OFFSET ?", 722 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
795 &plugin->get_random_stmt)) || 723 &plugin->get_closest_stmt)))
796 (SQLITE_OK !=
797 sq_prepare (plugin->dbh,
798 "SELECT value,expire,path,type,key FROM ds091 "
799 "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?",
800 &plugin->get_closest_stmt))
801 )
802 { 724 {
803 LOG_SQLITE (plugin->dbh, 725 LOG_SQLITE (plugin->dbh,
804 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 726 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
805 "sq_prepare"); 727 "sq_prepare");
806 GNUNET_break (SQLITE_OK == 728 GNUNET_break (SQLITE_OK == sqlite3_close (plugin->dbh));
807 sqlite3_close (plugin->dbh));
808 GNUNET_free (plugin); 729 GNUNET_free (plugin);
809 return NULL; 730 return NULL;
810 } 731 }
@@ -816,8 +737,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
816 api->del = &sqlite_plugin_del; 737 api->del = &sqlite_plugin_del;
817 api->get_random = &sqlite_plugin_get_random; 738 api->get_random = &sqlite_plugin_get_random;
818 api->get_closest = &sqlite_plugin_get_closest; 739 api->get_closest = &sqlite_plugin_get_closest;
819 LOG (GNUNET_ERROR_TYPE_INFO, 740 LOG (GNUNET_ERROR_TYPE_INFO, "Sqlite datacache running\n");
820 "Sqlite datacache running\n");
821 return api; 741 return api;
822} 742}
823 743
@@ -839,12 +759,9 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
839 sqlite3_stmt *stmt; 759 sqlite3_stmt *stmt;
840#endif 760#endif
841 761
842#if !WINDOWS || defined(__CYGWIN__) 762#if ! WINDOWS || defined(__CYGWIN__)
843 if ( (NULL != plugin->fn) && 763 if ((NULL != plugin->fn) && (0 != unlink (plugin->fn)))
844 (0 != UNLINK (plugin->fn)) ) 764 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
845 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
846 "unlink",
847 plugin->fn);
848 GNUNET_free_non_null (plugin->fn); 765 GNUNET_free_non_null (plugin->fn);
849#endif 766#endif
850 sqlite3_finalize (plugin->insert_stmt); 767 sqlite3_finalize (plugin->insert_stmt);
@@ -860,7 +777,8 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
860 if (SQLITE_BUSY == result) 777 if (SQLITE_BUSY == result)
861 { 778 {
862 LOG (GNUNET_ERROR_TYPE_WARNING, 779 LOG (GNUNET_ERROR_TYPE_WARNING,
863 _("Tried to close sqlite without finalizing all prepared statements.\n")); 780 _ (
781 "Tried to close sqlite without finalizing all prepared statements.\n"));
864 stmt = sqlite3_next_stmt (plugin->dbh, NULL); 782 stmt = sqlite3_next_stmt (plugin->dbh, NULL);
865 while (NULL != stmt) 783 while (NULL != stmt)
866 { 784 {
@@ -876,16 +794,11 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
876 } 794 }
877#endif 795#endif
878 if (SQLITE_OK != result) 796 if (SQLITE_OK != result)
879 LOG_SQLITE (plugin->dbh, 797 LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
880 GNUNET_ERROR_TYPE_ERROR, 798
881 "sqlite3_close"); 799#if WINDOWS && ! defined(__CYGWIN__)
882 800 if ((NULL != plugin->fn) && (0 != unlink (plugin->fn)))
883#if WINDOWS && !defined(__CYGWIN__) 801 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
884 if ( (NULL != plugin->fn) &&
885 (0 != UNLINK (plugin->fn)) )
886 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
887 "unlink",
888 plugin->fn);
889 GNUNET_free_non_null (plugin->fn); 802 GNUNET_free_non_null (plugin->fn);
890#endif 803#endif
891 GNUNET_free (plugin); 804 GNUNET_free (plugin);
@@ -894,5 +807,4 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
894} 807}
895 808
896 809
897
898/* end of plugin_datacache_sqlite.c */ 810/* end of plugin_datacache_sqlite.c */
diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c
index d62a31c27..572a775df 100644
--- a/src/datacache/test_datacache.c
+++ b/src/datacache/test_datacache.c
@@ -84,7 +84,7 @@ run (void *cls,
84 "testcache"); 84 "testcache");
85 if (h == NULL) 85 if (h == NULL)
86 { 86 {
87 FPRINTF (stderr, 87 fprintf (stderr,
88 "%s", 88 "%s",
89 "Failed to initialize datacache. Database likely not setup, skipping test.\n"); 89 "Failed to initialize datacache. Database likely not setup, skipping test.\n");
90 ok = 77; /* mark test as skipped */ 90 ok = 77; /* mark test as skipped */
@@ -183,7 +183,7 @@ main (int argc, char *argv[])
183 &run, 183 &run,
184 NULL); 184 NULL);
185 if ( (0 != ok) && (77 != ok) ) 185 if ( (0 != ok) && (77 != ok) )
186 FPRINTF (stderr, 186 fprintf (stderr,
187 "Missed some testcases: %d\n", 187 "Missed some testcases: %d\n",
188 ok); 188 ok);
189 return ok; 189 return ok;
diff --git a/src/datacache/test_datacache_quota.c b/src/datacache/test_datacache_quota.c
index 7c4e56ea5..0201df3b3 100644
--- a/src/datacache/test_datacache_quota.c
+++ b/src/datacache/test_datacache_quota.c
@@ -63,7 +63,7 @@ run (void *cls,
63 63
64 if (h == NULL) 64 if (h == NULL)
65 { 65 {
66 FPRINTF (stderr, 66 fprintf (stderr,
67 "%s", 67 "%s",
68 "Failed to initialize datacache. Database likely not setup, skipping test.\n"); 68 "Failed to initialize datacache. Database likely not setup, skipping test.\n");
69 return; 69 return;
@@ -73,7 +73,7 @@ run (void *cls,
73 memset (&k, 0, sizeof (struct GNUNET_HashCode)); 73 memset (&k, 0, sizeof (struct GNUNET_HashCode));
74 for (unsigned int i = 0; i < 10; i++) 74 for (unsigned int i = 0; i < 10; i++)
75 { 75 {
76 FPRINTF (stderr, 76 fprintf (stderr,
77 "%s", 77 "%s",
78 "."); 78 ".");
79 GNUNET_CRYPTO_hash (&k, 79 GNUNET_CRYPTO_hash (&k,
@@ -97,11 +97,11 @@ run (void *cls,
97 } 97 }
98 k = n; 98 k = n;
99 } 99 }
100 FPRINTF (stderr, "%s", "\n"); 100 fprintf (stderr, "%s", "\n");
101 memset (&k, 0, sizeof (struct GNUNET_HashCode)); 101 memset (&k, 0, sizeof (struct GNUNET_HashCode));
102 for (unsigned int i = 0; i < 10; i++) 102 for (unsigned int i = 0; i < 10; i++)
103 { 103 {
104 FPRINTF (stderr, "%s", "."); 104 fprintf (stderr, "%s", ".");
105 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 105 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
106 if (i < 2) 106 if (i < 2)
107 ASSERT (0 == GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL)); 107 ASSERT (0 == GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL));
@@ -109,7 +109,7 @@ run (void *cls,
109 ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL)); 109 ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL));
110 k = n; 110 k = n;
111 } 111 }
112 FPRINTF (stderr, "%s", "\n"); 112 fprintf (stderr, "%s", "\n");
113 GNUNET_DATACACHE_destroy (h); 113 GNUNET_DATACACHE_destroy (h);
114 return; 114 return;
115FAILURE: 115FAILURE:
@@ -152,7 +152,7 @@ main (int argc,
152 &run, 152 &run,
153 NULL); 153 NULL);
154 if (0 != ok) 154 if (0 != ok)
155 FPRINTF (stderr, 155 fprintf (stderr,
156 "Missed some testcases: %d\n", 156 "Missed some testcases: %d\n",
157 ok); 157 ok);
158 return ok; 158 return ok;