ARRAY_TYPE(const_string) parameters;
};
+#undef DEF
+#define DEF(type, name) \
+ SETTING_DEFINE_STRUCT_##type("pgsql_"#name, name, struct pgsql_settings)
+static const struct setting_define pgsql_setting_defines[] = {
+ DEF(STR, host),
+ DEF(STRLIST, parameters),
+
+ SETTING_DEFINE_LIST_END
+};
+
static const struct pgsql_settings pgsql_default_settings = {
.host = "",
.parameters = ARRAY_INIT,
};
+const struct setting_parser_info pgsql_setting_parser_info = {
+ .name = "pgsql",
+
+ .defines = pgsql_setting_defines,
+ .defaults = &pgsql_default_settings,
+
+ .struct_size = sizeof(struct pgsql_settings),
+ .pool_offset1 = 1 + offsetof(struct pgsql_settings, pool),
+};
+
struct pgsql_db {
struct sql_db api;
io_loop_time_refresh();
tv_start = ioloop_timeval;
- db->pg = PQconnectStart(db->legacy_connect_string);
+ if (db->legacy_connect_string != NULL)
+ db->pg = PQconnectStart(db->legacy_connect_string);
+ else {
+ ARRAY_TYPE(const_string) keywords, values;
+ t_array_init(&keywords, 16);
+ t_array_init(&values, 16);
+
+ const char *host_str = "host";
+ array_push_back(&keywords, &host_str);
+ array_push_back(&values, &db->set->host);
+
+ unsigned int i, count;
+ const char *const *strings =
+ array_get(&db->set->parameters, &count);
+ for (i = 0; i < count; i += 2) {
+ array_push_back(&keywords, &strings[i]);
+ array_push_back(&values, &strings[i + 1]);
+ }
+
+ array_append_zero(&keywords);
+ array_append_zero(&values);
+ db->pg = PQconnectStartParams(array_front(&keywords),
+ array_front(&values), 0);
+
+ }
+
if (db->pg == NULL) {
i_fatal_status(FATAL_OUTOFMEM, "pgsql: PQconnectStart() failed (out of memory)");
}
return db->flags;
}
-static int
-driver_pgsql_init_full_v(const struct sql_legacy_settings *legacy_set,
- struct sql_db **db_r, const char **error_r ATTR_UNUSED)
+static struct pgsql_db *
+driver_pgsql_init_common(struct event *event_parent,
+ const struct pgsql_settings *set)
{
struct pgsql_db *db;
- const char *value;
db = i_new(struct pgsql_db, 1);
- db->legacy_connect_string = i_strdup(legacy_set->connect_string);
db->api = driver_pgsql_db;
- db->api.event = event_create(legacy_set->event_parent);
+ db->api.event = event_create(event_parent);
+ db->set = set;
event_add_category(db->api.event, &event_category_pgsql);
+ event_set_append_log_prefix(db->api.event,
+ t_strdup_printf("pgsql(%s): ", set->host));
+ return db;
+}
+
+static int
+driver_pgsql_init_v(struct event *event, struct sql_db **db_r,
+ const char **error_r)
+{
+ const struct pgsql_settings *set;
+
+ if (settings_get(event, &pgsql_setting_parser_info, 0,
+ &set, error_r) < 0)
+ return -1;
+
+ struct pgsql_db *db = driver_pgsql_init_common(event, set);
+ *db_r = &db->api;
+ return 0;
+}
+
+static int
+driver_pgsql_init_full_v(const struct sql_legacy_settings *legacy_set,
+ struct sql_db **db_r, const char **error_r ATTR_UNUSED)
+{
+ const char *value;
pool_t pool = pool_alloconly_create("pgsql settings", 128);
struct pgsql_settings *set = p_new(pool, struct pgsql_settings, 1);
*set = pgsql_default_settings;
set->pool = pool;
- db->set = set;
/* NOTE: Connection string will be parsed by pgsql itself
We only pick the host part here */
}
} T_END;
-
- event_set_append_log_prefix(db->api.event,
- t_strdup_printf("pgsql(%s): ", set->host));
-
+ struct pgsql_db *db =
+ driver_pgsql_init_common(legacy_set->event_parent, set);
+ db->legacy_connect_string = i_strdup(legacy_set->connect_string);
*db_r = &db->api;
return 0;
}
.v = {
.get_flags = driver_pgsql_get_flags,
+ .init = driver_pgsql_init_v,
.init_legacy_full = driver_pgsql_init_full_v,
.deinit = driver_pgsql_deinit_v,
.connect = driver_pgsql_connect,