aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/plugin_datacache_postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datacache/plugin_datacache_postgres.c')
-rw-r--r--src/datacache/plugin_datacache_postgres.c699
1 files changed, 353 insertions, 346 deletions
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 6666c850c..59dff9067 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -28,7 +28,7 @@
28#include "gnunet_pq_lib.h" 28#include "gnunet_pq_lib.h"
29#include "gnunet_datacache_plugin.h" 29#include "gnunet_datacache_plugin.h"
30 30
31#define LOG(kind, ...) GNUNET_log_from(kind, "datacache-postgres", __VA_ARGS__) 31#define LOG(kind, ...) GNUNET_log_from (kind, "datacache-postgres", __VA_ARGS__)
32 32
33/** 33/**
34 * Per-entry overhead estimate 34 * Per-entry overhead estimate
@@ -38,7 +38,8 @@
38/** 38/**
39 * Context for all functions in this plugin. 39 * Context for all functions in this plugin.
40 */ 40 */
41struct Plugin { 41struct Plugin
42{
42 /** 43 /**
43 * Our execution environment. 44 * Our execution environment.
44 */ 45 */
@@ -63,81 +64,84 @@ struct Plugin {
63 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 64 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
64 */ 65 */
65static int 66static int
66init_connection(struct Plugin *plugin) 67init_connection (struct Plugin *plugin)
67{ 68{
68 struct GNUNET_PQ_ExecuteStatement es[] = { 69 struct GNUNET_PQ_ExecuteStatement es[] = {
69 GNUNET_PQ_make_execute("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc (" 70 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc ("
70 " type INTEGER NOT NULL," 71 " type INTEGER NOT NULL,"
71 " prox INTEGER NOT NULL," 72 " prox INTEGER NOT NULL,"
72 " discard_time BIGINT NOT NULL," 73 " discard_time BIGINT NOT NULL,"
73 " key BYTEA NOT NULL," 74 " key BYTEA NOT NULL,"
74 " value BYTEA NOT NULL," 75 " value BYTEA NOT NULL,"
75 " path BYTEA DEFAULT NULL)" 76 " path BYTEA DEFAULT NULL)"
76 "WITH OIDS"), 77 "WITH OIDS"),
77 GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_key ON gn011dc (key)"), 78 GNUNET_PQ_make_try_execute (
78 GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS idx_dt ON gn011dc (discard_time)"), 79 "CREATE INDEX IF NOT EXISTS idx_key ON gn011dc (key)"),
79 GNUNET_PQ_make_execute("ALTER TABLE gn011dc ALTER value SET STORAGE EXTERNAL"), 80 GNUNET_PQ_make_try_execute (
80 GNUNET_PQ_make_execute("ALTER TABLE gn011dc ALTER key SET STORAGE PLAIN"), 81 "CREATE INDEX IF NOT EXISTS idx_dt ON gn011dc (discard_time)"),
82 GNUNET_PQ_make_execute (
83 "ALTER TABLE gn011dc ALTER value SET STORAGE EXTERNAL"),
84 GNUNET_PQ_make_execute ("ALTER TABLE gn011dc ALTER key SET STORAGE PLAIN"),
81 GNUNET_PQ_EXECUTE_STATEMENT_END 85 GNUNET_PQ_EXECUTE_STATEMENT_END
82 }; 86 };
83 struct GNUNET_PQ_PreparedStatement ps[] = { 87 struct GNUNET_PQ_PreparedStatement ps[] = {
84 GNUNET_PQ_make_prepare("getkt", 88 GNUNET_PQ_make_prepare ("getkt",
85 "SELECT discard_time,type,value,path FROM gn011dc " 89 "SELECT discard_time,type,value,path FROM gn011dc "
86 "WHERE key=$1 AND type=$2 AND discard_time >= $3", 90 "WHERE key=$1 AND type=$2 AND discard_time >= $3",
87 3), 91 3),
88 GNUNET_PQ_make_prepare("getk", 92 GNUNET_PQ_make_prepare ("getk",
89 "SELECT discard_time,type,value,path FROM gn011dc " 93 "SELECT discard_time,type,value,path FROM gn011dc "
90 "WHERE key=$1 AND discard_time >= $2", 94 "WHERE key=$1 AND discard_time >= $2",
91 2), 95 2),
92 GNUNET_PQ_make_prepare("getex", 96 GNUNET_PQ_make_prepare ("getex",
93 "SELECT length(value) AS len,oid,key FROM gn011dc" 97 "SELECT length(value) AS len,oid,key FROM gn011dc"
94 " WHERE discard_time < $1" 98 " WHERE discard_time < $1"
95 " ORDER BY discard_time ASC LIMIT 1", 99 " ORDER BY discard_time ASC LIMIT 1",
96 1), 100 1),
97 GNUNET_PQ_make_prepare("getm", 101 GNUNET_PQ_make_prepare ("getm",
98 "SELECT length(value) AS len,oid,key FROM gn011dc" 102 "SELECT length(value) AS len,oid,key FROM gn011dc"
99 " ORDER BY prox ASC, discard_time ASC LIMIT 1", 103 " ORDER BY prox ASC, discard_time ASC LIMIT 1",
100 0), 104 0),
101 GNUNET_PQ_make_prepare("get_random", 105 GNUNET_PQ_make_prepare ("get_random",
102 "SELECT discard_time,type,value,path,key FROM gn011dc" 106 "SELECT discard_time,type,value,path,key FROM gn011dc"
103 " WHERE discard_time >= $1" 107 " WHERE discard_time >= $1"
104 " ORDER BY key ASC LIMIT 1 OFFSET $2", 108 " ORDER BY key ASC LIMIT 1 OFFSET $2",
105 2), 109 2),
106 GNUNET_PQ_make_prepare("get_closest", 110 GNUNET_PQ_make_prepare ("get_closest",
107 "SELECT discard_time,type,value,path,key FROM gn011dc " 111 "SELECT discard_time,type,value,path,key FROM gn011dc "
108 "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3", 112 "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3",
109 3), 113 3),
110 GNUNET_PQ_make_prepare("delrow", 114 GNUNET_PQ_make_prepare ("delrow",
111 "DELETE FROM gn011dc WHERE oid=$1", 115 "DELETE FROM gn011dc WHERE oid=$1",
112 1), 116 1),
113 GNUNET_PQ_make_prepare("put", 117 GNUNET_PQ_make_prepare ("put",
114 "INSERT INTO gn011dc (type, prox, discard_time, key, value, path) " 118 "INSERT INTO gn011dc (type, prox, discard_time, key, value, path) "
115 "VALUES ($1, $2, $3, $4, $5, $6)", 119 "VALUES ($1, $2, $3, $4, $5, $6)",
116 6), 120 6),
117 GNUNET_PQ_PREPARED_STATEMENT_END 121 GNUNET_PQ_PREPARED_STATEMENT_END
118 }; 122 };
119 123
120 plugin->dbh = GNUNET_PQ_connect_with_cfg(plugin->env->cfg, 124 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg,
121 "datacache-postgres"); 125 "datacache-postgres");
122 if (NULL == plugin->dbh) 126 if (NULL == plugin->dbh)
123 return GNUNET_SYSERR; 127 return GNUNET_SYSERR;
124 if (GNUNET_OK != 128 if (GNUNET_OK !=
125 GNUNET_PQ_exec_statements(plugin->dbh, 129 GNUNET_PQ_exec_statements (plugin->dbh,
126 es)) 130 es))
127 { 131 {
128 PQfinish(plugin->dbh); 132 PQfinish (plugin->dbh);
129 plugin->dbh = NULL; 133 plugin->dbh = NULL;
130 return GNUNET_SYSERR; 134 return GNUNET_SYSERR;
131 } 135 }
132 136
133 if (GNUNET_OK != 137 if (GNUNET_OK !=
134 GNUNET_PQ_prepare_statements(plugin->dbh, 138 GNUNET_PQ_prepare_statements (plugin->dbh,
135 ps)) 139 ps))
136 { 140 {
137 PQfinish(plugin->dbh); 141 PQfinish (plugin->dbh);
138 plugin->dbh = NULL; 142 plugin->dbh = NULL;
139 return GNUNET_SYSERR; 143 return GNUNET_SYSERR;
140 } 144 }
141 return GNUNET_OK; 145 return GNUNET_OK;
142} 146}
143 147
@@ -157,33 +161,34 @@ init_connection(struct Plugin *plugin)
157 * @return 0 if duplicate, -1 on error, number of bytes used otherwise 161 * @return 0 if duplicate, -1 on error, number of bytes used otherwise
158 */ 162 */
159static ssize_t 163static ssize_t
160postgres_plugin_put(void *cls, 164postgres_plugin_put (void *cls,
161 const struct GNUNET_HashCode *key, 165 const struct GNUNET_HashCode *key,
162 uint32_t prox, 166 uint32_t prox,
163 size_t data_size, 167 size_t data_size,
164 const char *data, 168 const char *data,
165 enum GNUNET_BLOCK_Type type, 169 enum GNUNET_BLOCK_Type type,
166 struct GNUNET_TIME_Absolute discard_time, 170 struct GNUNET_TIME_Absolute discard_time,
167 unsigned int path_info_len, 171 unsigned int path_info_len,
168 const struct GNUNET_PeerIdentity *path_info) 172 const struct GNUNET_PeerIdentity *path_info)
169{ 173{
170 struct Plugin *plugin = cls; 174 struct Plugin *plugin = cls;
171 uint32_t type32 = (uint32_t)type; 175 uint32_t type32 = (uint32_t) type;
172 struct GNUNET_PQ_QueryParam params[] = { 176 struct GNUNET_PQ_QueryParam params[] = {
173 GNUNET_PQ_query_param_uint32(&type32), 177 GNUNET_PQ_query_param_uint32 (&type32),
174 GNUNET_PQ_query_param_uint32(&prox), 178 GNUNET_PQ_query_param_uint32 (&prox),
175 GNUNET_PQ_query_param_absolute_time(&discard_time), 179 GNUNET_PQ_query_param_absolute_time (&discard_time),
176 GNUNET_PQ_query_param_auto_from_type(key), 180 GNUNET_PQ_query_param_auto_from_type (key),
177 GNUNET_PQ_query_param_fixed_size(data, data_size), 181 GNUNET_PQ_query_param_fixed_size (data, data_size),
178 GNUNET_PQ_query_param_fixed_size(path_info, 182 GNUNET_PQ_query_param_fixed_size (path_info,
179 path_info_len * sizeof(struct GNUNET_PeerIdentity)), 183 path_info_len * sizeof(struct
184 GNUNET_PeerIdentity)),
180 GNUNET_PQ_query_param_end 185 GNUNET_PQ_query_param_end
181 }; 186 };
182 enum GNUNET_DB_QueryStatus ret; 187 enum GNUNET_DB_QueryStatus ret;
183 188
184 ret = GNUNET_PQ_eval_prepared_non_select(plugin->dbh, 189 ret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
185 "put", 190 "put",
186 params); 191 params);
187 if (0 > ret) 192 if (0 > ret)
188 return -1; 193 return -1;
189 plugin->num_items++; 194 plugin->num_items++;
@@ -194,7 +199,8 @@ postgres_plugin_put(void *cls,
194/** 199/**
195 * Closure for #handle_results. 200 * Closure for #handle_results.
196 */ 201 */
197struct HandleResultContext { 202struct HandleResultContext
203{
198 /** 204 /**
199 * Function to call on each result, may be NULL. 205 * Function to call on each result, may be NULL.
200 */ 206 */
@@ -222,70 +228,70 @@ struct HandleResultContext {
222 * @param num_result the number of results in @a result 228 * @param num_result the number of results in @a result
223 */ 229 */
224static void 230static void
225handle_results(void *cls, 231handle_results (void *cls,
226 PGresult *result, 232 PGresult *result,
227 unsigned int num_results) 233 unsigned int num_results)
228{ 234{
229 struct HandleResultContext *hrc = cls; 235 struct HandleResultContext *hrc = cls;
230 236
231 for (unsigned int i = 0; i < num_results; i++) 237 for (unsigned int i = 0; i < num_results; i++)
238 {
239 struct GNUNET_TIME_Absolute expiration_time;
240 uint32_t type;
241 void *data;
242 size_t data_size;
243 struct GNUNET_PeerIdentity *path;
244 size_t path_len;
245 struct GNUNET_PQ_ResultSpec rs[] = {
246 GNUNET_PQ_result_spec_absolute_time ("discard_time",
247 &expiration_time),
248 GNUNET_PQ_result_spec_uint32 ("type",
249 &type),
250 GNUNET_PQ_result_spec_variable_size ("value",
251 &data,
252 &data_size),
253 GNUNET_PQ_result_spec_variable_size ("path",
254 (void **) &path,
255 &path_len),
256 GNUNET_PQ_result_spec_end
257 };
258
259 if (GNUNET_YES !=
260 GNUNET_PQ_extract_result (result,
261 rs,
262 i))
263 {
264 GNUNET_break (0);
265 return;
266 }
267 if (0 != (path_len % sizeof(struct GNUNET_PeerIdentity)))
232 { 268 {
233 struct GNUNET_TIME_Absolute expiration_time; 269 GNUNET_break (0);
234 uint32_t type; 270 path_len = 0;
235 void *data;
236 size_t data_size;
237 struct GNUNET_PeerIdentity *path;
238 size_t path_len;
239 struct GNUNET_PQ_ResultSpec rs[] = {
240 GNUNET_PQ_result_spec_absolute_time("discard_time",
241 &expiration_time),
242 GNUNET_PQ_result_spec_uint32("type",
243 &type),
244 GNUNET_PQ_result_spec_variable_size("value",
245 &data,
246 &data_size),
247 GNUNET_PQ_result_spec_variable_size("path",
248 (void **)&path,
249 &path_len),
250 GNUNET_PQ_result_spec_end
251 };
252
253 if (GNUNET_YES !=
254 GNUNET_PQ_extract_result(result,
255 rs,
256 i))
257 {
258 GNUNET_break(0);
259 return;
260 }
261 if (0 != (path_len % sizeof(struct GNUNET_PeerIdentity)))
262 {
263 GNUNET_break(0);
264 path_len = 0;
265 }
266 path_len %= sizeof(struct GNUNET_PeerIdentity);
267 LOG(GNUNET_ERROR_TYPE_DEBUG,
268 "Found result of size %u bytes and type %u in database\n",
269 (unsigned int)data_size,
270 (unsigned int)type);
271 if ((NULL != hrc->iter) &&
272 (GNUNET_SYSERR ==
273 hrc->iter(hrc->iter_cls,
274 hrc->key,
275 data_size,
276 data,
277 (enum GNUNET_BLOCK_Type)type,
278 expiration_time,
279 path_len,
280 path)))
281 {
282 LOG(GNUNET_ERROR_TYPE_DEBUG,
283 "Ending iteration (client error)\n");
284 GNUNET_PQ_cleanup_result(rs);
285 return;
286 }
287 GNUNET_PQ_cleanup_result(rs);
288 } 271 }
272 path_len %= sizeof(struct GNUNET_PeerIdentity);
273 LOG (GNUNET_ERROR_TYPE_DEBUG,
274 "Found result of size %u bytes and type %u in database\n",
275 (unsigned int) data_size,
276 (unsigned int) type);
277 if ((NULL != hrc->iter) &&
278 (GNUNET_SYSERR ==
279 hrc->iter (hrc->iter_cls,
280 hrc->key,
281 data_size,
282 data,
283 (enum GNUNET_BLOCK_Type) type,
284 expiration_time,
285 path_len,
286 path)))
287 {
288 LOG (GNUNET_ERROR_TYPE_DEBUG,
289 "Ending iteration (client error)\n");
290 GNUNET_PQ_cleanup_result (rs);
291 return;
292 }
293 GNUNET_PQ_cleanup_result (rs);
294 }
289} 295}
290 296
291 297
@@ -301,38 +307,38 @@ handle_results(void *cls,
301 * @return the number of results found 307 * @return the number of results found
302 */ 308 */
303static unsigned int 309static unsigned int
304postgres_plugin_get(void *cls, 310postgres_plugin_get (void *cls,
305 const struct GNUNET_HashCode *key, 311 const struct GNUNET_HashCode *key,
306 enum GNUNET_BLOCK_Type type, 312 enum GNUNET_BLOCK_Type type,
307 GNUNET_DATACACHE_Iterator iter, 313 GNUNET_DATACACHE_Iterator iter,
308 void *iter_cls) 314 void *iter_cls)
309{ 315{
310 struct Plugin *plugin = cls; 316 struct Plugin *plugin = cls;
311 uint32_t type32 = (uint32_t)type; 317 uint32_t type32 = (uint32_t) type;
312 struct GNUNET_TIME_Absolute now; 318 struct GNUNET_TIME_Absolute now;
313 struct GNUNET_PQ_QueryParam paramk[] = { 319 struct GNUNET_PQ_QueryParam paramk[] = {
314 GNUNET_PQ_query_param_auto_from_type(key), 320 GNUNET_PQ_query_param_auto_from_type (key),
315 GNUNET_PQ_query_param_absolute_time(&now), 321 GNUNET_PQ_query_param_absolute_time (&now),
316 GNUNET_PQ_query_param_end 322 GNUNET_PQ_query_param_end
317 }; 323 };
318 struct GNUNET_PQ_QueryParam paramkt[] = { 324 struct GNUNET_PQ_QueryParam paramkt[] = {
319 GNUNET_PQ_query_param_auto_from_type(key), 325 GNUNET_PQ_query_param_auto_from_type (key),
320 GNUNET_PQ_query_param_uint32(&type32), 326 GNUNET_PQ_query_param_uint32 (&type32),
321 GNUNET_PQ_query_param_absolute_time(&now), 327 GNUNET_PQ_query_param_absolute_time (&now),
322 GNUNET_PQ_query_param_end 328 GNUNET_PQ_query_param_end
323 }; 329 };
324 enum GNUNET_DB_QueryStatus res; 330 enum GNUNET_DB_QueryStatus res;
325 struct HandleResultContext hr_ctx; 331 struct HandleResultContext hr_ctx;
326 332
327 now = GNUNET_TIME_absolute_get(); 333 now = GNUNET_TIME_absolute_get ();
328 hr_ctx.iter = iter; 334 hr_ctx.iter = iter;
329 hr_ctx.iter_cls = iter_cls; 335 hr_ctx.iter_cls = iter_cls;
330 hr_ctx.key = key; 336 hr_ctx.key = key;
331 res = GNUNET_PQ_eval_prepared_multi_select(plugin->dbh, 337 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
332 (0 == type) ? "getk" : "getkt", 338 (0 == type) ? "getk" : "getkt",
333 (0 == type) ? paramk : paramkt, 339 (0 == type) ? paramk : paramkt,
334 &handle_results, 340 &handle_results,
335 &hr_ctx); 341 &hr_ctx);
336 if (res < 0) 342 if (res < 0)
337 return 0; 343 return 0;
338 return res; 344 return res;
@@ -347,7 +353,7 @@ postgres_plugin_get(void *cls,
347 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 353 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
348 */ 354 */
349static int 355static int
350postgres_plugin_del(void *cls) 356postgres_plugin_del (void *cls)
351{ 357{
352 struct Plugin *plugin = cls; 358 struct Plugin *plugin = cls;
353 struct GNUNET_PQ_QueryParam pempty[] = { 359 struct GNUNET_PQ_QueryParam pempty[] = {
@@ -357,57 +363,57 @@ postgres_plugin_del(void *cls)
357 uint32_t oid; 363 uint32_t oid;
358 struct GNUNET_HashCode key; 364 struct GNUNET_HashCode key;
359 struct GNUNET_PQ_ResultSpec rs[] = { 365 struct GNUNET_PQ_ResultSpec rs[] = {
360 GNUNET_PQ_result_spec_uint32("len", 366 GNUNET_PQ_result_spec_uint32 ("len",
361 &size), 367 &size),
362 GNUNET_PQ_result_spec_uint32("oid", 368 GNUNET_PQ_result_spec_uint32 ("oid",
363 &oid), 369 &oid),
364 GNUNET_PQ_result_spec_auto_from_type("key", 370 GNUNET_PQ_result_spec_auto_from_type ("key",
365 &key), 371 &key),
366 GNUNET_PQ_result_spec_end 372 GNUNET_PQ_result_spec_end
367 }; 373 };
368 enum GNUNET_DB_QueryStatus res; 374 enum GNUNET_DB_QueryStatus res;
369 struct GNUNET_PQ_QueryParam dparam[] = { 375 struct GNUNET_PQ_QueryParam dparam[] = {
370 GNUNET_PQ_query_param_uint32(&oid), 376 GNUNET_PQ_query_param_uint32 (&oid),
371 GNUNET_PQ_query_param_end 377 GNUNET_PQ_query_param_end
372 }; 378 };
373 struct GNUNET_TIME_Absolute now; 379 struct GNUNET_TIME_Absolute now;
374 struct GNUNET_PQ_QueryParam xparam[] = { 380 struct GNUNET_PQ_QueryParam xparam[] = {
375 GNUNET_PQ_query_param_absolute_time(&now), 381 GNUNET_PQ_query_param_absolute_time (&now),
376 GNUNET_PQ_query_param_end 382 GNUNET_PQ_query_param_end
377 }; 383 };
378 384
379 now = GNUNET_TIME_absolute_get(); 385 now = GNUNET_TIME_absolute_get ();
380 res = GNUNET_PQ_eval_prepared_singleton_select(plugin->dbh, 386 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
381 "getex", 387 "getex",
382 xparam, 388 xparam,
383 rs); 389 rs);
384 if (0 >= res) 390 if (0 >= res)
385 res = GNUNET_PQ_eval_prepared_singleton_select(plugin->dbh, 391 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
386 "getm", 392 "getm",
387 pempty, 393 pempty,
388 rs); 394 rs);
389 if (0 > res) 395 if (0 > res)
390 return GNUNET_SYSERR; 396 return GNUNET_SYSERR;
391 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) 397 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res)
392 { 398 {
393 /* no result */ 399 /* no result */
394 LOG(GNUNET_ERROR_TYPE_DEBUG, 400 LOG (GNUNET_ERROR_TYPE_DEBUG,
395 "Ending iteration (no more results)\n"); 401 "Ending iteration (no more results)\n");
396 return 0; 402 return 0;
397 } 403 }
398 res = GNUNET_PQ_eval_prepared_non_select(plugin->dbh, 404 res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
399 "delrow", 405 "delrow",
400 dparam); 406 dparam);
401 if (0 > res) 407 if (0 > res)
402 { 408 {
403 GNUNET_PQ_cleanup_result(rs); 409 GNUNET_PQ_cleanup_result (rs);
404 return GNUNET_SYSERR; 410 return GNUNET_SYSERR;
405 } 411 }
406 plugin->num_items--; 412 plugin->num_items--;
407 plugin->env->delete_notify(plugin->env->cls, 413 plugin->env->delete_notify (plugin->env->cls,
408 &key, 414 &key,
409 size + OVERHEAD); 415 size + OVERHEAD);
410 GNUNET_PQ_cleanup_result(rs); 416 GNUNET_PQ_cleanup_result (rs);
411 return GNUNET_OK; 417 return GNUNET_OK;
412} 418}
413 419
@@ -421,9 +427,9 @@ postgres_plugin_del(void *cls)
421 * @return the number of results found, zero (datacache empty) or one 427 * @return the number of results found, zero (datacache empty) or one
422 */ 428 */
423static unsigned int 429static unsigned int
424postgres_plugin_get_random(void *cls, 430postgres_plugin_get_random (void *cls,
425 GNUNET_DATACACHE_Iterator iter, 431 GNUNET_DATACACHE_Iterator iter,
426 void *iter_cls) 432 void *iter_cls)
427{ 433{
428 struct Plugin *plugin = cls; 434 struct Plugin *plugin = cls;
429 uint32_t off; 435 uint32_t off;
@@ -437,23 +443,23 @@ postgres_plugin_get_random(void *cls,
437 uint32_t type; 443 uint32_t type;
438 enum GNUNET_DB_QueryStatus res; 444 enum GNUNET_DB_QueryStatus res;
439 struct GNUNET_PQ_QueryParam params[] = { 445 struct GNUNET_PQ_QueryParam params[] = {
440 GNUNET_PQ_query_param_absolute_time(&now), 446 GNUNET_PQ_query_param_absolute_time (&now),
441 GNUNET_PQ_query_param_uint32(&off), 447 GNUNET_PQ_query_param_uint32 (&off),
442 GNUNET_PQ_query_param_end 448 GNUNET_PQ_query_param_end
443 }; 449 };
444 struct GNUNET_PQ_ResultSpec rs[] = { 450 struct GNUNET_PQ_ResultSpec rs[] = {
445 GNUNET_PQ_result_spec_absolute_time("discard_time", 451 GNUNET_PQ_result_spec_absolute_time ("discard_time",
446 &expiration_time), 452 &expiration_time),
447 GNUNET_PQ_result_spec_uint32("type", 453 GNUNET_PQ_result_spec_uint32 ("type",
448 &type), 454 &type),
449 GNUNET_PQ_result_spec_variable_size("value", 455 GNUNET_PQ_result_spec_variable_size ("value",
450 &data, 456 &data,
451 &data_size), 457 &data_size),
452 GNUNET_PQ_result_spec_variable_size("path", 458 GNUNET_PQ_result_spec_variable_size ("path",
453 (void **)&path, 459 (void **) &path,
454 &path_len), 460 &path_len),
455 GNUNET_PQ_result_spec_auto_from_type("key", 461 GNUNET_PQ_result_spec_auto_from_type ("key",
456 &key), 462 &key),
457 GNUNET_PQ_result_spec_end 463 GNUNET_PQ_result_spec_end
458 }; 464 };
459 465
@@ -461,43 +467,43 @@ postgres_plugin_get_random(void *cls,
461 return 0; 467 return 0;
462 if (NULL == iter) 468 if (NULL == iter)
463 return 1; 469 return 1;
464 now = GNUNET_TIME_absolute_get(); 470 now = GNUNET_TIME_absolute_get ();
465 off = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, 471 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
466 plugin->num_items); 472 plugin->num_items);
467 res = GNUNET_PQ_eval_prepared_singleton_select(plugin->dbh, 473 res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh,
468 "get_random", 474 "get_random",
469 params, 475 params,
470 rs); 476 rs);
471 if (0 > res) 477 if (0 > res)
472 { 478 {
473 GNUNET_break(0); 479 GNUNET_break (0);
474 return 0; 480 return 0;
475 } 481 }
476 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) 482 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res)
477 { 483 {
478 GNUNET_break(0); 484 GNUNET_break (0);
479 return 0; 485 return 0;
480 } 486 }
481 if (0 != (path_len % sizeof(struct GNUNET_PeerIdentity))) 487 if (0 != (path_len % sizeof(struct GNUNET_PeerIdentity)))
482 { 488 {
483 GNUNET_break(0); 489 GNUNET_break (0);
484 path_len = 0; 490 path_len = 0;
485 } 491 }
486 path_len %= sizeof(struct GNUNET_PeerIdentity); 492 path_len %= sizeof(struct GNUNET_PeerIdentity);
487 LOG(GNUNET_ERROR_TYPE_DEBUG, 493 LOG (GNUNET_ERROR_TYPE_DEBUG,
488 "Found random value with key %s of size %u bytes and type %u in database\n", 494 "Found random value with key %s of size %u bytes and type %u in database\n",
489 GNUNET_h2s(&key), 495 GNUNET_h2s (&key),
490 (unsigned int)data_size, 496 (unsigned int) data_size,
491 (unsigned int)type); 497 (unsigned int) type);
492 (void)iter(iter_cls, 498 (void) iter (iter_cls,
493 &key, 499 &key,
494 data_size, 500 data_size,
495 data, 501 data,
496 (enum GNUNET_BLOCK_Type)type, 502 (enum GNUNET_BLOCK_Type) type,
497 expiration_time, 503 expiration_time,
498 path_len, 504 path_len,
499 path); 505 path);
500 GNUNET_PQ_cleanup_result(rs); 506 GNUNET_PQ_cleanup_result (rs);
501 return 1; 507 return 1;
502} 508}
503 509
@@ -505,7 +511,8 @@ postgres_plugin_get_random(void *cls,
505/** 511/**
506 * Closure for #extract_result_cb. 512 * Closure for #extract_result_cb.
507 */ 513 */
508struct ExtractResultContext { 514struct ExtractResultContext
515{
509 /** 516 /**
510 * Function to call for each result found. 517 * Function to call for each result found.
511 */ 518 */
@@ -528,74 +535,74 @@ struct ExtractResultContext {
528 * @param num_result the number of results in @a result 535 * @param num_result the number of results in @a result
529 */ 536 */
530static void 537static void
531extract_result_cb(void *cls, 538extract_result_cb (void *cls,
532 PGresult *result, 539 PGresult *result,
533 unsigned int num_results) 540 unsigned int num_results)
534{ 541{
535 struct ExtractResultContext *erc = cls; 542 struct ExtractResultContext *erc = cls;
536 543
537 if (NULL == erc->iter) 544 if (NULL == erc->iter)
538 return; 545 return;
539 for (unsigned int i = 0; i < num_results; i++) 546 for (unsigned int i = 0; i < num_results; i++)
547 {
548 struct GNUNET_TIME_Absolute expiration_time;
549 uint32_t type;
550 void *data;
551 size_t data_size;
552 struct GNUNET_PeerIdentity *path;
553 size_t path_len;
554 struct GNUNET_HashCode key;
555 struct GNUNET_PQ_ResultSpec rs[] = {
556 GNUNET_PQ_result_spec_absolute_time ("",
557 &expiration_time),
558 GNUNET_PQ_result_spec_uint32 ("type",
559 &type),
560 GNUNET_PQ_result_spec_variable_size ("value",
561 &data,
562 &data_size),
563 GNUNET_PQ_result_spec_variable_size ("path",
564 (void **) &path,
565 &path_len),
566 GNUNET_PQ_result_spec_auto_from_type ("key",
567 &key),
568 GNUNET_PQ_result_spec_end
569 };
570
571 if (GNUNET_YES !=
572 GNUNET_PQ_extract_result (result,
573 rs,
574 i))
540 { 575 {
541 struct GNUNET_TIME_Absolute expiration_time; 576 GNUNET_break (0);
542 uint32_t type; 577 return;
543 void *data;
544 size_t data_size;
545 struct GNUNET_PeerIdentity *path;
546 size_t path_len;
547 struct GNUNET_HashCode key;
548 struct GNUNET_PQ_ResultSpec rs[] = {
549 GNUNET_PQ_result_spec_absolute_time("",
550 &expiration_time),
551 GNUNET_PQ_result_spec_uint32("type",
552 &type),
553 GNUNET_PQ_result_spec_variable_size("value",
554 &data,
555 &data_size),
556 GNUNET_PQ_result_spec_variable_size("path",
557 (void **)&path,
558 &path_len),
559 GNUNET_PQ_result_spec_auto_from_type("key",
560 &key),
561 GNUNET_PQ_result_spec_end
562 };
563
564 if (GNUNET_YES !=
565 GNUNET_PQ_extract_result(result,
566 rs,
567 i))
568 {
569 GNUNET_break(0);
570 return;
571 }
572 if (0 != (path_len % sizeof(struct GNUNET_PeerIdentity)))
573 {
574 GNUNET_break(0);
575 path_len = 0;
576 }
577 path_len %= sizeof(struct GNUNET_PeerIdentity);
578 LOG(GNUNET_ERROR_TYPE_DEBUG,
579 "Found result of size %u bytes and type %u in database\n",
580 (unsigned int)data_size,
581 (unsigned int)type);
582 if (GNUNET_SYSERR ==
583 erc->iter(erc->iter_cls,
584 &key,
585 data_size,
586 data,
587 (enum GNUNET_BLOCK_Type)type,
588 expiration_time,
589 path_len,
590 path))
591 {
592 LOG(GNUNET_ERROR_TYPE_DEBUG,
593 "Ending iteration (client error)\n");
594 GNUNET_PQ_cleanup_result(rs);
595 break;
596 }
597 GNUNET_PQ_cleanup_result(rs);
598 } 578 }
579 if (0 != (path_len % sizeof(struct GNUNET_PeerIdentity)))
580 {
581 GNUNET_break (0);
582 path_len = 0;
583 }
584 path_len %= sizeof(struct GNUNET_PeerIdentity);
585 LOG (GNUNET_ERROR_TYPE_DEBUG,
586 "Found result of size %u bytes and type %u in database\n",
587 (unsigned int) data_size,
588 (unsigned int) type);
589 if (GNUNET_SYSERR ==
590 erc->iter (erc->iter_cls,
591 &key,
592 data_size,
593 data,
594 (enum GNUNET_BLOCK_Type) type,
595 expiration_time,
596 path_len,
597 path))
598 {
599 LOG (GNUNET_ERROR_TYPE_DEBUG,
600 "Ending iteration (client error)\n");
601 GNUNET_PQ_cleanup_result (rs);
602 break;
603 }
604 GNUNET_PQ_cleanup_result (rs);
605 }
599} 606}
600 607
601 608
@@ -613,19 +620,19 @@ extract_result_cb(void *cls,
613 * @return the number of results found 620 * @return the number of results found
614 */ 621 */
615static unsigned int 622static unsigned int
616postgres_plugin_get_closest(void *cls, 623postgres_plugin_get_closest (void *cls,
617 const struct GNUNET_HashCode *key, 624 const struct GNUNET_HashCode *key,
618 unsigned int num_results, 625 unsigned int num_results,
619 GNUNET_DATACACHE_Iterator iter, 626 GNUNET_DATACACHE_Iterator iter,
620 void *iter_cls) 627 void *iter_cls)
621{ 628{
622 struct Plugin *plugin = cls; 629 struct Plugin *plugin = cls;
623 uint32_t num_results32 = (uint32_t)num_results; 630 uint32_t num_results32 = (uint32_t) num_results;
624 struct GNUNET_TIME_Absolute now; 631 struct GNUNET_TIME_Absolute now;
625 struct GNUNET_PQ_QueryParam params[] = { 632 struct GNUNET_PQ_QueryParam params[] = {
626 GNUNET_PQ_query_param_auto_from_type(key), 633 GNUNET_PQ_query_param_auto_from_type (key),
627 GNUNET_PQ_query_param_absolute_time(&now), 634 GNUNET_PQ_query_param_absolute_time (&now),
628 GNUNET_PQ_query_param_uint32(&num_results32), 635 GNUNET_PQ_query_param_uint32 (&num_results32),
629 GNUNET_PQ_query_param_end 636 GNUNET_PQ_query_param_end
630 }; 637 };
631 enum GNUNET_DB_QueryStatus res; 638 enum GNUNET_DB_QueryStatus res;
@@ -633,25 +640,25 @@ postgres_plugin_get_closest(void *cls,
633 640
634 erc.iter = iter; 641 erc.iter = iter;
635 erc.iter_cls = iter_cls; 642 erc.iter_cls = iter_cls;
636 now = GNUNET_TIME_absolute_get(); 643 now = GNUNET_TIME_absolute_get ();
637 res = GNUNET_PQ_eval_prepared_multi_select(plugin->dbh, 644 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
638 "get_closest", 645 "get_closest",
639 params, 646 params,
640 &extract_result_cb, 647 &extract_result_cb,
641 &erc); 648 &erc);
642 if (0 > res) 649 if (0 > res)
643 { 650 {
644 LOG(GNUNET_ERROR_TYPE_DEBUG, 651 LOG (GNUNET_ERROR_TYPE_DEBUG,
645 "Ending iteration (postgres error)\n"); 652 "Ending iteration (postgres error)\n");
646 return 0; 653 return 0;
647 } 654 }
648 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) 655 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res)
649 { 656 {
650 /* no result */ 657 /* no result */
651 LOG(GNUNET_ERROR_TYPE_DEBUG, 658 LOG (GNUNET_ERROR_TYPE_DEBUG,
652 "Ending iteration (no more results)\n"); 659 "Ending iteration (no more results)\n");
653 return 0; 660 return 0;
654 } 661 }
655 return res; 662 return res;
656} 663}
657 664
@@ -663,30 +670,30 @@ postgres_plugin_get_closest(void *cls,
663 * @return the plugin's closure (our `struct Plugin`) 670 * @return the plugin's closure (our `struct Plugin`)
664 */ 671 */
665void * 672void *
666libgnunet_plugin_datacache_postgres_init(void *cls) 673libgnunet_plugin_datacache_postgres_init (void *cls)
667{ 674{
668 struct GNUNET_DATACACHE_PluginEnvironment *env = cls; 675 struct GNUNET_DATACACHE_PluginEnvironment *env = cls;
669 struct GNUNET_DATACACHE_PluginFunctions *api; 676 struct GNUNET_DATACACHE_PluginFunctions *api;
670 struct Plugin *plugin; 677 struct Plugin *plugin;
671 678
672 plugin = GNUNET_new(struct Plugin); 679 plugin = GNUNET_new (struct Plugin);
673 plugin->env = env; 680 plugin->env = env;
674 681
675 if (GNUNET_OK != init_connection(plugin)) 682 if (GNUNET_OK != init_connection (plugin))
676 { 683 {
677 GNUNET_free(plugin); 684 GNUNET_free (plugin);
678 return NULL; 685 return NULL;
679 } 686 }
680 687
681 api = GNUNET_new(struct GNUNET_DATACACHE_PluginFunctions); 688 api = GNUNET_new (struct GNUNET_DATACACHE_PluginFunctions);
682 api->cls = plugin; 689 api->cls = plugin;
683 api->get = &postgres_plugin_get; 690 api->get = &postgres_plugin_get;
684 api->put = &postgres_plugin_put; 691 api->put = &postgres_plugin_put;
685 api->del = &postgres_plugin_del; 692 api->del = &postgres_plugin_del;
686 api->get_random = &postgres_plugin_get_random; 693 api->get_random = &postgres_plugin_get_random;
687 api->get_closest = &postgres_plugin_get_closest; 694 api->get_closest = &postgres_plugin_get_closest;
688 LOG(GNUNET_ERROR_TYPE_INFO, 695 LOG (GNUNET_ERROR_TYPE_INFO,
689 "Postgres datacache running\n"); 696 "Postgres datacache running\n");
690 return api; 697 return api;
691} 698}
692 699
@@ -698,14 +705,14 @@ libgnunet_plugin_datacache_postgres_init(void *cls)
698 * @return NULL 705 * @return NULL
699 */ 706 */
700void * 707void *
701libgnunet_plugin_datacache_postgres_done(void *cls) 708libgnunet_plugin_datacache_postgres_done (void *cls)
702{ 709{
703 struct GNUNET_DATACACHE_PluginFunctions *api = cls; 710 struct GNUNET_DATACACHE_PluginFunctions *api = cls;
704 struct Plugin *plugin = api->cls; 711 struct Plugin *plugin = api->cls;
705 712
706 PQfinish(plugin->dbh); 713 PQfinish (plugin->dbh);
707 GNUNET_free(plugin); 714 GNUNET_free (plugin);
708 GNUNET_free(api); 715 GNUNET_free (api);
709 return NULL; 716 return NULL;
710} 717}
711 718