implement sq_query_helper.c
authorChristian Grothoff <christian@grothoff.org>
Mon, 27 Feb 2017 01:08:21 +0000 (02:08 +0100)
committerChristian Grothoff <christian@grothoff.org>
Mon, 27 Feb 2017 01:08:21 +0000 (02:08 +0100)
po/POTFILES.in
src/include/gnunet_pq_lib.h
src/include/gnunet_sq_lib.h
src/sq/Makefile.am
src/sq/sq.c
src/sq/sq_query_helper.c
src/sq/sq_result_helper.c

index 2594104df599f3366b3b7545b66a16e3f6d1e1fc..6c156336b18337c89e4539cfec9752758a4b0f00 100644 (file)
@@ -65,6 +65,7 @@ src/cadet/gnunet-service-cadet_tunnel.c
 src/consensus/consensus_api.c
 src/consensus/gnunet-consensus-profiler.c
 src/consensus/gnunet-service-consensus.c
+src/consensus/plugin_block_consensus.c
 src/conversation/conversation_api.c
 src/conversation/conversation_api_call.c
 src/conversation/gnunet-conversation.c
@@ -114,13 +115,6 @@ src/dht/gnunet-service-dht_hello.c
 src/dht/gnunet-service-dht_neighbours.c
 src/dht/gnunet-service-dht_nse.c
 src/dht/gnunet-service-dht_routing.c
-src/dht/gnunet-service-wdht.c
-src/dht/gnunet-service-wdht_clients.c
-src/dht/gnunet-service-wdht_neighbours.c
-src/dht/gnunet-service-xdht.c
-src/dht/gnunet-service-xdht_hello.c
-src/dht/gnunet-service-xdht_neighbours.c
-src/dht/gnunet-service-xdht_routing.c
 src/dht/plugin_block_dht.c
 src/dns/dns_api.c
 src/dns/dnsparser.c
@@ -349,6 +343,9 @@ src/set/set_api.c
 src/social/gnunet-service-social.c
 src/social/gnunet-social.c
 src/social/social_api.c
+src/sq/sq.c
+src/sq/sq_query_helper.c
+src/sq/sq_result_helper.c
 src/statistics/gnunet-service-statistics.c
 src/statistics/gnunet-statistics.c
 src/statistics/statistics_api.c
index e8180f286766f84ee8440ed45a58c8a57d123bd7..756370b7401297aa9e6ea57ae91c464364c26d96 100644 (file)
@@ -316,20 +316,6 @@ GNUNET_PQ_result_spec_fixed_size (const char *name,
 #define GNUNET_PQ_result_spec_auto_from_type(name, dst) GNUNET_PQ_result_spec_fixed_size (name, (dst), sizeof (*(dst)))
 
 
-/**
- * Variable-size result expected.
- *
- * @param name name of the field in the table
- * @param[out] dst where to store the result, allocated
- * @param[out] sptr where to store the size of @a dst
- * @return array entry for the result specification to use
- */
-struct GNUNET_PQ_ResultSpec
-GNUNET_PQ_result_spec_variable_size (const char *name,
-                                    void **dst,
-                                    size_t *sptr);
-
-
 /**
  * 0-terminated string expected.
  *
index a068650ac1961fc6aa1e0b582e60bf84ded791a2..1606d11293c5861f4357758c8469f7f8ebad2087 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef GNUNET_SQ_LIB_H
 #define GNUNET_SQ_LIB_H
 
-#include <sqlite/sqlite3.h>
+#include <sqlite3.h>
 #include "gnunet_util_lib.h"
 
 
@@ -186,7 +186,8 @@ GNUNET_SQ_query_param_uint64 (const uint64_t *x);
  *
  * @param cls closure
  * @param result where to extract data from
- * @param int row to extract data from
+ * @param row row to extract data from
+ * @param column column to extract data from
  * @param[in,out] dst_size where to store size of result, may be NULL
  * @param[out] dst where to store the result
  * @return
@@ -197,20 +198,25 @@ typedef int
 (*GNUNET_SQ_ResultConverter)(void *cls,
                             sqlite3_stmt *result,
                             int row,
+                             unsigned int column,
                             size_t *dst_size,
                             void *dst);
 
 
+/**
+ * @brief Description of a DB result cell.
+ */
+struct GNUNET_SQ_ResultSpec;
+
+
 /**
  * Function called to clean up memory allocated
  * by a #GNUNET_SQ_ResultConverter.
  *
  * @param cls closure
- * @param rd result data to clean up
  */
 typedef void
-(*GNUNET_SQ_ResultCleanup)(void *cls,
-                          void *rd);
+(*GNUNET_SQ_ResultCleanup)(void *cls);
 
 
 /**
@@ -252,6 +258,11 @@ struct GNUNET_SQ_ResultSpec
    */
   size_t *result_size;
 
+  /**
+   * Number of parameters (columns) eaten by this operation.
+   */
+  unsigned int num_params;
+
 };
 
 
@@ -407,7 +418,7 @@ GNUNET_SQ_bind (sqlite3_stmt *stmt,
  * @param[in,out] rs result specification to extract for
  * @param row row from the result to extract
  * @return
- *   #GNUNET_YES if all results could be extracted
+ *   #GNUNET_OK if all results could be extracted
  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
  */
 int
index 7197e7ab44d77270df8319b3b63817a368cecf6b..c5f80bcf6bf0ae555e6e09d70703c1b525605f59 100644 (file)
@@ -17,7 +17,7 @@ libgnunetsq_la_SOURCES = \
   sq.c \
   sq_query_helper.c \
   sq_result_helper.c
-libgnunetsq_la_LIBADD = -lsq \
+libgnunetsq_la_LIBADD = -lsqlite3 \
  $(top_builddir)/src/util/libgnunetutil.la
 libgnunetsq_la_LDFLAGS = \
  $(POSTGRESQL_LDFLAGS) \
index 524014b0f21497eb427261650a9ced9a34e35971..74ab7beb5480b6f85c7f4dd7b063872357144f85 100644 (file)
@@ -33,6 +33,28 @@ int
 GNUNET_SQ_bind (sqlite3_stmt *stmt,
                 const struct GNUNET_SQ_QueryParam *params)
 {
+  unsigned int j;
+
+  j = 1;
+  for (unsigned int i=0;NULL != params[i].conv; i++)
+  {
+    if (GNUNET_OK !=
+        params[i].conv (params[i].conv_cls,
+                        params[i].data,
+                        params[i].size,
+                        stmt,
+                        j))
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
+                       "sq",
+                       _("Failure to bind %u-th SQL parameter\n"),
+                       i);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_assert (0 != params[i].num_params);
+    j += params[i].num_params;
+  }
+  return GNUNET_OK;
 }
 
 
@@ -43,7 +65,7 @@ GNUNET_SQ_bind (sqlite3_stmt *stmt,
  * @param[in,out] rs result specification to extract for
  * @param row row from the result to extract
  * @return
- *   #GNUNET_YES if all results could be extracted
+ *   #GNUNET_OK if all results could be extracted
  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
  */
 int
@@ -51,6 +73,22 @@ GNUNET_SQ_extract_result (sqlite3_stmt *result,
                          struct GNUNET_SQ_ResultSpec *rs,
                          int row)
 {
+  unsigned int j = 0;
+
+  for (unsigned int i=0;NULL != rs[i].conv; i++)
+  {
+    if (GNUNET_OK !=
+        rs[i].conv (rs[i].cls,
+                    result,
+                    row,
+                    j,
+                    rs[i].result_size,
+                    rs[i].dst))
+      return GNUNET_SYSERR;
+    GNUNET_assert (0 != rs[i].num_params);
+    j += rs[i].num_params;
+  }
+  return GNUNET_OK;
 }
 
 
@@ -63,6 +101,9 @@ GNUNET_SQ_extract_result (sqlite3_stmt *result,
 void
 GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs)
 {
+  for (unsigned int i=0;NULL != rs[i].conv; i++)
+    if (NULL != rs[i].cleaner)
+      rs[i].cleaner (rs[i].cls);
 }
 
 /* end of sq.c */
index 613a0c746d6d2801652031d178d746556e55a534..5529c5e6c2cae131f810c1451d023dfd3cd2920c 100644 (file)
  * @brief helper functions for queries
  * @author Christian Grothoff
  */
+#include "platform.h"
 #include "gnunet_sq_lib.h"
 
 
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_fixed_blob (void *cls,
+                 const void *data,
+                 size_t data_len,
+                 sqlite3_stmt *stmt,
+                 unsigned int off)
+{
+  if (SQLITE_OK !=
+      sqlite3_bind_blob64 (stmt,
+                           (int) off,
+                           data,
+                           (sqlite3_uint64) data_len,
+                           SQLITE_TRANSIENT))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
+}
+
+
 /**
  * Generate query parameter for a buffer @a ptr of
  * @a ptr_size bytes.
@@ -32,6 +62,42 @@ struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_fixed_size (const void *ptr,
                                  size_t ptr_size)
 {
+  struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_fixed_blob,
+    .data = ptr,
+    .size = ptr_size,
+    .num_params = 1
+  };
+  return qp;
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_string (void *cls,
+             const void *data,
+             size_t data_len,
+             sqlite3_stmt *stmt,
+             unsigned int off)
+{
+  if (SQLITE_OK !=
+      sqlite3_bind_text (stmt,
+                         (int) off,
+                         (const char *) data,
+                         -1,
+                         SQLITE_TRANSIENT))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 
 
@@ -43,6 +109,52 @@ GNUNET_SQ_query_param_fixed_size (const void *ptr,
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_string (const char *ptr)
 {
+  struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_string,
+    .data = ptr,
+    .num_params = 1
+  };
+  return qp;
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_rsa_pub (void *cls,
+              const void *data,
+              size_t data_len,
+              sqlite3_stmt *stmt,
+              unsigned int off)
+{
+  const struct GNUNET_CRYPTO_RsaPublicKey *rsa = data;
+  char *buf;
+  size_t buf_size;
+
+  GNUNET_break (NULL == cls);
+  buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa,
+                                                 &buf);
+  if (SQLITE_OK !=
+      sqlite3_bind_blob64 (stmt,
+                           (int) off,
+                           buf,
+                           (sqlite3_uint64) buf_size,
+                           SQLITE_TRANSIENT))
+  {
+    GNUNET_free (buf);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (buf);
+  return GNUNET_OK;
 }
 
 
@@ -55,6 +167,52 @@ GNUNET_SQ_query_param_string (const char *ptr)
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x)
 {
+ struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_rsa_pub,
+    .data = x,
+    .num_params = 1
+  };
+ return qp;
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_rsa_sig (void *cls,
+              const void *data,
+              size_t data_len,
+              sqlite3_stmt *stmt,
+              unsigned int off)
+{
+  const struct GNUNET_CRYPTO_RsaSignature *sig = data;
+  char *buf;
+  size_t buf_size;
+
+  GNUNET_break (NULL == cls);
+  buf_size = GNUNET_CRYPTO_rsa_signature_encode (sig,
+                                                &buf);
+  if (SQLITE_OK !=
+      sqlite3_bind_blob64 (stmt,
+                           (int) off,
+                           buf,
+                           (sqlite3_uint64) buf_size,
+                           SQLITE_TRANSIENT))
+  {
+    GNUNET_free (buf);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (buf);
+  return GNUNET_OK;
 }
 
 
@@ -67,6 +225,12 @@ GNUNET_SQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
 {
+ struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_rsa_sig,
+    .data = x,
+    .num_params = 1
+  };
+ return qp;
 }
 
 
@@ -79,6 +243,39 @@ GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x)
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
 {
+  return GNUNET_SQ_query_param_uint64 (&x->abs_value_us);
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_nbotime (void *cls,
+              const void *data,
+              size_t data_len,
+              sqlite3_stmt *stmt,
+              unsigned int off)
+{
+  const struct GNUNET_TIME_AbsoluteNBO *u = data;
+  struct GNUNET_TIME_Absolute abs;
+
+  abs = GNUNET_TIME_absolute_ntoh (*u);
+  GNUNET_assert (sizeof (uint64_t) == data_len);
+  if (SQLITE_OK !=
+      sqlite3_bind_int64 (stmt,
+                          (int) off,
+                          (sqlite3_int64) abs.abs_value_us))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 
 
@@ -91,6 +288,43 @@ GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x)
 {
+ struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_nbotime,
+    .data = x,
+    .size = sizeof (struct GNUNET_TIME_AbsoluteNBO),
+    .num_params = 1
+  };
+  return qp;
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_u16 (void *cls,
+          const void *data,
+          size_t data_len,
+          sqlite3_stmt *stmt,
+          unsigned int off)
+{
+  const uint16_t *u = data;
+
+  GNUNET_assert (sizeof (uint16_t) == data_len);
+  if (SQLITE_OK !=
+      sqlite3_bind_int (stmt,
+                        (int) off,
+                        (int) *u))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 
 
@@ -102,9 +336,45 @@ GNUNET_SQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_uint16 (const uint16_t *x)
 {
+ struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_u16,
+    .data = x,
+    .size = sizeof (uint16_t),
+    .num_params = 1
+  };
+  return qp;
 }
 
 
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_u32 (void *cls,
+          const void *data,
+          size_t data_len,
+          sqlite3_stmt *stmt,
+          unsigned int off)
+{
+  const uint32_t *u = data;
+
+  GNUNET_assert (sizeof (uint32_t) == data_len);
+  if (SQLITE_OK !=
+      sqlite3_bind_int64 (stmt,
+                          (int) off,
+                          (sqlite3_int64) *u))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
+}
+
 /**
  * Generate query parameter for an uint32_t in host byte order.
  *
@@ -113,6 +383,43 @@ GNUNET_SQ_query_param_uint16 (const uint16_t *x)
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_uint32 (const uint32_t *x)
 {
+ struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_u32,
+    .data = x,
+    .size = sizeof (uint32_t),
+    .num_params = 1
+  };
+  return qp;
+}
+
+
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param stmt sqlite statement to bind parameters for
+ * @param off offset of the argument to bind in @a stmt, numbered from 1,
+ *            so immediately suitable for passing to `sqlite3_bind`-functions.
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+static int
+bind_u64 (void *cls,
+          const void *data,
+          size_t data_len,
+          sqlite3_stmt *stmt,
+          unsigned int off)
+{
+  const uint64_t *u = data;
+
+  GNUNET_assert (sizeof (uint64_t) == data_len);
+  if (SQLITE_OK !=
+      sqlite3_bind_int64 (stmt,
+                          (int) off,
+                          (sqlite3_int64) *u))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 
 
@@ -124,6 +431,13 @@ GNUNET_SQ_query_param_uint32 (const uint32_t *x)
 struct GNUNET_SQ_QueryParam
 GNUNET_SQ_query_param_uint64 (const uint64_t *x)
 {
+  struct GNUNET_SQ_QueryParam qp = {
+    .conv = &bind_u64,
+    .data = x,
+    .size = sizeof (uint64_t),
+    .num_params = 1
+  };
+  return qp;
 }
 
 /* end of sq_query_helper.c */
index 361fea7bf5f838c7091b8cc7321c3414a2bd24d2..36ce533174420a0269cea2fcb61eebf22e3156f4 100644 (file)
 #include "gnunet_sq_lib.h"
 
 
+/**
+ * Extract fixed-sized binary data from a Postgres database @a result at row @a row.
+ *
+ * @param cls closure
+ * @param result where to extract data from
+ * @param row row to extract data from
+ * @param column column to extract data from
+ * @param[in,out] dst_size where to store size of result, may be NULL
+ * @param[out] dst where to store the result
+ * @return
+ *   #GNUNET_YES if all results could be extracted
+ *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
+ */
+static int
+extract_fixed_blob (void *cls,
+                    sqlite3_stmt *result,
+                    int row,
+                    unsigned int column,
+                    size_t *dst_size,
+                    void *dst)
+{
+}
+
+
 /**
  * Variable-size result expected.
  *
@@ -51,20 +75,6 @@ GNUNET_SQ_result_spec_fixed_size (void *dst,
 }
 
 
-/**
- * Variable-size result expected.
- *
- * @param[out] dst where to store the result, allocated
- * @param[out] sptr where to store the size of @a dst
- * @return array entry for the result specification to use
- */
-struct GNUNET_SQ_ResultSpec
-GNUNET_SQ_result_spec_variable_size (void **dst,
-                                    size_t *sptr)
-{
-}
-
-
 /**
  * 0-terminated string expected.
  *