gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 143/277: more SQL for tips


From: gnunet
Subject: [taler-merchant] 143/277: more SQL for tips
Date: Sun, 05 Jul 2020 20:50:56 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 7c355636735d989ee5a60f855f6f64a6b6fe50d2
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun May 24 00:38:49 2020 +0200

    more SQL for tips
---
 src/backenddb/merchant-0001.sql            |  20 +-
 src/backenddb/plugin_merchantdb_postgres.c | 540 ++++++++++++++++++++++++++---
 src/include/taler_merchantdb_plugin.h      |  32 +-
 3 files changed, 518 insertions(+), 74 deletions(-)

diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index bd05b6b..1aa5425 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -466,11 +466,12 @@ CREATE TABLE IF NOT EXISTS merchant_tips
      REFERENCES merchant_tip_reserves (reserve_serial) ON DELETE CASCADE
   ,tip_id BYTEA NOT NULL UNIQUE CHECK (LENGTH(tip_id)=64)
   ,justification VARCHAR NOT NULL
+  ,next_url VARCHAR NOT NULL
   ,expiration INT8 NOT NULL
   ,amount_val INT8 NOT NULL
   ,amount_frac INT4 NOT NULL
-  ,left_val INT8 NOT NULL
-  ,left_frac INT4 NOT NULL
+  ,picked_up_val INT8 NOT NULL
+  ,picked_up_frac INT4 NOT NULL
   ,was_picked_up BOOLEAN NOT NULL DEFAULT FALSE
   );
 CREATE INDEX IF NOT EXISTS merchant_tips_by_pickup_and_expiration
@@ -480,15 +481,16 @@ COMMENT ON TABLE merchant_tips
   IS 'tips that have been authorized';
 COMMENT ON COLUMN merchant_tips.amount_val
   IS 'Overall tip amount';
-COMMENT ON COLUMN merchant_tips.left_val
-  IS 'Tip amount not yet picked up';
+COMMENT ON COLUMN merchant_tips.picked_up_val
+  IS 'Tip amount left to be picked up';
 COMMENT ON COLUMN merchant_tips.reserve_serial
   IS 'Reserve from which this tip is funded';
 COMMENT ON COLUMN merchant_tips.expiration
-  IS 'time by which the wallet has to pick up the tip before it expires';
+  IS 'by when does the client have to pick up the tip';
 
 CREATE TABLE IF NOT EXISTS merchant_tip_pickups
-  (tip_serial BIGINT NOT NULL
+  (pickup_serial BIGSERIAL PRIMARY KEY NOT NULL
+  ,tip_serial BIGINT NOT NULL
       REFERENCES merchant_tips (tip_serial) ON DELETE CASCADE
   ,pickup_id BYTEA NOT NULL UNIQUE CHECK (LENGTH(pickup_id)=64)
   ,amount_val INT8 NOT NULL
@@ -500,11 +502,11 @@ COMMENT ON COLUMN merchant_tips.amount_val
   IS 'total transaction cost for all coins including withdraw fees';
 
 CREATE TABLE IF NOT EXISTS merchant_tip_pickup_signatures
-  (pickup_id BYTEA NOT NULL
-     REFERENCES merchant_tip_pickups (pickup_id) ON DELETE CASCADE
+  (pickup_serial INT8 NOT NULL
+     REFERENCES merchant_tip_pickups (pickup_serial) ON DELETE CASCADE
   ,coin_offset INT4 NOT NULL
   ,blind_sig BYTEA NOT NULL
-  ,PRIMARY KEY (pickup_id, coin_offset)
+  ,PRIMARY KEY (pickup_serial, coin_offset)
   );
 COMMENT ON TABLE merchant_tip_pickup_signatures
   IS 'blind signatures we got from the exchange during the tip pickup';
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index 8f96295..a5105a3 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -4227,9 +4227,21 @@ struct LookupReserveForTipContext
    * #GNUNET_TIME_UNIT_FOREVER_ABS if we found none.
    */
   struct GNUNET_TIME_Absolute expiration;
+
+  /**
+   * Error status.
+   */
+  enum TALER_ErrorCode ec;
 };
 
 
+/**
+ * How long must a reserve be at least still valid before we use
+ * it for a tip?
+ */
+#define MIN_EXPIRATION GNUNET_TIME_UNIT_HOURS
+
+
 /**
  * Function to be called with the results of a SELECT statement
  * that has returned @a num_results results about accounts.
@@ -4244,6 +4256,55 @@ lookup_reserve_for_tip_cb (void *cls,
                            unsigned int num_results)
 {
   struct LookupReserveForTipContext *lac = cls;
+  struct PostgresClosure *pg = lac->pg;
+
+  for (unsigned int i = 0; i < num_results; i++)
+  {
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct TALER_Amount committed_amount;
+    struct TALER_Amount remaining;
+    struct TALER_Amount initial_balance;
+    struct GNUNET_TIME_Absolute expiration;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                            &reserve_pub),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("exchange_initial_balance",
+                                   &initial_balance),
+      TALER_PQ_RESULT_SPEC_AMOUNT ("tips_committed",
+                                   &committed_amount),
+      GNUNET_PQ_result_spec_absolute_time ("expiration",
+                                           &expiration),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      lac->ec = GNUNET_DB_STATUS_HARD_ERROR; // FIXME
+      return;
+    }
+    if (0 >
+        TALER_amount_subtract (&remaining,
+                               &initial_balance,
+                               &committed_amount))
+    {
+      GNUNET_break (0);
+      continue;
+    }
+    if (0 >
+        TALER_amount_cmp (&remaining,
+                          &lac->required_amount))
+      continue; /* insufficient balance */
+    if ( (expiration.abs_value_us > lac->expiration.abs_value_us) &&
+         (GNUNET_TIME_absolute_get_remaining (lac->expiration).rel_value_us >
+          MIN_EXPIRATION.rel_value_us) )
+      continue;
+    lac->expiration = expiration;
+    lac->reserve_pub = reserve_pub;
+  }
 }
 
 
@@ -4306,11 +4367,12 @@ RETRY:
   {
     struct GNUNET_PQ_QueryParam params[] = {
       GNUNET_PQ_query_param_string (instance_id),
+      GNUNET_PQ_query_param_absolute_time (expiration),
       TALER_PQ_query_param_amount (amount),
       GNUNET_PQ_query_param_end
     };
     qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
-                                               "lookup_reserve", // FIXME: 
write SQL!
+                                               "lookup_reserve_for_tip",
                                                params,
                                                &lookup_reserve_for_tip_cb,
                                                &lac);
@@ -4338,10 +4400,6 @@ RETRY:
     struct GNUNET_PQ_QueryParam params[] = {
       GNUNET_PQ_query_param_string (instance_id),
       GNUNET_PQ_query_param_auto_from_type (reserve_pubp),
-      TALER_PQ_query_param_amount (amount),
-      GNUNET_PQ_query_param_string (justification),
-      GNUNET_PQ_query_param_string (next_url),
-      GNUNET_PQ_query_param_auto_from_type (tip_id),
       GNUNET_PQ_query_param_end
     };
     struct GNUNET_PQ_ResultSpec rs[] = {
@@ -4355,7 +4413,7 @@ RETRY:
     };
 
     qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                   "lookup_reserve_status", // 
FIXME: write SQL!
+                                                   "lookup_reserve_status",
                                                    params,
                                                    rs);
     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -4403,7 +4461,7 @@ RETRY:
     };
 
     qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "update_reserve_tips_committed", 
// FIXME: write SQL!
+                                             "update_reserve_tips_committed",
                                              params);
     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
     {
@@ -4424,15 +4482,15 @@ RETRY:
     struct GNUNET_PQ_QueryParam params[] = {
       GNUNET_PQ_query_param_string (instance_id),
       GNUNET_PQ_query_param_auto_from_type (reserve_pubp),
-      TALER_PQ_query_param_amount (amount),
+      GNUNET_PQ_query_param_auto_from_type (tip_id),
       GNUNET_PQ_query_param_string (justification),
       GNUNET_PQ_query_param_string (next_url),
-      GNUNET_PQ_query_param_auto_from_type (tip_id),
+      TALER_PQ_query_param_amount (amount),
       GNUNET_PQ_query_param_end
     };
 
     qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             
"update_reserve_tips_committed",// FIXME: write SQL!
+                                             "insert_tip",
                                              params);
     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
     {
@@ -4459,6 +4517,73 @@ RETRY:
 }
 
 
+/**
+ * Closure for #lookup_signatures_cb().
+ */
+struct LookupSignaturesContext
+{
+  /**
+   * Length of the @e sigs array
+   */
+  unsigned int sigs_length;
+
+  /**
+   * Where to store the signatures.
+   */
+  struct GNUNET_CRYPTO_RsaSignature **sigs;
+};
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results about accounts.
+ *
+ * @param[in,out] cls of type `struct LookupSignaturesContext *`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
+lookup_signatures_cb (void *cls,
+                      PGresult *result,
+                      unsigned int num_results)
+{
+  struct LookupSignaturesContext *lsc = cls;
+
+  for (unsigned int i = 0; i < num_results; i++)
+  {
+    uint32_t offset;
+    struct GNUNET_CRYPTO_RsaSignature *bsig;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_uint32 ("coin_offset",
+                                    &offset),
+      GNUNET_PQ_result_spec_rsa_signature ("blind_sig",
+                                           &bsig),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      return;
+    }
+    if (offset >= lsc->sigs_length)
+    {
+      GNUNET_break_op (0);
+      GNUNET_PQ_cleanup_result (rs);
+      continue;
+    }
+    /* Must be NULL due to UNIQUE constraint on offset and
+       requirement that client launched us with 'sigs'
+       pre-initialized to NULL. */
+    GNUNET_assert (NULL == lsc->sigs[offset]);
+    lsc->sigs[offset] = bsig;
+  }
+}
+
+
 /**
  * Lookup pickup details for pickup @a pickup_id.
  *
@@ -4483,29 +4608,67 @@ postgres_lookup_pickup (void *cls,
                         unsigned int sigs_length,
                         struct GNUNET_CRYPTO_RsaSignature *sigs[])
 {
+  struct PostgresClosure *pg = cls;
+  uint64_t pickup_serial;
+
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_string (instance_id),
+      GNUNET_PQ_query_param_auto_from_type (tip_id),
+      GNUNET_PQ_query_param_auto_from_type (pickup_id),
+      GNUNET_PQ_query_param_end
+    };
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_string ("exchange_url",
+                                    exchange_url),
+      GNUNET_PQ_result_spec_auto_from_type ("reserve_priv",
+                                            reserve_priv),
+      GNUNET_PQ_result_spec_uint64 ("pickup_serial",
+                                    &pickup_serial),
+      GNUNET_PQ_result_spec_end
+    };
+    enum GNUNET_DB_QueryStatus qs;
+
+    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                   "lookup_pickup",
+                                                   params,
+                                                   rs);
+    if (qs <= 0)
+      return qs;
+  }
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_uint64 (&pickup_serial),
+      GNUNET_PQ_query_param_end
+    };
+    struct LookupSignaturesContext lsc = {
+      .sigs_length = sigs_length,
+      .sigs = sigs
+    };
+
+    return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+                                                 "lookup_pickup_signatures",
+                                                 params,
+                                                 &lookup_signatures_cb,
+                                                 &lsc);
+  }
 }
 
 
 /**
-* Lookup tip details for tip @a tip_id.
-*
-* @param cls closure, typically a connection to the db
-* @param instance_id which instance should we lookup tip details for
-* @param tip_id which tip should we lookup details on
-* @param[out] total_authorized amount how high is the tip (with fees)
-* @param[out] total_picked_up how much of the tip was so far picked up (with 
fees)
-* @param[out] expiration set to when the tip expires
-* @param[out] exchange_url set to the exchange URL where the reserve is
-* @param[out] reserve_priv set to private key of reserve to be debited
-* @return transaction status,
-*      #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has 
expired
-*      #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
-*      #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has 
insufficient funds left
-*      #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
-*      #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should 
retry)
-*      #TALER_EC_NONE upon success
-*/
-static enum TALER_ErrorCode
+ * Lookup tip details for tip @a tip_id.
+ *
+ * @param cls closure, typically a connection to the db
+ * @param instance_id which instance should we lookup tip details for
+ * @param tip_id which tip should we lookup details on
+ * @param[out] total_authorized amount how high is the tip (with fees)
+ * @param[out] total_picked_up how much of the tip was so far picked up (with 
fees)
+ * @param[out] expiration set to when the tip expires
+ * @param[out] exchange_url set to the exchange URL where the reserve is
+ * @param[out] reserve_priv set to private key of reserve to be debited
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
 postgres_lookup_tip (void *cls,
                      const char *instance_id,
                      const struct GNUNET_HashCode *tip_id,
@@ -4522,9 +4685,9 @@ postgres_lookup_tip (void *cls,
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
-    TALER_PQ_RESULT_SPEC_AMOUNT ("total_authorized",
+    TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
                                  total_authorized),
-    TALER_PQ_RESULT_SPEC_AMOUNT ("total_picked_up",
+    TALER_PQ_RESULT_SPEC_AMOUNT ("picked_up",
                                  total_picked_up),
     GNUNET_PQ_result_spec_absolute_time ("expiration",
                                          expiration),
@@ -4537,7 +4700,7 @@ postgres_lookup_tip (void *cls,
 
   check_connection (pg);
   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
-                                                   "lookup_tip", // FIXME: 
write SQL!
+                                                   "lookup_tip",
                                                    params,
                                                    rs);
 }
@@ -4578,6 +4741,7 @@ postgres_lookup_tip_details (void *cls,
                              unsigned int *pickups_length,
                              struct TALER_MERCHANTDB_PickupDetails **pickups)
 {
+  // FIXME!
 }
 
 
@@ -4592,7 +4756,7 @@ postgres_lookup_tip_details (void *cls,
  * @param cls closure, typically a connection to the db
  * @param tip_id the unique ID for the tip
  * @param total_picked_up how much was picked up overall at this
- *          point (includes @total_requested)
+ *          point (includes @a total_requested)
  * @param pickup_id unique ID for the operation
  * @param total_requested how much is being picked up in this operation
  * @return transaction status, usually
@@ -4608,19 +4772,132 @@ postgres_insert_pickup (void *cls,
                         const struct TALER_Amount *total_requested)
 {
   struct PostgresClosure *pg = cls;
-  struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_string (instance_id),
-    GNUNET_PQ_query_param_auto_from_type (tip_id),
-    TALER_PQ_query_param_amount (total_picked_up),
-    GNUNET_PQ_query_param_auto_from_type (pickup_id),
-    TALER_PQ_query_param_amount (total_requested),
-    GNUNET_PQ_query_param_end
-  };
+  enum GNUNET_DB_QueryStatus qs;
+  unsigned int retries = 0;
 
   check_connection (pg);
-  return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "insert_pickup", // FIXME: write 
SQL!
+RETRY:
+  if (MAX_RETRIES < ++retries)
+    return GNUNET_DB_STATUS_SOFT_ERROR;
+  if (GNUNET_OK !=
+      postgres_start (pg,
+                      "insert pickup"))
+  {
+    GNUNET_break (0);
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
+
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_string (instance_id),
+      GNUNET_PQ_query_param_auto_from_type (tip_id),
+      GNUNET_PQ_query_param_auto_from_type (pickup_id),
+      TALER_PQ_query_param_amount (total_requested),
+      GNUNET_PQ_query_param_end
+    };
+
+    check_connection (pg);
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "insert_pickup",
                                              params);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      postgres_rollback (pg);
+      if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+        goto RETRY;
+      return qs;
+    }
+  }
+
+  {
+    struct GNUNET_PQ_QueryParam params[] = {
+      GNUNET_PQ_query_param_auto_from_type (tip_id),
+      TALER_PQ_query_param_amount (total_picked_up),
+      GNUNET_PQ_query_param_end
+    };
+
+    check_connection (pg);
+    qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                             "update_picked_up_tip",
+                                             params);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      postgres_rollback (pg);
+      if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+        goto RETRY;
+      return qs;
+    }
+  }
+  {
+    uint64_t reserve_serial;
+    struct TALER_Amount reserve_picked_up;
+    {
+      struct GNUNET_PQ_QueryParam params[] = {
+        GNUNET_PQ_query_param_string (instance_id),
+        GNUNET_PQ_query_param_auto_from_type (&tip_id),
+        GNUNET_PQ_query_param_end
+      };
+      struct GNUNET_PQ_ResultSpec rs[] = {
+        TALER_PQ_RESULT_SPEC_AMOUNT ("tips_picked_up",
+                                     &reserve_picked_up),
+        GNUNET_PQ_result_spec_uint64 ("reserve_serial",
+                                      &reserve_serial),
+        GNUNET_PQ_result_spec_end
+
+      };
+
+      qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+                                                     
"lookup_picked_up_reserve",
+                                                     params,
+                                                     rs);
+      if (0 > qs)
+      {
+        GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+        postgres_rollback (pg);
+        if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+          goto RETRY;
+        return qs;
+      }
+    }
+    if (0 <=
+        TALER_amount_add (&reserve_picked_up,
+                          &reserve_picked_up,
+                          total_requested))
+    {
+      GNUNET_break (0);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
+
+    {
+      struct GNUNET_PQ_QueryParam params[] = {
+        GNUNET_PQ_query_param_uint64 (&reserve_serial),
+        TALER_PQ_query_param_amount (&reserve_picked_up),
+        GNUNET_PQ_query_param_end
+      };
+
+      check_connection (pg);
+      qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                               "update_picked_up_reserve",
+                                               params);
+      if (0 > qs)
+      {
+        GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+        postgres_rollback (pg);
+        if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+          goto RETRY;
+        return qs;
+      }
+    }
+  }
+  qs = postgres_commit (pg);
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+    return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+  if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+    goto RETRY;
+  GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
+  return qs;
 }
 
 
@@ -4653,7 +4930,7 @@ postgres_insert_pickup_blind_signature (
 
   check_connection (pg);
   return GNUNET_PQ_eval_prepared_non_select (pg->conn,
-                                             "insert_pickup_blind_signature", 
// FIXME: write SQL!
+                                             "insert_pickup_blind_signature",
                                              params);
 }
 
@@ -4949,9 +5226,8 @@ postgres_enable_tip_reserve_TR (void *cls,
   enum GNUNET_DB_QueryStatus qs;
   struct GNUNET_TIME_Absolute new_expiration;
   struct TALER_Amount new_balance;
-  unsigned int retries;
+  unsigned int retries = 0;
 
-  retries = 0;
   check_connection (pg);
 RETRY:
   if (MAX_RETRIES < ++retries)
@@ -7224,6 +7500,178 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
                             "       FROM merchant_instances"
                             "      WHERE merchant_id=$1)",
                             2),
+    /* For postgres_authorize_tip() */
+    GNUNET_PQ_make_prepare ("lookup_reserve_for_tip",
+                            "SELECT"
+                            " reserve_pub"
+                            ",expiration"
+                            ",exchange_initial_balance_val"
+                            ",exchange_initial_balance_frac"
+                            ",tips_committed_val"
+                            ",tips_committed_frac"
+                            " FROM merchant_tip_reserves"
+                            " WHERE expiration < $2 "
+                            "  AND exchange_initial_balance_val - 
tips_committed_val >= $3"
+                            "  AND merchant_serial ="
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            3),
+
+    /* For postgres_authorize_tip() */
+    GNUNET_PQ_make_prepare ("lookup_reserve_status",
+                            "SELECT"
+                            " expiration"
+                            ",exchange_initial_balance_val"
+                            ",exchange_initial_balance_frac"
+                            ",tips_committed_val"
+                            ",tips_committed_frac"
+                            " FROM merchant_tip_reserves"
+                            " WHERE reserve_pub = $2"
+                            "   AND merchant_serial ="
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            2),
+    /* For postgres_authorize_tip() */
+    GNUNET_PQ_make_prepare ("update_reserve_tips_committed",
+                            "UPDATE merchant_tip_reserves SET"
+                            " tips_committed_val=$3"
+                            ",tips_committed_frac=$4"
+                            " WHERE reserve_pub = $2"
+                            "   AND merchant_serial ="
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            4),
+    /* For postgres_authorize_tip() */
+    GNUNET_PQ_make_prepare ("insert_tip",
+                            "INSERT INTO merchant_tips"
+                            "(reserve_serial"
+                            ",justification"
+                            ",next_url"
+                            ",expiration"
+                            ",amount_val"
+                            ",amount_frac"
+                            ") "
+                            "SELECT"
+                            " reserve_serial, $3, $4, $5, $6, $7"
+                            " FROM merchant_tip_reserves"
+                            " WHERE reserve_pub=$2"
+                            "  AND reserve_serial = "
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            7),
+    /* For postgres_lookup_pickup() */
+    GNUNET_PQ_make_prepare ("lookup_pickup",
+                            "SELECT"
+                            " exchange_url"
+                            ",reserve_priv"
+                            ",pickup_serial"
+                            " FROM merchant_tip_pickups"
+                            " JOIN merchant_tips USING (tip_serial)"
+                            " JOIN merchant_tip_reserves USING 
(reserve_serial)"
+                            " JOIN merchant_tip_reserve_keys USING 
(reserve_serial)"
+                            " WHERE pickup_id = $2"
+                            "   AND tip_id = $3"
+                            "   AND merchant_serial ="
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            2),
+    /* For postgres_lookup_pickup() */
+    GNUNET_PQ_make_prepare ("lookup_pickup_signatures",
+                            "SELECT"
+                            " coin_offset"
+                            ",blind_sig"
+                            " FROM merchant_tip_pickup_signatures"
+                            " WHERE pickup_serial = $1",
+                            1),
+
+    /* For postgres_lookup_tip() */
+    GNUNET_PQ_make_prepare ("lookup_tip",
+                            "SELECT"
+                            " amount_val"
+                            ",amount_frac"
+                            ",picked_up_val"
+                            ",picked_up_frac"
+                            ",merchant_tips.expiration"
+                            ",exchange_url"
+                            ",reserve_priv"
+                            " FROM merchant_tips"
+                            " JOIN merchant_tip_reserves USING 
(reserve_serial)"
+                            " JOIN merchant_tip_reserve_keys USING 
(reserve_serial)"
+                            " WHERE tip_id = $2"
+                            "   AND merchant_serial ="
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            2),
+    /* for postgres_lookup_tip_details() */
+    // FIXME!
+    /* for postgres_lookup_tip_details() */
+    // FIXME!
+
+    /* for postgres_insert_pickup() */
+    GNUNET_PQ_make_prepare ("insert_pickup",
+                            "INSERT INTO merchant_tip_pickups"
+                            "(tip_serial"
+                            ",pickup_id"
+                            ",amount_val"
+                            ",amount_frac"
+                            ") "
+                            "SELECT"
+                            " tip_serial, $3, $4, $5"
+                            " FROM merchant_tips"
+                            " WHERE tip_id=$2"
+                            "  AND reserve_serial = "
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            5),
+    /* for postgres_insert_pickup() */
+    GNUNET_PQ_make_prepare ("update_picked_up_tip",
+                            "UPDATE merchant_tips SET"
+                            " picked_up_val=$2"
+                            ",picked_up_frac=$3"
+                            ",was_picked_up = ($2 = amount_val AND $3 = 
amount_frac)"
+                            " WHERE tip_id = $1",
+                            3),
+    /* for postgres_insert_pickup() */
+    GNUNET_PQ_make_prepare ("lookup_picked_up_reserve",
+                            "SELECT"
+                            " reserve_serial"
+                            ",tips_picked_up_val"
+                            ",tips_picked_up_frac"
+                            " FROM merchant_tip_reserves"
+                            " JOIN merchant_tips USING (reserve_serial)"
+                            " WHERE tip_id=$2"
+                            "   AND merchant_serial ="
+                            "     (SELECT merchant_serial"
+                            "        FROM merchant_instances"
+                            "       WHERE merchant_id=$1)",
+                            2),
+    /* for postgres_insert_pickup() */
+    GNUNET_PQ_make_prepare ("update_picked_up_reserve",
+                            "UPDATE merchant_tip_reserves SET"
+                            " tips_picked_up_val=$2"
+                            ",tips_picked_up_frac=$3"
+                            " WHERE reserve_serial = $1",
+                            3),
+    /* for postgres_insert_pickup_blind_signature() */
+    GNUNET_PQ_make_prepare ("insert_pickup_blind_signature",
+                            "INSERT INTO merchant_tip_pickup_signatures"
+                            "(pickup_serial"
+                            ",coin_offset"
+                            ",blind_sig"
+                            ") "
+                            "SELECT"
+                            " pickup_serial, $2, $3"
+                            " FROM merchant_tip_pickups"
+                            " WHERE pickup_id=$1",
+                            3),
+
     /* OLD API: */
 #if 0
     GNUNET_PQ_make_prepare ("insert_contract_terms",
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index 1324b4d..23ad9b8 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1716,25 +1716,19 @@ struct TALER_MERCHANTDB_Plugin
 
 
   /**
- * Lookup tip details for tip @a tip_id.
- *
- * @param cls closure, typically a connection to the db
- * @param instance_id which instance should we lookup tip details for
- * @param tip_id which tip should we lookup details on
- * @param[out] total_authorized amount how high is the tip (with fees)
- * @param[out] total_picked_up how much of the tip was so far picked up (with 
fees)
- * @param[out] expiration set to when the tip expires
- * @param[out] exchange_url set to the exchange URL where the reserve is
- * @param[out] reserve_priv set to private key of reserve to be debited
- * @return transaction status,
- *      #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but 
has expired
- *      #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
- *      #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has 
insufficient funds left
- *      #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
- *      #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should 
retry)
- *      #TALER_EC_NONE upon success
- */
-  enum TALER_ErrorCode
+   * Lookup tip details for tip @a tip_id.
+   *
+   * @param cls closure, typically a connection to the db
+   * @param instance_id which instance should we lookup tip details for
+   * @param tip_id which tip should we lookup details on
+   * @param[out] total_authorized amount how high is the tip (with fees)
+   * @param[out] total_picked_up how much of the tip was so far picked up 
(with fees)
+   * @param[out] expiration set to when the tip expires
+   * @param[out] exchange_url set to the exchange URL where the reserve is
+   * @param[out] reserve_priv set to private key of reserve to be debited
+   * @return transaction status
+   */
+  enum GNUNET_DB_QueryStatus
   (*lookup_tip)(void *cls,
                 const char *instance_id,
                 const struct GNUNET_HashCode *tip_id,

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