diff options
Diffstat (limited to 'src/pq/pq_connect.c')
-rw-r--r-- | src/pq/pq_connect.c | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c index 02af17c8c..f6fd3e34b 100644 --- a/src/pq/pq_connect.c +++ b/src/pq/pq_connect.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2017, 2019, 2020, 2021 GNUnet e.V. | 3 | Copyright (C) 2017, 2019, 2020, 2021, 2023 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -21,6 +21,7 @@ | |||
21 | * @file pq/pq_connect.c | 21 | * @file pq/pq_connect.c |
22 | * @brief functions to connect to libpq (PostGres) | 22 | * @brief functions to connect to libpq (PostGres) |
23 | * @author Christian Grothoff | 23 | * @author Christian Grothoff |
24 | * @author Özgür Kesim | ||
24 | */ | 25 | */ |
25 | #include "platform.h" | 26 | #include "platform.h" |
26 | #include "pq.h" | 27 | #include "pq.h" |
@@ -321,6 +322,103 @@ GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) | |||
321 | } | 322 | } |
322 | 323 | ||
323 | 324 | ||
325 | /** | ||
326 | * Retrieves the Oid's for the supported array types and sets db->arraytype2oid | ||
327 | * on succes. | ||
328 | * | ||
329 | * @param db Context for the database connection | ||
330 | * @return GNUNET_OK on success, GNUNET_SYSERR otherwise | ||
331 | */ | ||
332 | static enum GNUNET_GenericReturnValue | ||
333 | get_array_type_oids (struct GNUNET_PQ_Context *db) | ||
334 | { | ||
335 | PGresult *res; | ||
336 | ExecStatusType est; | ||
337 | GNUNET_assert (NULL != db); | ||
338 | |||
339 | /* Initialize to Oid(0) (= unknown) */ | ||
340 | memset (db->arraytype2oid, | ||
341 | 0, | ||
342 | sizeof(db->arraytype2oid)); | ||
343 | |||
344 | res = PQexec (db->conn, | ||
345 | "SELECT" | ||
346 | " typname, oid" | ||
347 | " FROM pg_type " | ||
348 | " WHERE typname like '\\_%';"); | ||
349 | |||
350 | est = PQresultStatus (res); | ||
351 | if ( (PGRES_COMMAND_OK != est) && | ||
352 | (PGRES_TUPLES_OK != est)) | ||
353 | { | ||
354 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
355 | "Failed to run statement to retrieve Oids for array types!\n"); | ||
356 | return GNUNET_SYSERR; | ||
357 | } | ||
358 | |||
359 | if ( (2 != PQnfields (res)) || | ||
360 | (0 != PQfnumber (res, "typname")) || | ||
361 | (1 != PQfnumber (res, "oid")) | ||
362 | ) | ||
363 | { | ||
364 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
365 | "Unexpected table retrieved for array types\n"); | ||
366 | return GNUNET_SYSERR; | ||
367 | } | ||
368 | |||
369 | { | ||
370 | int nrows = PQntuples (res); | ||
371 | int nfound = 1; /* skip GNUNET_PQ_ARRAY_UNKNOWN */ | ||
372 | |||
373 | for (int r = 0; r < nrows; r++) | ||
374 | { | ||
375 | enum GNUNET_PQ_ArrayTypes atype = GNUNET_PQ_ARRAY_UNKNOWN; | ||
376 | char *typ_s = PQgetvalue (res,r,0); | ||
377 | char *oid_s = PQgetvalue (res,r,1); | ||
378 | GNUNET_assert (NULL != typ_s); | ||
379 | GNUNET_assert (NULL != oid_s); | ||
380 | |||
381 | if (! strcmp (typ_s,"_bool")) | ||
382 | atype = GNUNET_PQ_ARRAY_BOOL; | ||
383 | else if (! strcmp (typ_s,"_int2")) | ||
384 | atype = GNUNET_PQ_ARRAY_INT2; | ||
385 | else if (! strcmp (typ_s,"_int4")) | ||
386 | atype = GNUNET_PQ_ARRAY_INT4; | ||
387 | else if (! strcmp (typ_s,"_int8")) | ||
388 | atype = GNUNET_PQ_ARRAY_INT8; | ||
389 | else if (! strcmp (typ_s,"_bytea")) | ||
390 | atype = GNUNET_PQ_ARRAY_BYTEA; | ||
391 | else if (! strcmp (typ_s,"_varchar")) | ||
392 | atype = GNUNET_PQ_ARRAY_VARCHAR; | ||
393 | else | ||
394 | continue; | ||
395 | |||
396 | GNUNET_assert (GNUNET_PQ_ARRAY_MAX > atype); | ||
397 | |||
398 | if ((GNUNET_PQ_ARRAY_UNKNOWN != atype) && | ||
399 | (1 == sscanf (oid_s, "%u", &db->arraytype2oid[atype]))) | ||
400 | { | ||
401 | nfound++; | ||
402 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
403 | "OID[%s]: %d\n", | ||
404 | typ_s, db->arraytype2oid[atype]); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | if (GNUNET_PQ_ARRAY_MAX != nfound) | ||
409 | { | ||
410 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
411 | "Couldn't find all array types, only found %d of %d!\n", | ||
412 | nfound - 1, | ||
413 | GNUNET_PQ_ARRAY_MAX - 1); | ||
414 | return GNUNET_SYSERR; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | return GNUNET_OK; | ||
419 | } | ||
420 | |||
421 | |||
324 | void | 422 | void |
325 | GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | 423 | GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) |
326 | { | 424 | { |
@@ -411,6 +509,16 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | |||
411 | } | 509 | } |
412 | } | 510 | } |
413 | 511 | ||
512 | /* Retrieve the OIDs for the supported Array types */ | ||
513 | if (GNUNET_SYSERR == get_array_type_oids (db)) | ||
514 | { | ||
515 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
516 | "Failed to retrieve OID information for array types!\n"); | ||
517 | PQfinish (db->conn); | ||
518 | db->conn = NULL; | ||
519 | return; | ||
520 | } | ||
521 | |||
414 | if (NULL != db->auto_suffix) | 522 | if (NULL != db->auto_suffix) |
415 | { | 523 | { |
416 | PGresult *res; | 524 | PGresult *res; |
@@ -450,6 +558,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | |||
450 | return; | 558 | return; |
451 | } | 559 | } |
452 | } | 560 | } |
561 | |||
453 | if ( (NULL != db->es) && | 562 | if ( (NULL != db->es) && |
454 | (GNUNET_OK != | 563 | (GNUNET_OK != |
455 | GNUNET_PQ_exec_statements (db, | 564 | GNUNET_PQ_exec_statements (db, |