diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-06-03 23:33:43 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-06-03 23:33:55 +0200 |
commit | 8f254866dc993d2e832ef12ea7b4179f87ab3bd9 (patch) | |
tree | ebc1ced68bb48f74f189dadd4b29ff5119849224 | |
parent | 1a90e7878a8fa1f5b30421bd3045cf5d6d3e13e4 (diff) | |
download | gnunet-8f254866dc993d2e832ef12ea7b4179f87ab3bd9.tar.gz gnunet-8f254866dc993d2e832ef12ea7b4179f87ab3bd9.zip |
more pq work
-rw-r--r-- | src/datastore/plugin_datastore_postgres.c | 348 | ||||
-rw-r--r-- | src/include/gnunet_pq_lib.h | 6 | ||||
-rw-r--r-- | src/pq/pq_eval.c | 15 |
3 files changed, 154 insertions, 215 deletions
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c index 1c9ded4f4..7496aeacc 100644 --- a/src/datastore/plugin_datastore_postgres.c +++ b/src/datastore/plugin_datastore_postgres.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2009-2016 GNUnet e.V. | 3 | Copyright (C) 2009-2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -70,161 +70,103 @@ struct Plugin | |||
70 | static int | 70 | static int |
71 | init_connection (struct Plugin *plugin) | 71 | init_connection (struct Plugin *plugin) |
72 | { | 72 | { |
73 | PGresult *ret; | 73 | struct GNUNET_PQ_ExecuteStatement es[] = { |
74 | /* FIXME: PostgreSQL does not have unsigned integers! This is ok for the type column because | ||
75 | * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel | ||
76 | * we do math or inequality tests, so we can't handle the entire range of uint32_t. | ||
77 | * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC. | ||
78 | * PostgreSQL also recommends against using WITH OIDS. | ||
79 | */ | ||
80 | GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS gn090 (" | ||
81 | " repl INTEGER NOT NULL DEFAULT 0," | ||
82 | " type INTEGER NOT NULL DEFAULT 0," | ||
83 | " prio INTEGER NOT NULL DEFAULT 0," | ||
84 | " anonLevel INTEGER NOT NULL DEFAULT 0," | ||
85 | " expire BIGINT NOT NULL DEFAULT 0," | ||
86 | " rvalue BIGINT NOT NULL DEFAULT 0," | ||
87 | " hash BYTEA NOT NULL DEFAULT ''," | ||
88 | " vhash BYTEA NOT NULL DEFAULT ''," | ||
89 | " value BYTEA NOT NULL DEFAULT '')" | ||
90 | "WITH OIDS"), | ||
91 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)"), | ||
92 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_prio ON gn090 (prio)"), | ||
93 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_expire ON gn090 (expire)"), | ||
94 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_prio_anon ON gn090 (prio,anonLevel)"), | ||
95 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)"), | ||
96 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn090 (repl,rvalue)"), | ||
97 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_expire_hash ON gn090 (expire,hash)"), | ||
98 | GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"), | ||
99 | GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"), | ||
100 | GNUNET_PQ_make_execute ("ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"), | ||
101 | GNUNET_PQ_EXECUTE_STATEMENT_END | ||
102 | }; | ||
103 | #define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid" | ||
104 | struct GNUNET_PQ_PreparedStatement ps[] = { | ||
105 | GNUNET_PQ_make_prepare ("get", | ||
106 | "SELECT " RESULT_COLUMNS " FROM gn090 " | ||
107 | "WHERE oid >= $1::bigint AND " | ||
108 | "(rvalue >= $2 OR 0 = $3::smallint) AND " | ||
109 | "(hash = $4 OR 0 = $5::smallint) AND " | ||
110 | "(type = $6 OR 0 = $7::smallint) " | ||
111 | "ORDER BY oid ASC LIMIT 1", | ||
112 | 7), | ||
113 | GNUNET_PQ_make_prepare ("put", | ||
114 | "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) " | ||
115 | "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", | ||
116 | 9), | ||
117 | GNUNET_PQ_make_prepare ("update", | ||
118 | "UPDATE gn090 " | ||
119 | "SET prio = prio + $1, " | ||
120 | "repl = repl + $2, " | ||
121 | "expire = GREATEST(expire, $3) " | ||
122 | "WHERE hash = $4 AND vhash = $5", | ||
123 | 5), | ||
124 | GNUNET_PQ_make_prepare ("decrepl", | ||
125 | "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " | ||
126 | "WHERE oid = $1", | ||
127 | 1), | ||
128 | GNUNET_PQ_make_prepare ("select_non_anonymous", | ||
129 | "SELECT " RESULT_COLUMNS " FROM gn090 " | ||
130 | "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint " | ||
131 | "ORDER BY oid ASC LIMIT 1", | ||
132 | 2), | ||
133 | GNUNET_PQ_make_prepare ("select_expiration_order", | ||
134 | "(SELECT " RESULT_COLUMNS " FROM gn090 " | ||
135 | "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) " | ||
136 | "UNION " | ||
137 | "(SELECT " RESULT_COLUMNS " FROM gn090 " | ||
138 | "ORDER BY prio ASC LIMIT 1) " | ||
139 | "ORDER BY expire ASC LIMIT 1", | ||
140 | 1), | ||
141 | GNUNET_PQ_make_prepare ("select_replication_order", | ||
142 | "SELECT " RESULT_COLUMNS " FROM gn090 " | ||
143 | "ORDER BY repl DESC,RANDOM() LIMIT 1", | ||
144 | 0), | ||
145 | GNUNET_PQ_make_prepare ("delrow", | ||
146 | "DELETE FROM gn090 " "WHERE oid=$1", | ||
147 | 1), | ||
148 | GNUNET_PQ_make_prepare ("remove", "DELETE FROM gn090 " | ||
149 | "WHERE hash = $1 AND " | ||
150 | "value = $2", | ||
151 | 2), | ||
152 | GNUNET_PQ_make_prepare ("get_keys", | ||
153 | "SELECT hash FROM gn090", | ||
154 | 0), | ||
155 | GNUNET_PQ_PREPARED_STATEMENT_END | ||
156 | }; | ||
157 | #undef RESULT_COLUMNS | ||
74 | 158 | ||
75 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg, | 159 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg, |
76 | "datastore-postgres"); | 160 | "datastore-postgres"); |
77 | if (NULL == plugin->dbh) | 161 | if (NULL == plugin->dbh) |
78 | return GNUNET_SYSERR; | 162 | return GNUNET_SYSERR; |
79 | 163 | ||
80 | /* FIXME: PostgreSQL does not have unsigned integers! This is ok for the type column because | 164 | if ( (GNUNET_OK != |
81 | * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel | 165 | GNUNET_PQ_exec_statements (plugin->dbh, |
82 | * we do math or inequality tests, so we can't handle the entire range of uint32_t. | 166 | es)) || |
83 | * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC. | 167 | (GNUNET_OK != |
84 | * PostgreSQL also recommends against using WITH OIDS. | 168 | GNUNET_PQ_prepare_statements (plugin->dbh, |
85 | */ | 169 | ps)) ) |
86 | ret = | ||
87 | PQexec (plugin->dbh, | ||
88 | "CREATE TABLE IF NOT EXISTS gn090 (" | ||
89 | " repl INTEGER NOT NULL DEFAULT 0," | ||
90 | " type INTEGER NOT NULL DEFAULT 0," | ||
91 | " prio INTEGER NOT NULL DEFAULT 0," | ||
92 | " anonLevel INTEGER NOT NULL DEFAULT 0," | ||
93 | " expire BIGINT NOT NULL DEFAULT 0," | ||
94 | " rvalue BIGINT NOT NULL DEFAULT 0," | ||
95 | " hash BYTEA NOT NULL DEFAULT ''," | ||
96 | " vhash BYTEA NOT NULL DEFAULT ''," | ||
97 | " value BYTEA NOT NULL DEFAULT '')" | ||
98 | "WITH OIDS"); | ||
99 | if ( (NULL == ret) || | ||
100 | ((PQresultStatus (ret) != PGRES_COMMAND_OK) && | ||
101 | (0 != strcmp ("42P07", /* duplicate table */ | ||
102 | PQresultErrorField | ||
103 | (ret, | ||
104 | PG_DIAG_SQLSTATE))))) | ||
105 | { | ||
106 | (void) GNUNET_POSTGRES_check_result (plugin->dbh, | ||
107 | ret, | ||
108 | PGRES_COMMAND_OK, | ||
109 | "CREATE TABLE", | ||
110 | "gn090"); | ||
111 | PQfinish (plugin->dbh); | ||
112 | plugin->dbh = NULL; | ||
113 | return GNUNET_SYSERR; | ||
114 | } | ||
115 | |||
116 | if (PQresultStatus (ret) == PGRES_COMMAND_OK) | ||
117 | { | ||
118 | if ((GNUNET_OK != | ||
119 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
120 | "CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)")) || | ||
121 | (GNUNET_OK != | ||
122 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
123 | "CREATE INDEX IF NOT EXISTS idx_prio ON gn090 (prio)")) || | ||
124 | (GNUNET_OK != | ||
125 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
126 | "CREATE INDEX IF NOT EXISTS idx_expire ON gn090 (expire)")) || | ||
127 | (GNUNET_OK != | ||
128 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
129 | "CREATE INDEX IF NOT EXISTS idx_prio_anon ON gn090 (prio,anonLevel)")) || | ||
130 | (GNUNET_OK != | ||
131 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
132 | "CREATE INDEX IF NOT EXISTS idx_prio_hash_anon ON gn090 (prio,hash,anonLevel)")) || | ||
133 | (GNUNET_OK != | ||
134 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
135 | "CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn090 (repl,rvalue)")) || | ||
136 | (GNUNET_OK != | ||
137 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
138 | "CREATE INDEX IF NOT EXISTS idx_expire_hash ON gn090 (expire,hash)"))) | ||
139 | { | ||
140 | PQclear (ret); | ||
141 | PQfinish (plugin->dbh); | ||
142 | plugin->dbh = NULL; | ||
143 | return GNUNET_SYSERR; | ||
144 | } | ||
145 | } | ||
146 | PQclear (ret); | ||
147 | |||
148 | ret = | ||
149 | PQexec (plugin->dbh, | ||
150 | "ALTER TABLE gn090 ALTER value SET STORAGE EXTERNAL"); | ||
151 | if (GNUNET_OK != | ||
152 | GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) | ||
153 | { | ||
154 | PQfinish (plugin->dbh); | ||
155 | plugin->dbh = NULL; | ||
156 | return GNUNET_SYSERR; | ||
157 | } | ||
158 | PQclear (ret); | ||
159 | ret = PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER hash SET STORAGE PLAIN"); | ||
160 | if (GNUNET_OK != | ||
161 | GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) | ||
162 | { | ||
163 | PQfinish (plugin->dbh); | ||
164 | plugin->dbh = NULL; | ||
165 | return GNUNET_SYSERR; | ||
166 | } | ||
167 | PQclear (ret); | ||
168 | ret = PQexec (plugin->dbh, "ALTER TABLE gn090 ALTER vhash SET STORAGE PLAIN"); | ||
169 | if (GNUNET_OK != | ||
170 | GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090")) | ||
171 | { | ||
172 | PQfinish (plugin->dbh); | ||
173 | plugin->dbh = NULL; | ||
174 | return GNUNET_SYSERR; | ||
175 | } | ||
176 | PQclear (ret); | ||
177 | #define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid" | ||
178 | if ((GNUNET_OK != | ||
179 | GNUNET_POSTGRES_prepare (plugin->dbh, "get", | ||
180 | "SELECT " RESULT_COLUMNS " FROM gn090 " | ||
181 | "WHERE oid >= $1::bigint AND " | ||
182 | "(rvalue >= $2 OR 0 = $3::smallint) AND " | ||
183 | "(hash = $4 OR 0 = $5::smallint) AND " | ||
184 | "(type = $6 OR 0 = $7::smallint) " | ||
185 | "ORDER BY oid ASC LIMIT 1", 7)) || | ||
186 | (GNUNET_OK != | ||
187 | GNUNET_POSTGRES_prepare (plugin->dbh, "put", | ||
188 | "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) " | ||
189 | "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", 9)) || | ||
190 | (GNUNET_OK != | ||
191 | GNUNET_POSTGRES_prepare (plugin->dbh, "update", | ||
192 | "UPDATE gn090 " | ||
193 | "SET prio = prio + $1, " | ||
194 | "repl = repl + $2, " | ||
195 | "expire = GREATEST(expire, $3) " | ||
196 | "WHERE hash = $4 AND vhash = $5", 5)) || | ||
197 | (GNUNET_OK != | ||
198 | GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl", | ||
199 | "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " | ||
200 | "WHERE oid = $1", 1)) || | ||
201 | (GNUNET_OK != | ||
202 | GNUNET_POSTGRES_prepare (plugin->dbh, "select_non_anonymous", | ||
203 | "SELECT " RESULT_COLUMNS " FROM gn090 " | ||
204 | "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint " | ||
205 | "ORDER BY oid ASC LIMIT 1", | ||
206 | 2)) || | ||
207 | (GNUNET_OK != | ||
208 | GNUNET_POSTGRES_prepare (plugin->dbh, "select_expiration_order", | ||
209 | "(SELECT " RESULT_COLUMNS " FROM gn090 " | ||
210 | "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) " | ||
211 | "UNION " | ||
212 | "(SELECT " RESULT_COLUMNS " FROM gn090 " | ||
213 | "ORDER BY prio ASC LIMIT 1) " | ||
214 | "ORDER BY expire ASC LIMIT 1", | ||
215 | 1)) || | ||
216 | (GNUNET_OK != | ||
217 | GNUNET_POSTGRES_prepare (plugin->dbh, "select_replication_order", | ||
218 | "SELECT " RESULT_COLUMNS " FROM gn090 " | ||
219 | "ORDER BY repl DESC,RANDOM() LIMIT 1", 0)) || | ||
220 | (GNUNET_OK != | ||
221 | GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1)) || | ||
222 | (GNUNET_OK != | ||
223 | GNUNET_POSTGRES_prepare (plugin->dbh, "remove", "DELETE FROM gn090 " | ||
224 | "WHERE hash = $1 AND " | ||
225 | "value = $2", 2)) || | ||
226 | (GNUNET_OK != | ||
227 | GNUNET_POSTGRES_prepare (plugin->dbh, "get_keys", "SELECT hash FROM gn090", 0))) | ||
228 | { | 170 | { |
229 | PQfinish (plugin->dbh); | 171 | PQfinish (plugin->dbh); |
230 | plugin->dbh = NULL; | 172 | plugin->dbh = NULL; |
@@ -316,13 +258,12 @@ postgres_plugin_put (void *cls, | |||
316 | { | 258 | { |
317 | struct Plugin *plugin = cls; | 259 | struct Plugin *plugin = cls; |
318 | struct GNUNET_HashCode vhash; | 260 | struct GNUNET_HashCode vhash; |
319 | PGresult *ret; | 261 | enum GNUNET_PQ_QueryStatus ret; |
320 | 262 | ||
321 | GNUNET_CRYPTO_hash (data, | 263 | GNUNET_CRYPTO_hash (data, |
322 | size, | 264 | size, |
323 | &vhash); | 265 | &vhash); |
324 | 266 | if (! absent) | |
325 | if (!absent) | ||
326 | { | 267 | { |
327 | struct GNUNET_PQ_QueryParam params[] = { | 268 | struct GNUNET_PQ_QueryParam params[] = { |
328 | GNUNET_PQ_query_param_uint32 (&priority), | 269 | GNUNET_PQ_query_param_uint32 (&priority), |
@@ -332,15 +273,10 @@ postgres_plugin_put (void *cls, | |||
332 | GNUNET_PQ_query_param_auto_from_type (&vhash), | 273 | GNUNET_PQ_query_param_auto_from_type (&vhash), |
333 | GNUNET_PQ_query_param_end | 274 | GNUNET_PQ_query_param_end |
334 | }; | 275 | }; |
335 | ret = GNUNET_PQ_exec_prepared (plugin->dbh, | 276 | ret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh, |
336 | "update", | 277 | "update", |
337 | params); | 278 | params); |
338 | if (GNUNET_OK != | 279 | if (0 > ret) |
339 | GNUNET_POSTGRES_check_result (plugin->dbh, | ||
340 | ret, | ||
341 | PGRES_COMMAND_OK, | ||
342 | "PQexecPrepared", | ||
343 | "update")) | ||
344 | { | 280 | { |
345 | cont (cont_cls, | 281 | cont (cont_cls, |
346 | key, | 282 | key, |
@@ -349,9 +285,7 @@ postgres_plugin_put (void *cls, | |||
349 | _("Postgress exec failure")); | 285 | _("Postgress exec failure")); |
350 | return; | 286 | return; |
351 | } | 287 | } |
352 | /* What an awful API, this function really does return a string */ | 288 | bool affected = (0 != ret); |
353 | bool affected = 0 != strcmp ("0", PQcmdTuples (ret)); | ||
354 | PQclear (ret); | ||
355 | if (affected) | 289 | if (affected) |
356 | { | 290 | { |
357 | cont (cont_cls, | 291 | cont (cont_cls, |
@@ -363,44 +297,47 @@ postgres_plugin_put (void *cls, | |||
363 | } | 297 | } |
364 | } | 298 | } |
365 | 299 | ||
366 | uint32_t utype = type; | ||
367 | uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
368 | UINT64_MAX); | ||
369 | struct GNUNET_PQ_QueryParam params[] = { | ||
370 | GNUNET_PQ_query_param_uint32 (&replication), | ||
371 | GNUNET_PQ_query_param_uint32 (&utype), | ||
372 | GNUNET_PQ_query_param_uint32 (&priority), | ||
373 | GNUNET_PQ_query_param_uint32 (&anonymity), | ||
374 | GNUNET_PQ_query_param_absolute_time (&expiration), | ||
375 | GNUNET_PQ_query_param_uint64 (&rvalue), | ||
376 | GNUNET_PQ_query_param_auto_from_type (key), | ||
377 | GNUNET_PQ_query_param_auto_from_type (&vhash), | ||
378 | GNUNET_PQ_query_param_fixed_size (data, size), | ||
379 | GNUNET_PQ_query_param_end | ||
380 | }; | ||
381 | |||
382 | ret = GNUNET_PQ_exec_prepared (plugin->dbh, | ||
383 | "put", | ||
384 | params); | ||
385 | if (GNUNET_OK != | ||
386 | GNUNET_POSTGRES_check_result (plugin->dbh, | ||
387 | ret, | ||
388 | PGRES_COMMAND_OK, | ||
389 | "PQexecPrepared", "put")) | ||
390 | { | 300 | { |
391 | cont (cont_cls, key, size, | 301 | uint32_t utype = (uint32_t) type; |
392 | GNUNET_SYSERR, | 302 | uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, |
393 | _("Postgress exec failure")); | 303 | UINT64_MAX); |
394 | return; | 304 | struct GNUNET_PQ_QueryParam params[] = { |
305 | GNUNET_PQ_query_param_uint32 (&replication), | ||
306 | GNUNET_PQ_query_param_uint32 (&utype), | ||
307 | GNUNET_PQ_query_param_uint32 (&priority), | ||
308 | GNUNET_PQ_query_param_uint32 (&anonymity), | ||
309 | GNUNET_PQ_query_param_absolute_time (&expiration), | ||
310 | GNUNET_PQ_query_param_uint64 (&rvalue), | ||
311 | GNUNET_PQ_query_param_auto_from_type (key), | ||
312 | GNUNET_PQ_query_param_auto_from_type (&vhash), | ||
313 | GNUNET_PQ_query_param_fixed_size (data, size), | ||
314 | GNUNET_PQ_query_param_end | ||
315 | }; | ||
316 | |||
317 | ret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh, | ||
318 | "put", | ||
319 | params); | ||
320 | if (0 > ret) | ||
321 | { | ||
322 | cont (cont_cls, | ||
323 | key, | ||
324 | size, | ||
325 | GNUNET_SYSERR, | ||
326 | "Postgress exec failure"); | ||
327 | return; | ||
328 | } | ||
395 | } | 329 | } |
396 | PQclear (ret); | ||
397 | plugin->env->duc (plugin->env->cls, | 330 | plugin->env->duc (plugin->env->cls, |
398 | size + GNUNET_DATASTORE_ENTRY_OVERHEAD); | 331 | size + GNUNET_DATASTORE_ENTRY_OVERHEAD); |
399 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 332 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
400 | "datastore-postgres", | 333 | "datastore-postgres", |
401 | "Stored %u bytes in database\n", | 334 | "Stored %u bytes in database\n", |
402 | (unsigned int) size); | 335 | (unsigned int) size); |
403 | cont (cont_cls, key, size, GNUNET_OK, NULL); | 336 | cont (cont_cls, |
337 | key, | ||
338 | size, | ||
339 | GNUNET_OK, | ||
340 | NULL); | ||
404 | } | 341 | } |
405 | 342 | ||
406 | 343 | ||
@@ -864,21 +801,17 @@ postgres_plugin_remove_key (void *cls, | |||
864 | void *cont_cls) | 801 | void *cont_cls) |
865 | { | 802 | { |
866 | struct Plugin *plugin = cls; | 803 | struct Plugin *plugin = cls; |
867 | PGresult *ret; | 804 | enum GNUNET_PQ_QueryStatus ret; |
868 | struct GNUNET_PQ_QueryParam params[] = { | 805 | struct GNUNET_PQ_QueryParam params[] = { |
869 | GNUNET_PQ_query_param_auto_from_type (key), | 806 | GNUNET_PQ_query_param_auto_from_type (key), |
870 | GNUNET_PQ_query_param_fixed_size (data, size), | 807 | GNUNET_PQ_query_param_fixed_size (data, size), |
871 | GNUNET_PQ_query_param_end | 808 | GNUNET_PQ_query_param_end |
872 | }; | 809 | }; |
873 | ret = GNUNET_PQ_exec_prepared (plugin->dbh, | 810 | |
874 | "remove", | 811 | ret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh, |
875 | params); | 812 | "remove", |
876 | if (GNUNET_OK != | 813 | params); |
877 | GNUNET_POSTGRES_check_result (plugin->dbh, | 814 | if (0 > ret) |
878 | ret, | ||
879 | PGRES_COMMAND_OK, | ||
880 | "PQexecPrepared", | ||
881 | "remove")) | ||
882 | { | 815 | { |
883 | cont (cont_cls, | 816 | cont (cont_cls, |
884 | key, | 817 | key, |
@@ -887,10 +820,7 @@ postgres_plugin_remove_key (void *cls, | |||
887 | _("Postgress exec failure")); | 820 | _("Postgress exec failure")); |
888 | return; | 821 | return; |
889 | } | 822 | } |
890 | /* What an awful API, this function really does return a string */ | 823 | if (GNUNET_PQ_STATUS_SUCCESS_NO_RESULTS == ret) |
891 | bool affected = 0 != strcmp ("0", PQcmdTuples (ret)); | ||
892 | PQclear (ret); | ||
893 | if (!affected) | ||
894 | { | 824 | { |
895 | cont (cont_cls, | 825 | cont (cont_cls, |
896 | key, | 826 | key, |
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index 5e54813e3..ff4df563d 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h | |||
@@ -523,9 +523,9 @@ GNUNET_PQ_eval_result (PGconn *connection, | |||
523 | * @param statement_name name of the statement | 523 | * @param statement_name name of the statement |
524 | * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) | 524 | * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) |
525 | * @return status code from the result, mapping PQ status | 525 | * @return status code from the result, mapping PQ status |
526 | * codes to `enum GNUNET_PQ_QueryStatus`. Never | 526 | * codes to `enum GNUNET_PQ_QueryStatus`. If the |
527 | * returns positive values as this function does | 527 | * statement was a DELETE or UPDATE statement, the |
528 | * not look at the result set. | 528 | * number of affected rows is returned. |
529 | */ | 529 | */ |
530 | enum GNUNET_PQ_QueryStatus | 530 | enum GNUNET_PQ_QueryStatus |
531 | GNUNET_PQ_eval_prepared_non_select (PGconn *connection, | 531 | GNUNET_PQ_eval_prepared_non_select (PGconn *connection, |
diff --git a/src/pq/pq_eval.c b/src/pq/pq_eval.c index d6c10e2c5..9296dce2e 100644 --- a/src/pq/pq_eval.c +++ b/src/pq/pq_eval.c | |||
@@ -119,9 +119,9 @@ GNUNET_PQ_eval_result (PGconn *connection, | |||
119 | * @param statement_name name of the statement | 119 | * @param statement_name name of the statement |
120 | * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) | 120 | * @param params parameters to give to the statement (#GNUNET_PQ_query_param_end-terminated) |
121 | * @return status code from the result, mapping PQ status | 121 | * @return status code from the result, mapping PQ status |
122 | * codes to `enum GNUNET_PQ_QueryStatus`. Never | 122 | * codes to `enum GNUNET_PQ_QueryStatus`. If the |
123 | * returns positive values as this function does | 123 | * statement was a DELETE or UPDATE statement, the |
124 | * not look at the result set. | 124 | * number of affected rows is returned. |
125 | */ | 125 | */ |
126 | enum GNUNET_PQ_QueryStatus | 126 | enum GNUNET_PQ_QueryStatus |
127 | GNUNET_PQ_eval_prepared_non_select (PGconn *connection, | 127 | GNUNET_PQ_eval_prepared_non_select (PGconn *connection, |
@@ -137,6 +137,15 @@ GNUNET_PQ_eval_prepared_non_select (PGconn *connection, | |||
137 | qs = GNUNET_PQ_eval_result (connection, | 137 | qs = GNUNET_PQ_eval_result (connection, |
138 | statement_name, | 138 | statement_name, |
139 | result); | 139 | result); |
140 | if (GNUNET_PQ_STATUS_SUCCESS_NO_RESULTS == qs) | ||
141 | { | ||
142 | const char *tuples; | ||
143 | |||
144 | /* What an awful API, this function really does return a string */ | ||
145 | tuples = PQcmdTuples (result); | ||
146 | if (NULL != tuples) | ||
147 | qs = strtol (tuples, NULL, 10); | ||
148 | } | ||
140 | PQclear (result); | 149 | PQclear (result); |
141 | return qs; | 150 | return qs; |
142 | } | 151 | } |