diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-01-17 02:26:21 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-01-17 02:26:21 +0100 |
commit | 4353432b97bdc03ce31f11dfd1ff3e30cf0106af (patch) | |
tree | f6d92c64b324e30065051259b73e23e12f4c533f /src/pq | |
parent | 1126181ab98fd7e9e6cca0786939020b161fcb94 (diff) | |
download | gnunet-4353432b97bdc03ce31f11dfd1ff3e30cf0106af.tar.gz gnunet-4353432b97bdc03ce31f11dfd1ff3e30cf0106af.zip |
DB load API change
Diffstat (limited to 'src/pq')
-rw-r--r-- | src/pq/pq.h | 5 | ||||
-rw-r--r-- | src/pq/pq_connect.c | 92 |
2 files changed, 87 insertions, 10 deletions
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 | |||
52 | * Configuration to use to connect to the DB. | 52 | * Configuration to use to connect to the DB. |
53 | */ | 53 | */ |
54 | char *config_str; | 54 | char *config_str; |
55 | |||
56 | /** | ||
57 | * Path to load SQL files from. | ||
58 | */ | ||
59 | char *load_path; | ||
55 | }; | 60 | }; |
56 | 61 | ||
57 | #endif | 62 | #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, | |||
64 | 64 | ||
65 | 65 | ||
66 | /** | 66 | /** |
67 | * Create a connection to the Postgres database using @a config_str | 67 | * Create a connection to the Postgres database using @a config_str for the |
68 | * for the configuration. Initialize logging via GNUnet's log | 68 | * configuration. Initialize logging via GNUnet's log routines and disable |
69 | * routines and disable Postgres's logger. Also ensures that the | 69 | * Postgres's logger. Also ensures that the statements in @a load_path and @a |
70 | * statements in @a es are executed whenever we (re)connect to the | 70 | * es are executed whenever we (re)connect to the database, and that the |
71 | * database, and that the prepared statements in @a ps are "ready". | 71 | * prepared statements in @a ps are "ready". If statements in @es fail that |
72 | * If statements in @es fail that were created with | 72 | * were created with #GNUNET_PQ_make_execute(), then the entire operation |
73 | * #GNUNET_PQ_make_execute(), then the entire operation fails. | 73 | * fails. |
74 | * | 74 | * |
75 | * The caller MUST ensure that @a es and @a ps remain allocated and | 75 | * In @a load_path, a list of "$XXXX.sql" files is expected where $XXXX |
76 | * initialized in memory until #GNUNET_PQ_disconnect() is called, | 76 | * must be a sequence of contiguous integer values starting at 0000. |
77 | * as they may be needed repeatedly and no copy will be made. | 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. | ||
78 | * | 80 | * |
79 | * @param config_str configuration to use | 81 | * @param config_str configuration to use |
82 | * @param load_path path to directory with SQL transactions to run, can be NULL | ||
80 | * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated | 83 | * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated |
81 | * array of statements to execute upon EACH connection, can be NULL | 84 | * array of statements to execute upon EACH connection, can be NULL |
82 | * @param ps array of prepared statements to prepare, can be NULL | 85 | * @param ps array of prepared statements to prepare, can be NULL |
@@ -84,6 +87,7 @@ pq_notice_processor_cb (void *arg, | |||
84 | */ | 87 | */ |
85 | struct GNUNET_PQ_Context * | 88 | struct GNUNET_PQ_Context * |
86 | GNUNET_PQ_connect (const char *config_str, | 89 | GNUNET_PQ_connect (const char *config_str, |
90 | const char *load_path, | ||
87 | const struct GNUNET_PQ_ExecuteStatement *es, | 91 | const struct GNUNET_PQ_ExecuteStatement *es, |
88 | const struct GNUNET_PQ_PreparedStatement *ps) | 92 | const struct GNUNET_PQ_PreparedStatement *ps) |
89 | { | 93 | { |
@@ -100,6 +104,8 @@ GNUNET_PQ_connect (const char *config_str, | |||
100 | 104 | ||
101 | db = GNUNET_new (struct GNUNET_PQ_Context); | 105 | db = GNUNET_new (struct GNUNET_PQ_Context); |
102 | db->config_str = GNUNET_strdup (config_str); | 106 | db->config_str = GNUNET_strdup (config_str); |
107 | if (NULL != load_path) | ||
108 | db->load_path = GNUNET_strdup (load_path); | ||
103 | if (0 != elen) | 109 | if (0 != elen) |
104 | { | 110 | { |
105 | db->es = GNUNET_new_array (elen + 1, | 111 | db->es = GNUNET_new_array (elen + 1, |
@@ -175,6 +181,62 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) | |||
175 | PQsetNoticeProcessor (db->conn, | 181 | PQsetNoticeProcessor (db->conn, |
176 | &pq_notice_processor_cb, | 182 | &pq_notice_processor_cb, |
177 | db); | 183 | db); |
184 | if (NULL != db->load_path) | ||
185 | { | ||
186 | size_t slen = strlen (db->load_path) + 10; | ||
187 | |||
188 | for (unsigned int i = 0; i<10000; i++) | ||
189 | { | ||
190 | char buf[slen]; | ||
191 | struct GNUNET_OS_Process *psql; | ||
192 | enum GNUNET_OS_ProcessStatusType type; | ||
193 | unsigned long code; | ||
194 | |||
195 | GNUNET_snprintf (buf, | ||
196 | sizeof (buf), | ||
197 | "%s/%u.sql", | ||
198 | db->load_path, | ||
199 | i); | ||
200 | if (GNUNET_YES != | ||
201 | GNUNET_DISK_file_test (buf)) | ||
202 | break; /* We are done */ | ||
203 | psql = GNUNET_OS_start_process (GNUNET_NO, | ||
204 | GNUNET_OS_INHERIT_STD_ERR, | ||
205 | NULL, | ||
206 | NULL, | ||
207 | NULL, | ||
208 | "psql", | ||
209 | db->config_str, | ||
210 | "-f", | ||
211 | buf, | ||
212 | "-q", | ||
213 | NULL); | ||
214 | if (NULL == psql) | ||
215 | { | ||
216 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
217 | "exec", | ||
218 | "psql"); | ||
219 | PQfinish (db->conn); | ||
220 | db->conn = NULL; | ||
221 | return; | ||
222 | } | ||
223 | GNUNET_assert (GNUNET_OK == | ||
224 | GNUNET_OS_process_wait_status (psql, | ||
225 | &type, | ||
226 | &code)); | ||
227 | GNUNET_OS_process_destroy (psql); | ||
228 | if ( (GNUNET_OS_PROCESS_EXITED != type) || | ||
229 | (0 != code) ) | ||
230 | { | ||
231 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
232 | "psql", | ||
233 | buf); | ||
234 | PQfinish (db->conn); | ||
235 | db->conn = NULL; | ||
236 | return; | ||
237 | } | ||
238 | } | ||
239 | } | ||
178 | if ( (NULL != db->es) && | 240 | if ( (NULL != db->es) && |
179 | (GNUNET_OK != | 241 | (GNUNET_OK != |
180 | GNUNET_PQ_exec_statements (db, | 242 | GNUNET_PQ_exec_statements (db, |
@@ -221,6 +283,7 @@ GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
221 | { | 283 | { |
222 | struct GNUNET_PQ_Context *db; | 284 | struct GNUNET_PQ_Context *db; |
223 | char *conninfo; | 285 | char *conninfo; |
286 | char *load_path; | ||
224 | 287 | ||
225 | if (GNUNET_OK != | 288 | if (GNUNET_OK != |
226 | GNUNET_CONFIGURATION_get_value_string (cfg, | 289 | GNUNET_CONFIGURATION_get_value_string (cfg, |
@@ -228,9 +291,17 @@ GNUNET_PQ_connect_with_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
228 | "CONFIG", | 291 | "CONFIG", |
229 | &conninfo)) | 292 | &conninfo)) |
230 | conninfo = NULL; | 293 | conninfo = NULL; |
294 | if (GNUNET_OK != | ||
295 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
296 | section, | ||
297 | "SQL_PATH", | ||
298 | &load_path)) | ||
299 | load_path = NULL; | ||
231 | db = GNUNET_PQ_connect (conninfo == NULL ? "" : conninfo, | 300 | db = GNUNET_PQ_connect (conninfo == NULL ? "" : conninfo, |
301 | load_path, | ||
232 | es, | 302 | es, |
233 | ps); | 303 | ps); |
304 | GNUNET_free_non_null (load_path); | ||
234 | GNUNET_free_non_null (conninfo); | 305 | GNUNET_free_non_null (conninfo); |
235 | return db; | 306 | return db; |
236 | } | 307 | } |
@@ -247,6 +318,7 @@ GNUNET_PQ_disconnect (struct GNUNET_PQ_Context *db) | |||
247 | { | 318 | { |
248 | GNUNET_free_non_null (db->es); | 319 | GNUNET_free_non_null (db->es); |
249 | GNUNET_free_non_null (db->ps); | 320 | GNUNET_free_non_null (db->ps); |
321 | GNUNET_free_non_null (db->load_path); | ||
250 | PQfinish (db->conn); | 322 | PQfinish (db->conn); |
251 | GNUNET_free (db); | 323 | GNUNET_free (db); |
252 | } | 324 | } |