diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-06-02 23:12:31 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-06-02 23:12:31 +0200 |
commit | 0266efed64df149fd11a73e575be18cf03f36d25 (patch) | |
tree | edcdaac70ee6b6f018f54127f5523ecfc0e9c17c /src/datacache | |
parent | 70de9f42a397dc5f862355c81a16cb297ad2ee00 (diff) | |
download | gnunet-0266efed64df149fd11a73e575be18cf03f36d25.tar.gz gnunet-0266efed64df149fd11a73e575be18cf03f36d25.zip |
more work on pq-ification of datacache
Diffstat (limited to 'src/datacache')
-rw-r--r-- | src/datacache/Makefile.am | 1 | ||||
-rw-r--r-- | src/datacache/plugin_datacache_postgres.c | 463 |
2 files changed, 221 insertions, 243 deletions
diff --git a/src/datacache/Makefile.am b/src/datacache/Makefile.am index 670a64926..602b1d437 100644 --- a/src/datacache/Makefile.am +++ b/src/datacache/Makefile.am | |||
@@ -72,6 +72,7 @@ libgnunet_plugin_datacache_postgres_la_SOURCES = \ | |||
72 | plugin_datacache_postgres.c | 72 | plugin_datacache_postgres.c |
73 | libgnunet_plugin_datacache_postgres_la_LIBADD = \ | 73 | libgnunet_plugin_datacache_postgres_la_LIBADD = \ |
74 | $(top_builddir)/src/postgres/libgnunetpostgres.la \ | 74 | $(top_builddir)/src/postgres/libgnunetpostgres.la \ |
75 | $(top_builddir)/src/pq/libgnunetpq.la \ | ||
75 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 76 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
76 | $(top_builddir)/src/util/libgnunetutil.la \ | 77 | $(top_builddir)/src/util/libgnunetutil.la \ |
77 | $(GN_PLUGIN_LDFLAGS) -lpq | 78 | $(GN_PLUGIN_LDFLAGS) -lpq |
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index 8f5cdbde1..e69f2b2c6 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_postgres_lib.h" | 28 | #include "gnunet_postgres_lib.h" |
29 | #include "gnunet_pq_lib.h" | ||
29 | #include "gnunet_datacache_plugin.h" | 30 | #include "gnunet_datacache_plugin.h" |
30 | 31 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "datacache-postgres", __VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "datacache-postgres", __VA_ARGS__) |
@@ -66,115 +67,67 @@ struct Plugin | |||
66 | static int | 67 | static int |
67 | init_connection (struct Plugin *plugin) | 68 | init_connection (struct Plugin *plugin) |
68 | { | 69 | { |
69 | PGresult *ret; | 70 | struct GNUNET_PQ_ExecuteStatement es[] = { |
71 | GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn090dc (" | ||
72 | " type INTEGER NOT NULL DEFAULT 0," | ||
73 | " discard_time BIGINT NOT NULL DEFAULT 0," | ||
74 | " key BYTEA NOT NULL DEFAULT ''," | ||
75 | " value BYTEA NOT NULL DEFAULT ''," | ||
76 | " path BYTEA DEFAULT '')" | ||
77 | "WITH OIDS"), | ||
78 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_key ON gn090dc (key)"), | ||
79 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS idx_dt ON gn090dc (discard_time)"), | ||
80 | GNUNET_PQ_make_execute ("ALTER TABLE gn090dc ALTER value SET STORAGE EXTERNAL"), | ||
81 | GNUNET_PQ_make_execute ("ALTER TABLE gn090dc ALTER key SET STORAGE PLAIN"), | ||
82 | GNUNET_PQ_EXECUTE_STATEMENT_END | ||
83 | }; | ||
84 | struct GNUNET_PQ_PreparedStatement ps[] = { | ||
85 | GNUNET_PQ_make_prepare ("getkt", | ||
86 | "SELECT discard_time,type,value,path FROM gn090dc " | ||
87 | "WHERE key=$1 AND type=$2", | ||
88 | 2), | ||
89 | GNUNET_PQ_make_prepare ("getk", | ||
90 | "SELECT discard_time,type,value,path FROM gn090dc " | ||
91 | "WHERE key=$1", | ||
92 | 1), | ||
93 | GNUNET_PQ_make_prepare ("getm", | ||
94 | "SELECT length(value) AS len,oid,key FROM gn090dc " | ||
95 | "ORDER BY discard_time ASC LIMIT 1", | ||
96 | 0), | ||
97 | GNUNET_PQ_make_prepare ("get_random", | ||
98 | "SELECT discard_time,type,value,path,key FROM gn090dc " | ||
99 | "ORDER BY key ASC LIMIT 1 OFFSET $1", | ||
100 | 1), | ||
101 | GNUNET_PQ_make_prepare ("get_closest", | ||
102 | "SELECT discard_time,type,value,path,key FROM gn090dc " | ||
103 | "WHERE key>=$1 ORDER BY key ASC LIMIT $2", | ||
104 | 1), | ||
105 | GNUNET_PQ_make_prepare ("delrow", | ||
106 | "DELETE FROM gn090dc WHERE oid=$1", | ||
107 | 1), | ||
108 | GNUNET_PQ_make_prepare ("put", | ||
109 | "INSERT INTO gn090dc (type, discard_time, key, value, path) " | ||
110 | "VALUES ($1, $2, $3, $4, $5)", | ||
111 | 5), | ||
112 | GNUNET_PQ_PREPARED_STATEMENT_END | ||
113 | }; | ||
70 | 114 | ||
71 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg, | 115 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->env->cfg, |
72 | "datacache-postgres"); | 116 | "datacache-postgres"); |
73 | if (NULL == plugin->dbh) | 117 | if (NULL == plugin->dbh) |
74 | return GNUNET_SYSERR; | 118 | return GNUNET_SYSERR; |
75 | ret = | ||
76 | PQexec (plugin->dbh, | ||
77 | "CREATE TEMPORARY TABLE IF NOT EXISTS gn090dc (" | ||
78 | " type INTEGER NOT NULL DEFAULT 0," | ||
79 | " discard_time BIGINT NOT NULL DEFAULT 0," | ||
80 | " key BYTEA NOT NULL DEFAULT ''," | ||
81 | " value BYTEA NOT NULL DEFAULT ''," | ||
82 | " path BYTEA DEFAULT '')" | ||
83 | "WITH OIDS"); | ||
84 | if ( (ret == NULL) || | ||
85 | ((PQresultStatus (ret) != PGRES_COMMAND_OK) && | ||
86 | (0 != strcmp ("42P07", /* duplicate table */ | ||
87 | PQresultErrorField | ||
88 | (ret, | ||
89 | PG_DIAG_SQLSTATE))))) | ||
90 | { | ||
91 | (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, | ||
92 | PGRES_COMMAND_OK, | ||
93 | "CREATE TABLE", | ||
94 | "gn090dc"); | ||
95 | PQfinish (plugin->dbh); | ||
96 | plugin->dbh = NULL; | ||
97 | return GNUNET_SYSERR; | ||
98 | } | ||
99 | if (PQresultStatus (ret) == PGRES_COMMAND_OK) | ||
100 | { | ||
101 | if ((GNUNET_OK != | ||
102 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
103 | "CREATE INDEX IF NOT EXISTS idx_key ON gn090dc (key)")) || | ||
104 | (GNUNET_OK != | ||
105 | GNUNET_POSTGRES_exec (plugin->dbh, | ||
106 | "CREATE INDEX IF NOT EXISTS idx_dt ON gn090dc (discard_time)"))) | ||
107 | { | ||
108 | PQclear (ret); | ||
109 | PQfinish (plugin->dbh); | ||
110 | plugin->dbh = NULL; | ||
111 | return GNUNET_SYSERR; | ||
112 | } | ||
113 | } | ||
114 | PQclear (ret); | ||
115 | ret = | ||
116 | PQexec (plugin->dbh, | ||
117 | "ALTER TABLE gn090dc ALTER value SET STORAGE EXTERNAL"); | ||
118 | if (GNUNET_OK != | 119 | if (GNUNET_OK != |
119 | GNUNET_POSTGRES_check_result (plugin->dbh, | 120 | GNUNET_PQ_exec_statements (plugin->dbh, |
120 | ret, | 121 | es)) |
121 | PGRES_COMMAND_OK, | ||
122 | "ALTER TABLE", | ||
123 | "gn090dc")) | ||
124 | { | 122 | { |
125 | PQfinish (plugin->dbh); | 123 | PQfinish (plugin->dbh); |
126 | plugin->dbh = NULL; | 124 | plugin->dbh = NULL; |
127 | return GNUNET_SYSERR; | 125 | return GNUNET_SYSERR; |
128 | } | 126 | } |
129 | PQclear (ret); | 127 | |
130 | ret = PQexec (plugin->dbh, | ||
131 | "ALTER TABLE gn090dc ALTER key SET STORAGE PLAIN"); | ||
132 | if (GNUNET_OK != | 128 | if (GNUNET_OK != |
133 | GNUNET_POSTGRES_check_result (plugin->dbh, | 129 | GNUNET_PQ_prepare_statements (plugin->dbh, |
134 | ret, | 130 | ps)) |
135 | PGRES_COMMAND_OK, | ||
136 | "ALTER TABLE", | ||
137 | "gn090dc")) | ||
138 | { | ||
139 | PQfinish (plugin->dbh); | ||
140 | plugin->dbh = NULL; | ||
141 | return GNUNET_SYSERR; | ||
142 | } | ||
143 | PQclear (ret); | ||
144 | if ((GNUNET_OK != | ||
145 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
146 | "getkt", | ||
147 | "SELECT discard_time,type,value,path FROM gn090dc " | ||
148 | "WHERE key=$1 AND type=$2 ", 2)) || | ||
149 | (GNUNET_OK != | ||
150 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
151 | "getk", | ||
152 | "SELECT discard_time,type,value,path FROM gn090dc " | ||
153 | "WHERE key=$1", 1)) || | ||
154 | (GNUNET_OK != | ||
155 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
156 | "getm", | ||
157 | "SELECT length(value),oid,key FROM gn090dc " | ||
158 | "ORDER BY discard_time ASC LIMIT 1", 0)) || | ||
159 | (GNUNET_OK != | ||
160 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
161 | "get_random", | ||
162 | "SELECT discard_time,type,value,path,key FROM gn090dc " | ||
163 | "ORDER BY key ASC LIMIT 1 OFFSET $1", 1)) || | ||
164 | (GNUNET_OK != | ||
165 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
166 | "get_closest", | ||
167 | "SELECT discard_time,type,value,path,key FROM gn090dc " | ||
168 | "WHERE key>=$1 ORDER BY key ASC LIMIT $2", 1)) || | ||
169 | (GNUNET_OK != | ||
170 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
171 | "delrow", | ||
172 | "DELETE FROM gn090dc WHERE oid=$1", 1)) || | ||
173 | (GNUNET_OK != | ||
174 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
175 | "put", | ||
176 | "INSERT INTO gn090dc (type, discard_time, key, value, path) " | ||
177 | "VALUES ($1, $2, $3, $4, $5)", 5))) | ||
178 | { | 131 | { |
179 | PQfinish (plugin->dbh); | 132 | PQfinish (plugin->dbh); |
180 | plugin->dbh = NULL; | 133 | plugin->dbh = NULL; |
@@ -189,7 +142,7 @@ init_connection (struct Plugin *plugin) | |||
189 | * | 142 | * |
190 | * @param cls closure (our `struct Plugin`) | 143 | * @param cls closure (our `struct Plugin`) |
191 | * @param key key to store @a data under | 144 | * @param key key to store @a data under |
192 | * @param size number of bytes in @a data | 145 | * @param data_size number of bytes in @a data |
193 | * @param data data to store | 146 | * @param data data to store |
194 | * @param type type of the value | 147 | * @param type type of the value |
195 | * @param discard_time when to discard the value in any case | 148 | * @param discard_time when to discard the value in any case |
@@ -200,7 +153,7 @@ init_connection (struct Plugin *plugin) | |||
200 | static ssize_t | 153 | static ssize_t |
201 | postgres_plugin_put (void *cls, | 154 | postgres_plugin_put (void *cls, |
202 | const struct GNUNET_HashCode *key, | 155 | const struct GNUNET_HashCode *key, |
203 | size_t size, | 156 | size_t data_size, |
204 | const char *data, | 157 | const char *data, |
205 | enum GNUNET_BLOCK_Type type, | 158 | enum GNUNET_BLOCK_Type type, |
206 | struct GNUNET_TIME_Absolute discard_time, | 159 | struct GNUNET_TIME_Absolute discard_time, |
@@ -208,36 +161,125 @@ postgres_plugin_put (void *cls, | |||
208 | const struct GNUNET_PeerIdentity *path_info) | 161 | const struct GNUNET_PeerIdentity *path_info) |
209 | { | 162 | { |
210 | struct Plugin *plugin = cls; | 163 | struct Plugin *plugin = cls; |
211 | PGresult *ret; | 164 | uint32_t type32 = (uint32_t) type; |
212 | uint32_t btype = htonl (type); | 165 | struct GNUNET_PQ_QueryParam params[] = { |
213 | uint64_t bexpi = GNUNET_TIME_absolute_hton (discard_time).abs_value_us__; | 166 | GNUNET_PQ_query_param_uint32 (&type32), |
214 | 167 | GNUNET_PQ_query_param_absolute_time (&discard_time), | |
215 | const char *paramValues[] = { | 168 | GNUNET_PQ_query_param_auto_from_type (key), |
216 | (const char *) &btype, | 169 | GNUNET_PQ_query_param_fixed_size (data, data_size), |
217 | (const char *) &bexpi, | 170 | GNUNET_PQ_query_param_fixed_size (path_info, |
218 | (const char *) key, | 171 | path_info_len * sizeof (struct GNUNET_PeerIdentity)), |
219 | (const char *) data, | 172 | GNUNET_PQ_query_param_end |
220 | (const char *) path_info | ||
221 | }; | ||
222 | int paramLengths[] = { | ||
223 | sizeof (btype), | ||
224 | sizeof (bexpi), | ||
225 | sizeof (struct GNUNET_HashCode), | ||
226 | size, | ||
227 | path_info_len * sizeof (struct GNUNET_PeerIdentity) | ||
228 | }; | 173 | }; |
229 | const int paramFormats[] = { 1, 1, 1, 1, 1 }; | 174 | enum GNUNET_PQ_QueryStatus ret; |
230 | 175 | ||
231 | ret = | 176 | ret = GNUNET_PQ_eval_prepared_non_select (plugin->dbh, |
232 | PQexecPrepared (plugin->dbh, "put", 5, paramValues, paramLengths, | 177 | "put", |
233 | paramFormats, 1); | 178 | params); |
234 | if (GNUNET_OK != | 179 | if (0 > ret) |
235 | GNUNET_POSTGRES_check_result (plugin->dbh, ret, | ||
236 | PGRES_COMMAND_OK, "PQexecPrepared", "put")) | ||
237 | return -1; | 180 | return -1; |
238 | plugin->num_items++; | 181 | plugin->num_items++; |
239 | PQclear (ret); | 182 | return data_size + OVERHEAD; |
240 | return size + OVERHEAD; | 183 | } |
184 | |||
185 | |||
186 | /** | ||
187 | * Closure for #handle_results. | ||
188 | */ | ||
189 | struct HandleResultContext | ||
190 | { | ||
191 | |||
192 | /** | ||
193 | * Function to call on each result, may be NULL. | ||
194 | */ | ||
195 | GNUNET_DATACACHE_Iterator iter; | ||
196 | |||
197 | /** | ||
198 | * Closure for @e iter. | ||
199 | */ | ||
200 | void *iter_cls; | ||
201 | |||
202 | /** | ||
203 | * Key used. | ||
204 | */ | ||
205 | const struct GNUNET_HashCode *key; | ||
206 | }; | ||
207 | |||
208 | |||
209 | /** | ||
210 | * Function to be called with the results of a SELECT statement | ||
211 | * that has returned @a num_results results. Parse the result | ||
212 | * and call the callback given in @a cls | ||
213 | * | ||
214 | * @param cls closure of type `struct HandleResultContext` | ||
215 | * @param result the postgres result | ||
216 | * @param num_result the number of results in @a result | ||
217 | */ | ||
218 | static void | ||
219 | handle_results (void *cls, | ||
220 | PGresult *result, | ||
221 | unsigned int num_results) | ||
222 | { | ||
223 | struct HandleResultContext *hrc = cls; | ||
224 | |||
225 | for (unsigned int i=0;i<num_results;i++) | ||
226 | { | ||
227 | struct GNUNET_TIME_Absolute expiration_time; | ||
228 | uint32_t type; | ||
229 | void *data; | ||
230 | size_t data_size; | ||
231 | struct GNUNET_PeerIdentity *path; | ||
232 | size_t path_len; | ||
233 | struct GNUNET_PQ_ResultSpec rs[] = { | ||
234 | GNUNET_PQ_result_spec_absolute_time ("discard_time", | ||
235 | &expiration_time), | ||
236 | GNUNET_PQ_result_spec_uint32 ("type", | ||
237 | &type), | ||
238 | GNUNET_PQ_result_spec_variable_size ("value", | ||
239 | &data, | ||
240 | &data_size), | ||
241 | GNUNET_PQ_result_spec_variable_size ("path", | ||
242 | (void **) &path, | ||
243 | &path_len), | ||
244 | GNUNET_PQ_result_spec_end | ||
245 | }; | ||
246 | |||
247 | if (GNUNET_YES != | ||
248 | GNUNET_PQ_extract_result (result, | ||
249 | rs, | ||
250 | i)) | ||
251 | { | ||
252 | GNUNET_break (0); | ||
253 | return; | ||
254 | } | ||
255 | if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity))) | ||
256 | { | ||
257 | GNUNET_break (0); | ||
258 | path_len = 0; | ||
259 | } | ||
260 | path_len %= sizeof (struct GNUNET_PeerIdentity); | ||
261 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
262 | "Found result of size %u bytes and type %u in database\n", | ||
263 | (unsigned int) data_size, | ||
264 | (unsigned int) type); | ||
265 | if ( (NULL != hrc->iter) && | ||
266 | (GNUNET_SYSERR == | ||
267 | hrc->iter (hrc->iter_cls, | ||
268 | hrc->key, | ||
269 | data_size, | ||
270 | data, | ||
271 | (enum GNUNET_BLOCK_Type) type, | ||
272 | expiration_time, | ||
273 | path_len, | ||
274 | path)) ) | ||
275 | { | ||
276 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
277 | "Ending iteration (client error)\n"); | ||
278 | GNUNET_PQ_cleanup_result (rs); | ||
279 | return; | ||
280 | } | ||
281 | GNUNET_PQ_cleanup_result (rs); | ||
282 | } | ||
241 | } | 283 | } |
242 | 284 | ||
243 | 285 | ||
@@ -260,94 +302,30 @@ postgres_plugin_get (void *cls, | |||
260 | void *iter_cls) | 302 | void *iter_cls) |
261 | { | 303 | { |
262 | struct Plugin *plugin = cls; | 304 | struct Plugin *plugin = cls; |
263 | uint32_t btype = htonl (type); | 305 | uint32_t type32 = (uint32_t) type; |
264 | 306 | struct GNUNET_PQ_QueryParam paramk[] = { | |
265 | const char *paramValues[] = { | 307 | GNUNET_PQ_query_param_auto_from_type (key), |
266 | (const char *) key, | 308 | GNUNET_PQ_query_param_end |
267 | (const char *) &btype | ||
268 | }; | 309 | }; |
269 | int paramLengths[] = { | 310 | struct GNUNET_PQ_QueryParam paramkt[] = { |
270 | sizeof (struct GNUNET_HashCode), | 311 | GNUNET_PQ_query_param_auto_from_type (key), |
271 | sizeof (btype) | 312 | GNUNET_PQ_query_param_uint32 (&type32), |
313 | GNUNET_PQ_query_param_end | ||
272 | }; | 314 | }; |
273 | const int paramFormats[] = { 1, 1 }; | 315 | enum GNUNET_PQ_QueryStatus res; |
274 | struct GNUNET_TIME_Absolute expiration_time; | 316 | struct HandleResultContext hr_ctx; |
275 | uint32_t size; | 317 | |
276 | unsigned int cnt; | 318 | hr_ctx.iter = iter; |
277 | unsigned int i; | 319 | hr_ctx.iter_cls = iter_cls; |
278 | unsigned int path_len; | 320 | hr_ctx.key = key; |
279 | const struct GNUNET_PeerIdentity *path; | 321 | res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh, |
280 | PGresult *res; | 322 | (0 == type) ? "getk" : "getkt", |
281 | 323 | (0 == type) ? paramk : paramkt, | |
282 | res = | 324 | &handle_results, |
283 | PQexecPrepared (plugin->dbh, (type == 0) ? "getk" : "getkt", | 325 | &hr_ctx); |
284 | (type == 0) ? 1 : 2, paramValues, paramLengths, | 326 | if (res < 0) |
285 | paramFormats, 1); | ||
286 | if (GNUNET_OK != | ||
287 | GNUNET_POSTGRES_check_result (plugin->dbh, | ||
288 | res, | ||
289 | PGRES_TUPLES_OK, | ||
290 | "PQexecPrepared", | ||
291 | (type == 0) ? "getk" : "getkt")) | ||
292 | { | ||
293 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
294 | "Ending iteration (postgres error)\n"); | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | if (0 == (cnt = PQntuples (res))) | ||
299 | { | ||
300 | /* no result */ | ||
301 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
302 | "Ending iteration (no more results)\n"); | ||
303 | PQclear (res); | ||
304 | return 0; | ||
305 | } | ||
306 | if (iter == NULL) | ||
307 | { | ||
308 | PQclear (res); | ||
309 | return cnt; | ||
310 | } | ||
311 | if ( (4 != PQnfields (res)) || | ||
312 | (sizeof (uint64_t) != PQfsize (res, 0)) || | ||
313 | (sizeof (uint32_t) != PQfsize (res, 1))) | ||
314 | { | ||
315 | GNUNET_break (0); | ||
316 | PQclear (res); | ||
317 | return 0; | 327 | return 0; |
318 | } | 328 | return res; |
319 | for (i = 0; i < cnt; i++) | ||
320 | { | ||
321 | expiration_time.abs_value_us = | ||
322 | GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0)); | ||
323 | type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1)); | ||
324 | size = PQgetlength (res, i, 2); | ||
325 | path_len = PQgetlength (res, i, 3); | ||
326 | if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity))) | ||
327 | { | ||
328 | GNUNET_break (0); | ||
329 | path_len = 0; | ||
330 | } | ||
331 | path_len %= sizeof (struct GNUNET_PeerIdentity); | ||
332 | path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, i, 3); | ||
333 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
334 | "Found result of size %u bytes and type %u in database\n", | ||
335 | (unsigned int) size, (unsigned int) type); | ||
336 | if (GNUNET_SYSERR == | ||
337 | iter (iter_cls, key, size, PQgetvalue (res, i, 2), | ||
338 | (enum GNUNET_BLOCK_Type) type, | ||
339 | expiration_time, | ||
340 | path_len, | ||
341 | path)) | ||
342 | { | ||
343 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
344 | "Ending iteration (client error)\n"); | ||
345 | PQclear (res); | ||
346 | return cnt; | ||
347 | } | ||
348 | } | ||
349 | PQclear (res); | ||
350 | return cnt; | ||
351 | } | 329 | } |
352 | 330 | ||
353 | 331 | ||
@@ -362,54 +340,53 @@ static int | |||
362 | postgres_plugin_del (void *cls) | 340 | postgres_plugin_del (void *cls) |
363 | { | 341 | { |
364 | struct Plugin *plugin = cls; | 342 | struct Plugin *plugin = cls; |
343 | struct GNUNET_PQ_QueryParam pempty[] = { | ||
344 | GNUNET_PQ_query_param_end | ||
345 | }; | ||
365 | uint32_t size; | 346 | uint32_t size; |
366 | uint32_t oid; | 347 | uint32_t oid; |
367 | struct GNUNET_HashCode key; | 348 | struct GNUNET_HashCode key; |
368 | PGresult *res; | 349 | struct GNUNET_PQ_ResultSpec rs[] = { |
350 | GNUNET_PQ_result_spec_uint32 ("len", | ||
351 | &size), | ||
352 | GNUNET_PQ_result_spec_uint32 ("oid", | ||
353 | &oid), | ||
354 | GNUNET_PQ_result_spec_auto_from_type ("key", | ||
355 | &key), | ||
356 | GNUNET_PQ_result_spec_end | ||
357 | }; | ||
358 | enum GNUNET_PQ_QueryStatus res; | ||
359 | struct GNUNET_PQ_QueryParam dparam[] = { | ||
360 | GNUNET_PQ_query_param_uint32 (&oid), | ||
361 | GNUNET_PQ_query_param_end | ||
362 | }; | ||
369 | 363 | ||
370 | res = PQexecPrepared (plugin->dbh, | 364 | res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, |
371 | "getm", | 365 | "getm", |
372 | 0, NULL, NULL, NULL, 1); | 366 | pempty, |
373 | if (GNUNET_OK != | 367 | rs); |
374 | GNUNET_POSTGRES_check_result (plugin->dbh, | 368 | if (0 > res) |
375 | res, | 369 | return GNUNET_SYSERR; |
376 | PGRES_TUPLES_OK, | 370 | if (GNUNET_PQ_STATUS_SUCCESS_NO_RESULTS == res) |
377 | "PQexecPrepared", | ||
378 | "getm")) | ||
379 | { | ||
380 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
381 | "Ending iteration (postgres error)\n"); | ||
382 | return 0; | ||
383 | } | ||
384 | if (0 == PQntuples (res)) | ||
385 | { | 371 | { |
386 | /* no result */ | 372 | /* no result */ |
387 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 373 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
388 | "Ending iteration (no more results)\n"); | 374 | "Ending iteration (no more results)\n"); |
389 | PQclear (res); | ||
390 | return GNUNET_SYSERR; | ||
391 | } | ||
392 | if ((3 != PQnfields (res)) || (sizeof (size) != PQfsize (res, 0)) || | ||
393 | (sizeof (oid) != PQfsize (res, 1)) || | ||
394 | (sizeof (struct GNUNET_HashCode) != PQgetlength (res, 0, 2))) | ||
395 | { | ||
396 | GNUNET_break (0); | ||
397 | PQclear (res); | ||
398 | return 0; | 375 | return 0; |
399 | } | 376 | } |
400 | size = ntohl (*(uint32_t *) PQgetvalue (res, 0, 0)); | 377 | res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh, |
401 | oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1)); | 378 | "delrow", |
402 | GNUNET_memcpy (&key, PQgetvalue (res, 0, 2), sizeof (struct GNUNET_HashCode)); | 379 | dparam); |
403 | PQclear (res); | 380 | if (0 > res) |
404 | if (GNUNET_OK != | 381 | { |
405 | GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, | 382 | GNUNET_PQ_cleanup_result (rs); |
406 | "delrow", | ||
407 | oid)) | ||
408 | return GNUNET_SYSERR; | 383 | return GNUNET_SYSERR; |
384 | } | ||
409 | plugin->num_items--; | 385 | plugin->num_items--; |
410 | plugin->env->delete_notify (plugin->env->cls, | 386 | plugin->env->delete_notify (plugin->env->cls, |
411 | &key, | 387 | &key, |
412 | size + OVERHEAD); | 388 | size + OVERHEAD); |
389 | GNUNET_PQ_cleanup_result (rs); | ||
413 | return GNUNET_OK; | 390 | return GNUNET_OK; |
414 | } | 391 | } |
415 | 392 | ||