aboutsummaryrefslogtreecommitdiff
path: root/src/pq/pq_connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pq/pq_connect.c')
-rw-r--r--src/pq/pq_connect.c111
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 */
332static enum GNUNET_GenericReturnValue
333get_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
324void 422void
325GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) 423GNUNET_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,