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_units.c
18 : * @brief Implementation of the iterate_units function for Postgres
19 : * @author Bohdan Potuzhnyi
20 : */
21 : #include "platform.h"
22 : #include <taler/taler_pq_lib.h>
23 : #include "merchant-database/iterate_units.h"
24 : #include "helper.h"
25 :
26 :
27 : /**
28 : * Context used for TALER_MERCHANTDB_iterate_units().
29 : */
30 : struct LookupUnitsContext
31 : {
32 : TALER_MERCHANTDB_UnitsCallback cb;
33 : void *cb_cls;
34 : bool extract_failed;
35 : };
36 :
37 :
38 : static void
39 4 : lookup_units_cb (void *cls,
40 : PGresult *result,
41 : unsigned int num_results)
42 : {
43 4 : struct LookupUnitsContext *luc = cls;
44 :
45 152 : for (unsigned int i = 0; i<num_results; i++)
46 : {
47 148 : struct TALER_MERCHANTDB_UnitDetails ud = { 0 };
48 148 : struct GNUNET_PQ_ResultSpec rs[] = {
49 148 : GNUNET_PQ_result_spec_uint64 ("unit_serial",
50 : &ud.unit_serial),
51 148 : GNUNET_PQ_result_spec_string ("unit",
52 : &ud.unit),
53 148 : GNUNET_PQ_result_spec_string ("unit_name_long",
54 : &ud.unit_name_long),
55 148 : GNUNET_PQ_result_spec_string ("unit_name_short",
56 : &ud.unit_name_short),
57 148 : TALER_PQ_result_spec_json ("unit_name_long_i18n",
58 : &ud.unit_name_long_i18n),
59 148 : TALER_PQ_result_spec_json ("unit_name_short_i18n",
60 : &ud.unit_name_short_i18n),
61 148 : GNUNET_PQ_result_spec_bool ("unit_allow_fraction",
62 : &ud.unit_allow_fraction),
63 148 : GNUNET_PQ_result_spec_uint32 ("unit_precision_level",
64 : &ud.unit_precision_level),
65 148 : GNUNET_PQ_result_spec_bool ("unit_active",
66 : &ud.unit_active),
67 148 : GNUNET_PQ_result_spec_bool ("unit_builtin",
68 : &ud.unit_builtin),
69 : GNUNET_PQ_result_spec_end
70 : };
71 :
72 148 : if (GNUNET_OK !=
73 148 : GNUNET_PQ_extract_result (result,
74 : rs,
75 : i))
76 : {
77 0 : GNUNET_break (0);
78 0 : luc->extract_failed = true;
79 0 : return;
80 : }
81 148 : luc->cb (luc->cb_cls,
82 : ud.unit_serial,
83 : &ud);
84 148 : GNUNET_PQ_cleanup_result (rs);
85 : }
86 : }
87 :
88 :
89 : enum GNUNET_DB_QueryStatus
90 4 : TALER_MERCHANTDB_iterate_units (
91 : struct TALER_MERCHANTDB_PostgresContext *pg,
92 : const char *instance_id,
93 : TALER_MERCHANTDB_UnitsCallback cb,
94 : void *cb_cls)
95 : {
96 4 : struct LookupUnitsContext luc = {
97 : .cb = cb,
98 : .cb_cls = cb_cls,
99 : .extract_failed = false
100 : };
101 4 : struct GNUNET_PQ_QueryParam params[] = {
102 : GNUNET_PQ_query_param_end
103 : };
104 : enum GNUNET_DB_QueryStatus qs;
105 :
106 4 : GNUNET_assert (NULL != pg->current_merchant_id);
107 4 : GNUNET_assert (0 == strcmp (instance_id,
108 : pg->current_merchant_id));
109 4 : TMH_PQ_prepare_anon (pg,
110 : "SELECT cu.unit_serial"
111 : " ,cu.unit"
112 : " ,cu.unit_name_long"
113 : " ,cu.unit_name_short"
114 : " ,cu.unit_name_long_i18n"
115 : " ,cu.unit_name_short_i18n"
116 : " ,cu.unit_allow_fraction"
117 : " ,cu.unit_precision_level"
118 : " ,cu.unit_active"
119 : " ,FALSE AS unit_builtin"
120 : " FROM merchant_custom_units cu"
121 : " UNION ALL "
122 : "SELECT bu.unit_serial"
123 : " ,bu.unit"
124 : " ,bu.unit_name_long"
125 : " ,bu.unit_name_short"
126 : " ,bu.unit_name_long_i18n"
127 : " ,bu.unit_name_short_i18n"
128 : " ,COALESCE(bo.override_allow_fraction, bu.unit_allow_fraction)"
129 : " ,COALESCE(bo.override_precision_level, bu.unit_precision_level)"
130 : " ,COALESCE(bo.override_active, bu.unit_active)"
131 : " ,TRUE AS unit_builtin"
132 : " FROM merchant.merchant_builtin_units bu"
133 : " LEFT JOIN merchant_builtin_unit_overrides bo"
134 : " ON bo.builtin_unit_serial = bu.unit_serial"
135 : " ORDER BY unit");
136 4 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
137 : "",
138 : params,
139 : &lookup_units_cb,
140 : &luc);
141 4 : if (luc.extract_failed)
142 0 : return GNUNET_DB_STATUS_HARD_ERROR;
143 4 : return qs;
144 : }
|