From: Christian Grothoff Date: Fri, 17 Jan 2020 01:26:21 +0000 (+0100) Subject: DB load API change X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=4353432b97bdc03ce31f11dfd1ff3e30cf0106af;p=oweals%2Fgnunet.git DB load API change --- diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index 9376a1059..b79be5f70 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h @@ -413,7 +413,6 @@ GNUNET_DISK_pipe (int blocking_read, * @param blocking_read creates an asynchronous pipe for reading if set to #GNUNET_NO * @param blocking_write creates an asynchronous pipe for writing if set to #GNUNET_NO * @param fd an array of two fd values. One of them may be -1 for read-only or write-only pipes - * * @return handle to the new pipe, NULL on error */ struct GNUNET_DISK_PipeHandle * diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h index 50e9a4c92..a6188c1ca 100644 --- a/src/include/gnunet_os_lib.h +++ b/src/include/gnunet_os_lib.h @@ -597,7 +597,7 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, /** - * Retrieve the status of a process, waiting on it if dead. + * Retrieve the status of a process. * Nonblocking version. * * @param proc pointer to process structure diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index 2aea77b7f..8b32a9265 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h @@ -708,15 +708,22 @@ GNUNET_PQ_exec_statements (struct GNUNET_PQ_Context *db, /** - * Create a connection to the Postgres database using @a config_str - * for the configuration. Initialize logging via GNUnet's log - * routines and disable Postgres's logger. Also ensures that the - * statements in @a es are executed whenever we (re)connect to the - * database, and that the prepared statements in @a ps are "ready". - * If statements in @es fail that were created with - * #GNUNET_PQ_make_execute(), then the entire operation fails. + * Create a connection to the Postgres database using @a config_str for the + * configuration. Initialize logging via GNUnet's log routines and disable + * Postgres's logger. Also ensures that the statements in @a load_path and @a + * es are executed whenever we (re)connect to the database, and that the + * prepared statements in @a ps are "ready". If statements in @es fail that + * were created with #GNUNET_PQ_make_execute(), then the entire operation + * fails. + * + * In @a load_path, a list of "$XXXX.sql" files is expected where $XXXX + * must be a sequence of contiguous integer values starting at 0000. + * These files are then loaded in sequence using "psql $config_str" before + * running statements from @e es. The directory is inspected again on + * reconnect. * * @param config_str configuration to use + * @param load_path path to directory with SQL transactions to run, can be NULL * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated * array of statements to execute upon EACH connection, can be NULL * @param ps array of prepared statements to prepare, can be NULL @@ -724,6 +731,7 @@ GNUNET_PQ_exec_statements (struct GNUNET_PQ_Context *db, */ struct GNUNET_PQ_Context * GNUNET_PQ_connect (const char *config_str, + const char *load_path, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps); diff --git a/src/pq/pq.h b/src/pq/pq.h index b30f4f0d4..91a890bcb 100644 --- a/src/pq/pq.h +++ b/src/pq/pq.h @@ -52,6 +52,11 @@ struct GNUNET_PQ_Context * Configuration to use to connect to the DB. */ char *config_str; + + /** + * Path to load SQL files from. + */ + char *load_path; }; #endif diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c index 7d9a524b3..5ade12a3e 100644 --- a/src/pq/pq_connect.c +++ b/src/pq/pq_connect.c @@ -64,19 +64,22 @@ pq_notice_processor_cb (void *arg, /** - * Create a connection to the Postgres database using @a config_str - * for the configuration. Initialize logging via GNUnet's log - * routines and disable Postgres's logger. Also ensures that the - * statements in @a es are executed whenever we (re)connect to the - * database, and that the prepared statements in @a ps are "ready". - * If statements in @es fail that were created with - * #GNUNET_PQ_make_execute(), then the entire operation fails. + * Create a connection to the Postgres database using @a config_str for the + * configuration. Initialize logging via GNUnet's log routines and disable + * Postgres's logger. Also ensures that the statements in @a load_path and @a + * es are executed whenever we (re)connect to the database, and that the + * prepared statements in @a ps are "ready". If statements in @es fail that + * were created with #GNUNET_PQ_make_execute(), then the entire operation + * fails. * - * The caller MUST ensure that @a es and @a ps remain allocated and - * initialized in memory until #GNUNET_PQ_disconnect() is called, - * as they may be needed repeatedly and no copy will be made. + * In @a load_path, a list of "$XXXX.sql" files is expected where $XXXX + * must be a sequence of contiguous integer values starting at 0000. + * These files are then loaded in sequence using "psql $config_str" before + * running statements from @e es. The directory is inspected again on + * reconnect. * * @param config_str configuration to use + * @param load_path path to directory with SQL transactions to run, can be NULL * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated * array of statements to execute upon EACH connection, can be NULL * @param ps array of prepared statements to prepare, can be NULL @@ -84,6 +87,7 @@ pq_notice_processor_cb (void *arg, */ struct GNUNET_PQ_Context * GNUNET_PQ_connect (const char *config_str, + const char *load_path, const struct GNUNET_PQ_ExecuteStatement *es, const struct GNUNET_PQ_PreparedStatement *ps) { @@ -100,6 +104,8 @@ GNUNET_PQ_connect (const char *config_str, db = GNUNET_new (struct GNUNET_PQ_Context); db->config_str = GNUNET_strdup (config_str); + if (NULL != load_path) + db->load_path = GNUNET_strdup (load_path); if (0 != elen) { db->es = GNUNET_new_array (elen + 1, @@ -175,6 +181,62 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) PQsetNoticeProcessor (db->conn, &pq_notice_processor_cb, db); + if (NULL != db->load_path) + { + size_t slen = strlen (db->load_path) + 10; + + for (unsigned int i = 0; i<10000; i++) + { + char buf[slen]; + struct GNUNET_OS_Process *psql; + enum GNUNET_OS_ProcessStatusType type; + unsigned long code; + + GNUNET_snprintf (buf, + sizeof (buf), + "%s/%u.sql", + db->load_path, + i); + if (GNUNET_YES != + GNUNET_DISK_file_test (buf)) + break; /* We are done */ + psql = GNUNET_OS_start_process (GNUNET_NO, + GNUNET_OS_INHERIT_STD_ERR, + NULL, + NULL, + NULL, + "psql", + db->config_str, + "-f", + buf, + "-q", + NULL); + if (NULL == psql) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + "exec", + "psql"); + PQfinish (db->conn); + db->conn = NULL; + return; + } + GNUNET_assert (GNUNET_OK == + GNUNET_OS_process_wait_status (psql, + &type, + &code)); + GNUNET_OS_process_destroy (psql); + if ( (GNUNET_OS_PROCESS_EXITED != type) || + (0 != code) ) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + "psql", + buf); + PQfinish (db->conn); + db->conn = NULL; + return; + } + } + } if ( (NULL != db->es) && (GNUNET_OK != GNUNET_PQ_exec_statements (db, @@ -221,6 +283,7 @@ GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, { struct GNUNET_PQ_Context *db; char *conninfo; + char *load_path; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, @@ -228,9 +291,17 @@ GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, "CONFIG", &conninfo)) conninfo = NULL; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + section, + "SQL_PATH", + &load_path)) + load_path = NULL; db = GNUNET_PQ_connect (conninfo == NULL ? "" : conninfo, + load_path, es, ps); + GNUNET_free_non_null (load_path); GNUNET_free_non_null (conninfo); return db; } @@ -247,6 +318,7 @@ GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) { GNUNET_free_non_null (db->es); GNUNET_free_non_null (db->ps); + GNUNET_free_non_null (db->load_path); PQfinish (db->conn); GNUNET_free (db); } diff --git a/src/util/os_priority.c b/src/util/os_priority.c index d93e0d44f..722aac872 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c @@ -951,7 +951,7 @@ process_status (struct GNUNET_OS_Process *proc, /** - * Retrieve the status of a process, waiting on it if dead. + * Retrieve the status of a process. * Nonblocking version. * * @param proc process ID