diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-06-01 21:48:19 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-06-01 21:48:19 +0200 |
commit | 1defd30dfeb1867c2756b3fe6a437f695951d0c9 (patch) | |
tree | b48c0fe6bb32469cfcb4284bfac3142e22417ae8 /src/namecache | |
parent | bbbe0b2404d131cc0d9eda26725b65b47a7e073a (diff) | |
download | gnunet-1defd30dfeb1867c2756b3fe6a437f695951d0c9.tar.gz gnunet-1defd30dfeb1867c2756b3fe6a437f695951d0c9.zip |
adding more good helpers to libgnunetpq
Diffstat (limited to 'src/namecache')
-rw-r--r-- | src/namecache/plugin_namecache_postgres.c | 152 |
1 files changed, 70 insertions, 82 deletions
diff --git a/src/namecache/plugin_namecache_postgres.c b/src/namecache/plugin_namecache_postgres.c index bec8bffd2..9c85f4470 100644 --- a/src/namecache/plugin_namecache_postgres.c +++ b/src/namecache/plugin_namecache_postgres.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * This file is part of GNUnet | 2 | * This file is part of GNUnet |
3 | * Copyright (C) 2009-2013, 2016 GNUnet e.V. | 3 | * Copyright (C) 2009-2013, 2016, 2017 GNUnet e.V. |
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 |
@@ -72,40 +72,34 @@ struct Plugin | |||
72 | 72 | ||
73 | 73 | ||
74 | /** | 74 | /** |
75 | * Create our database indices. | ||
76 | * | ||
77 | * @param dbh handle to the database | ||
78 | */ | ||
79 | static void | ||
80 | create_indices (PGconn * dbh) | ||
81 | { | ||
82 | /* create indices */ | ||
83 | if ( (GNUNET_OK != | ||
84 | GNUNET_POSTGRES_exec (dbh, | ||
85 | "CREATE INDEX ir_query_hash ON ns096blocks (query,expiration_time)")) || | ||
86 | (GNUNET_OK != | ||
87 | GNUNET_POSTGRES_exec (dbh, | ||
88 | "CREATE INDEX ir_block_expiration ON ns096blocks (expiration_time)")) ) | ||
89 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
90 | _("Failed to create indices\n")); | ||
91 | } | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Initialize the database connections and associated | 75 | * Initialize the database connections and associated |
96 | * data structures (create tables and indices | 76 | * data structures (create tables and indices |
97 | * as needed as well). | 77 | * as needed as well). |
98 | * | 78 | * |
99 | * @param plugin the plugin context (state for this module) | 79 | * @param plugin the plugin context (state for this module) |
100 | * @return GNUNET_OK on success | 80 | * @return #GNUNET_OK on success |
101 | */ | 81 | */ |
102 | static int | 82 | static int |
103 | database_setup (struct Plugin *plugin) | 83 | database_setup (struct Plugin *plugin) |
104 | { | 84 | { |
105 | PGresult *res; | 85 | struct GNUNET_PQ_ExecuteStatement es_temporary = |
106 | 86 | GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS ns096blocks (" | |
107 | plugin->dbh = GNUNET_POSTGRES_connect (plugin->cfg, | 87 | " query BYTEA NOT NULL DEFAULT ''," |
108 | "namecache-postgres"); | 88 | " block BYTEA NOT NULL DEFAULT ''," |
89 | " expiration_time BIGINT NOT NULL DEFAULT 0" | ||
90 | ")" | ||
91 | "WITH OIDS"); | ||
92 | struct GNUNET_PQ_ExecuteStatement es_default = | ||
93 | GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS ns096blocks (" | ||
94 | " query BYTEA NOT NULL DEFAULT ''," | ||
95 | " block BYTEA NOT NULL DEFAULT ''," | ||
96 | " expiration_time BIGINT NOT NULL DEFAULT 0" | ||
97 | ")" | ||
98 | "WITH OIDS"); | ||
99 | const struct GNUNET_PQ_ExecuteStatement *cr; | ||
100 | |||
101 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg, | ||
102 | "namecache-postgres"); | ||
109 | if (NULL == plugin->dbh) | 103 | if (NULL == plugin->dbh) |
110 | return GNUNET_SYSERR; | 104 | return GNUNET_SYSERR; |
111 | if (GNUNET_YES == | 105 | if (GNUNET_YES == |
@@ -113,65 +107,56 @@ database_setup (struct Plugin *plugin) | |||
113 | "namecache-postgres", | 107 | "namecache-postgres", |
114 | "TEMPORARY_TABLE")) | 108 | "TEMPORARY_TABLE")) |
115 | { | 109 | { |
116 | res = | 110 | cr = &es_temporary; |
117 | PQexec (plugin->dbh, | ||
118 | "CREATE TEMPORARY TABLE ns096blocks (" | ||
119 | " query BYTEA NOT NULL DEFAULT ''," | ||
120 | " block BYTEA NOT NULL DEFAULT ''," | ||
121 | " expiration_time BIGINT NOT NULL DEFAULT 0" | ||
122 | ")" "WITH OIDS"); | ||
123 | } | 111 | } |
124 | else | 112 | else |
125 | { | 113 | { |
126 | res = | 114 | cr = &es_default; |
127 | PQexec (plugin->dbh, | ||
128 | "CREATE TABLE ns096blocks (" | ||
129 | " query BYTEA NOT NULL DEFAULT ''," | ||
130 | " block BYTEA NOT NULL DEFAULT ''," | ||
131 | " expiration_time BIGINT NOT NULL DEFAULT 0" | ||
132 | ")" "WITH OIDS"); | ||
133 | } | 115 | } |
134 | if ( (NULL == res) || | 116 | |
135 | ((PQresultStatus (res) != PGRES_COMMAND_OK) && | ||
136 | (0 != strcmp ("42P07", /* duplicate table */ | ||
137 | PQresultErrorField | ||
138 | (res, | ||
139 | PG_DIAG_SQLSTATE))))) | ||
140 | { | 117 | { |
141 | (void) GNUNET_POSTGRES_check_result (plugin->dbh, res, | 118 | struct GNUNET_PQ_ExecuteStatement es[] = { |
142 | PGRES_COMMAND_OK, "CREATE TABLE", | 119 | *cr, |
143 | "ns096blocks"); | 120 | GNUNET_PQ_make_try_execute ("CREATE INDEX ir_query_hash ON ns096blocks (query,expiration_time)"), |
144 | PQfinish (plugin->dbh); | 121 | GNUNET_PQ_make_try_execute ("CREATE INDEX ir_block_expiration ON ns096blocks (expiration_time)"), |
145 | plugin->dbh = NULL; | 122 | GNUNET_PQ_EXECUTE_STATEMENT_END |
146 | return GNUNET_SYSERR; | 123 | }; |
124 | |||
125 | if (GNUNET_OK != | ||
126 | GNUNET_PQ_exec_statements (plugin->dbh, | ||
127 | es)) | ||
128 | { | ||
129 | PQfinish (plugin->dbh); | ||
130 | plugin->dbh = NULL; | ||
131 | return GNUNET_SYSERR; | ||
132 | } | ||
147 | } | 133 | } |
148 | if (PQresultStatus (res) == PGRES_COMMAND_OK) | ||
149 | create_indices (plugin->dbh); | ||
150 | PQclear (res); | ||
151 | 134 | ||
152 | if ((GNUNET_OK != | ||
153 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
154 | "cache_block", | ||
155 | "INSERT INTO ns096blocks (query, block, expiration_time) VALUES " | ||
156 | "($1, $2, $3)", 3)) || | ||
157 | (GNUNET_OK != | ||
158 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
159 | "expire_blocks", | ||
160 | "DELETE FROM ns096blocks WHERE expiration_time<$1", 1)) || | ||
161 | (GNUNET_OK != | ||
162 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
163 | "delete_block", | ||
164 | "DELETE FROM ns096blocks WHERE query=$1 AND expiration_time<=$2", 2)) || | ||
165 | (GNUNET_OK != | ||
166 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
167 | "lookup_block", | ||
168 | "SELECT block FROM ns096blocks WHERE query=$1" | ||
169 | " ORDER BY expiration_time DESC LIMIT 1", 1))) | ||
170 | { | 135 | { |
171 | PQfinish (plugin->dbh); | 136 | struct GNUNET_PQ_PreparedStatement ps[] = { |
172 | plugin->dbh = NULL; | 137 | GNUNET_PQ_make_prepare ("cache_block", |
173 | return GNUNET_SYSERR; | 138 | "INSERT INTO ns096blocks (query, block, expiration_time) VALUES " |
139 | "($1, $2, $3)", 3), | ||
140 | GNUNET_PQ_make_prepare ("expire_blocks", | ||
141 | "DELETE FROM ns096blocks WHERE expiration_time<$1", 1), | ||
142 | GNUNET_PQ_make_prepare ("delete_block", | ||
143 | "DELETE FROM ns096blocks WHERE query=$1 AND expiration_time<=$2", 2), | ||
144 | GNUNET_PQ_make_prepare ("lookup_block", | ||
145 | "SELECT block FROM ns096blocks WHERE query=$1" | ||
146 | " ORDER BY expiration_time DESC LIMIT 1", 1), | ||
147 | GNUNET_PQ_PREPARED_STATEMENT_END | ||
148 | }; | ||
149 | |||
150 | if (GNUNET_OK != | ||
151 | GNUNET_PQ_prepare_statements (plugin->dbh, | ||
152 | ps)) | ||
153 | { | ||
154 | PQfinish (plugin->dbh); | ||
155 | plugin->dbh = NULL; | ||
156 | return GNUNET_SYSERR; | ||
157 | } | ||
174 | } | 158 | } |
159 | |||
175 | return GNUNET_OK; | 160 | return GNUNET_OK; |
176 | } | 161 | } |
177 | 162 | ||
@@ -185,7 +170,7 @@ static void | |||
185 | namecache_postgres_expire_blocks (struct Plugin *plugin) | 170 | namecache_postgres_expire_blocks (struct Plugin *plugin) |
186 | { | 171 | { |
187 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | 172 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); |
188 | struct GNUNET_PQ_QueryParam params[] = { | 173 | struct GNUNET_PQ_QueryParam params[] = { |
189 | GNUNET_PQ_query_param_absolute_time (&now), | 174 | GNUNET_PQ_query_param_absolute_time (&now), |
190 | GNUNET_PQ_query_param_end | 175 | GNUNET_PQ_query_param_end |
191 | }; | 176 | }; |
@@ -217,7 +202,7 @@ delete_old_block (struct Plugin *plugin, | |||
217 | const struct GNUNET_HashCode *query, | 202 | const struct GNUNET_HashCode *query, |
218 | struct GNUNET_TIME_AbsoluteNBO expiration_time) | 203 | struct GNUNET_TIME_AbsoluteNBO expiration_time) |
219 | { | 204 | { |
220 | struct GNUNET_PQ_QueryParam params[] = { | 205 | struct GNUNET_PQ_QueryParam params[] = { |
221 | GNUNET_PQ_query_param_auto_from_type (query), | 206 | GNUNET_PQ_query_param_auto_from_type (query), |
222 | GNUNET_PQ_query_param_absolute_time_nbo (&expiration_time), | 207 | GNUNET_PQ_query_param_absolute_time_nbo (&expiration_time), |
223 | GNUNET_PQ_query_param_end | 208 | GNUNET_PQ_query_param_end |
@@ -254,7 +239,7 @@ namecache_postgres_cache_block (void *cls, | |||
254 | size_t block_size = ntohl (block->purpose.size) + | 239 | size_t block_size = ntohl (block->purpose.size) + |
255 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + | 240 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + |
256 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature); | 241 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature); |
257 | struct GNUNET_PQ_QueryParam params[] = { | 242 | struct GNUNET_PQ_QueryParam params[] = { |
258 | GNUNET_PQ_query_param_auto_from_type (&query), | 243 | GNUNET_PQ_query_param_auto_from_type (&query), |
259 | GNUNET_PQ_query_param_fixed_size (block, block_size), | 244 | GNUNET_PQ_query_param_fixed_size (block, block_size), |
260 | GNUNET_PQ_query_param_absolute_time_nbo (&block->expiration_time), | 245 | GNUNET_PQ_query_param_absolute_time_nbo (&block->expiration_time), |
@@ -271,7 +256,9 @@ namecache_postgres_cache_block (void *cls, | |||
271 | GNUNET_break (0); | 256 | GNUNET_break (0); |
272 | return GNUNET_SYSERR; | 257 | return GNUNET_SYSERR; |
273 | } | 258 | } |
274 | delete_old_block (plugin, &query, block->expiration_time); | 259 | delete_old_block (plugin, |
260 | &query, | ||
261 | block->expiration_time); | ||
275 | 262 | ||
276 | res = GNUNET_PQ_exec_prepared (plugin->dbh, | 263 | res = GNUNET_PQ_exec_prepared (plugin->dbh, |
277 | "cache_block", | 264 | "cache_block", |
@@ -301,10 +288,11 @@ namecache_postgres_cache_block (void *cls, | |||
301 | static int | 288 | static int |
302 | namecache_postgres_lookup_block (void *cls, | 289 | namecache_postgres_lookup_block (void *cls, |
303 | const struct GNUNET_HashCode *query, | 290 | const struct GNUNET_HashCode *query, |
304 | GNUNET_NAMECACHE_BlockCallback iter, void *iter_cls) | 291 | GNUNET_NAMECACHE_BlockCallback iter, |
292 | void *iter_cls) | ||
305 | { | 293 | { |
306 | struct Plugin *plugin = cls; | 294 | struct Plugin *plugin = cls; |
307 | struct GNUNET_PQ_QueryParam params[] = { | 295 | struct GNUNET_PQ_QueryParam params[] = { |
308 | GNUNET_PQ_query_param_auto_from_type (query), | 296 | GNUNET_PQ_query_param_auto_from_type (query), |
309 | GNUNET_PQ_query_param_end | 297 | GNUNET_PQ_query_param_end |
310 | }; | 298 | }; |