gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 02/02: implement protocol v12, fixes #7948


From: gnunet
Subject: [taler-merchant] 02/02: implement protocol v12, fixes #7948
Date: Mon, 18 Mar 2024 23:09:21 +0100

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

grothoff pushed a commit to branch master
in repository merchant.

commit 42490d300851bf16e94d9ba19ed230fc41867e38
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Mar 18 23:09:15 2024 +0100

    implement protocol v12, fixes #7948
---
 configure.ac                                       |   4 +-
 src/backend/taler-merchant-httpd_config.c          |   2 +-
 .../taler-merchant-httpd_private-get-orders.c      | 107 +++++++--------------
 .../taler-merchant-httpd_private-get-products.c    |  20 +++-
 .../taler-merchant-httpd_private-get-transfers.c   |  63 ++----------
 src/backenddb/pg_lookup_products.c                 |  44 +++++++--
 src/backenddb/pg_lookup_products.h                 |   5 +
 src/backenddb/test_merchantdb.c                    |   6 ++
 src/include/taler_merchant_service.h               |   4 +
 src/include/taler_merchantdb_plugin.h              |   7 ++
 src/lib/merchant_api_get_config.c                  |   4 +-
 src/lib/merchant_api_get_products.c                |   4 +-
 12 files changed, 129 insertions(+), 141 deletions(-)

diff --git a/configure.ac b/configure.ac
index 659d7349..8fd422fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -268,12 +268,12 @@ AS_CASE([$with_exchange],
          CPPFLAGS="-I$with_exchange/include $CPPFLAGS $POSTGRESQL_CPPFLAGS"])
 
 AC_CHECK_HEADERS([taler/taler_mhd_lib.h],
- [AC_CHECK_LIB([talermhd], [TALER_MHD_parse_request_arg_amount], 
libtalermhd=1)])
+ [AC_CHECK_LIB([talermhd], [TALER_MHD_parse_request_arg_snumber], 
libtalermhd=1)])
 AM_CONDITIONAL(HAVE_TALERMHD, test x$libtalermhd = x1)
 AS_IF([test $libtalermhd != 1],
   [AC_MSG_ERROR([[
 ***
-*** You need libtalermhd >= 0.9.4a to build this program.
+*** You need libtalermhd >= 0.10.1 (API v2) to build this program.
 *** This library is part of the GNU Taler exchange, available at
 ***   https://taler.net
 *** ]])])
diff --git a/src/backend/taler-merchant-httpd_config.c 
b/src/backend/taler-merchant-httpd_config.c
index d020985b..969cf1ca 100644
--- a/src/backend/taler-merchant-httpd_config.c
+++ b/src/backend/taler-merchant-httpd_config.c
@@ -42,7 +42,7 @@
  * #MERCHANT_PROTOCOL_CURRENT and #MERCHANT_PROTOCOL_AGE in
  * merchant_api_config.c!
  */
-#define MERCHANT_PROTOCOL_VERSION "11:0:7"
+#define MERCHANT_PROTOCOL_VERSION "12:0:8"
 
 
 /**
diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c 
b/src/backend/taler-merchant-httpd_private-get-orders.c
index 92a1f389..5fc91188 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders.c
@@ -687,44 +687,23 @@ TMH_private_get_orders (const struct TMH_RequestHandler 
*rh,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
                                        "wired");
+  po->of.delta = -20;
+  /* deprecated in protocol v12 */
+  TALER_MHD_parse_request_snumber (connection,
+                                   "delta",
+                                   &po->of.delta);
+  /* since protocol v12 */
+  TALER_MHD_parse_request_snumber (connection,
+                                   "limit",
+                                   &po->of.delta);
+  if ( (-MAX_DELTA > po->of.delta) ||
+       (po->of.delta > MAX_DELTA) )
   {
-    const char *delta_str;
-
-    delta_str = MHD_lookup_connection_value (connection,
-                                             MHD_GET_ARGUMENT_KIND,
-                                             "delta");
-    if (NULL == delta_str)
-    {
-      po->of.delta = -20;
-    }
-    else
-    {
-      char dummy;
-      long long ll;
-
-      if (1 !=
-          sscanf (delta_str,
-                  "%lld%c",
-                  &ll,
-                  &dummy))
-      {
-        GNUNET_break_op (0);
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           "delta");
-      }
-      po->of.delta = (int64_t) ll;
-      if ( (-MAX_DELTA > po->of.delta) ||
-           (po->of.delta > MAX_DELTA) )
-      {
-        GNUNET_break_op (0);
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           "delta");
-      }
-    }
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                                       "delta");
   }
   {
     const char *date_s_str;
@@ -769,43 +748,25 @@ TMH_private_get_orders (const struct TMH_RequestHandler 
*rh,
       }
     }
   }
+  if (po->of.delta > 0)
+    po->of.start_row = 0;
+  else
+    po->of.start_row = INT64_MAX;
+  /* deprecated in protocol v12 */
+  TALER_MHD_parse_request_number (connection,
+                                  "start",
+                                  &po->of.start_row);
+  /* since protocol v12 */
+  TALER_MHD_parse_request_number (connection,
+                                  "offset",
+                                  &po->of.start_row);
+  if (INT64_MAX < po->of.start_row)
   {
-    const char *start_row_str;
-
-    start_row_str = MHD_lookup_connection_value (connection,
-                                                 MHD_GET_ARGUMENT_KIND,
-                                                 "start");
-    if (NULL == start_row_str)
-    {
-      if (po->of.delta > 0)
-        po->of.start_row = 0;
-      else
-        po->of.start_row = INT64_MAX;
-    }
-    else
-    {
-      char dummy;
-      unsigned long long ull;
-
-      if (1 !=
-          sscanf (start_row_str,
-                  "%llu%c",
-                  &ull,
-                  &dummy))
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           "start");
-      po->of.start_row = (uint64_t) ull;
-      if (INT64_MAX < po->of.start_row)
-      {
-        GNUNET_break_op (0);
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           "start");
-      }
-    }
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                                       "start");
   }
   po->of.session_id
     = MHD_lookup_connection_value (connection,
diff --git a/src/backend/taler-merchant-httpd_private-get-products.c 
b/src/backend/taler-merchant-httpd_private-get-products.c
index bc90c94d..d9fa4e49 100644
--- a/src/backend/taler-merchant-httpd_private-get-products.c
+++ b/src/backend/taler-merchant-httpd_private-get-products.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2019, 2020, 2021 Taler Systems SA
+  (C) 2019, 2020, 2021, 2024 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Affero General Public License as published by the Free 
Software
@@ -30,6 +30,7 @@
  */
 static void
 add_product (void *cls,
+             uint64_t product_serial,
              const char *product_id)
 {
   json_t *pa = cls;
@@ -38,6 +39,8 @@ add_product (void *cls,
                  json_array_append_new (
                    pa,
                    GNUNET_JSON_PACK (
+                     GNUNET_JSON_pack_uint64 ("product_serial",
+                                              product_serial),
                      GNUNET_JSON_pack_string ("product_id",
                                               product_id))));
 }
@@ -50,11 +53,26 @@ TMH_private_get_products (const struct TMH_RequestHandler 
*rh,
 {
   json_t *pa;
   enum GNUNET_DB_QueryStatus qs;
+  int64_t limit;
+  uint64_t offset;
 
+  limit = 20; /* default */
+  TALER_MHD_parse_request_snumber (connection,
+                                   "limit",
+                                   &limit);
+  if (limit < 0)
+    offset = INT64_MAX;
+  else
+    offset = 0;
+  TALER_MHD_parse_request_number (connection,
+                                  "offset",
+                                  &offset);
   pa = json_array ();
   GNUNET_assert (NULL != pa);
   qs = TMH_db->lookup_products (TMH_db->cls,
                                 hc->instance->settings.id,
+                                offset,
+                                limit,
                                 &add_product,
                                 pa);
   if (0 > qs)
diff --git a/src/backend/taler-merchant-httpd_private-get-transfers.c 
b/src/backend/taler-merchant-httpd_private-get-transfers.c
index c43781dd..3e540297 100644
--- a/src/backend/taler-merchant-httpd_private-get-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-get-transfers.c
@@ -137,59 +137,16 @@ TMH_private_get_transfers (const struct 
TMH_RequestHandler *rh,
                                          TALER_EC_GENERIC_PARAMETER_MALFORMED,
                                          "after");
   }
-  {
-    const char *limit_s;
-
-    limit_s = MHD_lookup_connection_value (connection,
-                                           MHD_GET_ARGUMENT_KIND,
-                                           "limit");
-    if (NULL != limit_s)
-    {
-      char dummy[2];
-      long long l;
-
-      if (1 !=
-          sscanf (limit_s,
-                  "%lld%1s",
-                  &l,
-                  dummy))
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           "limit");
-      limit = (int64_t) l;
-    }
-  }
-  {
-    const char *offset_s;
-
-    offset_s = MHD_lookup_connection_value (connection,
-                                            MHD_GET_ARGUMENT_KIND,
-                                            "offset");
-    if (NULL != offset_s)
-    {
-      char dummy[2];
-      unsigned long long o;
-
-      if (1 !=
-          sscanf (offset_s,
-                  "%llu%1s",
-                  &o,
-                  dummy))
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           "offset");
-      offset = (uint64_t) o;
-    }
-    else
-    {
-      if (limit < 0)
-        offset = INT64_MAX;
-      else
-        offset = 0;
-    }
-  }
+  TALER_MHD_parse_request_snumber (connection,
+                                   "limit",
+                                   &limit);
+  if (limit < 0)
+    offset = INT64_MAX;
+  else
+    offset = 0;
+  TALER_MHD_parse_request_number (connection,
+                                  "offset",
+                                  &offset);
   if (! (TALER_arg_to_yna (connection,
                            "verified",
                            TALER_EXCHANGE_YNA_ALL,
diff --git a/src/backenddb/pg_lookup_products.c 
b/src/backenddb/pg_lookup_products.c
index d16aeb8d..fa2887a8 100644
--- a/src/backenddb/pg_lookup_products.c
+++ b/src/backenddb/pg_lookup_products.c
@@ -65,9 +65,12 @@ lookup_products_cb (void *cls,
   for (unsigned int i = 0; i < num_results; i++)
   {
     char *product_id;
+    uint64_t product_serial;
     struct GNUNET_PQ_ResultSpec rs[] = {
       GNUNET_PQ_result_spec_string ("product_id",
                                     &product_id),
+      GNUNET_PQ_result_spec_uint64 ("product_serial",
+                                    &product_serial),
       GNUNET_PQ_result_spec_end
     };
 
@@ -81,6 +84,7 @@ lookup_products_cb (void *cls,
       return;
     }
     plc->cb (plc->cb_cls,
+             product_serial,
              product_id);
     GNUNET_PQ_cleanup_result (rs);
   }
@@ -90,10 +94,13 @@ lookup_products_cb (void *cls,
 enum GNUNET_DB_QueryStatus
 TMH_PG_lookup_products (void *cls,
                         const char *instance_id,
+                        uint64_t offset,
+                        int64_t limit,
                         TALER_MERCHANTDB_ProductsCallback cb,
                         void *cb_cls)
 {
   struct PostgresClosure *pg = cls;
+  uint64_t plimit = (uint64_t) ((limit < 0) ? -limit : limit);
   struct LookupProductsContext plc = {
     .cb = cb,
     .cb_cls = cb_cls,
@@ -102,24 +109,45 @@ TMH_PG_lookup_products (void *cls,
   };
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (instance_id),
+    GNUNET_PQ_query_param_uint64 (&offset),
+    GNUNET_PQ_query_param_uint64 (&plimit),
     GNUNET_PQ_query_param_end
   };
   enum GNUNET_DB_QueryStatus qs;
 
   check_connection (pg);
   PREPARE (pg,
-           "lookup_products",
+           "lookup_products_asc",
            "SELECT"
-           " product_id"
+           "  product_id"
+           " ,product_serial"
            " FROM merchant_inventory"
            " JOIN merchant_instances"
            "   USING (merchant_serial)"
-           " WHERE merchant_instances.merchant_id=$1");
-  qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                             "lookup_products",
-                                             params,
-                                             &lookup_products_cb,
-                                             &plc);
+           " WHERE merchant_instances.merchant_id=$1"
+           "   AND product_serial > $2"
+           " ORDER BY product_serial ASC"
+           " LIMIT $3");
+  PREPARE (pg,
+           "lookup_products_desc",
+           "SELECT"
+           "  product_id"
+           " ,product_serial"
+           " FROM merchant_inventory"
+           " JOIN merchant_instances"
+           "   USING (merchant_serial)"
+           " WHERE merchant_instances.merchant_id=$1"
+           "   AND product_serial < $2"
+           " ORDER BY product_serial DESC"
+           " LIMIT $3");
+  qs = GNUNET_PQ_eval_prepared_multi_select (
+    pg->conn,
+    (limit > 0)
+    ? "lookup_products_asc"
+    : "lookup_products_desc",
+    params,
+    &lookup_products_cb,
+    &plc);
   /* If there was an error inside lookup_products_cb, return a hard error. */
   if (plc.extract_failed)
     return GNUNET_DB_STATUS_HARD_ERROR;
diff --git a/src/backenddb/pg_lookup_products.h 
b/src/backenddb/pg_lookup_products.h
index 398b5eac..d96328c8 100644
--- a/src/backenddb/pg_lookup_products.h
+++ b/src/backenddb/pg_lookup_products.h
@@ -30,6 +30,9 @@
  *
  * @param cls closure
  * @param instance_id instance to lookup products for
+ * @param offset transfer_serial number of the transfer we want to offset from
+ * @param limit number of entries to return, negative for descending,
+ *                positive for ascending
  * @param cb function to call on all products found
  * @param cb_cls closure for @a cb
  * @return database result code
@@ -37,6 +40,8 @@
 enum GNUNET_DB_QueryStatus
 TMH_PG_lookup_products (void *cls,
                         const char *instance_id,
+                        uint64_t offset,
+                        int64_t limit,
                         TALER_MERCHANTDB_ProductsCallback cb,
                         void *cb_cls);
 
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index 53902b3d..60a0b08b 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -906,13 +906,17 @@ struct TestLookupProducts_Closure
  * Function called after calling @e test_lookup_products
  *
  * @param cls a pointer to the lookup closure.
+ * @param product_serial DB row ID
  * @param product_id the identifier of the product found.
  */
 static void
 lookup_products_cb (void *cls,
+                    uint64_t product_serial,
                     const char *product_id)
 {
   struct TestLookupProducts_Closure *cmp = cls;
+
+  GNUNET_assert (product_serial > 0);
   if (NULL == cmp)
     return;
   cmp->results_length += 1;
@@ -948,6 +952,8 @@ test_lookup_products (const struct InstanceData *instance,
   memset (results_matching, 0, sizeof (unsigned int) * products_length);
   if (0 > plugin->lookup_products (plugin->cls,
                                    instance->instance.id,
+                                   0,
+                                   20,
                                    &lookup_products_cb,
                                    &cls))
   {
diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 2ed51a29..6ddf3ee4 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -1386,6 +1386,10 @@ struct TALER_MERCHANT_InventoryEntry
    */
   const char *product_id;
 
+  /**
+   * Serial ID of the product.
+   */
+  uint64_t product_serial;
 };
 
 
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index 316b8678..404d0eb9 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -249,10 +249,12 @@ typedef void
  * Typically called by `lookup_products`.
  *
  * @param cls a `json_t *` JSON array to build
+ * @param product_serial row ID of the product
  * @param product_id ID of the product
  */
 typedef void
 (*TALER_MERCHANTDB_ProductsCallback)(void *cls,
+                                     uint64_t product_serial,
                                      const char *product_id);
 
 
@@ -1584,6 +1586,9 @@ struct TALER_MERCHANTDB_Plugin
    *
    * @param cls closure
    * @param instance_id instance to lookup products for
+   * @param offset transfer_serial number of the transfer we want to offset 
from
+   * @param limit number of entries to return, negative for descending,
+   *                positive for ascending
    * @param cb function to call on all products found
    * @param cb_cls closure for @a cb
    * @return database result code
@@ -1591,6 +1596,8 @@ struct TALER_MERCHANTDB_Plugin
   enum GNUNET_DB_QueryStatus
   (*lookup_products)(void *cls,
                      const char *instance_id,
+                     uint64_t offset,
+                     int64_t limit,
                      TALER_MERCHANTDB_ProductsCallback cb,
                      void *cb_cls);
 
diff --git a/src/lib/merchant_api_get_config.c 
b/src/lib/merchant_api_get_config.c
index 3f1471e3..3382c9f2 100644
--- a/src/lib/merchant_api_get_config.c
+++ b/src/lib/merchant_api_get_config.c
@@ -34,12 +34,12 @@
  * Which version of the Taler protocol is implemented
  * by this library?  Used to determine compatibility.
  */
-#define MERCHANT_PROTOCOL_CURRENT 11
+#define MERCHANT_PROTOCOL_CURRENT 12
 
 /**
  * How many configs are we backwards-compatible with?
  */
-#define MERCHANT_PROTOCOL_AGE 6
+#define MERCHANT_PROTOCOL_AGE 0
 
 
 /**
diff --git a/src/lib/merchant_api_get_products.c 
b/src/lib/merchant_api_get_products.c
index 01115094..21657cbd 100644
--- a/src/lib/merchant_api_get_products.c
+++ b/src/lib/merchant_api_get_products.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2023 Taler Systems SA
+  Copyright (C) 2014-2024 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -89,6 +89,8 @@ parse_products (const json_t *json,
     struct GNUNET_JSON_Specification spec[] = {
       GNUNET_JSON_spec_string ("product_id",
                                &ie->product_id),
+      GNUNET_JSON_spec_uint64 ("product_serial",
+                               &ie->product_serial),
       GNUNET_JSON_spec_end ()
     };
 

-- 
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]