From 8582408b5728fa88a24b224e5b57ce877279d67a Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 29 Feb 2024 14:28:07 +0200 Subject: [PATCH] lib-sql: mysql, pgsql - Implement sqlpool support for new init() API --- src/lib-sql/driver-mysql.c | 34 ++++++++++++++++++++++++++++++++++ src/lib-sql/driver-pgsql.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/lib-sql/driver-mysql.c b/src/lib-sql/driver-mysql.c index 231d7b4e42..9139bc9c00 100644 --- a/src/lib-sql/driver-mysql.c +++ b/src/lib-sql/driver-mysql.c @@ -31,9 +31,16 @@ #define MYSQL_DEFAULT_READ_TIMEOUT_SECS 30 #define MYSQL_DEFAULT_WRITE_TIMEOUT_SECS 30 +/* */ +#define MYSQL_SQLPOOL_SET_NAME "mysql" +/* */ + struct mysql_settings { pool_t pool; + ARRAY_TYPE(const_string) sqlpool_hosts; + unsigned int connection_limit; + const char *host; in_port_t port; const char *user; @@ -57,6 +64,11 @@ struct mysql_settings { #define DEF_SECS(type, name) \ SETTING_DEFINE_STRUCT_##type("mysql_"#name, name##_secs, struct mysql_settings) static const struct setting_define mysql_setting_defines[] = { + { .type = SET_FILTER_ARRAY, .key = MYSQL_SQLPOOL_SET_NAME, + .offset = offsetof(struct mysql_settings, sqlpool_hosts), + .filter_array_field_name = "host", }, + DEF(UINT, connection_limit), + DEF(STR, host), DEF(IN_PORT, port), DEF(STR, user), @@ -76,6 +88,9 @@ static const struct setting_define mysql_setting_defines[] = { }; static struct mysql_settings mysql_default_settings = { + .sqlpool_hosts = ARRAY_INIT, + .connection_limit = SQL_DEFAULT_CONNECTION_LIMIT, + .host = "", .port = 0, .user = "", @@ -414,6 +429,11 @@ driver_mysql_init_v(struct event *event, struct sql_db **db_r, if (settings_get(event, &mysql_setting_parser_info, 0, &set, error_r) < 0) return -1; + if (array_is_empty(&set->sqlpool_hosts)) { + *error_r = "mysql { .. } named list filter is missing"; + settings_free(set); + return -1; + } if (set->ssl) { if (settings_get(event, &ssl_setting_parser_info, 0, @@ -440,8 +460,22 @@ driver_mysql_init_v(struct event *event, struct sql_db **db_r, } } + if (event_get_ptr(event, SQLPOOL_EVENT_PTR) == NULL) { + /* Use sqlpool for managing multiple connections */ + *db_r = driver_sqlpool_init(&driver_mysql_db, event, + MYSQL_SQLPOOL_SET_NAME, + &set->sqlpool_hosts, + set->connection_limit); + settings_free(set); + settings_free(ssl_set); + return 0; + } + /* We're being initialized by sqlpool - create a real mysql + connection. */ + pool_t pool = pool_alloconly_create("mysql driver", 1024); *db_r = driver_mysql_init_common(pool, event, set, ssl_set); + event_drop_parent_log_prefixes((*db_r)->event, 1); sql_init_common(*db_r); return 0; } diff --git a/src/lib-sql/driver-pgsql.c b/src/lib-sql/driver-pgsql.c index c323a3e35f..a8280bedc2 100644 --- a/src/lib-sql/driver-pgsql.c +++ b/src/lib-sql/driver-pgsql.c @@ -15,9 +15,16 @@ #define PGSQL_DNS_WARN_MSECS 500 +/* */ +#define PGSQL_SQLPOOL_SET_NAME "pgsql" +/* */ + struct pgsql_settings { pool_t pool; + ARRAY_TYPE(const_string) sqlpool_hosts; + unsigned int connection_limit; + const char *host; ARRAY_TYPE(const_string) parameters; }; @@ -26,6 +33,11 @@ struct pgsql_settings { #define DEF(type, name) \ SETTING_DEFINE_STRUCT_##type("pgsql_"#name, name, struct pgsql_settings) static const struct setting_define pgsql_setting_defines[] = { + { .type = SET_FILTER_ARRAY, .key = PGSQL_SQLPOOL_SET_NAME, + .offset = offsetof(struct pgsql_settings, sqlpool_hosts), + .filter_array_field_name = "host", }, + DEF(UINT, connection_limit), + DEF(STR, host), DEF(STRLIST, parameters), @@ -33,6 +45,9 @@ static const struct setting_define pgsql_setting_defines[] = { }; static const struct pgsql_settings pgsql_default_settings = { + .sqlpool_hosts = ARRAY_INIT, + .connection_limit = SQL_DEFAULT_CONNECTION_LIMIT, + .host = "", .parameters = ARRAY_INIT, }; @@ -416,8 +431,26 @@ driver_pgsql_init_v(struct event *event, struct sql_db **db_r, if (settings_get(event, &pgsql_setting_parser_info, 0, &set, error_r) < 0) return -1; + if (array_is_empty(&set->sqlpool_hosts)) { + *error_r = "pgsql { .. } named list filter is missing"; + settings_free(set); + return -1; + } + + if (event_get_ptr(event, SQLPOOL_EVENT_PTR) == NULL) { + /* Use sqlpool for managing multiple connections */ + *db_r = driver_sqlpool_init(&driver_pgsql_db, event, + PGSQL_SQLPOOL_SET_NAME, + &set->sqlpool_hosts, + set->connection_limit); + settings_free(set); + return 0; + } + /* We're being initialized by sqlpool - create a real pgsql + connection. */ struct pgsql_db *db = driver_pgsql_init_common(event, set); + event_drop_parent_log_prefixes(db->api.event, 1); sql_init_common(&db->api); *db_r = &db->api; return 0; -- 2.47.3