aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/plugin_datacache_postgres.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-07-07 13:42:52 +0200
committerChristian Grothoff <christian@grothoff.org>2022-07-07 13:42:52 +0200
commit2906241b6a21d6009a0d195199f3a08e8f4d4e2a (patch)
treec9946fd81f343008877b41fc8471d13d0051f48a /src/datacache/plugin_datacache_postgres.c
parent374e3cf6de48f26f67cf93091a2bfbdab019a6eb (diff)
downloadgnunet-2906241b6a21d6009a0d195199f3a08e8f4d4e2a.tar.gz
gnunet-2906241b6a21d6009a0d195199f3a08e8f4d4e2a.zip
major modification to datacache to store route options (and clean up the API)
Diffstat (limited to 'src/datacache/plugin_datacache_postgres.c')
-rw-r--r--src/datacache/plugin_datacache_postgres.c205
1 files changed, 101 insertions, 104 deletions
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index 1a83cda86..d9e25992b 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -63,73 +63,75 @@ struct Plugin
63 * @param plugin global context 63 * @param plugin global context
64 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 64 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
65 */ 65 */
66static int 66static enum GNUNET_GenericReturnValue
67init_connection (struct Plugin *plugin) 67init_connection (struct Plugin *plugin)
68{ 68{
69 struct GNUNET_PQ_ExecuteStatement es[] = { 69 struct GNUNET_PQ_ExecuteStatement es[] = {
70 GNUNET_PQ_make_try_execute ( 70 GNUNET_PQ_make_try_execute (
71 "CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn011dc_oid_seq"), 71 "CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn180dc_oid_seq"),
72 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc (" 72 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn180dc ("
73 " oid OID NOT NULL DEFAULT nextval('gn011dc_oid_seq')," 73 " oid OID NOT NULL DEFAULT nextval('gn180dc_oid_seq'),"
74 " type INTEGER NOT NULL," 74 " type INTEGER NOT NULL,"
75 " ro INTEGER NOT NULL,"
75 " prox INTEGER NOT NULL," 76 " prox INTEGER NOT NULL,"
76 " discard_time BIGINT NOT NULL," 77 " expiration_time BIGINT NOT NULL,"
77 " key BYTEA NOT NULL," 78 " key BYTEA NOT NULL,"
78 " value BYTEA NOT NULL," 79 " value BYTEA NOT NULL,"
79 " path BYTEA DEFAULT NULL)"), 80 " path BYTEA DEFAULT NULL)"),
80 GNUNET_PQ_make_try_execute ( 81 GNUNET_PQ_make_try_execute (
81 "ALTER SEQUENCE gnu011dc_oid_seq OWNED BY gn011dc.oid"), 82 "ALTER SEQUENCE gnu011dc_oid_seq OWNED BY gn180dc.oid"),
82 GNUNET_PQ_make_try_execute ( 83 GNUNET_PQ_make_try_execute (
83 "CREATE INDEX IF NOT EXISTS idx_oid ON gn011dc (oid)"), 84 "CREATE INDEX IF NOT EXISTS idx_oid ON gn180dc (oid)"),
84 GNUNET_PQ_make_try_execute ( 85 GNUNET_PQ_make_try_execute (
85 "CREATE INDEX IF NOT EXISTS idx_key ON gn011dc (key)"), 86 "CREATE INDEX IF NOT EXISTS idx_key ON gn180dc (key)"),
86 GNUNET_PQ_make_try_execute ( 87 GNUNET_PQ_make_try_execute (
87 "CREATE INDEX IF NOT EXISTS idx_dt ON gn011dc (discard_time)"), 88 "CREATE INDEX IF NOT EXISTS idx_dt ON gn180dc (expiration_time)"),
88 GNUNET_PQ_make_execute ( 89 GNUNET_PQ_make_execute (
89 "ALTER TABLE gn011dc ALTER value SET STORAGE EXTERNAL"), 90 "ALTER TABLE gn180dc ALTER value SET STORAGE EXTERNAL"),
90 GNUNET_PQ_make_execute ("ALTER TABLE gn011dc ALTER key SET STORAGE PLAIN"), 91 GNUNET_PQ_make_execute ("ALTER TABLE gn180dc ALTER key SET STORAGE PLAIN"),
91 GNUNET_PQ_EXECUTE_STATEMENT_END 92 GNUNET_PQ_EXECUTE_STATEMENT_END
92 }; 93 };
93 struct GNUNET_PQ_PreparedStatement ps[] = { 94 struct GNUNET_PQ_PreparedStatement ps[] = {
94 GNUNET_PQ_make_prepare ("getkt", 95 GNUNET_PQ_make_prepare ("getkt",
95 "SELECT discard_time,type,value,path FROM gn011dc " 96 "SELECT expiration_time,type,ro,value,path FROM gn180dc "
96 "WHERE key=$1 AND type=$2 AND discard_time >= $3", 97 "WHERE key=$1 AND type=$2 AND expiration_time >= $3",
97 3), 98 3),
98 GNUNET_PQ_make_prepare ("getk", 99 GNUNET_PQ_make_prepare ("getk",
99 "SELECT discard_time,type,value,path FROM gn011dc " 100 "SELECT expiration_time,type,ro,value,path FROM gn180dc "
100 "WHERE key=$1 AND discard_time >= $2", 101 "WHERE key=$1 AND expiration_time >= $2",
101 2), 102 2),
102 GNUNET_PQ_make_prepare ("getex", 103 GNUNET_PQ_make_prepare ("getex",
103 "SELECT length(value) AS len,oid,key FROM gn011dc" 104 "SELECT LENGTH(value) AS len,oid,key FROM gn180dc"
104 " WHERE discard_time < $1" 105 " WHERE expiration_time < $1"
105 " ORDER BY discard_time ASC LIMIT 1", 106 " ORDER BY expiration_time ASC LIMIT 1",
106 1), 107 1),
107 GNUNET_PQ_make_prepare ("getm", 108 GNUNET_PQ_make_prepare ("getm",
108 "SELECT length(value) AS len,oid,key FROM gn011dc" 109 "SELECT LENGTH(value) AS len,oid,key FROM gn180dc"
109 " ORDER BY prox ASC, discard_time ASC LIMIT 1", 110 " ORDER BY prox ASC, expiration_time ASC LIMIT 1",
110 0), 111 0),
111 GNUNET_PQ_make_prepare ("get_closest", 112 GNUNET_PQ_make_prepare ("get_closest",
112 "(SELECT discard_time,type,value,path,key FROM gn011dc" 113 "(SELECT expiration_time,type,ro,value,path,key FROM gn180dc"
113 " WHERE key >= $1" 114 " WHERE key >= $1"
114 " AND discard_time >= $2" 115 " AND expiration_time >= $2"
115 " AND ( (type = $3) OR ( 0 = $3) )" 116 " AND ( (type = $3) OR ( 0 = $3) )"
116 " ORDER BY key ASC" 117 " ORDER BY key ASC"
117 " LIMIT $4)" 118 " LIMIT $4)"
118 " UNION " 119 " UNION "
119 "(SELECT discard_time,type,value,path,key FROM gn011dc" 120 "(SELECT expiration_time,type,ro,value,path,key FROM gn180dc"
120 " WHERE key <= $1" 121 " WHERE key <= $1"
121 " AND discard_time >= $2" 122 " AND expiration_time >= $2"
122 " AND ( (type = $3) OR ( 0 = $3) )" 123 " AND ( (type = $3) OR ( 0 = $3) )"
123 " ORDER BY key DESC" 124 " ORDER BY key DESC"
124 " LIMIT $4)", 125 " LIMIT $4)",
125 4), 126 4),
126 GNUNET_PQ_make_prepare ("delrow", 127 GNUNET_PQ_make_prepare ("delrow",
127 "DELETE FROM gn011dc WHERE oid=$1", 128 "DELETE FROM gn180dc WHERE oid=$1",
128 1), 129 1),
129 GNUNET_PQ_make_prepare ("put", 130 GNUNET_PQ_make_prepare ("put",
130 "INSERT INTO gn011dc (type, prox, discard_time, key, value, path) " 131 "INSERT INTO gn180dc"
131 "VALUES ($1, $2, $3, $4, $5, $6)", 132 " (type, ro, prox, expiration_time, key, value, path) "
132 6), 133 "VALUES ($1, $2, $3, $4, $5, $6, $7)",
134 7),
133 GNUNET_PQ_PREPARED_STATEMENT_END 135 GNUNET_PQ_PREPARED_STATEMENT_END
134 }; 136 };
135 137
@@ -148,38 +150,29 @@ init_connection (struct Plugin *plugin)
148 * Store an item in the datastore. 150 * Store an item in the datastore.
149 * 151 *
150 * @param cls closure (our `struct Plugin`) 152 * @param cls closure (our `struct Plugin`)
151 * @param key key to store @a data under
152 * @param prox proximity of @a key to my PID 153 * @param prox proximity of @a key to my PID
153 * @param data_size number of bytes in @a data 154 * @param block data to store
154 * @param data data to store
155 * @param type type of the value
156 * @param discard_time when to discard the value in any case
157 * @param path_info_len number of entries in @a path_info
158 * @param path_info a path through the network
159 * @return 0 if duplicate, -1 on error, number of bytes used otherwise 155 * @return 0 if duplicate, -1 on error, number of bytes used otherwise
160 */ 156 */
161static ssize_t 157static ssize_t
162postgres_plugin_put (void *cls, 158postgres_plugin_put (void *cls,
163 const struct GNUNET_HashCode *key,
164 uint32_t prox, 159 uint32_t prox,
165 size_t data_size, 160 const struct GNUNET_DATACACHE_Block *block)
166 const char *data,
167 enum GNUNET_BLOCK_Type type,
168 struct GNUNET_TIME_Absolute discard_time,
169 unsigned int path_info_len,
170 const struct GNUNET_DHT_PathElement *path_info)
171{ 161{
172 struct Plugin *plugin = cls; 162 struct Plugin *plugin = cls;
173 uint32_t type32 = (uint32_t) type; 163 uint32_t type32 = (uint32_t) block->type;
164 uint32_t ro32 = (uint32_t) block->type;
174 struct GNUNET_PQ_QueryParam params[] = { 165 struct GNUNET_PQ_QueryParam params[] = {
175 GNUNET_PQ_query_param_uint32 (&type32), 166 GNUNET_PQ_query_param_uint32 (&type32),
167 GNUNET_PQ_query_param_uint32 (&ro32),
176 GNUNET_PQ_query_param_uint32 (&prox), 168 GNUNET_PQ_query_param_uint32 (&prox),
177 GNUNET_PQ_query_param_absolute_time (&discard_time), 169 GNUNET_PQ_query_param_absolute_time (&block->expiration_time),
178 GNUNET_PQ_query_param_auto_from_type (key), 170 GNUNET_PQ_query_param_auto_from_type (&block->key),
179 GNUNET_PQ_query_param_fixed_size (data, data_size), 171 GNUNET_PQ_query_param_fixed_size (block->data,
180 GNUNET_PQ_query_param_fixed_size (path_info, 172 block->data_size),
181 path_info_len * sizeof(struct 173 GNUNET_PQ_query_param_fixed_size (block->put_path,
182 GNUNET_DHT_PathElement)), 174 block->put_path_length
175 * sizeof(struct GNUNET_DHT_PathElement)),
183 GNUNET_PQ_query_param_end 176 GNUNET_PQ_query_param_end
184 }; 177 };
185 enum GNUNET_DB_QueryStatus ret; 178 enum GNUNET_DB_QueryStatus ret;
@@ -190,7 +183,7 @@ postgres_plugin_put (void *cls,
190 if (0 > ret) 183 if (0 > ret)
191 return -1; 184 return -1;
192 plugin->num_items++; 185 plugin->num_items++;
193 return data_size + OVERHEAD; 186 return block->data_size + OVERHEAD;
194} 187}
195 188
196 189
@@ -234,23 +227,25 @@ handle_results (void *cls,
234 227
235 for (unsigned int i = 0; i < num_results; i++) 228 for (unsigned int i = 0; i < num_results; i++)
236 { 229 {
237 struct GNUNET_TIME_Absolute expiration_time; 230 uint32_t type32;
238 uint32_t type; 231 uint32_t bro32;
239 void *data; 232 void *data;
240 size_t data_size; 233 struct GNUNET_DATACACHE_Block block;
241 struct GNUNET_DHT_PathElement *path; 234 void *path;
242 size_t path_len; 235 size_t path_size;
243 struct GNUNET_PQ_ResultSpec rs[] = { 236 struct GNUNET_PQ_ResultSpec rs[] = {
244 GNUNET_PQ_result_spec_absolute_time ("discard_time", 237 GNUNET_PQ_result_spec_absolute_time ("expiration_time",
245 &expiration_time), 238 &block.expiration_time),
246 GNUNET_PQ_result_spec_uint32 ("type", 239 GNUNET_PQ_result_spec_uint32 ("type",
247 &type), 240 &type32),
241 GNUNET_PQ_result_spec_uint32 ("ro",
242 &bro32),
248 GNUNET_PQ_result_spec_variable_size ("value", 243 GNUNET_PQ_result_spec_variable_size ("value",
249 &data, 244 &data,
250 &data_size), 245 &block.data_size),
251 GNUNET_PQ_result_spec_variable_size ("path", 246 GNUNET_PQ_result_spec_variable_size ("path",
252 (void **) &path, 247 &path,
253 &path_len), 248 &path_size),
254 GNUNET_PQ_result_spec_end 249 GNUNET_PQ_result_spec_end
255 }; 250 };
256 251
@@ -262,26 +257,27 @@ handle_results (void *cls,
262 GNUNET_break (0); 257 GNUNET_break (0);
263 return; 258 return;
264 } 259 }
265 if (0 != (path_len % sizeof(struct GNUNET_DHT_PathElement))) 260 if (0 != (path_size % sizeof(struct GNUNET_DHT_PathElement)))
266 { 261 {
267 GNUNET_break (0); 262 GNUNET_break (0);
268 path_len = 0; 263 path_size = 0;
264 path = NULL;
269 } 265 }
270 path_len %= sizeof(struct GNUNET_DHT_PathElement); 266 block.data = data;
267 block.put_path = path;
268 block.put_path_length
269 = path_size / sizeof (struct GNUNET_DHT_PathElement);
270 block.type = (enum GNUNET_BLOCK_Type) type32;
271 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
272 block.key = *hrc->key;
271 LOG (GNUNET_ERROR_TYPE_DEBUG, 273 LOG (GNUNET_ERROR_TYPE_DEBUG,
272 "Found result of size %u bytes and type %u in database\n", 274 "Found result of size %u bytes and type %u in database\n",
273 (unsigned int) data_size, 275 (unsigned int) block.data_size,
274 (unsigned int) type); 276 (unsigned int) block.type);
275 if ((NULL != hrc->iter) && 277 if ( (NULL != hrc->iter) &&
276 (GNUNET_SYSERR == 278 (GNUNET_SYSERR ==
277 hrc->iter (hrc->iter_cls, 279 hrc->iter (hrc->iter_cls,
278 hrc->key, 280 &block)) )
279 data_size,
280 data,
281 (enum GNUNET_BLOCK_Type) type,
282 expiration_time,
283 path_len,
284 path)))
285 { 281 {
286 LOG (GNUNET_ERROR_TYPE_DEBUG, 282 LOG (GNUNET_ERROR_TYPE_DEBUG,
287 "Ending iteration (client error)\n"); 283 "Ending iteration (client error)\n");
@@ -350,7 +346,7 @@ postgres_plugin_get (void *cls,
350 * @param cls closure (our `struct Plugin`) 346 * @param cls closure (our `struct Plugin`)
351 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 347 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
352 */ 348 */
353static int 349static enum GNUNET_GenericReturnValue
354postgres_plugin_del (void *cls) 350postgres_plugin_del (void *cls)
355{ 351{
356 struct Plugin *plugin = cls; 352 struct Plugin *plugin = cls;
@@ -453,26 +449,27 @@ extract_result_cb (void *cls,
453 return; 449 return;
454 for (unsigned int i = 0; i < num_results; i++) 450 for (unsigned int i = 0; i < num_results; i++)
455 { 451 {
456 struct GNUNET_TIME_Absolute expiration_time; 452 uint32_t type32;
457 uint32_t type; 453 uint32_t bro32;
454 struct GNUNET_DATACACHE_Block block;
458 void *data; 455 void *data;
459 size_t data_size; 456 void *path;
460 struct GNUNET_DHT_PathElement *path; 457 size_t path_size;
461 size_t path_len;
462 struct GNUNET_HashCode key;
463 struct GNUNET_PQ_ResultSpec rs[] = { 458 struct GNUNET_PQ_ResultSpec rs[] = {
464 GNUNET_PQ_result_spec_absolute_time ("", 459 GNUNET_PQ_result_spec_absolute_time ("expiration_time",
465 &expiration_time), 460 &block.expiration_time),
466 GNUNET_PQ_result_spec_uint32 ("type", 461 GNUNET_PQ_result_spec_uint32 ("type",
467 &type), 462 &type32),
463 GNUNET_PQ_result_spec_uint32 ("ro",
464 &bro32),
468 GNUNET_PQ_result_spec_variable_size ("value", 465 GNUNET_PQ_result_spec_variable_size ("value",
469 &data, 466 &data,
470 &data_size), 467 &block.data_size),
471 GNUNET_PQ_result_spec_variable_size ("path", 468 GNUNET_PQ_result_spec_variable_size ("path",
472 (void **) &path, 469 &path,
473 &path_len), 470 &path_size),
474 GNUNET_PQ_result_spec_auto_from_type ("key", 471 GNUNET_PQ_result_spec_auto_from_type ("key",
475 &key), 472 &block.key),
476 GNUNET_PQ_result_spec_end 473 GNUNET_PQ_result_spec_end
477 }; 474 };
478 475
@@ -484,25 +481,25 @@ extract_result_cb (void *cls,
484 GNUNET_break (0); 481 GNUNET_break (0);
485 return; 482 return;
486 } 483 }
487 if (0 != (path_len % sizeof(struct GNUNET_DHT_PathElement))) 484 if (0 != (path_size % sizeof(struct GNUNET_DHT_PathElement)))
488 { 485 {
489 GNUNET_break (0); 486 GNUNET_break (0);
490 path_len = 0; 487 path_size = 0;
488 path = NULL;
491 } 489 }
492 path_len %= sizeof(struct GNUNET_DHT_PathElement); 490 block.type = (enum GNUNET_BLOCK_Type) type32;
491 block.ro = (enum GNUNET_DHT_RouteOption) bro32;
492 block.data = data;
493 block.put_path = path;
494 block.put_path_length = path_size / sizeof (struct GNUNET_DHT_PathElement);
493 LOG (GNUNET_ERROR_TYPE_DEBUG, 495 LOG (GNUNET_ERROR_TYPE_DEBUG,
494 "Found result of size %u bytes and type %u in database\n", 496 "Found result of size %u bytes and type %u in database\n",
495 (unsigned int) data_size, 497 (unsigned int) block.data_size,
496 (unsigned int) type); 498 (unsigned int) block.type);
497 if (GNUNET_SYSERR == 499 if ( (NULL != erc->iter) &&
498 erc->iter (erc->iter_cls, 500 (GNUNET_SYSERR ==
499 &key, 501 erc->iter (erc->iter_cls,
500 data_size, 502 &block)) )
501 data,
502 (enum GNUNET_BLOCK_Type) type,
503 expiration_time,
504 path_len,
505 path))
506 { 503 {
507 LOG (GNUNET_ERROR_TYPE_DEBUG, 504 LOG (GNUNET_ERROR_TYPE_DEBUG,
508 "Ending iteration (client error)\n"); 505 "Ending iteration (client error)\n");