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