/* This file is part of TALER Copyright (C) 2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see */ /** * @file backenddb/pg_lookup_orders.c * @brief Implementation of the lookup_orders function for Postgres * @author Iván Ávalos */ #include "platform.h" #include #include #include #include "pg_lookup_orders.h" #include "pg_helper.h" /** * Context used for TMH_PG_lookup_orders(). */ struct LookupOrdersContext { /** * Function to call with the results. */ TALER_MERCHANTDB_OrdersCallback cb; /** * Closure for @a cb. */ void *cb_cls; /** * Did database result extraction fail? */ bool extract_failed; }; /** * Function to be called with the results of a SELECT statement * that has returned @a num_results results about orders. * * @param[in,out] cls of type `struct LookupOrdersContext *` * @param result the postgres result * @param num_results the number of results in @a result */ static void lookup_orders_cb (void *cls, PGresult *result, unsigned int num_results) { struct LookupOrdersContext *plc = cls; for (unsigned int i = 0; i < num_results; i++) { char *order_id; uint64_t order_serial; struct GNUNET_TIME_Timestamp ts; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_string ("order_id", &order_id), GNUNET_PQ_result_spec_uint64 ("order_serial", &order_serial), GNUNET_PQ_result_spec_timestamp ("creation_time", &ts), GNUNET_PQ_result_spec_end }; if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, i)) { GNUNET_break (0); plc->extract_failed = true; return; } plc->cb (plc->cb_cls, order_id, order_serial, ts); GNUNET_PQ_cleanup_result (rs); } } enum GNUNET_DB_QueryStatus TMH_PG_lookup_orders (void *cls, const char *instance_id, const struct TALER_MERCHANTDB_OrderFilter *of, TALER_MERCHANTDB_OrdersCallback cb, void *cb_cls) { struct PostgresClosure *pg = cls; struct LookupOrdersContext plc = { .cb = cb, .cb_cls = cb_cls }; uint64_t limit = (of->delta > 0) ? of->delta : -of->delta; uint8_t paid; uint8_t refunded; uint8_t wired; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (instance_id), GNUNET_PQ_query_param_uint64 (&limit), GNUNET_PQ_query_param_uint64 (&of->start_row), GNUNET_PQ_query_param_timestamp (&of->date), GNUNET_PQ_query_param_auto_from_type (&paid), GNUNET_PQ_query_param_auto_from_type (&refunded), GNUNET_PQ_query_param_auto_from_type (&wired), GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus qs; char stmt[128]; paid = (TALER_EXCHANGE_YNA_YES == of->paid); refunded = (TALER_EXCHANGE_YNA_YES == of->refunded); wired = (TALER_EXCHANGE_YNA_YES == of->wired); /* painfully many cases..., note that "_xxx" being present in 'stmt' merely means that we filter by that variable, the value we filter for is computed above */ GNUNET_snprintf (stmt, sizeof (stmt), "lookup_orders_%s%s%s%s", (of->delta > 0) ? "inc" : "dec", (TALER_EXCHANGE_YNA_ALL == of->paid) ? "" : "_paid", (TALER_EXCHANGE_YNA_ALL == of->refunded) ? "" : "_refunded", (TALER_EXCHANGE_YNA_ALL == of->wired) ? "" : "_wired"); PREPARE (pg, "lookup_orders_inc", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_inc_paid", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " BOOL($5) = paid" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_inc_refunded", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " CAST($6 as BOOL) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_inc_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " BOOL($7) = wired" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_inc_paid_refunded", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " BOOL($5) = paid" " AND" " BOOL($6) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_inc_paid_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " BOOL($5) = paid" " AND" " BOOL($7) = wired" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_inc_refunded_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " BOOL($6) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " AND" " BOOL($7) = wired" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_inc_paid_refunded_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial ASC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial > $3" " AND" " creation_time > $4" " AND" " BOOL($5) = paid" " AND" " BOOL($6) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " AND" " BOOL($7) = wired" " ORDER BY order_serial ASC" " LIMIT $2)" " ORDER BY order_serial ASC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec_paid", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " BOOL($5) = paid" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec_refunded", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " BOOL($6) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " BOOL($7) = wired" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec_paid_refunded", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " BOOL($5) = paid" " AND" " BOOL($6) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec_paid_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " BOOL($5) = paid" " AND" " BOOL($7) = wired" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec_refunded_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " BOOL($6) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " AND" " BOOL($7) = wired" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); PREPARE (pg, "lookup_orders_dec_paid_refunded_wired", "(SELECT" " order_id" ",order_serial" ",creation_time" " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " NOT CAST($5 as BOOL)" /* unclaimed orders are never paid */ " AND" " NOT CAST($6 as BOOL)"/* unclaimed orders are never refunded */ " AND" " NOT CAST($7 as BOOL)" /* unclaimed orders are never wired */ " AND" " order_serial NOT IN" " (SELECT order_serial" " FROM merchant_contract_terms)" /* only select unclaimed orders */ " ORDER BY order_serial DESC" " LIMIT $2)" "UNION " /* union ensures elements are distinct! */ "(SELECT" " order_id" ",order_serial" ",creation_time" " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" " AND" " order_serial < $3" " AND" " creation_time < $4" " AND" " BOOL($5) = paid" " AND" " BOOL($6) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " AND" " BOOL($7) = wired" " ORDER BY order_serial DESC" " LIMIT $2)" " ORDER BY order_serial DESC" " LIMIT $2"); qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, stmt, params, &lookup_orders_cb, &plc); if (plc.extract_failed) return GNUNET_DB_STATUS_HARD_ERROR; return qs; }