aboutsummaryrefslogtreecommitdiff
path: root/src/postgres
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-03-22 18:47:07 +0000
committerChristian Grothoff <christian@grothoff.org>2012-03-22 18:47:07 +0000
commit4c01d543d10a24b30e279cdb061d9ebe459cdcaf (patch)
tree3ccec82f8e23c009e7366f421dbfacbf43e01055 /src/postgres
parent84b6e8491d8712f772a2297d59b2a1f4f21427fa (diff)
downloadgnunet-4c01d543d10a24b30e279cdb061d9ebe459cdcaf.tar.gz
gnunet-4c01d543d10a24b30e279cdb061d9ebe459cdcaf.zip
adding libgnunetpostgres for shared postgres functionality between postgres datastore/datacache backends
Diffstat (limited to 'src/postgres')
-rw-r--r--src/postgres/Makefile.am20
-rw-r--r--src/postgres/postgres.c194
2 files changed, 214 insertions, 0 deletions
diff --git a/src/postgres/Makefile.am b/src/postgres/Makefile.am
new file mode 100644
index 000000000..0b3be5e2b
--- /dev/null
+++ b/src/postgres/Makefile.am
@@ -0,0 +1,20 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = --coverage
9endif
10
11lib_LTLIBRARIES = libgnunetpostgres.la
12
13libgnunetpostgres_la_SOURCES = \
14 postgres.c
15libgnunetpostgres_la_LIBADD = -lpq \
16 $(top_builddir)/src/util/libgnunetutil.la
17libgnunetpostgres_la_LDFLAGS = \
18 $(GN_LIB_LDFLAGS) \
19 -version-info 0:0:0
20
diff --git a/src/postgres/postgres.c b/src/postgres/postgres.c
new file mode 100644
index 000000000..c6b9a5aa6
--- /dev/null
+++ b/src/postgres/postgres.c
@@ -0,0 +1,194 @@
1/*
2 This file is part of GNUnet
3 (C) 2009, 2010, 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file postgres/postgres.c
22 * @brief library to help with access to a Postgres database
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_postgres_lib.h"
27
28
29/**
30 * Check if the result obtained from Postgres has
31 * the desired status code. If not, log an error, clear the
32 * result and return GNUNET_SYSERR.
33 *
34 * @param dbh database handle
35 * @param ret return value from database operation to check
36 * @param expected_status desired status
37 * @param command description of the command that was run
38 * @param args arguments given to the command
39 * @param filename name of the source file where the command was run
40 * @param line line number in the source file
41 * @return GNUNET_OK if the result is acceptable
42 */
43int
44GNUNET_POSTGRES_check_result_ (PGconn *dbh, PGresult * ret, int expected_status,
45 const char *command, const char *args, const char *filename,
46 int line)
47{
48 if (ret == NULL)
49 {
50 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
51 "postgres",
52 "Postgres failed to allocate result for `%s:%s' at %s:%d\n",
53 command, args, filename, line);
54 return GNUNET_SYSERR;
55 }
56 if (PQresultStatus (ret) != expected_status)
57 {
58 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
59 "postgres",
60 _("`%s:%s' failed at %s:%d with error: %s"), command, args,
61 filename, line, PQerrorMessage (dbh));
62 PQclear (ret);
63 return GNUNET_SYSERR;
64 }
65 return GNUNET_OK;
66}
67
68
69/**
70 * Run simple SQL statement (without results).
71 *
72 * @param dbh database handle
73 * @param sql statement to run
74 * @param filename filename for error reporting
75 * @param line code line for error reporting
76 * @return GNUNET_OK on success
77 */
78int
79GNUNET_POSTGRES_exec_ (PGconn *dbh, const char *sql,
80 const char *filename,
81 int line)
82{
83 PGresult *ret;
84
85 ret = PQexec (dbh, sql);
86 if (GNUNET_OK !=
87 GNUNET_POSTGRES_check_result_ (dbh, ret, PGRES_COMMAND_OK, "PQexec", sql, filename, line))
88 return GNUNET_SYSERR;
89 PQclear (ret);
90 return GNUNET_OK;
91}
92
93
94/**
95 * Prepare SQL statement.
96 *
97 * @param dbh database handle
98 * @param name name for the prepared SQL statement
99 * @param sql SQL code to prepare
100 * @param nparams number of parameters in sql
101 * @param filename filename for error reporting
102 * @param line code line for error reporting
103 * @return GNUNET_OK on success
104 */
105int
106GNUNET_POSTGRES_prepare_ (PGconn *dbh, const char *name, const char *sql,
107 int nparms, const char *filename, int line)
108{
109 PGresult *ret;
110
111 ret = PQprepare (dbh, name, sql, nparms, NULL);
112 if (GNUNET_OK !=
113 GNUNET_POSTGRES_check_result_ (dbh, ret, PGRES_COMMAND_OK, "PQprepare", sql, filename, line))
114 return GNUNET_SYSERR;
115 PQclear (ret);
116 return GNUNET_OK;
117}
118
119
120/**
121 * Connect to a postgres database
122 *
123 * @param cfg configuration
124 * @param section configuration section to use to get Postgres configuration options
125 * @return the postgres handle
126 */
127PGconn *
128GNUNET_POSTGRES_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
129 const char *section)
130{
131 PGconn *dbh;
132 char *conninfo;
133
134 /* Open database and precompile statements */
135 if (GNUNET_OK !=
136 GNUNET_CONFIGURATION_get_value_string (cfg,
137 section, "CONFIG",
138 &conninfo))
139 conninfo = NULL;
140 dbh = PQconnectdb (conninfo == NULL ? "" : conninfo);
141 GNUNET_free_non_null (conninfo);
142 if (NULL == dbh)
143 {
144 /* FIXME: warn about out-of-memory? */
145 return NULL;
146 }
147 if (PQstatus (dbh) != CONNECTION_OK)
148 {
149 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "postgres",
150 _("Unable to initialize Postgres: %s"),
151 PQerrorMessage (dbh));
152 PQfinish (dbh);
153 return NULL;
154 }
155 return dbh;
156}
157
158
159/**
160 * Delete the row identified by the given rowid (qid
161 * in postgres).
162 *
163 * @param database handle
164 * @param stmt name of the prepared statement
165 * @param rowid which row to delete
166 * @return GNUNET_OK on success
167 */
168int
169GNUNET_POSTGRES_delete_by_rowid (PGconn *dbh,
170 const char *stmt,
171 uint32_t rowid)
172{
173 uint32_t brow = htonl (rowid);
174 const char *paramValues[] = { (const char *) &brow };
175 int paramLengths[] = { sizeof (brow) };
176 const int paramFormats[] = { 1 };
177 PGresult *ret;
178
179 ret =
180 PQexecPrepared (dbh, stmt, 1, paramValues, paramLengths,
181 paramFormats, 1);
182 if (GNUNET_OK !=
183 GNUNET_POSTGRES_check_result_ (dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "delrow",
184 __FILE__,
185 __LINE__))
186 {
187 return GNUNET_SYSERR;
188 }
189 PQclear (ret);
190 return GNUNET_OK;
191}
192
193
194/* end of postgres.c */