diff options
author | Özgür Kesim <oec-taler@kesim.org> | 2023-05-06 15:21:41 +0200 |
---|---|---|
committer | Özgür Kesim <oec-taler@kesim.org> | 2023-05-06 15:21:41 +0200 |
commit | 25fb12006dd655e31e345593ad5da2ef724b5c45 (patch) | |
tree | f805fa3c4cf661f27fd66172bbbaeec33c389b28 | |
parent | cd8d83a631c92086a606fad0952219333afc3272 (diff) | |
download | gnunet-25fb12006dd655e31e345593ad5da2ef724b5c45.tar.gz gnunet-25fb12006dd655e31e345593ad5da2ef724b5c45.zip |
pq: add array-type support for PQ [WIP, 1/n]
NEWS: initial steps towards support of array-types in posgresql
- added enum GNUNET_PQ_ArrayTypes
- generate mapping of supported array-types and OIDs during connect()
-rw-r--r-- | src/include/gnunet_pq_lib.h | 15 | ||||
-rw-r--r-- | src/pq/pq.h | 6 | ||||
-rw-r--r-- | src/pq/pq_connect.c | 111 |
3 files changed, 131 insertions, 1 deletions
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index 4cbc2a139..3e4ce3427 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h | |||
@@ -148,6 +148,21 @@ GNUNET_PQ_query_param_bool (bool b); | |||
148 | 148 | ||
149 | 149 | ||
150 | /** | 150 | /** |
151 | * Array types (in Postgres) that are supported in GNUnet. | ||
152 | */ | ||
153 | enum GNUNET_PQ_ArrayTypes | ||
154 | { | ||
155 | GNUNET_PQ_ARRAY_UNKNOWN, /* Unsupported type */ | ||
156 | GNUNET_PQ_ARRAY_BOOL, | ||
157 | GNUNET_PQ_ARRAY_INT2, | ||
158 | GNUNET_PQ_ARRAY_INT4, | ||
159 | GNUNET_PQ_ARRAY_INT8, | ||
160 | GNUNET_PQ_ARRAY_BYTEA, | ||
161 | GNUNET_PQ_ARRAY_VARCHAR, | ||
162 | GNUNET_PQ_ARRAY_MAX, /* Must be last */ | ||
163 | }; | ||
164 | |||
165 | /** | ||
151 | * Information for an array argument. | 166 | * Information for an array argument. |
152 | */ | 167 | */ |
153 | struct GNUNET_PQ_ArraySpec | 168 | struct GNUNET_PQ_ArraySpec |
diff --git a/src/pq/pq.h b/src/pq/pq.h index f9b59e058..e69f0ed96 100644 --- a/src/pq/pq.h +++ b/src/pq/pq.h | |||
@@ -98,9 +98,15 @@ struct GNUNET_PQ_Context | |||
98 | * Flags controlling the connection. | 98 | * Flags controlling the connection. |
99 | */ | 99 | */ |
100 | enum GNUNET_PQ_Options flags; | 100 | enum GNUNET_PQ_Options flags; |
101 | |||
102 | /** | ||
103 | * Mapping between array types and Oid's, filled at reconnect | ||
104 | */ | ||
105 | Oid arraytype2oid[GNUNET_PQ_ARRAY_MAX]; | ||
101 | }; | 106 | }; |
102 | 107 | ||
103 | 108 | ||
109 | |||
104 | /** | 110 | /** |
105 | * Internal API. Reconnect should re-register notifications | 111 | * Internal API. Reconnect should re-register notifications |
106 | * after a disconnect. | 112 | * after a disconnect. |
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, |