Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2025 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file src/backenddb/iterate_categories_by_ids.c
18 : * @brief Lookup product categories by ID
19 : * @author Bohdan Potuzhnyi
20 : */
21 : #include "platform.h"
22 : #include <taler/taler_pq_lib.h>
23 : #include "merchant-database/iterate_categories_by_ids.h"
24 : #include "helper.h"
25 :
26 :
27 : /**
28 : * Context used for TALER_MERCHANTDB_iterate_categories_by_ids().
29 : */
30 : struct LookupCategoryContext
31 : {
32 : /**
33 : * Function to call with the results.
34 : */
35 : TALER_MERCHANTDB_CategoriesCallback cb;
36 :
37 : /**
38 : * Closure for @a cb.
39 : */
40 : void *cb_cls;
41 :
42 : /**
43 : * Did database result extraction fail?
44 : */
45 : bool extract_failed;
46 : };
47 :
48 :
49 : static void
50 2 : lookup_categories_cb (void *cls,
51 : PGresult *result,
52 : unsigned int num_results)
53 : {
54 2 : struct LookupCategoryContext *tlc = cls;
55 :
56 6 : for (unsigned int i = 0; i < num_results; i++)
57 : {
58 : uint64_t category_id;
59 : char *category_name;
60 : json_t *category_name_i18n;
61 : uint64_t product_count;
62 4 : struct GNUNET_PQ_ResultSpec rs[] = {
63 4 : GNUNET_PQ_result_spec_uint64 ("category_serial",
64 : &category_id),
65 4 : GNUNET_PQ_result_spec_string ("category_name",
66 : &category_name),
67 4 : TALER_PQ_result_spec_json ("category_name_i18n",
68 : &category_name_i18n),
69 4 : GNUNET_PQ_result_spec_uint64 ("product_count",
70 : &product_count),
71 : GNUNET_PQ_result_spec_end
72 : };
73 :
74 4 : if (GNUNET_OK !=
75 4 : GNUNET_PQ_extract_result (result,
76 : rs,
77 : i))
78 : {
79 0 : GNUNET_break (0);
80 0 : tlc->extract_failed = true;
81 0 : return;
82 : }
83 4 : tlc->cb (tlc->cb_cls,
84 : category_id,
85 : category_name,
86 : category_name_i18n,
87 : product_count);
88 4 : GNUNET_PQ_cleanup_result (rs);
89 : }
90 : }
91 :
92 :
93 : enum GNUNET_DB_QueryStatus
94 2 : TALER_MERCHANTDB_iterate_categories_by_ids (struct TALER_MERCHANTDB_PostgresContext *pg,
95 : const char *instance_id,
96 : const uint64_t *category_ids,
97 : size_t num_category_ids,
98 : TALER_MERCHANTDB_CategoriesCallback cb,
99 : void *cb_cls)
100 : {
101 2 : struct LookupCategoryContext tlc = {
102 : .cb = cb,
103 : .cb_cls = cb_cls,
104 : /* Can be overwritten by the lookup_categories_cb */
105 : .extract_failed = false,
106 : };
107 2 : struct GNUNET_PQ_QueryParam params[] = {
108 2 : GNUNET_PQ_query_param_array_uint64 (num_category_ids,
109 : category_ids,
110 : pg->conn),
111 : GNUNET_PQ_query_param_end
112 : };
113 : enum GNUNET_DB_QueryStatus qs;
114 :
115 2 : GNUNET_assert (NULL != pg->current_merchant_id);
116 2 : GNUNET_assert (0 == strcmp (instance_id,
117 : pg->current_merchant_id));
118 2 : TMH_PQ_prepare_anon (pg,
119 : "SELECT"
120 : " mc.category_serial"
121 : ",mc.category_name"
122 : ",mc.category_name_i18n::TEXT"
123 : ",COALESCE(COUNT(mpc.product_serial),0)"
124 : " AS product_count"
125 : " FROM merchant_categories mc"
126 : " LEFT JOIN merchant_product_categories mpc"
127 : " USING (category_serial)"
128 : " WHERE mc.category_serial = ANY ($1)"
129 : " GROUP BY mc.category_serial"
130 : " ORDER BY mc.category_serial;");
131 2 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
132 : "",
133 : params,
134 : &lookup_categories_cb,
135 : &tlc);
136 2 : GNUNET_PQ_cleanup_query_params_closures (params);
137 2 : if (tlc.extract_failed)
138 0 : return GNUNET_DB_STATUS_HARD_ERROR;
139 2 : return qs;
140 : }
|