glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / pq / pq_exec.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 /**
16  * @file pq/pq_exec.c
17  * @brief functions to execute plain SQL statements (PostGres)
18  * @author Christian Grothoff
19  */
20 #include "platform.h"
21 #include "gnunet_util_lib.h"
22 #include "gnunet_pq_lib.h"
23
24
25 /**
26  * Create a `struct GNUNET_PQ_ExecuteStatement` where errors are fatal.
27  *
28  * @param sql actual SQL statement
29  * @return initialized struct
30  */
31 struct GNUNET_PQ_ExecuteStatement
32 GNUNET_PQ_make_execute (const char *sql)
33 {
34   struct GNUNET_PQ_ExecuteStatement es = {
35     .sql = sql,
36     .ignore_errors = GNUNET_NO
37   };
38
39   return es;
40 }
41
42
43 /**
44  * Create a `struct GNUNET_PQ_ExecuteStatement` where errors should
45  * be tolerated.
46  *
47  * @param sql actual SQL statement
48  * @return initialized struct
49  */
50 struct GNUNET_PQ_ExecuteStatement
51 GNUNET_PQ_make_try_execute (const char *sql)
52 {
53   struct GNUNET_PQ_ExecuteStatement es = {
54     .sql = sql,
55     .ignore_errors = GNUNET_YES
56   };
57
58   return es;
59 }
60
61
62 /**
63  * Request execution of an array of statements @a es from Postgres.
64  *
65  * @param connection connection to execute the statements over
66  * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared
67  *            statements.
68  * @return #GNUNET_OK on success (modulo statements where errors can be ignored)
69  *         #GNUNET_SYSERR on error
70  */
71 int
72 GNUNET_PQ_exec_statements (PGconn *connection,
73                            const struct GNUNET_PQ_ExecuteStatement *es)
74 {
75   for (unsigned int i=0; NULL != es[i].sql; i++)
76   {
77     PGresult *result;
78
79     result = PQexec (connection,
80                      es[i].sql);
81     if ( (GNUNET_NO == es[i].ignore_errors) &&
82          (PGRES_COMMAND_OK != PQresultStatus (result)) )
83     {
84       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
85                        "pq",
86                        "Failed to execute `%s': %s/%s/%s/%s/%s",
87                        es[i].sql,
88                        PQresultErrorField (result,
89                                            PG_DIAG_MESSAGE_PRIMARY),
90                        PQresultErrorField (result,
91                                            PG_DIAG_MESSAGE_DETAIL),
92                        PQresultErrorMessage (result),
93                        PQresStatus (PQresultStatus (result)),
94                        PQerrorMessage (connection));
95       PQclear (result);
96       return GNUNET_SYSERR;
97     }
98     PQclear (result);
99   }
100   return GNUNET_OK;
101 }
102
103
104 /* end of pq/pq_exec.c */