aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_namestore_postgres.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-10-05 15:09:28 +0200
committerChristian Grothoff <christian@grothoff.org>2019-10-05 15:09:28 +0200
commitc4e9ba925ffd758aaa3feee2ccfc0b76f26fe207 (patch)
treecac3ce030d77b4cbe7c7dc62ed58cfe6d24f73e1 /src/namestore/plugin_namestore_postgres.c
parentfbb71d527c7d6babf269a8fefce1db291b9f7068 (diff)
downloadgnunet-c4e9ba925ffd758aaa3feee2ccfc0b76f26fe207.tar.gz
gnunet-c4e9ba925ffd758aaa3feee2ccfc0b76f26fe207.zip
global reindent, now with uncrustify hook enabled
Diffstat (limited to 'src/namestore/plugin_namestore_postgres.c')
-rw-r--r--src/namestore/plugin_namestore_postgres.c630
1 files changed, 320 insertions, 310 deletions
diff --git a/src/namestore/plugin_namestore_postgres.c b/src/namestore/plugin_namestore_postgres.c
index ac35b01b4..5148ca0f5 100644
--- a/src/namestore/plugin_namestore_postgres.c
+++ b/src/namestore/plugin_namestore_postgres.c
@@ -31,13 +31,14 @@
31#include "namestore.h" 31#include "namestore.h"
32 32
33 33
34#define LOG(kind, ...) GNUNET_log_from(kind, "namestore-postgres", __VA_ARGS__) 34#define LOG(kind, ...) GNUNET_log_from (kind, "namestore-postgres", __VA_ARGS__)
35 35
36 36
37/** 37/**
38 * Context for all functions in this plugin. 38 * Context for all functions in this plugin.
39 */ 39 */
40struct Plugin { 40struct Plugin
41{
41 /** 42 /**
42 * Our configuration. 43 * Our configuration.
43 */ 44 */
@@ -59,136 +60,137 @@ struct Plugin {
59 * @return #GNUNET_OK on success 60 * @return #GNUNET_OK on success
60 */ 61 */
61static int 62static int
62database_setup(struct Plugin *plugin) 63database_setup (struct Plugin *plugin)
63{ 64{
64 struct GNUNET_PQ_ExecuteStatement es_temporary = 65 struct GNUNET_PQ_ExecuteStatement es_temporary =
65 GNUNET_PQ_make_execute("CREATE TEMPORARY TABLE IF NOT EXISTS ns098records (" 66 GNUNET_PQ_make_execute (
66 " seq BIGSERIAL PRIMARY KEY," 67 "CREATE TEMPORARY TABLE IF NOT EXISTS ns098records ("
67 " zone_private_key BYTEA NOT NULL DEFAULT ''," 68 " seq BIGSERIAL PRIMARY KEY,"
68 " pkey BYTEA DEFAULT ''," 69 " zone_private_key BYTEA NOT NULL DEFAULT '',"
69 " rvalue BYTEA NOT NULL DEFAULT ''," 70 " pkey BYTEA DEFAULT '',"
70 " record_count INTEGER NOT NULL DEFAULT 0," 71 " rvalue BYTEA NOT NULL DEFAULT '',"
71 " record_data BYTEA NOT NULL DEFAULT ''," 72 " record_count INTEGER NOT NULL DEFAULT 0,"
72 " label TEXT NOT NULL DEFAULT ''," 73 " record_data BYTEA NOT NULL DEFAULT '',"
73 " CONSTRAINT zl UNIQUE (zone_private_key,label)" 74 " label TEXT NOT NULL DEFAULT '',"
74 ")" 75 " CONSTRAINT zl UNIQUE (zone_private_key,label)"
75 "WITH OIDS"); 76 ")"
77 "WITH OIDS");
76 struct GNUNET_PQ_ExecuteStatement es_default = 78 struct GNUNET_PQ_ExecuteStatement es_default =
77 GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS ns098records (" 79 GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
78 " seq BIGSERIAL PRIMARY KEY," 80 " seq BIGSERIAL PRIMARY KEY,"
79 " zone_private_key BYTEA NOT NULL DEFAULT ''," 81 " zone_private_key BYTEA NOT NULL DEFAULT '',"
80 " pkey BYTEA DEFAULT ''," 82 " pkey BYTEA DEFAULT '',"
81 " rvalue BYTEA NOT NULL DEFAULT ''," 83 " rvalue BYTEA NOT NULL DEFAULT '',"
82 " record_count INTEGER NOT NULL DEFAULT 0," 84 " record_count INTEGER NOT NULL DEFAULT 0,"
83 " record_data BYTEA NOT NULL DEFAULT ''," 85 " record_data BYTEA NOT NULL DEFAULT '',"
84 " label TEXT NOT NULL DEFAULT ''," 86 " label TEXT NOT NULL DEFAULT '',"
85 " CONSTRAINT zl UNIQUE (zone_private_key,label)" 87 " CONSTRAINT zl UNIQUE (zone_private_key,label)"
86 ")" 88 ")"
87 "WITH OIDS"); 89 "WITH OIDS");
88 const struct GNUNET_PQ_ExecuteStatement *cr; 90 const struct GNUNET_PQ_ExecuteStatement *cr;
89 91
90 plugin->dbh = GNUNET_PQ_connect_with_cfg(plugin->cfg, 92 plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg,
91 "namestore-postgres"); 93 "namestore-postgres");
92 if (NULL == plugin->dbh) 94 if (NULL == plugin->dbh)
93 return GNUNET_SYSERR; 95 return GNUNET_SYSERR;
94 if (GNUNET_YES == 96 if (GNUNET_YES ==
95 GNUNET_CONFIGURATION_get_value_yesno(plugin->cfg, 97 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
96 "namestore-postgres", 98 "namestore-postgres",
97 "ASYNC_COMMIT")) 99 "ASYNC_COMMIT"))
98 { 100 {
99 struct GNUNET_PQ_ExecuteStatement es[] = { 101 struct GNUNET_PQ_ExecuteStatement es[] = {
100 GNUNET_PQ_make_try_execute("SET synchronous_commit TO off"), 102 GNUNET_PQ_make_try_execute ("SET synchronous_commit TO off"),
101 GNUNET_PQ_EXECUTE_STATEMENT_END 103 GNUNET_PQ_EXECUTE_STATEMENT_END
102 }; 104 };
103 105
104 if (GNUNET_OK != 106 if (GNUNET_OK !=
105 GNUNET_PQ_exec_statements(plugin->dbh, 107 GNUNET_PQ_exec_statements (plugin->dbh,
106 es)) 108 es))
107 {
108 PQfinish(plugin->dbh);
109 plugin->dbh = NULL;
110 return GNUNET_SYSERR;
111 }
112 }
113 if (GNUNET_YES ==
114 GNUNET_CONFIGURATION_get_value_yesno(plugin->cfg,
115 "namestore-postgres",
116 "TEMPORARY_TABLE"))
117 { 109 {
118 cr = &es_temporary; 110 PQfinish (plugin->dbh);
111 plugin->dbh = NULL;
112 return GNUNET_SYSERR;
119 } 113 }
114 }
115 if (GNUNET_YES ==
116 GNUNET_CONFIGURATION_get_value_yesno (plugin->cfg,
117 "namestore-postgres",
118 "TEMPORARY_TABLE"))
119 {
120 cr = &es_temporary;
121 }
120 else 122 else
121 { 123 {
122 cr = &es_default; 124 cr = &es_default;
123 } 125 }
124 126
125 { 127 {
126 struct GNUNET_PQ_ExecuteStatement es[] = { 128 struct GNUNET_PQ_ExecuteStatement es[] = {
127 *cr, 129 *cr,
128 GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS ir_pkey_reverse " 130 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse "
129 "ON ns098records (zone_private_key,pkey)"), 131 "ON ns098records (zone_private_key,pkey)"),
130 GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS ir_pkey_iter " 132 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter "
131 "ON ns098records (zone_private_key,seq)"), 133 "ON ns098records (zone_private_key,seq)"),
132 GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS ir_label " 134 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_label "
133 "ON ns098records (label)"), 135 "ON ns098records (label)"),
134 GNUNET_PQ_make_try_execute("CREATE INDEX IF NOT EXISTS zone_label " 136 GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS zone_label "
135 "ON ns098records (zone_private_key,label)"), 137 "ON ns098records (zone_private_key,label)"),
136 GNUNET_PQ_EXECUTE_STATEMENT_END 138 GNUNET_PQ_EXECUTE_STATEMENT_END
137 }; 139 };
138 140
139 if (GNUNET_OK != 141 if (GNUNET_OK !=
140 GNUNET_PQ_exec_statements(plugin->dbh, 142 GNUNET_PQ_exec_statements (plugin->dbh,
141 es)) 143 es))
142 { 144 {
143 PQfinish(plugin->dbh); 145 PQfinish (plugin->dbh);
144 plugin->dbh = NULL; 146 plugin->dbh = NULL;
145 return GNUNET_SYSERR; 147 return GNUNET_SYSERR;
146 } 148 }
147 } 149 }
148 150
149 { 151 {
150 struct GNUNET_PQ_PreparedStatement ps[] = { 152 struct GNUNET_PQ_PreparedStatement ps[] = {
151 GNUNET_PQ_make_prepare("store_records", 153 GNUNET_PQ_make_prepare ("store_records",
152 "INSERT INTO ns098records" 154 "INSERT INTO ns098records"
153 " (zone_private_key, pkey, rvalue, record_count, record_data, label)" 155 " (zone_private_key, pkey, rvalue, record_count, record_data, label)"
154 " VALUES ($1, $2, $3, $4, $5, $6)" 156 " VALUES ($1, $2, $3, $4, $5, $6)"
155 " ON CONFLICT ON CONSTRAINT zl" 157 " ON CONFLICT ON CONSTRAINT zl"
156 " DO UPDATE" 158 " DO UPDATE"
157 " SET pkey=$2,rvalue=$3,record_count=$4,record_data=$5" 159 " SET pkey=$2,rvalue=$3,record_count=$4,record_data=$5"
158 " WHERE ns098records.zone_private_key = $1" 160 " WHERE ns098records.zone_private_key = $1"
159 " AND ns098records.label = $6", 161 " AND ns098records.label = $6",
160 6), 162 6),
161 GNUNET_PQ_make_prepare("delete_records", 163 GNUNET_PQ_make_prepare ("delete_records",
162 "DELETE FROM ns098records " 164 "DELETE FROM ns098records "
163 "WHERE zone_private_key=$1 AND label=$2", 165 "WHERE zone_private_key=$1 AND label=$2",
164 2), 166 2),
165 GNUNET_PQ_make_prepare("zone_to_name", 167 GNUNET_PQ_make_prepare ("zone_to_name",
166 "SELECT seq,record_count,record_data,label FROM ns098records" 168 "SELECT seq,record_count,record_data,label FROM ns098records"
167 " WHERE zone_private_key=$1 AND pkey=$2", 169 " WHERE zone_private_key=$1 AND pkey=$2",
168 2), 170 2),
169 GNUNET_PQ_make_prepare("iterate_zone", 171 GNUNET_PQ_make_prepare ("iterate_zone",
170 "SELECT seq,record_count,record_data,label FROM ns098records " 172 "SELECT seq,record_count,record_data,label FROM ns098records "
171 "WHERE zone_private_key=$1 AND seq > $2 ORDER BY seq ASC LIMIT $3", 173 "WHERE zone_private_key=$1 AND seq > $2 ORDER BY seq ASC LIMIT $3",
172 3), 174 3),
173 GNUNET_PQ_make_prepare("iterate_all_zones", 175 GNUNET_PQ_make_prepare ("iterate_all_zones",
174 "SELECT seq,record_count,record_data,label,zone_private_key" 176 "SELECT seq,record_count,record_data,label,zone_private_key"
175 " FROM ns098records WHERE seq > $1 ORDER BY seq ASC LIMIT $2", 177 " FROM ns098records WHERE seq > $1 ORDER BY seq ASC LIMIT $2",
176 2), 178 2),
177 GNUNET_PQ_make_prepare("lookup_label", 179 GNUNET_PQ_make_prepare ("lookup_label",
178 "SELECT seq,record_count,record_data,label " 180 "SELECT seq,record_count,record_data,label "
179 "FROM ns098records WHERE zone_private_key=$1 AND label=$2", 181 "FROM ns098records WHERE zone_private_key=$1 AND label=$2",
180 2), 182 2),
181 GNUNET_PQ_PREPARED_STATEMENT_END 183 GNUNET_PQ_PREPARED_STATEMENT_END
182 }; 184 };
183 185
184 if (GNUNET_OK != 186 if (GNUNET_OK !=
185 GNUNET_PQ_prepare_statements(plugin->dbh, 187 GNUNET_PQ_prepare_statements (plugin->dbh,
186 ps)) 188 ps))
187 { 189 {
188 PQfinish(plugin->dbh); 190 PQfinish (plugin->dbh);
189 plugin->dbh = NULL; 191 plugin->dbh = NULL;
190 return GNUNET_SYSERR; 192 return GNUNET_SYSERR;
191 } 193 }
192 } 194 }
193 195
194 return GNUNET_OK; 196 return GNUNET_OK;
@@ -207,97 +209,99 @@ database_setup(struct Plugin *plugin)
207 * @return #GNUNET_OK on success, else #GNUNET_SYSERR 209 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
208 */ 210 */
209static int 211static int
210namestore_postgres_store_records(void *cls, 212namestore_postgres_store_records (void *cls,
211 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, 213 const struct
212 const char *label, 214 GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
213 unsigned int rd_count, 215 const char *label,
214 const struct GNUNET_GNSRECORD_Data *rd) 216 unsigned int rd_count,
217 const struct GNUNET_GNSRECORD_Data *rd)
215{ 218{
216 struct Plugin *plugin = cls; 219 struct Plugin *plugin = cls;
217 struct GNUNET_CRYPTO_EcdsaPublicKey pkey; 220 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
218 uint64_t rvalue; 221 uint64_t rvalue;
219 uint32_t rd_count32 = (uint32_t)rd_count; 222 uint32_t rd_count32 = (uint32_t) rd_count;
220 ssize_t data_size; 223 ssize_t data_size;
221 224
222 memset(&pkey, 225 memset (&pkey,
223 0, 226 0,
224 sizeof(pkey)); 227 sizeof(pkey));
225 for (unsigned int i = 0; i < rd_count; i++) 228 for (unsigned int i = 0; i < rd_count; i++)
226 if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type) 229 if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type)
227 {
228 GNUNET_break(sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) == rd[i].data_size);
229 GNUNET_memcpy(&pkey,
230 rd[i].data,
231 rd[i].data_size);
232 break;
233 }
234 rvalue = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK,
235 UINT64_MAX);
236 data_size = GNUNET_GNSRECORD_records_get_size(rd_count,
237 rd);
238 if (data_size < 0)
239 { 230 {
240 GNUNET_break(0); 231 GNUNET_break (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) ==
241 return GNUNET_SYSERR; 232 rd[i].data_size);
233 GNUNET_memcpy (&pkey,
234 rd[i].data,
235 rd[i].data_size);
236 break;
242 } 237 }
238 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
239 UINT64_MAX);
240 data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
241 rd);
242 if (data_size < 0)
243 {
244 GNUNET_break (0);
245 return GNUNET_SYSERR;
246 }
243 if (data_size >= UINT16_MAX) 247 if (data_size >= UINT16_MAX)
244 { 248 {
245 GNUNET_break(0); 249 GNUNET_break (0);
246 return GNUNET_SYSERR; 250 return GNUNET_SYSERR;
247 } 251 }
248 /* if record set is empty, delete existing records */ 252 /* if record set is empty, delete existing records */
249 if (0 == rd_count) 253 if (0 == rd_count)
254 {
255 struct GNUNET_PQ_QueryParam params[] = {
256 GNUNET_PQ_query_param_auto_from_type (zone_key),
257 GNUNET_PQ_query_param_string (label),
258 GNUNET_PQ_query_param_end
259 };
260 enum GNUNET_DB_QueryStatus res;
261
262 res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
263 "delete_records",
264 params);
265 if ((GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != res) &&
266 (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != res))
250 { 267 {
251 struct GNUNET_PQ_QueryParam params[] = { 268 GNUNET_break (0);
252 GNUNET_PQ_query_param_auto_from_type(zone_key), 269 return GNUNET_SYSERR;
253 GNUNET_PQ_query_param_string(label),
254 GNUNET_PQ_query_param_end
255 };
256 enum GNUNET_DB_QueryStatus res;
257
258 res = GNUNET_PQ_eval_prepared_non_select(plugin->dbh,
259 "delete_records",
260 params);
261 if ((GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != res) &&
262 (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != res))
263 {
264 GNUNET_break(0);
265 return GNUNET_SYSERR;
266 }
267 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG,
268 "postgres",
269 "Record deleted\n");
270 return GNUNET_OK;
271 } 270 }
271 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
272 "postgres",
273 "Record deleted\n");
274 return GNUNET_OK;
275 }
272 /* otherwise, UPSERT (i.e. UPDATE if exists, otherwise INSERT) */ 276 /* otherwise, UPSERT (i.e. UPDATE if exists, otherwise INSERT) */
273 { 277 {
274 char data[data_size]; 278 char data[data_size];
275 struct GNUNET_PQ_QueryParam params[] = { 279 struct GNUNET_PQ_QueryParam params[] = {
276 GNUNET_PQ_query_param_auto_from_type(zone_key), 280 GNUNET_PQ_query_param_auto_from_type (zone_key),
277 GNUNET_PQ_query_param_auto_from_type(&pkey), 281 GNUNET_PQ_query_param_auto_from_type (&pkey),
278 GNUNET_PQ_query_param_uint64(&rvalue), 282 GNUNET_PQ_query_param_uint64 (&rvalue),
279 GNUNET_PQ_query_param_uint32(&rd_count32), 283 GNUNET_PQ_query_param_uint32 (&rd_count32),
280 GNUNET_PQ_query_param_fixed_size(data, data_size), 284 GNUNET_PQ_query_param_fixed_size (data, data_size),
281 GNUNET_PQ_query_param_string(label), 285 GNUNET_PQ_query_param_string (label),
282 GNUNET_PQ_query_param_end 286 GNUNET_PQ_query_param_end
283 }; 287 };
284 enum GNUNET_DB_QueryStatus res; 288 enum GNUNET_DB_QueryStatus res;
285 ssize_t ret; 289 ssize_t ret;
286 290
287 ret = GNUNET_GNSRECORD_records_serialize(rd_count, 291 ret = GNUNET_GNSRECORD_records_serialize (rd_count,
288 rd, 292 rd,
289 data_size, 293 data_size,
290 data); 294 data);
291 if ((ret < 0) || 295 if ((ret < 0) ||
292 (data_size != ret)) 296 (data_size != ret))
293 { 297 {
294 GNUNET_break(0); 298 GNUNET_break (0);
295 return GNUNET_SYSERR; 299 return GNUNET_SYSERR;
296 } 300 }
297 301
298 res = GNUNET_PQ_eval_prepared_non_select(plugin->dbh, 302 res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh,
299 "store_records", 303 "store_records",
300 params); 304 params);
301 if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != res) 305 if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != res)
302 return GNUNET_SYSERR; 306 return GNUNET_SYSERR;
303 } 307 }
@@ -308,7 +312,8 @@ namestore_postgres_store_records(void *cls,
308/** 312/**
309 * Closure for #parse_result_call_iterator. 313 * Closure for #parse_result_call_iterator.
310 */ 314 */
311struct ParserContext { 315struct ParserContext
316{
312 /** 317 /**
313 * Function to call for each result. 318 * Function to call for each result.
314 */ 319 */
@@ -341,81 +346,81 @@ struct ParserContext {
341 * @param num_result the number of results in @a result 346 * @param num_result the number of results in @a result
342 */ 347 */
343static void 348static void
344parse_result_call_iterator(void *cls, 349parse_result_call_iterator (void *cls,
345 PGresult *res, 350 PGresult *res,
346 unsigned int num_results) 351 unsigned int num_results)
347{ 352{
348 struct ParserContext *pc = cls; 353 struct ParserContext *pc = cls;
349 354
350 if (NULL == pc->iter) 355 if (NULL == pc->iter)
351 return; /* no need to do more work */ 356 return; /* no need to do more work */
352 for (unsigned int i = 0; i < num_results; i++) 357 for (unsigned int i = 0; i < num_results; i++)
358 {
359 uint64_t serial;
360 void *data;
361 size_t data_size;
362 uint32_t record_count;
363 char *label;
364 struct GNUNET_CRYPTO_EcdsaPrivateKey zk;
365 struct GNUNET_PQ_ResultSpec rs_with_zone[] = {
366 GNUNET_PQ_result_spec_uint64 ("seq", &serial),
367 GNUNET_PQ_result_spec_uint32 ("record_count", &record_count),
368 GNUNET_PQ_result_spec_variable_size ("record_data", &data, &data_size),
369 GNUNET_PQ_result_spec_string ("label", &label),
370 GNUNET_PQ_result_spec_auto_from_type ("zone_private_key", &zk),
371 GNUNET_PQ_result_spec_end
372 };
373 struct GNUNET_PQ_ResultSpec rs_without_zone[] = {
374 GNUNET_PQ_result_spec_uint64 ("seq", &serial),
375 GNUNET_PQ_result_spec_uint32 ("record_count", &record_count),
376 GNUNET_PQ_result_spec_variable_size ("record_data", &data, &data_size),
377 GNUNET_PQ_result_spec_string ("label", &label),
378 GNUNET_PQ_result_spec_end
379 };
380 struct GNUNET_PQ_ResultSpec *rs;
381
382 rs = (NULL == pc->zone_key) ? rs_with_zone : rs_without_zone;
383 if (GNUNET_YES !=
384 GNUNET_PQ_extract_result (res,
385 rs,
386 i))
353 { 387 {
354 uint64_t serial; 388 GNUNET_break (0);
355 void *data; 389 return;
356 size_t data_size; 390 }
357 uint32_t record_count;
358 char *label;
359 struct GNUNET_CRYPTO_EcdsaPrivateKey zk;
360 struct GNUNET_PQ_ResultSpec rs_with_zone[] = {
361 GNUNET_PQ_result_spec_uint64("seq", &serial),
362 GNUNET_PQ_result_spec_uint32("record_count", &record_count),
363 GNUNET_PQ_result_spec_variable_size("record_data", &data, &data_size),
364 GNUNET_PQ_result_spec_string("label", &label),
365 GNUNET_PQ_result_spec_auto_from_type("zone_private_key", &zk),
366 GNUNET_PQ_result_spec_end
367 };
368 struct GNUNET_PQ_ResultSpec rs_without_zone[] = {
369 GNUNET_PQ_result_spec_uint64("seq", &serial),
370 GNUNET_PQ_result_spec_uint32("record_count", &record_count),
371 GNUNET_PQ_result_spec_variable_size("record_data", &data, &data_size),
372 GNUNET_PQ_result_spec_string("label", &label),
373 GNUNET_PQ_result_spec_end
374 };
375 struct GNUNET_PQ_ResultSpec *rs;
376
377 rs = (NULL == pc->zone_key) ? rs_with_zone : rs_without_zone;
378 if (GNUNET_YES !=
379 GNUNET_PQ_extract_result(res,
380 rs,
381 i))
382 {
383 GNUNET_break(0);
384 return;
385 }
386
387 if (record_count > 64 * 1024)
388 {
389 /* sanity check, don't stack allocate far too much just
390 because database might contain a large value here */
391 GNUNET_break(0);
392 GNUNET_PQ_cleanup_result(rs);
393 return;
394 }
395 391
392 if (record_count > 64 * 1024)
393 {
394 /* sanity check, don't stack allocate far too much just
395 because database might contain a large value here */
396 GNUNET_break (0);
397 GNUNET_PQ_cleanup_result (rs);
398 return;
399 }
400
401 {
402 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (record_count)];
403
404 GNUNET_assert (0 != serial);
405 if (GNUNET_OK !=
406 GNUNET_GNSRECORD_records_deserialize (data_size,
407 data,
408 record_count,
409 rd))
396 { 410 {
397 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(record_count)]; 411 GNUNET_break (0);
398 412 GNUNET_PQ_cleanup_result (rs);
399 GNUNET_assert(0 != serial); 413 return;
400 if (GNUNET_OK !=
401 GNUNET_GNSRECORD_records_deserialize(data_size,
402 data,
403 record_count,
404 rd))
405 {
406 GNUNET_break(0);
407 GNUNET_PQ_cleanup_result(rs);
408 return;
409 }
410 pc->iter(pc->iter_cls,
411 serial,
412 (NULL == pc->zone_key) ? &zk : pc->zone_key,
413 label,
414 record_count,
415 rd);
416 } 414 }
417 GNUNET_PQ_cleanup_result(rs); 415 pc->iter (pc->iter_cls,
416 serial,
417 (NULL == pc->zone_key) ? &zk : pc->zone_key,
418 label,
419 record_count,
420 rd);
418 } 421 }
422 GNUNET_PQ_cleanup_result (rs);
423 }
419 pc->limit -= num_results; 424 pc->limit -= num_results;
420} 425}
421 426
@@ -431,34 +436,35 @@ parse_result_call_iterator(void *cls,
431 * @return #GNUNET_OK on success, #GNUNET_NO for no results, else #GNUNET_SYSERR 436 * @return #GNUNET_OK on success, #GNUNET_NO for no results, else #GNUNET_SYSERR
432 */ 437 */
433static int 438static int
434namestore_postgres_lookup_records(void *cls, 439namestore_postgres_lookup_records (void *cls,
435 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, 440 const struct
436 const char *label, 441 GNUNET_CRYPTO_EcdsaPrivateKey *zone,
437 GNUNET_NAMESTORE_RecordIterator iter, 442 const char *label,
438 void *iter_cls) 443 GNUNET_NAMESTORE_RecordIterator iter,
444 void *iter_cls)
439{ 445{
440 struct Plugin *plugin = cls; 446 struct Plugin *plugin = cls;
441 struct GNUNET_PQ_QueryParam params[] = { 447 struct GNUNET_PQ_QueryParam params[] = {
442 GNUNET_PQ_query_param_auto_from_type(zone), 448 GNUNET_PQ_query_param_auto_from_type (zone),
443 GNUNET_PQ_query_param_string(label), 449 GNUNET_PQ_query_param_string (label),
444 GNUNET_PQ_query_param_end 450 GNUNET_PQ_query_param_end
445 }; 451 };
446 struct ParserContext pc; 452 struct ParserContext pc;
447 enum GNUNET_DB_QueryStatus res; 453 enum GNUNET_DB_QueryStatus res;
448 454
449 if (NULL == zone) 455 if (NULL == zone)
450 { 456 {
451 GNUNET_break(0); 457 GNUNET_break (0);
452 return GNUNET_SYSERR; 458 return GNUNET_SYSERR;
453 } 459 }
454 pc.iter = iter; 460 pc.iter = iter;
455 pc.iter_cls = iter_cls; 461 pc.iter_cls = iter_cls;
456 pc.zone_key = zone; 462 pc.zone_key = zone;
457 res = GNUNET_PQ_eval_prepared_multi_select(plugin->dbh, 463 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
458 "lookup_label", 464 "lookup_label",
459 params, 465 params,
460 &parse_result_call_iterator, 466 &parse_result_call_iterator,
461 &pc); 467 &pc);
462 if (res < 0) 468 if (res < 0)
463 return GNUNET_SYSERR; 469 return GNUNET_SYSERR;
464 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) 470 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res)
@@ -480,12 +486,13 @@ namestore_postgres_lookup_records(void *cls,
480 * @return #GNUNET_OK on success, #GNUNET_NO if there were no more results, #GNUNET_SYSERR on error 486 * @return #GNUNET_OK on success, #GNUNET_NO if there were no more results, #GNUNET_SYSERR on error
481 */ 487 */
482static int 488static int
483namestore_postgres_iterate_records(void *cls, 489namestore_postgres_iterate_records (void *cls,
484 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, 490 const struct
485 uint64_t serial, 491 GNUNET_CRYPTO_EcdsaPrivateKey *zone,
486 uint64_t limit, 492 uint64_t serial,
487 GNUNET_NAMESTORE_RecordIterator iter, 493 uint64_t limit,
488 void *iter_cls) 494 GNUNET_NAMESTORE_RecordIterator iter,
495 void *iter_cls)
489{ 496{
490 struct Plugin *plugin = cls; 497 struct Plugin *plugin = cls;
491 enum GNUNET_DB_QueryStatus res; 498 enum GNUNET_DB_QueryStatus res;
@@ -496,34 +503,34 @@ namestore_postgres_iterate_records(void *cls,
496 pc.zone_key = zone; 503 pc.zone_key = zone;
497 pc.limit = limit; 504 pc.limit = limit;
498 if (NULL == zone) 505 if (NULL == zone)
499 { 506 {
500 struct GNUNET_PQ_QueryParam params_without_zone[] = { 507 struct GNUNET_PQ_QueryParam params_without_zone[] = {
501 GNUNET_PQ_query_param_uint64(&serial), 508 GNUNET_PQ_query_param_uint64 (&serial),
502 GNUNET_PQ_query_param_uint64(&limit), 509 GNUNET_PQ_query_param_uint64 (&limit),
503 GNUNET_PQ_query_param_end 510 GNUNET_PQ_query_param_end
504 }; 511 };
505 512
506 res = GNUNET_PQ_eval_prepared_multi_select(plugin->dbh, 513 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
507 "iterate_all_zones", 514 "iterate_all_zones",
508 params_without_zone, 515 params_without_zone,
509 &parse_result_call_iterator, 516 &parse_result_call_iterator,
510 &pc); 517 &pc);
511 } 518 }
512 else 519 else
513 { 520 {
514 struct GNUNET_PQ_QueryParam params_with_zone[] = { 521 struct GNUNET_PQ_QueryParam params_with_zone[] = {
515 GNUNET_PQ_query_param_auto_from_type(zone), 522 GNUNET_PQ_query_param_auto_from_type (zone),
516 GNUNET_PQ_query_param_uint64(&serial), 523 GNUNET_PQ_query_param_uint64 (&serial),
517 GNUNET_PQ_query_param_uint64(&limit), 524 GNUNET_PQ_query_param_uint64 (&limit),
518 GNUNET_PQ_query_param_end 525 GNUNET_PQ_query_param_end
519 }; 526 };
520 527
521 res = GNUNET_PQ_eval_prepared_multi_select(plugin->dbh, 528 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
522 "iterate_zone", 529 "iterate_zone",
523 params_with_zone, 530 params_with_zone,
524 &parse_result_call_iterator, 531 &parse_result_call_iterator,
525 &pc); 532 &pc);
526 } 533 }
527 if (res < 0) 534 if (res < 0)
528 return GNUNET_SYSERR; 535 return GNUNET_SYSERR;
529 536
@@ -546,15 +553,18 @@ namestore_postgres_iterate_records(void *cls,
546 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 553 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
547 */ 554 */
548static int 555static int
549namestore_postgres_zone_to_name(void *cls, 556namestore_postgres_zone_to_name (void *cls,
550 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, 557 const struct
551 const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, 558 GNUNET_CRYPTO_EcdsaPrivateKey *zone,
552 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) 559 const struct
560 GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
561 GNUNET_NAMESTORE_RecordIterator iter,
562 void *iter_cls)
553{ 563{
554 struct Plugin *plugin = cls; 564 struct Plugin *plugin = cls;
555 struct GNUNET_PQ_QueryParam params[] = { 565 struct GNUNET_PQ_QueryParam params[] = {
556 GNUNET_PQ_query_param_auto_from_type(zone), 566 GNUNET_PQ_query_param_auto_from_type (zone),
557 GNUNET_PQ_query_param_auto_from_type(value_zone), 567 GNUNET_PQ_query_param_auto_from_type (value_zone),
558 GNUNET_PQ_query_param_end 568 GNUNET_PQ_query_param_end
559 }; 569 };
560 enum GNUNET_DB_QueryStatus res; 570 enum GNUNET_DB_QueryStatus res;
@@ -563,11 +573,11 @@ namestore_postgres_zone_to_name(void *cls,
563 pc.iter = iter; 573 pc.iter = iter;
564 pc.iter_cls = iter_cls; 574 pc.iter_cls = iter_cls;
565 pc.zone_key = zone; 575 pc.zone_key = zone;
566 res = GNUNET_PQ_eval_prepared_multi_select(plugin->dbh, 576 res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh,
567 "zone_to_name", 577 "zone_to_name",
568 params, 578 params,
569 &parse_result_call_iterator, 579 &parse_result_call_iterator,
570 &pc); 580 &pc);
571 if (res < 0) 581 if (res < 0)
572 return GNUNET_SYSERR; 582 return GNUNET_SYSERR;
573 return GNUNET_OK; 583 return GNUNET_OK;
@@ -581,9 +591,9 @@ namestore_postgres_zone_to_name(void *cls,
581 * @param plugin the plugin context (state for this module) 591 * @param plugin the plugin context (state for this module)
582 */ 592 */
583static void 593static void
584database_shutdown(struct Plugin *plugin) 594database_shutdown (struct Plugin *plugin)
585{ 595{
586 PQfinish(plugin->dbh); 596 PQfinish (plugin->dbh);
587 plugin->dbh = NULL; 597 plugin->dbh = NULL;
588} 598}
589 599
@@ -595,7 +605,7 @@ database_shutdown(struct Plugin *plugin)
595 * @return NULL on error, othrewise the plugin context 605 * @return NULL on error, othrewise the plugin context
596 */ 606 */
597void * 607void *
598libgnunet_plugin_namestore_postgres_init(void *cls) 608libgnunet_plugin_namestore_postgres_init (void *cls)
599{ 609{
600 static struct Plugin plugin; 610 static struct Plugin plugin;
601 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 611 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
@@ -603,21 +613,21 @@ libgnunet_plugin_namestore_postgres_init(void *cls)
603 613
604 if (NULL != plugin.cfg) 614 if (NULL != plugin.cfg)
605 return NULL; /* can only initialize once! */ 615 return NULL; /* can only initialize once! */
606 memset(&plugin, 0, sizeof(struct Plugin)); 616 memset (&plugin, 0, sizeof(struct Plugin));
607 plugin.cfg = cfg; 617 plugin.cfg = cfg;
608 if (GNUNET_OK != database_setup(&plugin)) 618 if (GNUNET_OK != database_setup (&plugin))
609 { 619 {
610 database_shutdown(&plugin); 620 database_shutdown (&plugin);
611 return NULL; 621 return NULL;
612 } 622 }
613 api = GNUNET_new(struct GNUNET_NAMESTORE_PluginFunctions); 623 api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
614 api->cls = &plugin; 624 api->cls = &plugin;
615 api->store_records = &namestore_postgres_store_records; 625 api->store_records = &namestore_postgres_store_records;
616 api->iterate_records = &namestore_postgres_iterate_records; 626 api->iterate_records = &namestore_postgres_iterate_records;
617 api->zone_to_name = &namestore_postgres_zone_to_name; 627 api->zone_to_name = &namestore_postgres_zone_to_name;
618 api->lookup_records = &namestore_postgres_lookup_records; 628 api->lookup_records = &namestore_postgres_lookup_records;
619 LOG(GNUNET_ERROR_TYPE_INFO, 629 LOG (GNUNET_ERROR_TYPE_INFO,
620 "Postgres namestore plugin running\n"); 630 "Postgres namestore plugin running\n");
621 return api; 631 return api;
622} 632}
623 633
@@ -629,16 +639,16 @@ libgnunet_plugin_namestore_postgres_init(void *cls)
629 * @return always NULL 639 * @return always NULL
630 */ 640 */
631void * 641void *
632libgnunet_plugin_namestore_postgres_done(void *cls) 642libgnunet_plugin_namestore_postgres_done (void *cls)
633{ 643{
634 struct GNUNET_NAMESTORE_PluginFunctions *api = cls; 644 struct GNUNET_NAMESTORE_PluginFunctions *api = cls;
635 struct Plugin *plugin = api->cls; 645 struct Plugin *plugin = api->cls;
636 646
637 database_shutdown(plugin); 647 database_shutdown (plugin);
638 plugin->cfg = NULL; 648 plugin->cfg = NULL;
639 GNUNET_free(api); 649 GNUNET_free (api);
640 LOG(GNUNET_ERROR_TYPE_DEBUG, 650 LOG (GNUNET_ERROR_TYPE_DEBUG,
641 "Postgres namestore plugin is finished\n"); 651 "Postgres namestore plugin is finished\n");
642 return NULL; 652 return NULL;
643} 653}
644 654