gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: pq: add array-type support for PQ [WIP,


From: gnunet
Subject: [gnunet] branch master updated: pq: add array-type support for PQ [WIP, 1/n]
Date: Sat, 06 May 2023 15:25:40 +0200

This is an automated email from the git hooks/post-receive script.

oec pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 25fb12006 pq: add array-type support for PQ [WIP, 1/n]
25fb12006 is described below

commit 25fb12006dd655e31e345593ad5da2ef724b5c45
Author: Özgür Kesim <oec-taler@kesim.org>
AuthorDate: Sat May 6 15:21:41 2023 +0200

    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()
---
 src/include/gnunet_pq_lib.h |  15 ++++++
 src/pq/pq.h                 |   6 +++
 src/pq/pq_connect.c         | 111 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 131 insertions(+), 1 deletion(-)

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
@@ -147,6 +147,21 @@ struct GNUNET_PQ_QueryParam
 GNUNET_PQ_query_param_bool (bool b);
 
 
+/**
+ *  Array types (in Postgres) that are supported in GNUnet.
+ */
+enum GNUNET_PQ_ArrayTypes
+{
+  GNUNET_PQ_ARRAY_UNKNOWN, /* Unsupported type */
+  GNUNET_PQ_ARRAY_BOOL,
+  GNUNET_PQ_ARRAY_INT2,
+  GNUNET_PQ_ARRAY_INT4,
+  GNUNET_PQ_ARRAY_INT8,
+  GNUNET_PQ_ARRAY_BYTEA,
+  GNUNET_PQ_ARRAY_VARCHAR,
+  GNUNET_PQ_ARRAY_MAX, /* Must be last */
+};
+
 /**
  * Information for an array argument.
  */
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
    * Flags controlling the connection.
    */
   enum GNUNET_PQ_Options flags;
+
+  /**
+   * Mapping between array types and Oid's, filled at reconnect
+   */
+  Oid arraytype2oid[GNUNET_PQ_ARRAY_MAX];
 };
 
 
+
 /**
  * Internal API. Reconnect should re-register notifications
  * 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 @@
 /*
    This file is part of GNUnet
-   Copyright (C) 2017, 2019, 2020, 2021 GNUnet e.V.
+   Copyright (C) 2017, 2019, 2020, 2021, 2023 GNUnet e.V.
 
    GNUnet is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
@@ -21,6 +21,7 @@
  * @file pq/pq_connect.c
  * @brief functions to connect to libpq (PostGres)
  * @author Christian Grothoff
+ * @author Özgür Kesim
  */
 #include "platform.h"
 #include "pq.h"
@@ -321,6 +322,103 @@ GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db)
 }
 
 
+/**
+ * Retrieves the Oid's for the supported array types and sets db->arraytype2oid
+ * on succes.
+ *
+ * @param db Context for the database connection
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+static enum GNUNET_GenericReturnValue
+get_array_type_oids (struct GNUNET_PQ_Context *db)
+{
+  PGresult *res;
+  ExecStatusType est;
+  GNUNET_assert (NULL != db);
+
+  /* Initialize to Oid(0) (= unknown) */
+  memset (db->arraytype2oid,
+          0,
+          sizeof(db->arraytype2oid));
+
+  res = PQexec (db->conn,
+                "SELECT"
+                " typname, oid"
+                " FROM pg_type "
+                " WHERE typname like '\\_%';");
+
+  est = PQresultStatus (res);
+  if ( (PGRES_COMMAND_OK != est) &&
+       (PGRES_TUPLES_OK != est))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to run statement to retrieve Oids for array types!\n");
+    return GNUNET_SYSERR;
+  }
+
+  if ( (2 != PQnfields (res)) ||
+       (0 != PQfnumber (res, "typname")) ||
+       (1 != PQfnumber (res, "oid"))
+       )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected table retrieved for array types\n");
+    return GNUNET_SYSERR;
+  }
+
+  {
+    int nrows = PQntuples (res);
+    int nfound = 1; /* skip GNUNET_PQ_ARRAY_UNKNOWN */
+
+    for (int r = 0; r < nrows; r++)
+    {
+      enum GNUNET_PQ_ArrayTypes atype = GNUNET_PQ_ARRAY_UNKNOWN;
+      char *typ_s = PQgetvalue (res,r,0);
+      char *oid_s = PQgetvalue (res,r,1);
+      GNUNET_assert (NULL != typ_s);
+      GNUNET_assert (NULL != oid_s);
+
+      if (! strcmp (typ_s,"_bool"))
+        atype = GNUNET_PQ_ARRAY_BOOL;
+      else if (! strcmp (typ_s,"_int2"))
+        atype = GNUNET_PQ_ARRAY_INT2;
+      else if (! strcmp (typ_s,"_int4"))
+        atype = GNUNET_PQ_ARRAY_INT4;
+      else if (! strcmp (typ_s,"_int8"))
+        atype = GNUNET_PQ_ARRAY_INT8;
+      else if (! strcmp (typ_s,"_bytea"))
+        atype = GNUNET_PQ_ARRAY_BYTEA;
+      else if (! strcmp (typ_s,"_varchar"))
+        atype = GNUNET_PQ_ARRAY_VARCHAR;
+      else
+        continue;
+
+      GNUNET_assert (GNUNET_PQ_ARRAY_MAX > atype);
+
+      if ((GNUNET_PQ_ARRAY_UNKNOWN != atype) &&
+          (1 == sscanf (oid_s, "%u", &db->arraytype2oid[atype])))
+      {
+        nfound++;
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    "OID[%s]: %d\n",
+                    typ_s, db->arraytype2oid[atype]);
+      }
+    }
+
+    if (GNUNET_PQ_ARRAY_MAX != nfound)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Couldn't find all array types, only found %d of %d!\n",
+                  nfound - 1,
+                  GNUNET_PQ_ARRAY_MAX - 1);
+      return GNUNET_SYSERR;
+    }
+  }
+
+  return GNUNET_OK;
+}
+
+
 void
 GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
 {
@@ -411,6 +509,16 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
     }
   }
 
+  /* Retrieve the OIDs for the supported Array types */
+  if (GNUNET_SYSERR == get_array_type_oids (db))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to retrieve OID information for array types!\n");
+    PQfinish (db->conn);
+    db->conn = NULL;
+    return;
+  }
+
   if (NULL != db->auto_suffix)
   {
     PGresult *res;
@@ -450,6 +558,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db)
       return;
     }
   }
+
   if ( (NULL != db->es) &&
        (GNUNET_OK !=
         GNUNET_PQ_exec_statements (db,

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]