summaryrefslogtreecommitdiffstats
path: root/src/global/dict_pgsql.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/global/dict_pgsql.c')
-rw-r--r--src/global/dict_pgsql.c73
1 files changed, 35 insertions, 38 deletions
diff --git a/src/global/dict_pgsql.c b/src/global/dict_pgsql.c
index 5992135..c626854 100644
--- a/src/global/dict_pgsql.c
+++ b/src/global/dict_pgsql.c
@@ -108,18 +108,18 @@
#define TYPEUNIX (1<<0)
#define TYPEINET (1<<1)
-#define TYPECONNSTRING (1<<2)
+#define TYPECONNSTR (1<<2)
#define RETRY_CONN_MAX 100
-#define RETRY_CONN_INTV 60 /* 1 minute */
-#define IDLE_CONN_INTV 60 /* 1 minute */
+#define DEF_RETRY_INTV 60 /* 1 minute */
+#define DEF_IDLE_INTV 60 /* 1 minute */
typedef struct {
PGconn *db;
char *hostname;
char *name;
char *port;
- unsigned type; /* TYPEUNIX | TYPEINET | TYPECONNSTRING */
+ unsigned type; /* TYPEUNIX | TYPEINET | TYPECONNSTR */
unsigned stat; /* STATUNTRIED | STATFAIL | STATCUR */
time_t ts; /* used for attempting reconnection */
} HOST;
@@ -140,6 +140,8 @@ typedef struct {
char *password;
char *dbname;
char *encoding;
+ int retry_interval;
+ int idle_interval;
char *table;
ARGV *hosts;
PLPGSQL *pldb;
@@ -152,12 +154,11 @@ typedef struct {
/* internal function declarations */
static PLPGSQL *plpgsql_init(ARGV *);
-static PGSQL_RES *plpgsql_query(DICT_PGSQL *, const char *, VSTRING *, char *,
- char *, char *, char *);
+static PGSQL_RES *plpgsql_query(DICT_PGSQL *, const char *, VSTRING *);
static void plpgsql_dealloc(PLPGSQL *);
static void plpgsql_close_host(HOST *);
-static void plpgsql_down_host(HOST *);
-static void plpgsql_connect_single(HOST *, char *, char *, char *, char *);
+static void plpgsql_down_host(HOST *, int);
+static void plpgsql_connect_single(DICT_PGSQL *, HOST *);
static const char *dict_pgsql_lookup(DICT *, const char *);
DICT *dict_pgsql_open(const char *, int, int);
static void dict_pgsql_close(DICT *);
@@ -280,7 +281,7 @@ static const char *dict_pgsql_lookup(DICT *dict, const char *name)
*/
#ifdef SNAPSHOT
if ((dict->flags & DICT_FLAG_UTF8_ACTIVE) == 0
- && !valid_utf8_string(name, strlen(name))) {
+ && !valid_utf8_stringz(name)) {
if (msg_verbose)
msg_info("%s: %s: Skipping lookup of non-UTF-8 key '%s'",
myname, dict_pgsql->parser->name, name);
@@ -324,11 +325,7 @@ static const char *dict_pgsql_lookup(DICT *dict, const char *name)
return (0);
/* do the query - set dict->error & cleanup if there's an error */
- if ((query_res = plpgsql_query(dict_pgsql, name, query,
- dict_pgsql->dbname,
- dict_pgsql->encoding,
- dict_pgsql->username,
- dict_pgsql->password)) == 0) {
+ if ((query_res = plpgsql_query(dict_pgsql, name, query)) == 0) {
dict->error = DICT_ERR_RETRY;
return 0;
}
@@ -404,8 +401,7 @@ static HOST *dict_pgsql_find_host(PLPGSQL *PLDB, unsigned stat, unsigned type)
/* dict_pgsql_get_active - get an active connection */
-static HOST *dict_pgsql_get_active(PLPGSQL *PLDB, char *dbname, char *encoding,
- char *username, char *password)
+static HOST *dict_pgsql_get_active(DICT_PGSQL *dict_pgsql, PLPGSQL *PLDB)
{
const char *myname = "dict_pgsql_get_active";
HOST *host;
@@ -414,7 +410,7 @@ static HOST *dict_pgsql_get_active(PLPGSQL *PLDB, char *dbname, char *encoding,
/* try the active connections first; prefer the ones to UNIX sockets */
if ((host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPEUNIX)) != NULL ||
(host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPEINET)) != NULL ||
- (host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPECONNSTRING)) != NULL) {
+ (host = dict_pgsql_find_host(PLDB, STATACTIVE, TYPECONNSTR)) != NULL) {
if (msg_verbose)
msg_info("%s: found active connection to host %s", myname,
host->hostname);
@@ -432,11 +428,11 @@ static HOST *dict_pgsql_get_active(PLPGSQL *PLDB, char *dbname, char *encoding,
(host = dict_pgsql_find_host(PLDB, STATUNTRIED | STATFAIL,
TYPEINET)) != NULL ||
(host = dict_pgsql_find_host(PLDB, STATUNTRIED | STATFAIL,
- TYPECONNSTRING)) != NULL)) {
+ TYPECONNSTR)) != NULL)) {
if (msg_verbose)
msg_info("%s: attempting to connect to host %s", myname,
host->hostname);
- plpgsql_connect_single(host, dbname, encoding, username, password);
+ plpgsql_connect_single(dict_pgsql, host);
if (host->stat == STATACTIVE)
return host;
}
@@ -464,18 +460,14 @@ static void dict_pgsql_event(int unused_event, void *context)
static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql,
const char *name,
- VSTRING *query,
- char *dbname,
- char *encoding,
- char *username,
- char *password)
+ VSTRING *query)
{
PLPGSQL *PLDB = dict_pgsql->pldb;
HOST *host;
PGSQL_RES *res = 0;
ExecStatusType status;
- while ((host = dict_pgsql_get_active(PLDB, dbname, encoding, username, password)) != NULL) {
+ while ((host = dict_pgsql_get_active(dict_pgsql, PLDB)) != NULL) {
/*
* The active host is used to escape strings in the context of the
@@ -490,7 +482,7 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql,
/* Check for potential dict_pgsql_quote() failure. */
if (host->stat == STATFAIL) {
- plpgsql_down_host(host);
+ plpgsql_down_host(host, dict_pgsql->retry_interval);
continue;
}
@@ -528,7 +520,7 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql,
msg_info("dict_pgsql: successful query from host %s",
host->hostname);
event_request_timer(dict_pgsql_event, (void *) host,
- IDLE_CONN_INTV);
+ dict_pgsql->idle_interval);
return (res);
case PGRES_FATAL_ERROR:
msg_warn("pgsql query failed: fatal error from host %s: %s",
@@ -559,7 +551,7 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql,
*/
if (res != 0)
PQclear(res);
- plpgsql_down_host(host);
+ plpgsql_down_host(host, dict_pgsql->retry_interval);
}
return (0);
@@ -570,24 +562,25 @@ static PGSQL_RES *plpgsql_query(DICT_PGSQL *dict_pgsql,
* used to reconnect to a single database when one is down or none is
* connected yet. Log all errors and set the stat field of host accordingly
*/
-static void plpgsql_connect_single(HOST *host, char *dbname, char *encoding, char *username, char *password)
+static void plpgsql_connect_single(DICT_PGSQL *dict_pgsql, HOST *host)
{
- if (host->type == TYPECONNSTRING) {
+ if (host->type == TYPECONNSTR) {
host->db = PQconnectdb(host->name);
} else {
host->db = PQsetdbLogin(host->name, host->port, NULL, NULL,
- dbname, username, password);
+ dict_pgsql->dbname, dict_pgsql->username,
+ dict_pgsql->password);
}
if (host->db == NULL || PQstatus(host->db) != CONNECTION_OK) {
msg_warn("connect to pgsql server %s: %s",
host->hostname, PQerrorMessage(host->db));
- plpgsql_down_host(host);
+ plpgsql_down_host(host, dict_pgsql->retry_interval);
return;
}
- if (PQsetClientEncoding(host->db, encoding) != 0) {
+ if (PQsetClientEncoding(host->db, dict_pgsql->encoding) != 0) {
msg_warn("dict_pgsql: cannot set the encoding to %s, skipping %s",
- encoding, host->hostname);
- plpgsql_down_host(host);
+ dict_pgsql->encoding, host->hostname);
+ plpgsql_down_host(host, dict_pgsql->retry_interval);
return;
}
if (msg_verbose)
@@ -611,12 +604,12 @@ static void plpgsql_close_host(HOST *host)
* plpgsql_down_host - close a failed connection AND set a "stay away from
* this host" timer.
*/
-static void plpgsql_down_host(HOST *host)
+static void plpgsql_down_host(HOST *host, int retry_interval)
{
if (host->db)
PQfinish(host->db);
host->db = 0;
- host->ts = time((time_t *) 0) + RETRY_CONN_INTV;
+ host->ts = time((time_t *) 0) + retry_interval;
host->stat = STATFAIL;
event_cancel_timer(dict_pgsql_event, (void *) host);
}
@@ -635,6 +628,10 @@ static void pgsql_parse_config(DICT_PGSQL *dict_pgsql, const char *pgsqlcf)
dict_pgsql->password = cfg_get_str(p, "password", "", 0, 0);
dict_pgsql->dbname = cfg_get_str(p, "dbname", "", 1, 0);
dict_pgsql->encoding = cfg_get_str(p, "encoding", "UTF8", 1, 0);
+ dict_pgsql->retry_interval = cfg_get_int(p, "retry_interval",
+ DEF_RETRY_INTV, 1, 0);
+ dict_pgsql->idle_interval = cfg_get_int(p, "idle_interval",
+ DEF_IDLE_INTV, 1, 0);
dict_pgsql->result_format = cfg_get_str(p, "result_format", "%s", 1, 0);
/*
@@ -764,7 +761,7 @@ static HOST *host_init(const char *hostname)
* Modern syntax: "postgresql://connection-info".
*/
if (strncmp(d, "postgresql:", 11) == 0) {
- host->type = TYPECONNSTRING;
+ host->type = TYPECONNSTR;
host->name = mystrdup(d);
host->port = 0;
}