diff options
Diffstat (limited to 'src/pq/pq_connect.c')
-rw-r--r-- | src/pq/pq_connect.c | 84 |
1 files changed, 16 insertions, 68 deletions
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c index 00664dcd0..a2dce3fb0 100644 --- a/src/pq/pq_connect.c +++ b/src/pq/pq_connect.c | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | #include "platform.h" | 25 | #include "platform.h" |
26 | #include "pq.h" | 26 | #include "pq.h" |
27 | #include <pthread.h> | ||
27 | 28 | ||
28 | 29 | ||
29 | /** | 30 | /** |
@@ -63,28 +64,6 @@ pq_notice_processor_cb (void *arg, | |||
63 | } | 64 | } |
64 | 65 | ||
65 | 66 | ||
66 | /** | ||
67 | * Create a connection to the Postgres database using @a config_str for the | ||
68 | * configuration. Initialize logging via GNUnet's log routines and disable | ||
69 | * Postgres's logger. Also ensures that the statements in @a load_path and @a | ||
70 | * es are executed whenever we (re)connect to the database, and that the | ||
71 | * prepared statements in @a ps are "ready". If statements in @es fail that | ||
72 | * were created with #GNUNET_PQ_make_execute(), then the entire operation | ||
73 | * fails. | ||
74 | * | ||
75 | * In @a load_path, a list of "$XXXX.sql" files is expected where $XXXX | ||
76 | * must be a sequence of contiguous integer values starting at 0000. | ||
77 | * These files are then loaded in sequence using "psql $config_str" before | ||
78 | * running statements from @e es. The directory is inspected again on | ||
79 | * reconnect. | ||
80 | * | ||
81 | * @param config_str configuration to use | ||
82 | * @param load_path path to directory with SQL transactions to run, can be NULL | ||
83 | * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated | ||
84 | * array of statements to execute upon EACH connection, can be NULL | ||
85 | * @param ps array of prepared statements to prepare, can be NULL | ||
86 | * @return NULL on error | ||
87 | */ | ||
88 | struct GNUNET_PQ_Context * | 67 | struct GNUNET_PQ_Context * |
89 | GNUNET_PQ_connect (const char *config_str, | 68 | GNUNET_PQ_connect (const char *config_str, |
90 | const char *load_path, | 69 | const char *load_path, |
@@ -122,6 +101,8 @@ GNUNET_PQ_connect (const char *config_str, | |||
122 | ps, | 101 | ps, |
123 | plen * sizeof (struct GNUNET_PQ_PreparedStatement)); | 102 | plen * sizeof (struct GNUNET_PQ_PreparedStatement)); |
124 | } | 103 | } |
104 | db->channel_map = GNUNET_CONTAINER_multishortmap_create (16, | ||
105 | GNUNET_YES); | ||
125 | GNUNET_PQ_reconnect (db); | 106 | GNUNET_PQ_reconnect (db); |
126 | if (NULL == db->conn) | 107 | if (NULL == db->conn) |
127 | { | 108 | { |
@@ -142,7 +123,7 @@ GNUNET_PQ_connect (const char *config_str, | |||
142 | * @param i patch number to append to the @a load_path | 123 | * @param i patch number to append to the @a load_path |
143 | * @return #GNUNET_OK on success, #GNUNET_NO if patch @a i does not exist, #GNUNET_SYSERR on error | 124 | * @return #GNUNET_OK on success, #GNUNET_NO if patch @a i does not exist, #GNUNET_SYSERR on error |
144 | */ | 125 | */ |
145 | static int | 126 | static enum GNUNET_GenericReturnValue |
146 | apply_patch (struct GNUNET_PQ_Context *db, | 127 | apply_patch (struct GNUNET_PQ_Context *db, |
147 | const char *load_path, | 128 | const char *load_path, |
148 | unsigned int i) | 129 | unsigned int i) |
@@ -162,7 +143,7 @@ apply_patch (struct GNUNET_PQ_Context *db, | |||
162 | "Applying SQL file `%s' on database %s\n", | 143 | "Applying SQL file `%s' on database %s\n", |
163 | buf, | 144 | buf, |
164 | db->config_str); | 145 | db->config_str); |
165 | psql = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_NONE, | 146 | psql = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, |
166 | NULL, | 147 | NULL, |
167 | NULL, | 148 | NULL, |
168 | NULL, | 149 | NULL, |
@@ -191,7 +172,7 @@ apply_patch (struct GNUNET_PQ_Context *db, | |||
191 | (0 != code) ) | 172 | (0 != code) ) |
192 | { | 173 | { |
193 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 174 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
194 | "Could not run PSQL on file %s: %d\n", | 175 | "Could not run PSQL on file %s: psql exit code was %d\n", |
195 | buf, | 176 | buf, |
196 | (int) code); | 177 | (int) code); |
197 | return GNUNET_SYSERR; | 178 | return GNUNET_SYSERR; |
@@ -200,15 +181,6 @@ apply_patch (struct GNUNET_PQ_Context *db, | |||
200 | } | 181 | } |
201 | 182 | ||
202 | 183 | ||
203 | /** | ||
204 | * Within the @a db context, run all the SQL files | ||
205 | * from the @a load_path from 0000-9999.sql (as long | ||
206 | * as the files exist contiguously). | ||
207 | * | ||
208 | * @param db database context to use | ||
209 | * @param load_path where to find the XXXX.sql files | ||
210 | * @return #GNUNET_OK on success | ||
211 | */ | ||
212 | enum GNUNET_GenericReturnValue | 184 | enum GNUNET_GenericReturnValue |
213 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, | 185 | GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, |
214 | const char *load_path) | 186 | const char *load_path) |
@@ -304,11 +276,6 @@ GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db, | |||
304 | } | 276 | } |
305 | 277 | ||
306 | 278 | ||
307 | /** | ||
308 | * Reinitialize the database @a db if the connection is down. | ||
309 | * | ||
310 | * @param db database connection to reinitialize | ||
311 | */ | ||
312 | void | 279 | void |
313 | GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) | 280 | GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) |
314 | { | 281 | { |
@@ -321,14 +288,11 @@ GNUNET_PQ_reconnect_if_down (struct GNUNET_PQ_Context *db) | |||
321 | } | 288 | } |
322 | 289 | ||
323 | 290 | ||
324 | /** | ||
325 | * Reinitialize the database @a db. | ||
326 | * | ||
327 | * @param db database connection to reinitialize | ||
328 | */ | ||
329 | void | 291 | void |
330 | GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | 292 | GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) |
331 | { | 293 | { |
294 | GNUNET_PQ_event_reconnect_ (db, | ||
295 | -1); | ||
332 | if (NULL != db->conn) | 296 | if (NULL != db->conn) |
333 | PQfinish (db->conn); | 297 | PQfinish (db->conn); |
334 | db->conn = PQconnectdb (db->config_str); | 298 | db->conn = PQconnectdb (db->config_str); |
@@ -380,7 +344,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | |||
380 | 0); | 344 | 0); |
381 | if (GNUNET_NO == ret) | 345 | if (GNUNET_NO == ret) |
382 | { | 346 | { |
383 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 347 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
384 | "Failed to find SQL file to load database versioning logic\n"); | 348 | "Failed to find SQL file to load database versioning logic\n"); |
385 | PQfinish (db->conn); | 349 | PQfinish (db->conn); |
386 | db->conn = NULL; | 350 | db->conn = NULL; |
@@ -448,26 +412,11 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | |||
448 | db->conn = NULL; | 412 | db->conn = NULL; |
449 | return; | 413 | return; |
450 | } | 414 | } |
415 | GNUNET_PQ_event_reconnect_ (db, | ||
416 | PQsocket (db->conn)); | ||
451 | } | 417 | } |
452 | 418 | ||
453 | 419 | ||
454 | /** | ||
455 | * Connect to a postgres database using the configuration | ||
456 | * option "CONFIG" in @a section. Also ensures that the | ||
457 | * statements in @a es are executed whenever we (re)connect to the | ||
458 | * database, and that the prepared statements in @a ps are "ready". | ||
459 | * | ||
460 | * The caller does not have to ensure that @a es and @a ps remain allocated | ||
461 | * and initialized in memory until #GNUNET_PQ_disconnect() is called, as a copy will be made. | ||
462 | * | ||
463 | * @param cfg configuration | ||
464 | * @param section configuration section to use to get Postgres configuration options | ||
465 | * @param load_path_suffix suffix to append to the SQL_DIR in the configuration | ||
466 | * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated | ||
467 | * array of statements to execute upon EACH connection, can be NULL | ||
468 | * @param ps array of prepared statements to prepare, can be NULL | ||
469 | * @return the postgres handle, NULL on error | ||
470 | */ | ||
471 | struct GNUNET_PQ_Context * | 420 | struct GNUNET_PQ_Context * |
472 | GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | 421 | GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, |
473 | const char *section, | 422 | const char *section, |
@@ -509,15 +458,14 @@ GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
509 | } | 458 | } |
510 | 459 | ||
511 | 460 | ||
512 | /** | ||
513 | * Disconnect from the database, destroying the prepared statements | ||
514 | * and releasing other associated resources. | ||
515 | * | ||
516 | * @param db database handle to disconnect (will be free'd) | ||
517 | */ | ||
518 | void | 461 | void |
519 | GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) | 462 | GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) |
520 | { | 463 | { |
464 | if (NULL == db) | ||
465 | return; | ||
466 | GNUNET_assert (0 == | ||
467 | GNUNET_CONTAINER_multishortmap_size (db->channel_map)); | ||
468 | GNUNET_CONTAINER_multishortmap_destroy (db->channel_map); | ||
521 | GNUNET_free (db->es); | 469 | GNUNET_free (db->es); |
522 | GNUNET_free (db->ps); | 470 | GNUNET_free (db->ps); |
523 | GNUNET_free (db->load_path); | 471 | GNUNET_free (db->load_path); |