aboutsummaryrefslogtreecommitdiff
path: root/src/namecache
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-06-01 21:48:19 +0200
committerChristian Grothoff <christian@grothoff.org>2017-06-01 21:48:19 +0200
commit1defd30dfeb1867c2756b3fe6a437f695951d0c9 (patch)
treeb48c0fe6bb32469cfcb4284bfac3142e22417ae8 /src/namecache
parentbbbe0b2404d131cc0d9eda26725b65b47a7e073a (diff)
downloadgnunet-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.c152
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 */
79static void
80create_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 */
102static int 82static int
103database_setup (struct Plugin *plugin) 83database_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
185namecache_postgres_expire_blocks (struct Plugin *plugin) 170namecache_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,
301static int 288static int
302namecache_postgres_lookup_block (void *cls, 289namecache_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 };