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/namestore/plugin_namestore_postgres.c | |
parent | bbbe0b2404d131cc0d9eda26725b65b47a7e073a (diff) | |
download | gnunet-1defd30dfeb1867c2756b3fe6a437f695951d0c9.tar.gz gnunet-1defd30dfeb1867c2756b3fe6a437f695951d0c9.zip |
adding more good helpers to libgnunetpq
Diffstat (limited to 'src/namestore/plugin_namestore_postgres.c')
-rw-r--r-- | src/namestore/plugin_namestore_postgres.c | 200 |
1 files changed, 95 insertions, 105 deletions
diff --git a/src/namestore/plugin_namestore_postgres.c b/src/namestore/plugin_namestore_postgres.c index 01dbf9e61..4bf931c93 100644 --- a/src/namestore/plugin_namestore_postgres.c +++ b/src/namestore/plugin_namestore_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 |
@@ -75,30 +75,6 @@ struct Plugin | |||
75 | 75 | ||
76 | 76 | ||
77 | /** | 77 | /** |
78 | * Create our database indices. | ||
79 | * | ||
80 | * @param dbh handle to the database | ||
81 | */ | ||
82 | static void | ||
83 | create_indices (PGconn * dbh) | ||
84 | { | ||
85 | /* create indices */ | ||
86 | if ( (GNUNET_OK != | ||
87 | GNUNET_POSTGRES_exec (dbh, | ||
88 | "CREATE INDEX IF NOT EXISTS ir_pkey_reverse ON ns097records (zone_private_key,pkey)")) || | ||
89 | (GNUNET_OK != | ||
90 | GNUNET_POSTGRES_exec (dbh, | ||
91 | "CREATE INDEX IF NOT EXISTS ir_pkey_iter ON ns097records (zone_private_key,rvalue)")) || | ||
92 | (GNUNET_OK != | ||
93 | GNUNET_POSTGRES_exec (dbh, "CREATE INDEX IF NOT EXISTS it_iter ON ns097records (rvalue)")) || | ||
94 | (GNUNET_OK != | ||
95 | GNUNET_POSTGRES_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_label ON ns097records (label)")) ) | ||
96 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
97 | _("Failed to create indices\n")); | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * Initialize the database connections and associated | 78 | * Initialize the database connections and associated |
103 | * data structures (create tables and indices | 79 | * data structures (create tables and indices |
104 | * as needed as well). | 80 | * as needed as well). |
@@ -109,10 +85,30 @@ create_indices (PGconn * dbh) | |||
109 | static int | 85 | static int |
110 | database_setup (struct Plugin *plugin) | 86 | database_setup (struct Plugin *plugin) |
111 | { | 87 | { |
112 | PGresult *res; | 88 | struct GNUNET_PQ_ExecuteStatement es_temporary = |
113 | 89 | GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS ns097records (" | |
114 | plugin->dbh = GNUNET_POSTGRES_connect (plugin->cfg, | 90 | " zone_private_key BYTEA NOT NULL DEFAULT ''," |
115 | "namestore-postgres"); | 91 | " pkey BYTEA DEFAULT ''," |
92 | " rvalue BYTEA NOT NULL DEFAULT ''," | ||
93 | " record_count INTEGER NOT NULL DEFAULT 0," | ||
94 | " record_data BYTEA NOT NULL DEFAULT ''," | ||
95 | " label TEXT NOT NULL DEFAULT ''" | ||
96 | ")" | ||
97 | "WITH OIDS"); | ||
98 | struct GNUNET_PQ_ExecuteStatement es_default = | ||
99 | GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS ns097records (" | ||
100 | " zone_private_key BYTEA NOT NULL DEFAULT ''," | ||
101 | " pkey BYTEA DEFAULT ''," | ||
102 | " rvalue BYTEA NOT NULL DEFAULT ''," | ||
103 | " record_count INTEGER NOT NULL DEFAULT 0," | ||
104 | " record_data BYTEA NOT NULL DEFAULT ''," | ||
105 | " label TEXT NOT NULL DEFAULT ''" | ||
106 | ")" | ||
107 | "WITH OIDS"); | ||
108 | const struct GNUNET_PQ_ExecuteStatement *cr; | ||
109 | |||
110 | plugin->dbh = GNUNET_PQ_connect_with_cfg (plugin->cfg, | ||
111 | "namestore-postgres"); | ||
116 | if (NULL == plugin->dbh) | 112 | if (NULL == plugin->dbh) |
117 | return GNUNET_SYSERR; | 113 | return GNUNET_SYSERR; |
118 | if (GNUNET_YES == | 114 | if (GNUNET_YES == |
@@ -120,80 +116,70 @@ database_setup (struct Plugin *plugin) | |||
120 | "namestore-postgres", | 116 | "namestore-postgres", |
121 | "TEMPORARY_TABLE")) | 117 | "TEMPORARY_TABLE")) |
122 | { | 118 | { |
123 | res = | 119 | cr = &es_temporary; |
124 | PQexec (plugin->dbh, | ||
125 | "CREATE TEMPORARY TABLE IF NOT EXISTS ns097records (" | ||
126 | " zone_private_key BYTEA NOT NULL DEFAULT ''," | ||
127 | " pkey BYTEA DEFAULT ''," | ||
128 | " rvalue BYTEA NOT NULL DEFAULT ''," | ||
129 | " record_count INTEGER NOT NULL DEFAULT 0," | ||
130 | " record_data BYTEA NOT NULL DEFAULT ''," | ||
131 | " label TEXT NOT NULL DEFAULT ''" | ||
132 | ")" "WITH OIDS"); | ||
133 | } | 120 | } |
134 | else | 121 | else |
135 | { | 122 | { |
136 | res = | 123 | cr = &es_default; |
137 | PQexec (plugin->dbh, | ||
138 | "CREATE TABLE IF NOT EXISTS ns097records (" | ||
139 | " zone_private_key BYTEA NOT NULL DEFAULT ''," | ||
140 | " pkey BYTEA DEFAULT ''," | ||
141 | " rvalue BYTEA NOT NULL DEFAULT ''," | ||
142 | " record_count INTEGER NOT NULL DEFAULT 0," | ||
143 | " record_data BYTEA NOT NULL DEFAULT ''," | ||
144 | " label TEXT NOT NULL DEFAULT ''" | ||
145 | ")" "WITH OIDS"); | ||
146 | } | 124 | } |
147 | if ( (NULL == res) || | 125 | |
148 | ((PQresultStatus (res) != PGRES_COMMAND_OK) && | ||
149 | (0 != strcmp ("42P07", /* duplicate table */ | ||
150 | PQresultErrorField | ||
151 | (res, | ||
152 | PG_DIAG_SQLSTATE))))) | ||
153 | { | 126 | { |
154 | (void) GNUNET_POSTGRES_check_result (plugin->dbh, res, | 127 | struct GNUNET_PQ_ExecuteStatement es[] = { |
155 | PGRES_COMMAND_OK, "CREATE TABLE", | 128 | *cr, |
156 | "ns097records"); | 129 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_reverse " |
157 | PQfinish (plugin->dbh); | 130 | "ON ns097records (zone_private_key,pkey)"), |
158 | plugin->dbh = NULL; | 131 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_pkey_iter " |
159 | return GNUNET_SYSERR; | 132 | "ON ns097records (zone_private_key,rvalue)"), |
133 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS it_iter " | ||
134 | "ON ns097records (rvalue)"), | ||
135 | GNUNET_PQ_make_try_execute ("CREATE INDEX IF NOT EXISTS ir_label " | ||
136 | "ON ns097records (label)"), | ||
137 | GNUNET_PQ_EXECUTE_STATEMENT_END | ||
138 | }; | ||
139 | |||
140 | if (GNUNET_OK != | ||
141 | GNUNET_PQ_exec_statements (plugin->dbh, | ||
142 | es)) | ||
143 | { | ||
144 | PQfinish (plugin->dbh); | ||
145 | plugin->dbh = NULL; | ||
146 | return GNUNET_SYSERR; | ||
147 | } | ||
160 | } | 148 | } |
161 | create_indices (plugin->dbh); | 149 | |
162 | |||
163 | if ((GNUNET_OK != | ||
164 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
165 | "store_records", | ||
166 | "INSERT INTO ns097records (zone_private_key, pkey, rvalue, record_count, record_data, label) VALUES " | ||
167 | "($1, $2, $3, $4, $5, $6)", 6)) || | ||
168 | (GNUNET_OK != | ||
169 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
170 | "delete_records", | ||
171 | "DELETE FROM ns097records WHERE zone_private_key=$1 AND label=$2", 2)) || | ||
172 | (GNUNET_OK != | ||
173 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
174 | "zone_to_name", | ||
175 | "SELECT record_count,record_data,label FROM ns097records" | ||
176 | " WHERE zone_private_key=$1 AND pkey=$2", 2)) || | ||
177 | (GNUNET_OK != | ||
178 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
179 | "iterate_zone", | ||
180 | "SELECT record_count,record_data,label FROM ns097records" | ||
181 | " WHERE zone_private_key=$1 ORDER BY rvalue LIMIT 1 OFFSET $2", 2)) || | ||
182 | (GNUNET_OK != | ||
183 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
184 | "iterate_all_zones", | ||
185 | "SELECT record_count,record_data,label,zone_private_key" | ||
186 | " FROM ns097records ORDER BY rvalue LIMIT 1 OFFSET $1", 1)) || | ||
187 | (GNUNET_OK != | ||
188 | GNUNET_POSTGRES_prepare (plugin->dbh, | ||
189 | "lookup_label", | ||
190 | "SELECT record_count,record_data,label" | ||
191 | " FROM ns097records WHERE zone_private_key=$1 AND label=$2", 2))) | ||
192 | { | 150 | { |
193 | PQfinish (plugin->dbh); | 151 | struct GNUNET_PQ_PreparedStatement ps[] = { |
194 | plugin->dbh = NULL; | 152 | GNUNET_PQ_make_prepare ("store_records", |
195 | return GNUNET_SYSERR; | 153 | "INSERT INTO ns097records (zone_private_key, pkey, rvalue, record_count, record_data, label) VALUES " |
154 | "($1, $2, $3, $4, $5, $6)", 6), | ||
155 | GNUNET_PQ_make_prepare ("delete_records", | ||
156 | "DELETE FROM ns097records " | ||
157 | "WHERE zone_private_key=$1 AND label=$2", 2), | ||
158 | GNUNET_PQ_make_prepare ("zone_to_name", | ||
159 | "SELECT record_count,record_data,label FROM ns097records" | ||
160 | " WHERE zone_private_key=$1 AND pkey=$2", 2), | ||
161 | GNUNET_PQ_make_prepare ("iterate_zone", | ||
162 | "SELECT record_count,record_data,label FROM ns097records " | ||
163 | "WHERE zone_private_key=$1 ORDER BY rvalue LIMIT 1 OFFSET $2", 2), | ||
164 | GNUNET_PQ_make_prepare ("iterate_all_zones", | ||
165 | "SELECT record_count,record_data,label,zone_private_key" | ||
166 | " FROM ns097records ORDER BY rvalue LIMIT 1 OFFSET $1", 1), | ||
167 | GNUNET_PQ_make_prepare ("lookup_label", | ||
168 | "SELECT record_count,record_data,label " | ||
169 | "FROM ns097records WHERE zone_private_key=$1 AND label=$2", 2), | ||
170 | GNUNET_PQ_PREPARED_STATEMENT_END | ||
171 | }; | ||
172 | |||
173 | if (GNUNET_OK != | ||
174 | GNUNET_PQ_prepare_statements (plugin->dbh, | ||
175 | ps)) | ||
176 | { | ||
177 | PQfinish (plugin->dbh); | ||
178 | plugin->dbh = NULL; | ||
179 | return GNUNET_SYSERR; | ||
180 | } | ||
196 | } | 181 | } |
182 | |||
197 | return GNUNET_OK; | 183 | return GNUNET_OK; |
198 | } | 184 | } |
199 | 185 | ||
@@ -221,19 +207,19 @@ namestore_postgres_store_records (void *cls, | |||
221 | uint64_t rvalue; | 207 | uint64_t rvalue; |
222 | uint32_t rd_count_nbo = htonl ((uint32_t) rd_count); | 208 | uint32_t rd_count_nbo = htonl ((uint32_t) rd_count); |
223 | size_t data_size; | 209 | size_t data_size; |
224 | unsigned int i; | ||
225 | 210 | ||
226 | memset (&pkey, 0, sizeof (pkey)); | 211 | memset (&pkey, 0, sizeof (pkey)); |
227 | for (i=0;i<rd_count;i++) | 212 | for (unsigned int i=0;i<rd_count;i++) |
228 | if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type) | 213 | if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type) |
229 | { | 214 | { |
230 | GNUNET_break (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) == rd[i].data_size); | 215 | GNUNET_break (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) == rd[i].data_size); |
231 | GNUNET_memcpy (&pkey, | 216 | GNUNET_memcpy (&pkey, |
232 | rd[i].data, | 217 | rd[i].data, |
233 | rd[i].data_size); | 218 | rd[i].data_size); |
234 | break; | 219 | break; |
235 | } | 220 | } |
236 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); | 221 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, |
222 | UINT64_MAX); | ||
237 | data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd); | 223 | data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd); |
238 | if (data_size > 64 * 65536) | 224 | if (data_size > 64 * 65536) |
239 | { | 225 | { |
@@ -262,9 +248,10 @@ namestore_postgres_store_records (void *cls, | |||
262 | const int paramFormats[] = { 1, 1, 1, 1, 1, 1 }; | 248 | const int paramFormats[] = { 1, 1, 1, 1, 1, 1 }; |
263 | PGresult *res; | 249 | PGresult *res; |
264 | 250 | ||
265 | if (data_size != GNUNET_GNSRECORD_records_serialize (rd_count, rd, | 251 | if (data_size != |
266 | data_size, data)) | 252 | GNUNET_GNSRECORD_records_serialize (rd_count, rd, |
267 | { | 253 | data_size, data)) |
254 | { | ||
268 | GNUNET_break (0); | 255 | GNUNET_break (0); |
269 | return GNUNET_SYSERR; | 256 | return GNUNET_SYSERR; |
270 | } | 257 | } |
@@ -301,7 +288,8 @@ static int | |||
301 | get_record_and_call_iterator (struct Plugin *plugin, | 288 | get_record_and_call_iterator (struct Plugin *plugin, |
302 | PGresult *res, | 289 | PGresult *res, |
303 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, | 290 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, |
304 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) | 291 | GNUNET_NAMESTORE_RecordIterator iter, |
292 | void *iter_cls) | ||
305 | { | 293 | { |
306 | const char *data; | 294 | const char *data; |
307 | size_t data_size; | 295 | size_t data_size; |
@@ -311,7 +299,9 @@ get_record_and_call_iterator (struct Plugin *plugin, | |||
311 | unsigned int cnt; | 299 | unsigned int cnt; |
312 | 300 | ||
313 | if (GNUNET_OK != | 301 | if (GNUNET_OK != |
314 | GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, | 302 | GNUNET_POSTGRES_check_result (plugin->dbh, |
303 | res, | ||
304 | PGRES_TUPLES_OK, | ||
315 | "PQexecPrepared", | 305 | "PQexecPrepared", |
316 | "iteration")) | 306 | "iteration")) |
317 | { | 307 | { |