diff options
Diffstat (limited to 'src/psycstore')
-rw-r--r-- | src/psycstore/plugin_psycstore_postgres.c | 370 |
1 files changed, 177 insertions, 193 deletions
diff --git a/src/psycstore/plugin_psycstore_postgres.c b/src/psycstore/plugin_psycstore_postgres.c index 2dcafd4..360d0eb 100644 --- a/src/psycstore/plugin_psycstore_postgres.c +++ b/src/psycstore/plugin_psycstore_postgres.c | |||
@@ -70,7 +70,7 @@ struct Plugin | |||
70 | /** | 70 | /** |
71 | * Native Postgres database handle. | 71 | * Native Postgres database handle. |
72 | */ | 72 | */ |
73 | PGconn *dbh; | 73 | struct GNUNET_PQ_Context *dbh; |
74 | 74 | ||
75 | enum Transactions transaction; | 75 | enum Transactions transaction; |
76 | 76 | ||
@@ -160,201 +160,185 @@ database_setup (struct Plugin *plugin) | |||
160 | GNUNET_PQ_EXECUTE_STATEMENT_END | 160 | GNUNET_PQ_EXECUTE_STATEMENT_END |
161 | }; | 161 | }; |
162 | 162 | ||
163 | /* Prepare statements */ | ||
164 | struct GNUNET_PQ_PreparedStatement ps[] = { | ||
165 | GNUNET_PQ_make_prepare ("transaction_begin", | ||
166 | "BEGIN", 0), | ||
167 | GNUNET_PQ_make_prepare ("transaction_commit", | ||
168 | "COMMIT", 0), | ||
169 | GNUNET_PQ_make_prepare ("transaction_rollback", | ||
170 | "ROLLBACK", 0), | ||
171 | GNUNET_PQ_make_prepare ("insert_channel_key", | ||
172 | "INSERT INTO channels (pub_key) VALUES ($1)" | ||
173 | " ON CONFLICT DO NOTHING", 1), | ||
174 | GNUNET_PQ_make_prepare ("insert_slave_key", | ||
175 | "INSERT INTO slaves (pub_key) VALUES ($1)" | ||
176 | " ON CONFLICT DO NOTHING", 1), | ||
177 | GNUNET_PQ_make_prepare ("insert_membership", | ||
178 | "INSERT INTO membership\n" | ||
179 | " (channel_id, slave_id, did_join, announced_at,\n" | ||
180 | " effective_since, group_generation)\n" | ||
181 | "VALUES (get_chan_id($1),\n" | ||
182 | " get_slave_id($2),\n" | ||
183 | " $3, $4, $5, $6)", 6), | ||
184 | GNUNET_PQ_make_prepare ("select_membership", | ||
185 | "SELECT did_join FROM membership\n" | ||
186 | "WHERE channel_id = get_chan_id($1)\n" | ||
187 | " AND slave_id = get_slave_id($2)\n" | ||
188 | " AND effective_since <= $3 AND did_join = 1\n" | ||
189 | "ORDER BY announced_at DESC LIMIT 1", 3), | ||
190 | GNUNET_PQ_make_prepare ("insert_fragment", | ||
191 | "INSERT INTO messages\n" | ||
192 | " (channel_id, hop_counter, signature, purpose,\n" | ||
193 | " fragment_id, fragment_offset, message_id,\n" | ||
194 | " group_generation, multicast_flags, psycstore_flags, data)\n" | ||
195 | "VALUES (get_chan_id($1),\n" | ||
196 | " $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)" | ||
197 | "ON CONFLICT DO NOTHING", 11), | ||
198 | GNUNET_PQ_make_prepare ("update_message_flags", | ||
199 | "UPDATE messages\n" | ||
200 | "SET psycstore_flags = psycstore_flags | $1\n" | ||
201 | "WHERE channel_id = get_chan_id($2) \n" | ||
202 | " AND message_id = $3 AND fragment_offset = 0", 3), | ||
203 | GNUNET_PQ_make_prepare ("select_fragments", | ||
204 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
205 | " fragment_offset, message_id, group_generation,\n" | ||
206 | " multicast_flags, psycstore_flags, data\n" | ||
207 | "FROM messages\n" | ||
208 | "WHERE channel_id = get_chan_id($1) \n" | ||
209 | " AND $2 <= fragment_id AND fragment_id <= $3", 3), | ||
210 | /** @todo select_messages: add method_prefix filter */ | ||
211 | GNUNET_PQ_make_prepare ("select_messages", | ||
212 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
213 | " fragment_offset, message_id, group_generation,\n" | ||
214 | " multicast_flags, psycstore_flags, data\n" | ||
215 | "FROM messages\n" | ||
216 | "WHERE channel_id = get_chan_id($1) \n" | ||
217 | " AND $2 <= message_id AND message_id <= $3\n" | ||
218 | "LIMIT $4;", 4), | ||
219 | /** @todo select_latest_messages: add method_prefix filter */ | ||
220 | GNUNET_PQ_make_prepare ("select_latest_fragments", | ||
221 | "SELECT rev.hop_counter AS hop_counter,\n" | ||
222 | " rev.signature AS signature,\n" | ||
223 | " rev.purpose AS purpose,\n" | ||
224 | " rev.fragment_id AS fragment_id,\n" | ||
225 | " rev.fragment_offset AS fragment_offset,\n" | ||
226 | " rev.message_id AS message_id,\n" | ||
227 | " rev.group_generation AS group_generation,\n" | ||
228 | " rev.multicast_flags AS multicast_flags,\n" | ||
229 | " rev.psycstore_flags AS psycstore_flags,\n" | ||
230 | " rev.data AS data\n" | ||
231 | " FROM\n" | ||
232 | " (SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
233 | " fragment_offset, message_id, group_generation,\n" | ||
234 | " multicast_flags, psycstore_flags, data \n" | ||
235 | " FROM messages\n" | ||
236 | " WHERE channel_id = get_chan_id($1) \n" | ||
237 | " ORDER BY fragment_id DESC\n" | ||
238 | " LIMIT $2) AS rev\n" | ||
239 | " ORDER BY rev.fragment_id;", 2), | ||
240 | GNUNET_PQ_make_prepare ("select_latest_messages", | ||
241 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
242 | " fragment_offset, message_id, group_generation,\n" | ||
243 | " multicast_flags, psycstore_flags, data\n" | ||
244 | "FROM messages\n" | ||
245 | "WHERE channel_id = get_chan_id($1)\n" | ||
246 | " AND message_id IN\n" | ||
247 | " (SELECT message_id\n" | ||
248 | " FROM messages\n" | ||
249 | " WHERE channel_id = get_chan_id($2) \n" | ||
250 | " GROUP BY message_id\n" | ||
251 | " ORDER BY message_id\n" | ||
252 | " DESC LIMIT $3)\n" | ||
253 | "ORDER BY fragment_id", 3), | ||
254 | GNUNET_PQ_make_prepare ("select_message_fragment", | ||
255 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
256 | " fragment_offset, message_id, group_generation,\n" | ||
257 | " multicast_flags, psycstore_flags, data\n" | ||
258 | "FROM messages\n" | ||
259 | "WHERE channel_id = get_chan_id($1) \n" | ||
260 | " AND message_id = $2 AND fragment_offset = $3", 3), | ||
261 | GNUNET_PQ_make_prepare ("select_counters_message", | ||
262 | "SELECT fragment_id, message_id, group_generation\n" | ||
263 | "FROM messages\n" | ||
264 | "WHERE channel_id = get_chan_id($1)\n" | ||
265 | "ORDER BY fragment_id DESC LIMIT 1", 1), | ||
266 | GNUNET_PQ_make_prepare ("select_counters_state", | ||
267 | "SELECT max_state_message_id\n" | ||
268 | "FROM channels\n" | ||
269 | "WHERE pub_key = $1 AND max_state_message_id IS NOT NULL", 1), | ||
270 | GNUNET_PQ_make_prepare ("update_max_state_message_id", | ||
271 | "UPDATE channels\n" | ||
272 | "SET max_state_message_id = $1\n" | ||
273 | "WHERE pub_key = $2", 2), | ||
274 | |||
275 | GNUNET_PQ_make_prepare ("update_state_hash_message_id", | ||
276 | "UPDATE channels\n" | ||
277 | "SET state_hash_message_id = $1\n" | ||
278 | "WHERE pub_key = $2", 2), | ||
279 | GNUNET_PQ_make_prepare ("insert_state_current", | ||
280 | "INSERT INTO state\n" | ||
281 | " (channel_id, name, value_current, value_signed)\n" | ||
282 | "SELECT new.channel_id, new.name,\n" | ||
283 | " new.value_current, old.value_signed\n" | ||
284 | "FROM (SELECT get_chan_id($1) AS channel_id,\n" | ||
285 | " $2::TEXT AS name, $3::BYTEA AS value_current) AS new\n" | ||
286 | "LEFT JOIN (SELECT channel_id, name, value_signed\n" | ||
287 | " FROM state) AS old\n" | ||
288 | "ON new.channel_id = old.channel_id AND new.name = old.name\n" | ||
289 | "ON CONFLICT (channel_id, name)\n" | ||
290 | " DO UPDATE SET value_current = EXCLUDED.value_current,\n" | ||
291 | " value_signed = EXCLUDED.value_signed", 3), | ||
292 | GNUNET_PQ_make_prepare ("delete_state_empty", | ||
293 | "DELETE FROM state\n" | ||
294 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = $1)\n" | ||
295 | " AND (value_current IS NULL OR length(value_current) = 0)\n" | ||
296 | " AND (value_signed IS NULL OR length(value_signed) = 0)", 1), | ||
297 | GNUNET_PQ_make_prepare ("update_state_signed", | ||
298 | "UPDATE state\n" | ||
299 | "SET value_signed = value_current\n" | ||
300 | "WHERE channel_id = get_chan_id($1) ", 1), | ||
301 | GNUNET_PQ_make_prepare ("delete_state", | ||
302 | "DELETE FROM state\n" | ||
303 | "WHERE channel_id = get_chan_id($1) ", 1), | ||
304 | GNUNET_PQ_make_prepare ("insert_state_sync", | ||
305 | "INSERT INTO state_sync (channel_id, name, value)\n" | ||
306 | "VALUES (get_chan_id($1), $2, $3)", 3), | ||
307 | GNUNET_PQ_make_prepare ("insert_state_from_sync", | ||
308 | "INSERT INTO state\n" | ||
309 | " (channel_id, name, value_current, value_signed)\n" | ||
310 | "SELECT channel_id, name, value, value\n" | ||
311 | "FROM state_sync\n" | ||
312 | "WHERE channel_id = get_chan_id($1)", 1), | ||
313 | GNUNET_PQ_make_prepare ("delete_state_sync", | ||
314 | "DELETE FROM state_sync\n" | ||
315 | "WHERE channel_id = get_chan_id($1)", 1), | ||
316 | GNUNET_PQ_make_prepare ("select_state_one", | ||
317 | "SELECT value_current\n" | ||
318 | "FROM state\n" | ||
319 | "WHERE channel_id = get_chan_id($1)\n" | ||
320 | " AND name = $2", 2), | ||
321 | GNUNET_PQ_make_prepare ("select_state_prefix", | ||
322 | "SELECT name, value_current\n" | ||
323 | "FROM state\n" | ||
324 | "WHERE channel_id = get_chan_id($1)\n" | ||
325 | " AND (name = $2 OR substr(name, 1, $3) = $4)", 4), | ||
326 | GNUNET_PQ_make_prepare ("select_state_signed", | ||
327 | "SELECT name, value_signed\n" | ||
328 | "FROM state\n" | ||
329 | "WHERE channel_id = get_chan_id($1)\n" | ||
330 | " AND value_signed IS NOT NULL", 1), | ||
331 | GNUNET_PQ_PREPARED_STATEMENT_END | ||
332 | }; | ||
333 | |||
163 | /* Open database and precompile statements */ | 334 | /* Open database and precompile statements */ |
164 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg, | 335 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg, |
165 | "psycstore-postgres"); | 336 | "psycstore-postgres", |
337 | es, | ||
338 | ps); | ||
339 | |||
166 | if (NULL == plugin->dbh) | 340 | if (NULL == plugin->dbh) |
167 | return GNUNET_SYSERR; | 341 | return GNUNET_SYSERR; |
168 | if (GNUNET_OK != | ||
169 | GNUNET_PQ_exec_statements (plugin->dbh, | ||
170 | es)) | ||
171 | { | ||
172 | PQfinish (plugin->dbh); | ||
173 | plugin->dbh = NULL; | ||
174 | return GNUNET_SYSERR; | ||
175 | } | ||
176 | |||
177 | /* Prepare statements */ | ||
178 | { | ||
179 | struct GNUNET_PQ_PreparedStatement ps[] = { | ||
180 | GNUNET_PQ_make_prepare ("transaction_begin", | ||
181 | "BEGIN", 0), | ||
182 | GNUNET_PQ_make_prepare ("transaction_commit", | ||
183 | "COMMIT", 0), | ||
184 | GNUNET_PQ_make_prepare ("transaction_rollback", | ||
185 | "ROLLBACK", 0), | ||
186 | GNUNET_PQ_make_prepare ("insert_channel_key", | ||
187 | "INSERT INTO channels (pub_key) VALUES ($1)" | ||
188 | " ON CONFLICT DO NOTHING", 1), | ||
189 | GNUNET_PQ_make_prepare ("insert_slave_key", | ||
190 | "INSERT INTO slaves (pub_key) VALUES ($1)" | ||
191 | " ON CONFLICT DO NOTHING", 1), | ||
192 | GNUNET_PQ_make_prepare ("insert_membership", | ||
193 | "INSERT INTO membership\n" | ||
194 | " (channel_id, slave_id, did_join, announced_at,\n" | ||
195 | " effective_since, group_generation)\n" | ||
196 | "VALUES (get_chan_id($1),\n" | ||
197 | " get_slave_id($2),\n" | ||
198 | " $3, $4, $5, $6)", 6), | ||
199 | GNUNET_PQ_make_prepare ("select_membership", | ||
200 | "SELECT did_join FROM membership\n" | ||
201 | "WHERE channel_id = get_chan_id($1)\n" | ||
202 | " AND slave_id = get_slave_id($2)\n" | ||
203 | " AND effective_since <= $3 AND did_join = 1\n" | ||
204 | "ORDER BY announced_at DESC LIMIT 1", 3), | ||
205 | GNUNET_PQ_make_prepare ("insert_fragment", | ||
206 | "INSERT INTO messages\n" | ||
207 | " (channel_id, hop_counter, signature, purpose,\n" | ||
208 | " fragment_id, fragment_offset, message_id,\n" | ||
209 | " group_generation, multicast_flags, psycstore_flags, data)\n" | ||
210 | "VALUES (get_chan_id($1),\n" | ||
211 | " $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)" | ||
212 | "ON CONFLICT DO NOTHING", 11), | ||
213 | GNUNET_PQ_make_prepare ("update_message_flags", | ||
214 | "UPDATE messages\n" | ||
215 | "SET psycstore_flags = psycstore_flags | $1\n" | ||
216 | "WHERE channel_id = get_chan_id($2) \n" | ||
217 | " AND message_id = $3 AND fragment_offset = 0", 3), | ||
218 | GNUNET_PQ_make_prepare ("select_fragments", | ||
219 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
220 | " fragment_offset, message_id, group_generation,\n" | ||
221 | " multicast_flags, psycstore_flags, data\n" | ||
222 | "FROM messages\n" | ||
223 | "WHERE channel_id = get_chan_id($1) \n" | ||
224 | " AND $2 <= fragment_id AND fragment_id <= $3", 3), | ||
225 | /** @todo select_messages: add method_prefix filter */ | ||
226 | GNUNET_PQ_make_prepare ("select_messages", | ||
227 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
228 | " fragment_offset, message_id, group_generation,\n" | ||
229 | " multicast_flags, psycstore_flags, data\n" | ||
230 | "FROM messages\n" | ||
231 | "WHERE channel_id = get_chan_id($1) \n" | ||
232 | " AND $2 <= message_id AND message_id <= $3\n" | ||
233 | "LIMIT $4;", 4), | ||
234 | /** @todo select_latest_messages: add method_prefix filter */ | ||
235 | GNUNET_PQ_make_prepare ("select_latest_fragments", | ||
236 | "SELECT rev.hop_counter AS hop_counter,\n" | ||
237 | " rev.signature AS signature,\n" | ||
238 | " rev.purpose AS purpose,\n" | ||
239 | " rev.fragment_id AS fragment_id,\n" | ||
240 | " rev.fragment_offset AS fragment_offset,\n" | ||
241 | " rev.message_id AS message_id,\n" | ||
242 | " rev.group_generation AS group_generation,\n" | ||
243 | " rev.multicast_flags AS multicast_flags,\n" | ||
244 | " rev.psycstore_flags AS psycstore_flags,\n" | ||
245 | " rev.data AS data\n" | ||
246 | " FROM\n" | ||
247 | " (SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
248 | " fragment_offset, message_id, group_generation,\n" | ||
249 | " multicast_flags, psycstore_flags, data \n" | ||
250 | " FROM messages\n" | ||
251 | " WHERE channel_id = get_chan_id($1) \n" | ||
252 | " ORDER BY fragment_id DESC\n" | ||
253 | " LIMIT $2) AS rev\n" | ||
254 | " ORDER BY rev.fragment_id;", 2), | ||
255 | GNUNET_PQ_make_prepare ("select_latest_messages", | ||
256 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
257 | " fragment_offset, message_id, group_generation,\n" | ||
258 | " multicast_flags, psycstore_flags, data\n" | ||
259 | "FROM messages\n" | ||
260 | "WHERE channel_id = get_chan_id($1)\n" | ||
261 | " AND message_id IN\n" | ||
262 | " (SELECT message_id\n" | ||
263 | " FROM messages\n" | ||
264 | " WHERE channel_id = get_chan_id($2) \n" | ||
265 | " GROUP BY message_id\n" | ||
266 | " ORDER BY message_id\n" | ||
267 | " DESC LIMIT $3)\n" | ||
268 | "ORDER BY fragment_id", 3), | ||
269 | GNUNET_PQ_make_prepare ("select_message_fragment", | ||
270 | "SELECT hop_counter, signature, purpose, fragment_id,\n" | ||
271 | " fragment_offset, message_id, group_generation,\n" | ||
272 | " multicast_flags, psycstore_flags, data\n" | ||
273 | "FROM messages\n" | ||
274 | "WHERE channel_id = get_chan_id($1) \n" | ||
275 | " AND message_id = $2 AND fragment_offset = $3", 3), | ||
276 | GNUNET_PQ_make_prepare ("select_counters_message", | ||
277 | "SELECT fragment_id, message_id, group_generation\n" | ||
278 | "FROM messages\n" | ||
279 | "WHERE channel_id = get_chan_id($1)\n" | ||
280 | "ORDER BY fragment_id DESC LIMIT 1", 1), | ||
281 | GNUNET_PQ_make_prepare ("select_counters_state", | ||
282 | "SELECT max_state_message_id\n" | ||
283 | "FROM channels\n" | ||
284 | "WHERE pub_key = $1 AND max_state_message_id IS NOT NULL", 1), | ||
285 | GNUNET_PQ_make_prepare ("update_max_state_message_id", | ||
286 | "UPDATE channels\n" | ||
287 | "SET max_state_message_id = $1\n" | ||
288 | "WHERE pub_key = $2", 2), | ||
289 | |||
290 | GNUNET_PQ_make_prepare ("update_state_hash_message_id", | ||
291 | "UPDATE channels\n" | ||
292 | "SET state_hash_message_id = $1\n" | ||
293 | "WHERE pub_key = $2", 2), | ||
294 | GNUNET_PQ_make_prepare ("insert_state_current", | ||
295 | "INSERT INTO state\n" | ||
296 | " (channel_id, name, value_current, value_signed)\n" | ||
297 | "SELECT new.channel_id, new.name,\n" | ||
298 | " new.value_current, old.value_signed\n" | ||
299 | "FROM (SELECT get_chan_id($1) AS channel_id,\n" | ||
300 | " $2::TEXT AS name, $3::BYTEA AS value_current) AS new\n" | ||
301 | "LEFT JOIN (SELECT channel_id, name, value_signed\n" | ||
302 | " FROM state) AS old\n" | ||
303 | "ON new.channel_id = old.channel_id AND new.name = old.name\n" | ||
304 | "ON CONFLICT (channel_id, name)\n" | ||
305 | " DO UPDATE SET value_current = EXCLUDED.value_current,\n" | ||
306 | " value_signed = EXCLUDED.value_signed", 3), | ||
307 | GNUNET_PQ_make_prepare ("delete_state_empty", | ||
308 | "DELETE FROM state\n" | ||
309 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = $1)\n" | ||
310 | " AND (value_current IS NULL OR length(value_current) = 0)\n" | ||
311 | " AND (value_signed IS NULL OR length(value_signed) = 0)", 1), | ||
312 | GNUNET_PQ_make_prepare ("update_state_signed", | ||
313 | "UPDATE state\n" | ||
314 | "SET value_signed = value_current\n" | ||
315 | "WHERE channel_id = get_chan_id($1) ", 1), | ||
316 | GNUNET_PQ_make_prepare ("delete_state", | ||
317 | "DELETE FROM state\n" | ||
318 | "WHERE channel_id = get_chan_id($1) ", 1), | ||
319 | GNUNET_PQ_make_prepare ("insert_state_sync", | ||
320 | "INSERT INTO state_sync (channel_id, name, value)\n" | ||
321 | "VALUES (get_chan_id($1), $2, $3)", 3), | ||
322 | GNUNET_PQ_make_prepare ("insert_state_from_sync", | ||
323 | "INSERT INTO state\n" | ||
324 | " (channel_id, name, value_current, value_signed)\n" | ||
325 | "SELECT channel_id, name, value, value\n" | ||
326 | "FROM state_sync\n" | ||
327 | "WHERE channel_id = get_chan_id($1)", 1), | ||
328 | GNUNET_PQ_make_prepare ("delete_state_sync", | ||
329 | "DELETE FROM state_sync\n" | ||
330 | "WHERE channel_id = get_chan_id($1)", 1), | ||
331 | GNUNET_PQ_make_prepare ("select_state_one", | ||
332 | "SELECT value_current\n" | ||
333 | "FROM state\n" | ||
334 | "WHERE channel_id = get_chan_id($1)\n" | ||
335 | " AND name = $2", 2), | ||
336 | GNUNET_PQ_make_prepare ("select_state_prefix", | ||
337 | "SELECT name, value_current\n" | ||
338 | "FROM state\n" | ||
339 | "WHERE channel_id = get_chan_id($1)\n" | ||
340 | " AND (name = $2 OR substr(name, 1, $3) = $4)", 4), | ||
341 | GNUNET_PQ_make_prepare ("select_state_signed", | ||
342 | "SELECT name, value_signed\n" | ||
343 | "FROM state\n" | ||
344 | "WHERE channel_id = get_chan_id($1)\n" | ||
345 | " AND value_signed IS NOT NULL", 1), | ||
346 | GNUNET_PQ_PREPARED_STATEMENT_END | ||
347 | }; | ||
348 | |||
349 | if (GNUNET_OK != | ||
350 | GNUNET_PQ_prepare_statements (plugin->dbh, | ||
351 | ps)) | ||
352 | { | ||
353 | PQfinish (plugin->dbh); | ||
354 | plugin->dbh = NULL; | ||
355 | return GNUNET_SYSERR; | ||
356 | } | ||
357 | } | ||
358 | 342 | ||
359 | return GNUNET_OK; | 343 | return GNUNET_OK; |
360 | } | 344 | } |
@@ -368,7 +352,7 @@ database_setup (struct Plugin *plugin) | |||
368 | static void | 352 | static void |
369 | database_shutdown (struct Plugin *plugin) | 353 | database_shutdown (struct Plugin *plugin) |
370 | { | 354 | { |
371 | PQfinish (plugin->dbh); | 355 | GNUNET_PQ_disconnect (plugin->dbh); |
372 | plugin->dbh = NULL; | 356 | plugin->dbh = NULL; |
373 | } | 357 | } |
374 | 358 | ||