Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2022, 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 backenddb/pg_lookup_product.c
18 : * @brief Implementation of the lookup_product function for Postgres
19 : * @author Iván Ávalos
20 : */
21 : #include "platform.h"
22 : #include <taler/taler_error_codes.h>
23 : #include <taler/taler_dbevents.h>
24 : #include <taler/taler_pq_lib.h>
25 : #include "pg_lookup_product.h"
26 : #include "pg_helper.h"
27 :
28 :
29 : enum GNUNET_DB_QueryStatus
30 64 : TMH_PG_lookup_product (void *cls,
31 : const char *instance_id,
32 : const char *product_id,
33 : struct TALER_MERCHANTDB_ProductDetails *pd,
34 : size_t *num_categories,
35 : uint64_t **categories)
36 : {
37 64 : struct PostgresClosure *pg = cls;
38 64 : struct GNUNET_PQ_QueryParam params[] = {
39 64 : GNUNET_PQ_query_param_string (instance_id),
40 64 : GNUNET_PQ_query_param_string (product_id),
41 : GNUNET_PQ_query_param_end
42 : };
43 :
44 64 : PREPARE (pg,
45 : "lookup_product",
46 : "SELECT"
47 : " mi.description"
48 : ",mi.description_i18n::TEXT"
49 : ",mi.product_name"
50 : ",mi.unit"
51 : ",mi.price_array"
52 : ",mi.taxes::TEXT"
53 : ",mi.total_stock"
54 : ",mi.total_stock_frac"
55 : ",mi.allow_fractional_quantity"
56 : ",mi.fractional_precision_level"
57 : ",mi.total_sold"
58 : ",mi.total_sold_frac"
59 : ",mi.total_lost"
60 : ",mi.total_lost_frac"
61 : ",mi.image"
62 : ",mi.address::TEXT"
63 : ",mi.next_restock"
64 : ",mi.minimum_age"
65 : ",mi.product_group_serial"
66 : ",mi.money_pot_serial"
67 : ",mi.price_is_net"
68 : ",t.category_array AS categories"
69 : " FROM merchant_inventory mi"
70 : " JOIN merchant_instances inst"
71 : " USING (merchant_serial)"
72 : ",LATERAL ("
73 : " SELECT ARRAY ("
74 : " SELECT mpc.category_serial"
75 : " FROM merchant_product_categories mpc"
76 : " WHERE mpc.product_serial = mi.product_serial"
77 : " ) AS category_array"
78 : " ) t"
79 : " WHERE inst.merchant_id=$1"
80 : " AND mi.product_id=$2"
81 : );
82 64 : if (NULL == pd)
83 : {
84 5 : struct GNUNET_PQ_ResultSpec rs_null[] = {
85 : GNUNET_PQ_result_spec_end
86 : };
87 :
88 5 : check_connection (pg);
89 5 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
90 : "lookup_product",
91 : params,
92 : rs_null);
93 : }
94 : else
95 : {
96 59 : char *my_name = NULL;
97 59 : char *my_description = NULL;
98 59 : json_t *my_description_i18n = NULL;
99 59 : char *my_unit = NULL;
100 59 : char *my_image = NULL;
101 59 : json_t *my_address = NULL;
102 59 : json_t *my_taxes = NULL;
103 59 : uint64_t *my_categories = NULL;
104 59 : struct TALER_Amount *my_price_array = NULL;
105 59 : size_t my_price_array_length = 0;
106 59 : struct GNUNET_PQ_ResultSpec rs[] = {
107 59 : GNUNET_PQ_result_spec_string ("description",
108 : &my_description),
109 59 : TALER_PQ_result_spec_json ("description_i18n",
110 : &my_description_i18n),
111 59 : GNUNET_PQ_result_spec_string ("product_name",
112 : &my_name),
113 59 : GNUNET_PQ_result_spec_string ("unit",
114 : &my_unit),
115 59 : TALER_PQ_result_spec_array_amount_with_currency (pg->conn,
116 : "price_array",
117 : &my_price_array_length,
118 : &my_price_array),
119 59 : TALER_PQ_result_spec_json ("taxes",
120 : &my_taxes),
121 59 : GNUNET_PQ_result_spec_uint64 ("total_stock",
122 : &pd->total_stock),
123 59 : GNUNET_PQ_result_spec_uint32 ("total_stock_frac",
124 : &pd->total_stock_frac),
125 59 : GNUNET_PQ_result_spec_bool ("allow_fractional_quantity",
126 : &pd->allow_fractional_quantity),
127 59 : GNUNET_PQ_result_spec_uint32 ("fractional_precision_level",
128 : &pd->fractional_precision_level),
129 59 : GNUNET_PQ_result_spec_uint64 ("total_sold",
130 : &pd->total_sold),
131 59 : GNUNET_PQ_result_spec_uint32 ("total_sold_frac",
132 : &pd->total_sold_frac),
133 59 : GNUNET_PQ_result_spec_uint64 ("total_lost",
134 : &pd->total_lost),
135 59 : GNUNET_PQ_result_spec_uint32 ("total_lost_frac",
136 : &pd->total_lost_frac),
137 59 : GNUNET_PQ_result_spec_string ("image",
138 : &my_image),
139 59 : TALER_PQ_result_spec_json ("address",
140 : &my_address),
141 59 : GNUNET_PQ_result_spec_timestamp ("next_restock",
142 : &pd->next_restock),
143 59 : GNUNET_PQ_result_spec_uint32 ("minimum_age",
144 : &pd->minimum_age),
145 59 : GNUNET_PQ_result_spec_array_uint64 (pg->conn,
146 : "categories",
147 : num_categories,
148 : &my_categories),
149 59 : GNUNET_PQ_result_spec_allow_null (
150 : GNUNET_PQ_result_spec_uint64 ("product_group_serial",
151 : &pd->product_group_id),
152 : NULL),
153 59 : GNUNET_PQ_result_spec_allow_null (
154 : GNUNET_PQ_result_spec_uint64 ("money_pot_serial",
155 : &pd->money_pot_id),
156 : NULL),
157 59 : GNUNET_PQ_result_spec_bool ("price_is_net",
158 : &pd->price_is_net),
159 : GNUNET_PQ_result_spec_end
160 : };
161 : enum GNUNET_DB_QueryStatus qs;
162 :
163 59 : check_connection (pg);
164 59 : pd->product_group_id = 0;
165 59 : pd->money_pot_id = 0;
166 59 : qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
167 : "lookup_product",
168 : params,
169 : rs);
170 59 : pd->product_name = my_name;
171 59 : pd->description = my_description;
172 59 : pd->description_i18n = my_description_i18n;
173 59 : pd->unit = my_unit;
174 59 : pd->taxes = my_taxes;
175 59 : pd->image = my_image;
176 59 : pd->address = my_address;
177 59 : pd->price_array = my_price_array;
178 59 : pd->price_array_length = my_price_array_length;
179 59 : *categories = my_categories;
180 : /* Clear original pointers to that cleanup_result doesn't squash them */
181 59 : my_name = NULL;
182 59 : my_description = NULL;
183 59 : my_description_i18n = NULL;
184 59 : my_unit = NULL;
185 59 : my_taxes = NULL;
186 59 : my_image = NULL;
187 59 : my_address = NULL;
188 59 : my_price_array = NULL;
189 59 : my_price_array_length = 0;
190 59 : my_categories = NULL;
191 59 : GNUNET_PQ_cleanup_result (rs);
192 59 : return qs;
193 : }
194 : }
|