diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-03-22 18:47:07 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-03-22 18:47:07 +0000 |
commit | 4c01d543d10a24b30e279cdb061d9ebe459cdcaf (patch) | |
tree | 3ccec82f8e23c009e7366f421dbfacbf43e01055 /src/datacache | |
parent | 84b6e8491d8712f772a2297d59b2a1f4f21427fa (diff) | |
download | gnunet-4c01d543d10a24b30e279cdb061d9ebe459cdcaf.tar.gz gnunet-4c01d543d10a24b30e279cdb061d9ebe459cdcaf.zip |
adding libgnunetpostgres for shared postgres functionality between postgres datastore/datacache backends
Diffstat (limited to 'src/datacache')
-rw-r--r-- | src/datacache/Makefile.am | 1 | ||||
-rw-r--r-- | src/datacache/plugin_datacache_postgres.c | 180 |
2 files changed, 25 insertions, 156 deletions
diff --git a/src/datacache/Makefile.am b/src/datacache/Makefile.am index 88545dcdc..d34e6e8c7 100644 --- a/src/datacache/Makefile.am +++ b/src/datacache/Makefile.am | |||
@@ -70,6 +70,7 @@ libgnunet_plugin_datacache_mysql_la_LDFLAGS = \ | |||
70 | libgnunet_plugin_datacache_postgres_la_SOURCES = \ | 70 | libgnunet_plugin_datacache_postgres_la_SOURCES = \ |
71 | plugin_datacache_postgres.c | 71 | plugin_datacache_postgres.c |
72 | libgnunet_plugin_datacache_postgres_la_LIBADD = \ | 72 | libgnunet_plugin_datacache_postgres_la_LIBADD = \ |
73 | $(top_builddir)/src/postgres/libgnunetpostgres.la \ | ||
73 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 74 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
74 | $(top_builddir)/src/util/libgnunetutil.la \ | 75 | $(top_builddir)/src/util/libgnunetutil.la \ |
75 | $(GN_PLUGIN_LDFLAGS) $(POSTGRES_LDFLAGS) -lpq | 76 | $(GN_PLUGIN_LDFLAGS) $(POSTGRES_LDFLAGS) -lpq |
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index 0fabdb4c2..cd4286b92 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2006, 2009, 2010 Christian Grothoff (and other contributing authors) | 3 | (C) 2006, 2009, 2010, 2012 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_postgres_lib.h" | ||
28 | #include "gnunet_datacache_plugin.h" | 29 | #include "gnunet_datacache_plugin.h" |
29 | #include <postgresql/libpq-fe.h> | 30 | #include <postgresql/libpq-fe.h> |
30 | 31 | ||
@@ -54,83 +55,6 @@ struct Plugin | |||
54 | 55 | ||
55 | 56 | ||
56 | /** | 57 | /** |
57 | * Check if the result obtained from Postgres has | ||
58 | * the desired status code. If not, log an error, clear the | ||
59 | * result and return GNUNET_SYSERR. | ||
60 | * | ||
61 | * @return GNUNET_OK if the result is acceptable | ||
62 | */ | ||
63 | static int | ||
64 | check_result (struct Plugin *plugin, PGresult * ret, int expected_status, | ||
65 | const char *command, const char *args, int line) | ||
66 | { | ||
67 | if (ret == NULL) | ||
68 | { | ||
69 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
70 | "datastore-postgres", | ||
71 | "Postgres failed to allocate result for `%s:%s' at %d\n", | ||
72 | command, args, line); | ||
73 | return GNUNET_SYSERR; | ||
74 | } | ||
75 | if (PQresultStatus (ret) != expected_status) | ||
76 | { | ||
77 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
78 | "datastore-postgres", | ||
79 | _("`%s:%s' failed at %s:%d with error: %s"), command, args, | ||
80 | __FILE__, line, PQerrorMessage (plugin->dbh)); | ||
81 | PQclear (ret); | ||
82 | return GNUNET_SYSERR; | ||
83 | } | ||
84 | return GNUNET_OK; | ||
85 | } | ||
86 | |||
87 | |||
88 | /** | ||
89 | * Run simple SQL statement (without results). | ||
90 | * | ||
91 | * @param plugin global context | ||
92 | * @param sql statement to run | ||
93 | * @param line code line for error reporting */ | ||
94 | static int | ||
95 | pq_exec (struct Plugin *plugin, const char *sql, int line) | ||
96 | { | ||
97 | PGresult *ret; | ||
98 | |||
99 | ret = PQexec (plugin->dbh, sql); | ||
100 | if (GNUNET_OK != | ||
101 | check_result (plugin, ret, PGRES_COMMAND_OK, "PQexec", sql, line)) | ||
102 | return GNUNET_SYSERR; | ||
103 | PQclear (ret); | ||
104 | return GNUNET_OK; | ||
105 | } | ||
106 | |||
107 | |||
108 | /** | ||
109 | * Prepare SQL statement. | ||
110 | * | ||
111 | * @param plugin global context | ||
112 | * @param name name for the prepared SQL statement | ||
113 | * @param sql SQL code to prepare | ||
114 | * @param nparams number of parameters in sql | ||
115 | * @param line code line for error reporting | ||
116 | * @return GNUNET_OK on success | ||
117 | */ | ||
118 | static int | ||
119 | pq_prepare (struct Plugin *plugin, const char *name, const char *sql, | ||
120 | int nparms, int line) | ||
121 | { | ||
122 | PGresult *ret; | ||
123 | |||
124 | ret = PQprepare (plugin->dbh, name, sql, nparms, NULL); | ||
125 | if (GNUNET_OK != | ||
126 | check_result (plugin, ret, PGRES_COMMAND_OK, "PQprepare", sql, line)) | ||
127 | return GNUNET_SYSERR; | ||
128 | PQclear (ret); | ||
129 | return GNUNET_OK; | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * @brief Get a database handle | 58 | * @brief Get a database handle |
135 | * | 59 | * |
136 | * @param plugin global context | 60 | * @param plugin global context |
@@ -139,31 +63,12 @@ pq_prepare (struct Plugin *plugin, const char *name, const char *sql, | |||
139 | static int | 63 | static int |
140 | init_connection (struct Plugin *plugin) | 64 | init_connection (struct Plugin *plugin) |
141 | { | 65 | { |
142 | char *conninfo; | ||
143 | PGresult *ret; | 66 | PGresult *ret; |
144 | 67 | ||
145 | /* Open database and precompile statements */ | 68 | plugin->dbh = GNUNET_POSTGRES_connect (plugin->env->cfg, |
146 | if (GNUNET_OK != | 69 | "datacache-postgres"); |
147 | GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, | ||
148 | "datacache-postgres", "CONFIG", | ||
149 | &conninfo)) | ||
150 | conninfo = NULL; | ||
151 | plugin->dbh = PQconnectdb (conninfo == NULL ? "" : conninfo); | ||
152 | GNUNET_free_non_null (conninfo); | ||
153 | if (NULL == plugin->dbh) | 70 | if (NULL == plugin->dbh) |
154 | { | ||
155 | /* FIXME: warn about out-of-memory? */ | ||
156 | return GNUNET_SYSERR; | 71 | return GNUNET_SYSERR; |
157 | } | ||
158 | if (PQstatus (plugin->dbh) != CONNECTION_OK) | ||
159 | { | ||
160 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "datacache-postgres", | ||
161 | _("Unable to initialize Postgres: %s"), | ||
162 | PQerrorMessage (plugin->dbh)); | ||
163 | PQfinish (plugin->dbh); | ||
164 | plugin->dbh = NULL; | ||
165 | return GNUNET_SYSERR; | ||
166 | } | ||
167 | ret = | 72 | ret = |
168 | PQexec (plugin->dbh, | 73 | PQexec (plugin->dbh, |
169 | "CREATE TEMPORARY TABLE gn090dc (" | 74 | "CREATE TEMPORARY TABLE gn090dc (" |
@@ -176,8 +81,8 @@ init_connection (struct Plugin *plugin) | |||
176 | (ret, | 81 | (ret, |
177 | PG_DIAG_SQLSTATE))))) | 82 | PG_DIAG_SQLSTATE))))) |
178 | { | 83 | { |
179 | (void) check_result (plugin, ret, PGRES_COMMAND_OK, "CREATE TABLE", | 84 | (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "CREATE TABLE", |
180 | "gn090dc", __LINE__); | 85 | "gn090dc"); |
181 | PQfinish (plugin->dbh); | 86 | PQfinish (plugin->dbh); |
182 | plugin->dbh = NULL; | 87 | plugin->dbh = NULL; |
183 | return GNUNET_SYSERR; | 88 | return GNUNET_SYSERR; |
@@ -185,10 +90,9 @@ init_connection (struct Plugin *plugin) | |||
185 | if (PQresultStatus (ret) == PGRES_COMMAND_OK) | 90 | if (PQresultStatus (ret) == PGRES_COMMAND_OK) |
186 | { | 91 | { |
187 | if ((GNUNET_OK != | 92 | if ((GNUNET_OK != |
188 | pq_exec (plugin, "CREATE INDEX idx_key ON gn090dc (key)", __LINE__)) || | 93 | GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_key ON gn090dc (key)")) || |
189 | (GNUNET_OK != | 94 | (GNUNET_OK != |
190 | pq_exec (plugin, "CREATE INDEX idx_dt ON gn090dc (discard_time)", | 95 | GNUNET_POSTGRES_exec (plugin->dbh, "CREATE INDEX idx_dt ON gn090dc (discard_time)"))) |
191 | __LINE__))) | ||
192 | { | 96 | { |
193 | PQclear (ret); | 97 | PQclear (ret); |
194 | PQfinish (plugin->dbh); | 98 | PQfinish (plugin->dbh); |
@@ -201,8 +105,7 @@ init_connection (struct Plugin *plugin) | |||
201 | PQexec (plugin->dbh, | 105 | PQexec (plugin->dbh, |
202 | "ALTER TABLE gn090dc ALTER value SET STORAGE EXTERNAL"); | 106 | "ALTER TABLE gn090dc ALTER value SET STORAGE EXTERNAL"); |
203 | if (GNUNET_OK != | 107 | if (GNUNET_OK != |
204 | check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc", | 108 | GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc")) |
205 | __LINE__)) | ||
206 | { | 109 | { |
207 | PQfinish (plugin->dbh); | 110 | PQfinish (plugin->dbh); |
208 | plugin->dbh = NULL; | 111 | plugin->dbh = NULL; |
@@ -211,8 +114,7 @@ init_connection (struct Plugin *plugin) | |||
211 | PQclear (ret); | 114 | PQclear (ret); |
212 | ret = PQexec (plugin->dbh, "ALTER TABLE gn090dc ALTER key SET STORAGE PLAIN"); | 115 | ret = PQexec (plugin->dbh, "ALTER TABLE gn090dc ALTER key SET STORAGE PLAIN"); |
213 | if (GNUNET_OK != | 116 | if (GNUNET_OK != |
214 | check_result (plugin, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc", | 117 | GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "ALTER TABLE", "gn090dc")) |
215 | __LINE__)) | ||
216 | { | 118 | { |
217 | PQfinish (plugin->dbh); | 119 | PQfinish (plugin->dbh); |
218 | plugin->dbh = NULL; | 120 | plugin->dbh = NULL; |
@@ -220,24 +122,23 @@ init_connection (struct Plugin *plugin) | |||
220 | } | 122 | } |
221 | PQclear (ret); | 123 | PQclear (ret); |
222 | if ((GNUNET_OK != | 124 | if ((GNUNET_OK != |
223 | pq_prepare (plugin, "getkt", | 125 | GNUNET_POSTGRES_prepare (plugin->dbh, "getkt", |
224 | "SELECT discard_time,type,value FROM gn090dc " | 126 | "SELECT discard_time,type,value FROM gn090dc " |
225 | "WHERE key=$1 AND type=$2 ", 2, __LINE__)) || | 127 | "WHERE key=$1 AND type=$2 ", 2)) || |
226 | (GNUNET_OK != | 128 | (GNUNET_OK != |
227 | pq_prepare (plugin, "getk", | 129 | GNUNET_POSTGRES_prepare (plugin->dbh, "getk", |
228 | "SELECT discard_time,type,value FROM gn090dc " | 130 | "SELECT discard_time,type,value FROM gn090dc " |
229 | "WHERE key=$1", 1, __LINE__)) || | 131 | "WHERE key=$1", 1)) || |
230 | (GNUNET_OK != | 132 | (GNUNET_OK != |
231 | pq_prepare (plugin, "getm", | 133 | GNUNET_POSTGRES_prepare (plugin->dbh, "getm", |
232 | "SELECT length(value),oid,key FROM gn090dc " | 134 | "SELECT length(value),oid,key FROM gn090dc " |
233 | "ORDER BY discard_time ASC LIMIT 1", 0, __LINE__)) || | 135 | "ORDER BY discard_time ASC LIMIT 1", 0)) || |
234 | (GNUNET_OK != | 136 | (GNUNET_OK != |
235 | pq_prepare (plugin, "delrow", "DELETE FROM gn090dc WHERE oid=$1", 1, | 137 | GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090dc WHERE oid=$1", 1)) || |
236 | __LINE__)) || | ||
237 | (GNUNET_OK != | 138 | (GNUNET_OK != |
238 | pq_prepare (plugin, "put", | 139 | GNUNET_POSTGRES_prepare (plugin->dbh, "put", |
239 | "INSERT INTO gn090dc (type, discard_time, key, value) " | 140 | "INSERT INTO gn090dc (type, discard_time, key, value) " |
240 | "VALUES ($1, $2, $3, $4)", 4, __LINE__))) | 141 | "VALUES ($1, $2, $3, $4)", 4))) |
241 | { | 142 | { |
242 | PQfinish (plugin->dbh); | 143 | PQfinish (plugin->dbh); |
243 | plugin->dbh = NULL; | 144 | plugin->dbh = NULL; |
@@ -248,37 +149,6 @@ init_connection (struct Plugin *plugin) | |||
248 | 149 | ||
249 | 150 | ||
250 | /** | 151 | /** |
251 | * Delete the row identified by the given rowid (qid | ||
252 | * in postgres). | ||
253 | * | ||
254 | * @param plugin global context | ||
255 | * @param rowid which row to delete | ||
256 | * @return GNUNET_OK on success | ||
257 | */ | ||
258 | static int | ||
259 | delete_by_rowid (struct Plugin *plugin, uint32_t rowid) | ||
260 | { | ||
261 | uint32_t brow = htonl (rowid); | ||
262 | const char *paramValues[] = { (const char *) &brow }; | ||
263 | int paramLengths[] = { sizeof (brow) }; | ||
264 | const int paramFormats[] = { 1 }; | ||
265 | PGresult *ret; | ||
266 | |||
267 | ret = | ||
268 | PQexecPrepared (plugin->dbh, "delrow", 1, paramValues, paramLengths, | ||
269 | paramFormats, 1); | ||
270 | if (GNUNET_OK != | ||
271 | check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "delrow", | ||
272 | __LINE__)) | ||
273 | { | ||
274 | return GNUNET_SYSERR; | ||
275 | } | ||
276 | PQclear (ret); | ||
277 | return GNUNET_OK; | ||
278 | } | ||
279 | |||
280 | |||
281 | /** | ||
282 | * Store an item in the datastore. | 152 | * Store an item in the datastore. |
283 | * | 153 | * |
284 | * @param cls closure (our "struct Plugin") | 154 | * @param cls closure (our "struct Plugin") |
@@ -317,8 +187,7 @@ postgres_plugin_put (void *cls, const GNUNET_HashCode * key, size_t size, | |||
317 | PQexecPrepared (plugin->dbh, "put", 4, paramValues, paramLengths, | 187 | PQexecPrepared (plugin->dbh, "put", 4, paramValues, paramLengths, |
318 | paramFormats, 1); | 188 | paramFormats, 1); |
319 | if (GNUNET_OK != | 189 | if (GNUNET_OK != |
320 | check_result (plugin, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put", | 190 | GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put")) |
321 | __LINE__)) | ||
322 | return GNUNET_SYSERR; | 191 | return GNUNET_SYSERR; |
323 | PQclear (ret); | 192 | PQclear (ret); |
324 | return size + OVERHEAD; | 193 | return size + OVERHEAD; |
@@ -364,8 +233,8 @@ postgres_plugin_get (void *cls, const GNUNET_HashCode * key, | |||
364 | (type == 0) ? 1 : 2, paramValues, paramLengths, | 233 | (type == 0) ? 1 : 2, paramValues, paramLengths, |
365 | paramFormats, 1); | 234 | paramFormats, 1); |
366 | if (GNUNET_OK != | 235 | if (GNUNET_OK != |
367 | check_result (plugin, res, PGRES_TUPLES_OK, "PQexecPrepared", | 236 | GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", |
368 | (type == 0) ? "getk" : "getkt", __LINE__)) | 237 | (type == 0) ? "getk" : "getkt")) |
369 | { | 238 | { |
370 | #if DEBUG_POSTGRES | 239 | #if DEBUG_POSTGRES |
371 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", | 240 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", |
@@ -442,8 +311,7 @@ postgres_plugin_del (void *cls) | |||
442 | 311 | ||
443 | res = PQexecPrepared (plugin->dbh, "getm", 0, NULL, NULL, NULL, 1); | 312 | res = PQexecPrepared (plugin->dbh, "getm", 0, NULL, NULL, NULL, 1); |
444 | if (GNUNET_OK != | 313 | if (GNUNET_OK != |
445 | check_result (plugin, res, PGRES_TUPLES_OK, "PQexecPrepared", "getm", | 314 | GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "getm")) |
446 | __LINE__)) | ||
447 | { | 315 | { |
448 | #if DEBUG_POSTGRES | 316 | #if DEBUG_POSTGRES |
449 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", | 317 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "datacache-postgres", |
@@ -473,7 +341,7 @@ postgres_plugin_del (void *cls) | |||
473 | oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1)); | 341 | oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1)); |
474 | memcpy (&key, PQgetvalue (res, 0, 2), sizeof (GNUNET_HashCode)); | 342 | memcpy (&key, PQgetvalue (res, 0, 2), sizeof (GNUNET_HashCode)); |
475 | PQclear (res); | 343 | PQclear (res); |
476 | if (GNUNET_OK != delete_by_rowid (plugin, oid)) | 344 | if (GNUNET_OK != GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", oid)) |
477 | return GNUNET_SYSERR; | 345 | return GNUNET_SYSERR; |
478 | plugin->env->delete_notify (plugin->env->cls, &key, size + OVERHEAD); | 346 | plugin->env->delete_notify (plugin->env->cls, &key, size + OVERHEAD); |
479 | return GNUNET_OK; | 347 | return GNUNET_OK; |