aboutsummaryrefslogtreecommitdiff
path: root/src/pq/pq.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pq/pq.c')
-rw-r--r--src/pq/pq.c190
1 files changed, 0 insertions, 190 deletions
diff --git a/src/pq/pq.c b/src/pq/pq.c
deleted file mode 100644
index 130ff355f..000000000
--- a/src/pq/pq.c
+++ /dev/null
@@ -1,190 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016, 2017, 2019, 2020 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file pq/pq.c
22 * @brief helper functions for libpq (PostGres) interactions
23 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
24 * @author Florian Dold
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "pq.h"
29
30
31PGresult *
32GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db,
33 const char *name,
34 const struct GNUNET_PQ_QueryParam *params)
35{
36 unsigned int len;
37
38 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
39 "Running prepared statement `%s' on %p\n",
40 name,
41 db);
42 /* count the number of parameters */
43 len = 0;
44 for (unsigned int i = 0; 0 != params[i].num_params; i++)
45 len += params[i].num_params;
46
47 /* new scope to allow stack allocation without alloca */
48 {
49 /* Scratch buffer for temporary storage */
50 void *scratch[len];
51 /* Parameter array we are building for the query */
52 void *param_values[len];
53 int param_lengths[len];
54 int param_formats[len];
55 unsigned int off;
56 /* How many entries in the scratch buffer are in use? */
57 unsigned int soff;
58 PGresult *res;
59 int ret;
60 ConnStatusType status;
61
62 off = 0;
63 soff = 0;
64 for (unsigned int i = 0; 0 != params[i].num_params; i++)
65 {
66 const struct GNUNET_PQ_QueryParam *x = &params[i];
67
68 ret = x->conv (x->conv_cls,
69 x->data,
70 x->size,
71 &param_values[off],
72 &param_lengths[off],
73 &param_formats[off],
74 x->num_params,
75 &scratch[soff],
76 len - soff);
77 if (ret < 0)
78 {
79 for (off = 0; off < soff; off++)
80 GNUNET_free (scratch[off]);
81 return NULL;
82 }
83 soff += ret;
84 off += x->num_params;
85 }
86 GNUNET_assert (off == len);
87 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
88 "pq",
89 "Executing prepared SQL statement `%s'\n",
90 name);
91 res = PQexecPrepared (db->conn,
92 name,
93 len,
94 (const char **) param_values,
95 param_lengths,
96 param_formats,
97 1);
98 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
99 "pq",
100 "Execution of prepared SQL statement `%s' finished (%d)\n",
101 name,
102 PGRES_COMMAND_OK == PQresultStatus (res));
103 if ( (PGRES_COMMAND_OK != PQresultStatus (res)) &&
104 (CONNECTION_OK != (status = PQstatus (db->conn))) )
105 {
106 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
107 "pq",
108 "Database disconnected on SQL statement `%s' (reconnecting)\n",
109 name);
110 GNUNET_PQ_reconnect (db);
111 res = NULL;
112 }
113
114 for (off = 0; off < soff; off++)
115 GNUNET_free (scratch[off]);
116 return res;
117 }
118}
119
120
121void
122GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs)
123{
124 for (unsigned int i = 0; NULL != rs[i].conv; i++)
125 if (NULL != rs[i].cleaner)
126 rs[i].cleaner (rs[i].cls,
127 rs[i].dst);
128}
129
130
131enum GNUNET_GenericReturnValue
132GNUNET_PQ_extract_result (PGresult *result,
133 struct GNUNET_PQ_ResultSpec *rs,
134 int row)
135{
136 unsigned int i;
137
138 if (NULL == result)
139 return GNUNET_SYSERR;
140 for (i = 0; NULL != rs[i].conv; i++)
141 {
142 struct GNUNET_PQ_ResultSpec *spec;
143 enum GNUNET_GenericReturnValue ret;
144
145 spec = &rs[i];
146 ret = spec->conv (spec->cls,
147 result,
148 row,
149 spec->fname,
150 &spec->dst_size,
151 spec->dst);
152 switch (ret)
153 {
154 case GNUNET_OK:
155 /* canonical case, continue below */
156 if (NULL != spec->is_null)
157 *spec->is_null = false;
158 break;
159 case GNUNET_NO:
160 if (spec->is_nullable)
161 {
162 if (NULL != spec->is_null)
163 *spec->is_null = true;
164 continue;
165 }
166 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
167 "NULL field encountered for `%s' where non-NULL was required\n",
168 spec->fname);
169 goto cleanup;
170 case GNUNET_SYSERR:
171 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
172 "Failed to extract field `%s'\n",
173 spec->fname);
174 GNUNET_break (0);
175 goto cleanup;
176 }
177 if (NULL != spec->result_size)
178 *spec->result_size = spec->dst_size;
179 }
180 return GNUNET_OK;
181cleanup:
182 for (unsigned int j = 0; j < i; j++)
183 if (NULL != rs[j].cleaner)
184 rs[j].cleaner (rs[j].cls,
185 rs[j].dst);
186 return GNUNET_SYSERR;
187}
188
189
190/* end of pq/pq.c */