NAMESTORE/JSON: fix parsing exp and flags
[oweals/gnunet.git] / src / sq / sq.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2017 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 sq/sq.c
22  * @brief helper functions for Sqlite3 DB interactions
23  * @author Christian Grothoff
24  */
25 #include "platform.h"
26 #include "gnunet_sq_lib.h"
27
28
29 /**
30  * Execute a prepared statement.
31  *
32  * @param db_conn database connection
33  * @param params parameters to the statement
34  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
35  */
36 int
37 GNUNET_SQ_bind (sqlite3_stmt *stmt,
38                 const struct GNUNET_SQ_QueryParam *params)
39 {
40   unsigned int j;
41
42   j = 1;
43   for (unsigned int i=0;NULL != params[i].conv; i++)
44   {
45     if (GNUNET_OK !=
46         params[i].conv (params[i].conv_cls,
47                         params[i].data,
48                         params[i].size,
49                         stmt,
50                         j))
51     {
52       GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
53                        "sq",
54                        _("Failure to bind %u-th SQL parameter\n"),
55                        i);
56       if (SQLITE_OK !=
57           sqlite3_reset (stmt))
58       {
59         GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
60                          "sq",
61                          _("Failure in sqlite3_reset (!)\n"));
62         return GNUNET_SYSERR;
63       }
64     }
65     GNUNET_assert (0 != params[i].num_params);
66     j += params[i].num_params;
67   }
68   return GNUNET_OK;
69 }
70
71
72 /**
73  * Extract results from a query result according to the given specification.
74  *
75  * @param result result to process
76  * @param[in,out] rs result specification to extract for
77  * @return
78  *   #GNUNET_OK if all results could be extracted
79  *   #GNUNET_SYSERR if a result was invalid (non-existing field)
80  */
81 int
82 GNUNET_SQ_extract_result (sqlite3_stmt *result,
83                           struct GNUNET_SQ_ResultSpec *rs)
84 {
85   unsigned int j = 0;
86
87   for (unsigned int i=0;NULL != rs[i].conv; i++)
88   {
89     if (NULL == rs[i].result_size)
90       rs[i].result_size = &rs[i].dst_size;
91     if (GNUNET_OK !=
92         rs[i].conv (rs[i].cls,
93                     result,
94                     j,
95                     rs[i].result_size,
96                     rs[i].dst))
97     {
98       for (unsigned int k=0;k<i;k++)
99         if (NULL != rs[k].cleaner)
100           rs[k].cleaner (rs[k].cls);
101       return GNUNET_SYSERR;
102     }
103     GNUNET_assert (0 != rs[i].num_params);
104     j += rs[i].num_params;
105   }
106   return GNUNET_OK;
107 }
108
109
110 /**
111  * Free all memory that was allocated in @a rs during
112  * #GNUNET_SQ_extract_result().
113  *
114  * @param rs reult specification to clean up
115  */
116 void
117 GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs)
118 {
119   for (unsigned int i=0;NULL != rs[i].conv; i++)
120     if (NULL != rs[i].cleaner)
121       rs[i].cleaner (rs[i].cls);
122 }
123
124
125 /**
126  * Reset @a stmt and log error.
127  *
128  * @param dbh database handle
129  * @param stmt statement to reset
130  */
131 void
132 GNUNET_SQ_reset (sqlite3 *dbh,
133                  sqlite3_stmt *stmt)
134 {
135   if (SQLITE_OK !=
136       sqlite3_reset (stmt))
137     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
138                      "sqlite",
139                      _("Failed to reset sqlite statement with error: %s\n"),
140                      sqlite3_errmsg (dbh));
141 }
142
143
144 /* end of sq.c */