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