summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-06-12 14:48:00 +0200
committerChristian Grothoff <christian@grothoff.org>2018-06-12 14:48:00 +0200
commitf6a87ee66310529edf76c0fab76cdc7cd2aac216 (patch)
treee3697e5f549bd6d0adbeede9935b67313d4907cf /src
parentae8b5cb2eac770be0d18b7d46c238bf865e34023 (diff)
downloadgnunet-f6a87ee66310529edf76c0fab76cdc7cd2aac216.tar.gz
gnunet-f6a87ee66310529edf76c0fab76cdc7cd2aac216.zip
ensure datacache does not return expired records, fixig pq behavior with respect to FOREVER absolute time
Diffstat (limited to 'src')
-rw-r--r--src/datacache/plugin_datacache_heap.c3
-rw-r--r--src/datacache/plugin_datacache_postgres.c33
-rw-r--r--src/datacache/test_datacache.c73
-rw-r--r--src/datacache/test_datacache_quota.c31
-rw-r--r--src/pq/pq_query_helper.c58
-rw-r--r--src/pq/pq_result_helper.c85
6 files changed, 242 insertions, 41 deletions
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c
index 2a08fc81b..494d1ae17 100644
--- a/src/datacache/plugin_datacache_heap.c
+++ b/src/datacache/plugin_datacache_heap.c
@@ -314,6 +314,9 @@ get_cb (void *cls,
314 if ( (get_ctx->type != val->type) && 314 if ( (get_ctx->type != val->type) &&
315 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) ) 315 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) )
316 return GNUNET_OK; 316 return GNUNET_OK;
317 if (0 ==
318 GNUNET_TIME_absolute_get_remaining (val->discard_time).rel_value_us)
319 return GNUNET_OK;
317 if (NULL != get_ctx->iter) 320 if (NULL != get_ctx->iter)
318 ret = get_ctx->iter (get_ctx->iter_cls, 321 ret = get_ctx->iter (get_ctx->iter_cls,
319 key, 322 key,
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 6eeeb5873..ea87acc1f 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -82,12 +82,12 @@ init_connection (struct Plugin *plugin)
82 struct GNUNET_PQ_PreparedStatement ps[] = { 82 struct GNUNET_PQ_PreparedStatement ps[] = {
83 GNUNET_PQ_make_prepare ("getkt", 83 GNUNET_PQ_make_prepare ("getkt",
84 "SELECT discard_time,type,value,path FROM gn011dc " 84 "SELECT discard_time,type,value,path FROM gn011dc "
85 "WHERE key=$1 AND type=$2", 85 "WHERE key=$1 AND type=$2 AND discard_time >= $3",
86 2), 86 3),
87 GNUNET_PQ_make_prepare ("getk", 87 GNUNET_PQ_make_prepare ("getk",
88 "SELECT discard_time,type,value,path FROM gn011dc " 88 "SELECT discard_time,type,value,path FROM gn011dc "
89 "WHERE key=$1", 89 "WHERE key=$1 AND discard_time >= $2",
90 1), 90 2),
91 GNUNET_PQ_make_prepare ("getex", 91 GNUNET_PQ_make_prepare ("getex",
92 "SELECT length(value) AS len,oid,key FROM gn011dc" 92 "SELECT length(value) AS len,oid,key FROM gn011dc"
93 " WHERE discard_time < $1" 93 " WHERE discard_time < $1"
@@ -97,18 +97,15 @@ init_connection (struct Plugin *plugin)
97 "SELECT length(value) AS len,oid,key FROM gn011dc" 97 "SELECT length(value) AS len,oid,key FROM gn011dc"
98 " ORDER BY prox ASC, discard_time ASC LIMIT 1", 98 " ORDER BY prox ASC, discard_time ASC LIMIT 1",
99 0), 99 0),
100 GNUNET_PQ_make_prepare ("getp",
101 "SELECT length(value) AS len,oid,key FROM gn011dc "
102 "ORDER BY discard_time ASC LIMIT 1",
103 0),
104 GNUNET_PQ_make_prepare ("get_random", 100 GNUNET_PQ_make_prepare ("get_random",
105 "SELECT discard_time,type,value,path,key FROM gn011dc " 101 "SELECT discard_time,type,value,path,key FROM gn011dc"
106 "ORDER BY key ASC LIMIT 1 OFFSET $1", 102 " WHERE discard_time >= $1"
107 1), 103 " ORDER BY key ASC LIMIT 1 OFFSET $2",
104 2),
108 GNUNET_PQ_make_prepare ("get_closest", 105 GNUNET_PQ_make_prepare ("get_closest",
109 "SELECT discard_time,type,value,path,key FROM gn011dc " 106 "SELECT discard_time,type,value,path,key FROM gn011dc "
110 "WHERE key>=$1 ORDER BY key ASC LIMIT $2", 107 "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3",
111 1), 108 3),
112 GNUNET_PQ_make_prepare ("delrow", 109 GNUNET_PQ_make_prepare ("delrow",
113 "DELETE FROM gn011dc WHERE oid=$1", 110 "DELETE FROM gn011dc WHERE oid=$1",
114 1), 111 1),
@@ -313,18 +310,22 @@ postgres_plugin_get (void *cls,
313{ 310{
314 struct Plugin *plugin = cls; 311 struct Plugin *plugin = cls;
315 uint32_t type32 = (uint32_t) type; 312 uint32_t type32 = (uint32_t) type;
313 struct GNUNET_TIME_Absolute now;
316 struct GNUNET_PQ_QueryParam paramk[] = { 314 struct GNUNET_PQ_QueryParam paramk[] = {
317 GNUNET_PQ_query_param_auto_from_type (key), 315 GNUNET_PQ_query_param_auto_from_type (key),
316 GNUNET_PQ_query_param_absolute_time (&now),
318 GNUNET_PQ_query_param_end 317 GNUNET_PQ_query_param_end
319 }; 318 };
320 struct GNUNET_PQ_QueryParam paramkt[] = { 319 struct GNUNET_PQ_QueryParam paramkt[] = {
321 GNUNET_PQ_query_param_auto_from_type (key), 320 GNUNET_PQ_query_param_auto_from_type (key),
322 GNUNET_PQ_query_param_uint32 (&type32), 321 GNUNET_PQ_query_param_uint32 (&type32),
322 GNUNET_PQ_query_param_absolute_time (&now),
323 GNUNET_PQ_query_param_end 323 GNUNET_PQ_query_param_end
324 }; 324 };
325 enum GNUNET_DB_QueryStatus res; 325 enum GNUNET_DB_QueryStatus res;
326 struct HandleResultContext hr_ctx; 326 struct HandleResultContext hr_ctx;
327 327
328 now = GNUNET_TIME_absolute_get ();
328 hr_ctx.iter = iter; 329 hr_ctx.iter = iter;
329 hr_ctx.iter_cls = iter_cls; 330 hr_ctx.iter_cls = iter_cls;
330 hr_ctx.key = key; 331 hr_ctx.key = key;
@@ -427,6 +428,7 @@ postgres_plugin_get_random (void *cls,
427{ 428{
428 struct Plugin *plugin = cls; 429 struct Plugin *plugin = cls;
429 uint32_t off; 430 uint32_t off;
431 struct GNUNET_TIME_Absolute now;
430 struct GNUNET_TIME_Absolute expiration_time; 432 struct GNUNET_TIME_Absolute expiration_time;
431 size_t data_size; 433 size_t data_size;
432 void *data; 434 void *data;
@@ -436,6 +438,7 @@ postgres_plugin_get_random (void *cls,
436 uint32_t type; 438 uint32_t type;
437 enum GNUNET_DB_QueryStatus res; 439 enum GNUNET_DB_QueryStatus res;
438 struct GNUNET_PQ_QueryParam params[] = { 440 struct GNUNET_PQ_QueryParam params[] = {
441 GNUNET_PQ_query_param_absolute_time (&now),
439 GNUNET_PQ_query_param_uint32 (&off), 442 GNUNET_PQ_query_param_uint32 (&off),
440 GNUNET_PQ_query_param_end 443 GNUNET_PQ_query_param_end
441 }; 444 };
@@ -459,6 +462,7 @@ postgres_plugin_get_random (void *cls,
459 return 0; 462 return 0;
460 if (NULL == iter) 463 if (NULL == iter)
461 return 1; 464 return 1;
465 now = GNUNET_TIME_absolute_get ();
462 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 466 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
463 plugin->num_items); 467 plugin->num_items);
464 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, 468 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
@@ -620,8 +624,10 @@ postgres_plugin_get_closest (void *cls,
620{ 624{
621 struct Plugin *plugin = cls; 625 struct Plugin *plugin = cls;
622 uint32_t num_results32 = (uint32_t) num_results; 626 uint32_t num_results32 = (uint32_t) num_results;
627 struct GNUNET_TIME_Absolute now;
623 struct GNUNET_PQ_QueryParam params[] = { 628 struct GNUNET_PQ_QueryParam params[] = {
624 GNUNET_PQ_query_param_auto_from_type (key), 629 GNUNET_PQ_query_param_auto_from_type (key),
630 GNUNET_PQ_query_param_absolute_time (&now),
625 GNUNET_PQ_query_param_uint32 (&num_results32), 631 GNUNET_PQ_query_param_uint32 (&num_results32),
626 GNUNET_PQ_query_param_end 632 GNUNET_PQ_query_param_end
627 }; 633 };
@@ -630,6 +636,7 @@ postgres_plugin_get_closest (void *cls,
630 636
631 erc.iter = iter; 637 erc.iter = iter;
632 erc.iter_cls = iter_cls; 638 erc.iter_cls = iter_cls;
639 now = GNUNET_TIME_absolute_get ();
633 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh, 640 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
634 "get_closest", 641 "get_closest",
635 params, 642 params,
diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c
index 12edb62f8..50e45012d 100644
--- a/src/datacache/test_datacache.c
+++ b/src/datacache/test_datacache.c
@@ -44,6 +44,11 @@ checkIt (void *cls,
44 unsigned int path_len, 44 unsigned int path_len,
45 const struct GNUNET_PeerIdentity *path) 45 const struct GNUNET_PeerIdentity *path)
46{ 46{
47 (void) key;
48 (void) type;
49 (void) exp;
50 (void) path_len;
51 (void) path;
47 if (size != sizeof (struct GNUNET_HashCode)) 52 if (size != sizeof (struct GNUNET_HashCode))
48 { 53 {
49 GNUNET_break (0); 54 GNUNET_break (0);
@@ -59,17 +64,22 @@ checkIt (void *cls,
59 64
60 65
61static void 66static void
62run (void *cls, char *const *args, const char *cfgfile, 67run (void *cls,
68 char *const *args,
69 const char *cfgfile,
63 const struct GNUNET_CONFIGURATION_Handle *cfg) 70 const struct GNUNET_CONFIGURATION_Handle *cfg)
64{ 71{
65 struct GNUNET_DATACACHE_Handle *h; 72 struct GNUNET_DATACACHE_Handle *h;
66 struct GNUNET_HashCode k; 73 struct GNUNET_HashCode k;
67 struct GNUNET_HashCode n; 74 struct GNUNET_HashCode n;
68 struct GNUNET_TIME_Absolute exp; 75 struct GNUNET_TIME_Absolute exp;
69 unsigned int i;
70 76
77 (void) cls;
78 (void) args;
79 (void) cfgfile;
71 ok = 0; 80 ok = 0;
72 h = GNUNET_DATACACHE_create (cfg, "testcache"); 81 h = GNUNET_DATACACHE_create (cfg,
82 "testcache");
73 if (h == NULL) 83 if (h == NULL)
74 { 84 {
75 FPRINTF (stderr, 85 FPRINTF (stderr,
@@ -81,7 +91,7 @@ run (void *cls, char *const *args, const char *cfgfile,
81 exp = GNUNET_TIME_absolute_get (); 91 exp = GNUNET_TIME_absolute_get ();
82 exp.abs_value_us += 5 * 60 * 1000 * 1000LL; 92 exp.abs_value_us += 5 * 60 * 1000 * 1000LL;
83 memset (&k, 0, sizeof (struct GNUNET_HashCode)); 93 memset (&k, 0, sizeof (struct GNUNET_HashCode));
84 for (i = 0; i < 100; i++) 94 for (unsigned int i = 0; i < 100; i++)
85 { 95 {
86 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 96 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
87 ASSERT (GNUNET_OK == 97 ASSERT (GNUNET_OK ==
@@ -93,26 +103,43 @@ run (void *cls, char *const *args, const char *cfgfile,
93 0, NULL)); 103 0, NULL));
94 k = n; 104 k = n;
95 } 105 }
96 memset (&k, 0, sizeof (struct GNUNET_HashCode)); 106 memset (&k,
97 for (i = 0; i < 100; i++) 107 0,
108 sizeof (struct GNUNET_HashCode));
109 for (unsigned int i = 0; i < 100; i++)
98 { 110 {
99 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 111 GNUNET_CRYPTO_hash (&k,
100 ASSERT (1 == GNUNET_DATACACHE_get (h, &k, 1 + i % 16, &checkIt, &n)); 112 sizeof (struct GNUNET_HashCode),
113 &n);
114 ASSERT (1 == GNUNET_DATACACHE_get (h,
115 &k,
116 1 + i % 16,
117 &checkIt,
118 &n));
101 k = n; 119 k = n;
102 } 120 }
103 121
104 memset (&k, 42, sizeof (struct GNUNET_HashCode)); 122 memset (&k,
105 GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); 123 42,
124 sizeof (struct GNUNET_HashCode));
125 GNUNET_CRYPTO_hash (&k,
126 sizeof (struct GNUNET_HashCode),
127 &n);
106 ASSERT (GNUNET_OK == 128 ASSERT (GNUNET_OK ==
107 GNUNET_DATACACHE_put (h, 129 GNUNET_DATACACHE_put (h,
108 &k, 130 &k,
109 GNUNET_YES, 131 GNUNET_YES,
110 sizeof (struct GNUNET_HashCode), 132 sizeof (struct GNUNET_HashCode),
111 (const char *) &n, 792, 133 (const char *) &n,
134 792,
112 GNUNET_TIME_UNIT_FOREVER_ABS, 135 GNUNET_TIME_UNIT_FOREVER_ABS,
113 0, NULL)); 136 0,
114 ASSERT (0 != GNUNET_DATACACHE_get (h, &k, 792, &checkIt, &n)); 137 NULL));
115 138 ASSERT (0 != GNUNET_DATACACHE_get (h,
139 &k,
140 792,
141 &checkIt,
142 &n));
116 GNUNET_DATACACHE_destroy (h); 143 GNUNET_DATACACHE_destroy (h);
117 ASSERT (ok == 0); 144 ASSERT (ok == 0);
118 return; 145 return;
@@ -137,16 +164,26 @@ main (int argc, char *argv[])
137 GNUNET_GETOPT_OPTION_END 164 GNUNET_GETOPT_OPTION_END
138 }; 165 };
139 166
167 (void) argc;
140 GNUNET_log_setup ("test-datacache", 168 GNUNET_log_setup ("test-datacache",
141 "WARNING", 169 "WARNING",
142 NULL); 170 NULL);
143 plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); 171 plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
144 GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_datacache_data_%s.conf", 172 GNUNET_snprintf (cfg_name,
173 sizeof (cfg_name),
174 "test_datacache_data_%s.conf",
145 plugin_name); 175 plugin_name);
146 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, 176 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1,
147 "test-datacache", "nohelp", options, &run, NULL); 177 xargv,
178 "test-datacache",
179 "nohelp",
180 options,
181 &run,
182 NULL);
148 if ( (0 != ok) && (77 != ok) ) 183 if ( (0 != ok) && (77 != ok) )
149 FPRINTF (stderr, "Missed some testcases: %d\n", ok); 184 FPRINTF (stderr,
185 "Missed some testcases: %d\n",
186 ok);
150 return ok; 187 return ok;
151} 188}
152 189
diff --git a/src/datacache/test_datacache_quota.c b/src/datacache/test_datacache_quota.c
index 3d02a7244..21e373608 100644
--- a/src/datacache/test_datacache_quota.c
+++ b/src/datacache/test_datacache_quota.c
@@ -41,7 +41,9 @@ static const char *plugin_name;
41 * some of the data from the last iteration is still there. 41 * some of the data from the last iteration is still there.
42 */ 42 */
43static void 43static void
44run (void *cls, char *const *args, const char *cfgfile, 44run (void *cls,
45 char *const *args,
46 const char *cfgfile,
45 const struct GNUNET_CONFIGURATION_Handle *cfg) 47 const struct GNUNET_CONFIGURATION_Handle *cfg)
46{ 48{
47 struct GNUNET_DATACACHE_Handle *h; 49 struct GNUNET_DATACACHE_Handle *h;
@@ -50,8 +52,12 @@ run (void *cls, char *const *args, const char *cfgfile,
50 char buf[3200]; 52 char buf[3200];
51 struct GNUNET_TIME_Absolute exp; 53 struct GNUNET_TIME_Absolute exp;
52 54
55 (void) cls;
56 (void) args;
57 (void) cfgfile;
53 ok = 0; 58 ok = 0;
54 h = GNUNET_DATACACHE_create (cfg, "testcache"); 59 h = GNUNET_DATACACHE_create (cfg,
60 "testcache");
55 61
56 if (h == NULL) 62 if (h == NULL)
57 { 63 {
@@ -112,7 +118,8 @@ FAILURE:
112 118
113 119
114int 120int
115main (int argc, char *argv[]) 121main (int argc,
122 char *argv[])
116{ 123{
117 char cfg_name[128]; 124 char cfg_name[128];
118 char *const xargv[] = { 125 char *const xargv[] = {
@@ -125,17 +132,27 @@ main (int argc, char *argv[])
125 GNUNET_GETOPT_OPTION_END 132 GNUNET_GETOPT_OPTION_END
126 }; 133 };
127 134
135 (void) argc;
128 GNUNET_log_setup ("test-datacache-quota", 136 GNUNET_log_setup ("test-datacache-quota",
129 "WARNING", 137 "WARNING",
130 NULL); 138 NULL);
131 139
132 plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); 140 plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
133 GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_datacache_data_%s.conf", 141 GNUNET_snprintf (cfg_name,
142 sizeof (cfg_name),
143 "test_datacache_data_%s.conf",
134 plugin_name); 144 plugin_name);
135 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, 145 GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1,
136 "test-datacache-quota", "nohelp", options, &run, NULL); 146 xargv,
147 "test-datacache-quota",
148 "nohelp",
149 options,
150 &run,
151 NULL);
137 if (0 != ok) 152 if (0 != ok)
138 FPRINTF (stderr, "Missed some testcases: %d\n", ok); 153 FPRINTF (stderr,
154 "Missed some testcases: %d\n",
155 ok);
139 return ok; 156 return ok;
140} 157}
141 158
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index 799f82ebe..98f697b5d 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -50,6 +50,8 @@ qconv_fixed (void *cls,
50 void *scratch[], 50 void *scratch[],
51 unsigned int scratch_length) 51 unsigned int scratch_length)
52{ 52{
53 (void) scratch;
54 (void) scratch_length;
53 GNUNET_break (NULL == cls); 55 GNUNET_break (NULL == cls);
54 if (1 != param_length) 56 if (1 != param_length)
55 return -1; 57 return -1;
@@ -117,6 +119,8 @@ qconv_uint16 (void *cls,
117 const uint16_t *u_hbo = data; 119 const uint16_t *u_hbo = data;
118 uint16_t *u_nbo; 120 uint16_t *u_nbo;
119 121
122 (void) scratch;
123 (void) scratch_length;
120 GNUNET_break (NULL == cls); 124 GNUNET_break (NULL == cls);
121 if (1 != param_length) 125 if (1 != param_length)
122 return -1; 126 return -1;
@@ -172,6 +176,8 @@ qconv_uint32 (void *cls,
172 const uint32_t *u_hbo = data; 176 const uint32_t *u_hbo = data;
173 uint32_t *u_nbo; 177 uint32_t *u_nbo;
174 178
179 (void) scratch;
180 (void) scratch_length;
175 GNUNET_break (NULL == cls); 181 GNUNET_break (NULL == cls);
176 if (1 != param_length) 182 if (1 != param_length)
177 return -1; 183 return -1;
@@ -227,6 +233,8 @@ qconv_uint64 (void *cls,
227 const uint64_t *u_hbo = data; 233 const uint64_t *u_hbo = data;
228 uint64_t *u_nbo; 234 uint64_t *u_nbo;
229 235
236 (void) scratch;
237 (void) scratch_length;
230 GNUNET_break (NULL == cls); 238 GNUNET_break (NULL == cls);
231 if (1 != param_length) 239 if (1 != param_length)
232 return -1; 240 return -1;
@@ -371,6 +379,51 @@ GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
371 379
372 380
373/** 381/**
382 * Function called to convert input argument into SQL parameters.
383 *
384 * @param cls closure
385 * @param data pointer to input argument
386 * @param data_len number of bytes in @a data (if applicable)
387 * @param[out] param_values SQL data to set
388 * @param[out] param_lengths SQL length data to set
389 * @param[out] param_formats SQL format data to set
390 * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
391 * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
392 * @param scratch_length number of entries left in @a scratch
393 * @return -1 on error, number of offsets used in @a scratch otherwise
394 */
395static int
396qconv_abs_time (void *cls,
397 const void *data,
398 size_t data_len,
399 void *param_values[],
400 int param_lengths[],
401 int param_formats[],
402 unsigned int param_length,
403 void *scratch[],
404 unsigned int scratch_length)
405{
406 const struct GNUNET_TIME_Absolute *u = data;
407 struct GNUNET_TIME_Absolute abs;
408 uint64_t *u_nbo;
409
410 GNUNET_break (NULL == cls);
411 if (1 != param_length)
412 return -1;
413 abs = *u;
414 if (abs.abs_value_us > INT64_MAX)
415 abs.abs_value_us = INT64_MAX;
416 u_nbo = GNUNET_new (uint64_t);
417 scratch[0] = u_nbo;
418 *u_nbo = GNUNET_htonll (abs.abs_value_us);
419 param_values[0] = (void *) u_nbo;
420 param_lengths[0] = sizeof (uint64_t);
421 param_formats[0] = 1;
422 return 1;
423}
424
425
426/**
374 * Generate query parameter for an absolute time value. 427 * Generate query parameter for an absolute time value.
375 * The database must store a 64-bit integer. 428 * The database must store a 64-bit integer.
376 * 429 *
@@ -380,7 +433,10 @@ GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
380struct GNUNET_PQ_QueryParam 433struct GNUNET_PQ_QueryParam
381GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) 434GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
382{ 435{
383 return GNUNET_PQ_query_param_uint64 (&x->abs_value_us); 436 struct GNUNET_PQ_QueryParam res =
437 { &qconv_abs_time, NULL, x, sizeof (*x), 1 };
438
439 return res;
384} 440}
385 441
386 442
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index 3805b8a8d..dc1a1554f 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -38,6 +38,7 @@ clean_varsize_blob (void *cls,
38{ 38{
39 void **dst = rd; 39 void **dst = rd;
40 40
41 (void) cls;
41 if (NULL != *dst) 42 if (NULL != *dst)
42 { 43 {
43 GNUNET_free (*dst); 44 GNUNET_free (*dst);
@@ -72,6 +73,7 @@ extract_varsize_blob (void *cls,
72 void *idst; 73 void *idst;
73 int fnum; 74 int fnum;
74 75
76 (void) cls;
75 *dst_size = 0; 77 *dst_size = 0;
76 *((void **) dst) = NULL; 78 *((void **) dst) = NULL;
77 79
@@ -154,6 +156,7 @@ extract_fixed_blob (void *cls,
154 const char *res; 156 const char *res;
155 int fnum; 157 int fnum;
156 158
159 (void) cls;
157 fnum = PQfnumber (result, 160 fnum = PQfnumber (result,
158 fname); 161 fname);
159 if (fnum < 0) 162 if (fnum < 0)
@@ -237,6 +240,7 @@ extract_rsa_public_key (void *cls,
237 const char *res; 240 const char *res;
238 int fnum; 241 int fnum;
239 242
243 (void) cls;
240 *pk = NULL; 244 *pk = NULL;
241 fnum = PQfnumber (result, 245 fnum = PQfnumber (result,
242 fname); 246 fname);
@@ -284,6 +288,7 @@ clean_rsa_public_key (void *cls,
284{ 288{
285 struct GNUNET_CRYPTO_RsaPublicKey **pk = rd; 289 struct GNUNET_CRYPTO_RsaPublicKey **pk = rd;
286 290
291 (void) cls;
287 if (NULL != *pk) 292 if (NULL != *pk)
288 { 293 {
289 GNUNET_CRYPTO_rsa_public_key_free (*pk); 294 GNUNET_CRYPTO_rsa_public_key_free (*pk);
@@ -338,6 +343,7 @@ extract_rsa_signature (void *cls,
338 const char *res; 343 const char *res;
339 int fnum; 344 int fnum;
340 345
346 (void) cls;
341 *sig = NULL; 347 *sig = NULL;
342 fnum = PQfnumber (result, 348 fnum = PQfnumber (result,
343 fname); 349 fname);
@@ -385,6 +391,7 @@ clean_rsa_signature (void *cls,
385{ 391{
386 struct GNUNET_CRYPTO_RsaSignature **sig = rd; 392 struct GNUNET_CRYPTO_RsaSignature **sig = rd;
387 393
394 (void) cls;
388 if (NULL != *sig) 395 if (NULL != *sig)
389 { 396 {
390 GNUNET_CRYPTO_rsa_signature_free (*sig); 397 GNUNET_CRYPTO_rsa_signature_free (*sig);
@@ -439,6 +446,7 @@ extract_string (void *cls,
439 const char *res; 446 const char *res;
440 int fnum; 447 int fnum;
441 448
449 (void) cls;
442 *str = NULL; 450 *str = NULL;
443 fnum = PQfnumber (result, 451 fnum = PQfnumber (result,
444 fname); 452 fname);
@@ -486,6 +494,7 @@ clean_string (void *cls,
486{ 494{
487 char **str = rd; 495 char **str = rd;
488 496
497 (void) cls;
489 if (NULL != *str) 498 if (NULL != *str)
490 { 499 {
491 GNUNET_free (*str); 500 GNUNET_free (*str);
@@ -515,6 +524,71 @@ GNUNET_PQ_result_spec_string (const char *name,
515 524
516 525
517/** 526/**
527 * Extract data from a Postgres database @a result at row @a row.
528 *
529 * @param cls closure
530 * @param result where to extract data from
531 * @param int row to extract data from
532 * @param fname name (or prefix) of the fields to extract from
533 * @param[in,out] dst_size where to store size of result, may be NULL
534 * @param[out] dst where to store the result
535 * @return
536 * #GNUNET_YES if all results could be extracted
537 * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
538 */
539static int
540extract_abs_time (void *cls,
541 PGresult *result,
542 int row,
543 const char *fname,
544 size_t *dst_size,
545 void *dst)
546{
547 struct GNUNET_TIME_Absolute *udst = dst;
548 const int64_t *res;
549 int fnum;
550
551 (void) cls;
552 fnum = PQfnumber (result,
553 fname);
554 if (fnum < 0)
555 {
556 GNUNET_break (0);
557 return GNUNET_SYSERR;
558 }
559 if (PQgetisnull (result,
560 row,
561 fnum))
562 {
563 GNUNET_break (0);
564 return GNUNET_SYSERR;
565 }
566 GNUNET_assert (NULL != dst);
567 if (sizeof (struct GNUNET_TIME_Absolute) != *dst_size)
568 {
569 GNUNET_break (0);
570 return GNUNET_SYSERR;
571 }
572 if (sizeof (int64_t) !=
573 PQgetlength (result,
574 row,
575 fnum))
576 {
577 GNUNET_break (0);
578 return GNUNET_SYSERR;
579 }
580 res = (int64_t *) PQgetvalue (result,
581 row,
582 fnum);
583 if (INT64_MAX == *res)
584 *udst = GNUNET_TIME_UNIT_FOREVER_ABS;
585 else
586 udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res);
587 return GNUNET_OK;
588}
589
590
591/**
518 * Absolute time expected. 592 * Absolute time expected.
519 * 593 *
520 * @param name name of the field in the table 594 * @param name name of the field in the table
@@ -525,8 +599,12 @@ struct GNUNET_PQ_ResultSpec
525GNUNET_PQ_result_spec_absolute_time (const char *name, 599GNUNET_PQ_result_spec_absolute_time (const char *name,
526 struct GNUNET_TIME_Absolute *at) 600 struct GNUNET_TIME_Absolute *at)
527{ 601{
528 return GNUNET_PQ_result_spec_uint64 (name, 602 struct GNUNET_PQ_ResultSpec res =
529 &at->abs_value_us); 603 { &extract_abs_time,
604 NULL,
605 NULL,
606 (void *) at, sizeof (*at), (name), NULL };
607 return res;
530} 608}
531 609
532 610
@@ -572,6 +650,7 @@ extract_uint16 (void *cls,
572 const uint16_t *res; 650 const uint16_t *res;
573 int fnum; 651 int fnum;
574 652
653 (void) cls;
575 fnum = PQfnumber (result, 654 fnum = PQfnumber (result,
576 fname); 655 fname);
577 if (fnum < 0) 656 if (fnum < 0)
@@ -653,6 +732,7 @@ extract_uint32 (void *cls,
653 const uint32_t *res; 732 const uint32_t *res;
654 int fnum; 733 int fnum;
655 734
735 (void) cls;
656 fnum = PQfnumber (result, 736 fnum = PQfnumber (result,
657 fname); 737 fname);
658 if (fnum < 0) 738 if (fnum < 0)
@@ -734,6 +814,7 @@ extract_uint64 (void *cls,
734 const uint64_t *res; 814 const uint64_t *res;
735 int fnum; 815 int fnum;
736 816
817 (void) cls;
737 fnum = PQfnumber (result, 818 fnum = PQfnumber (result,
738 fname); 819 fname);
739 if (fnum < 0) 820 if (fnum < 0)