summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 09c001b)
raw | patch | inline | side by side (parent: 09c001b)
author | Sebastian Harl <sh@tokkee.org> | |
Fri, 18 Jul 2008 19:38:48 +0000 (21:38 +0200) | ||
committer | Florian Forster <octo@huhu.verplant.org> | |
Thu, 24 Jul 2008 12:18:04 +0000 (14:18 +0200) |
The parameters are referred to in the query string as $1, $2, ... The value of
a parameter is specified using the new "Param <name>" config option of a
"<Query>" block. <name> may be any of "hostname", "database" or "username"
which will be replaced by the value of the appropriate connection parameters.
The hostname will not evaluate to the the UNIX domain socket path -
"localhost" will be used instead.
Signed-off-by: Sebastian Harl <sh@tokkee.org>
Signed-off-by: Florian Forster <octo@huhu.verplant.org>
a parameter is specified using the new "Param <name>" config option of a
"<Query>" block. <name> may be any of "hostname", "database" or "username"
which will be replaced by the value of the appropriate connection parameters.
The hostname will not evaluate to the the UNIX domain socket path -
"localhost" will be used instead.
Signed-off-by: Sebastian Harl <sh@tokkee.org>
Signed-off-by: Florian Forster <octo@huhu.verplant.org>
src/postgresql.c | patch | blob | history |
diff --git a/src/postgresql.c b/src/postgresql.c
index 5c5fbb38e0d26a21972e9152bc8f75588a5c1e08..d65a66fd04d0bd8e033c28486c08156588f07c8d 100644 (file)
--- a/src/postgresql.c
+++ b/src/postgresql.c
C_PSQL_IS_UNIX_DOMAIN_SOCKET (host) ? "/.s.PGSQL." : ":", \
port
+typedef enum {
+ C_PSQL_PARAM_HOST = 1,
+ C_PSQL_PARAM_DB,
+ C_PSQL_PARAM_USER,
+} c_psql_param_t;
+
typedef struct {
char *type;
char *type_instance;
char *name;
char *query;
+ c_psql_param_t *params;
+ int params_num;
+
c_psql_col_t *cols;
int cols_num;
} c_psql_query_t;
PGconn *conn;
c_complain_t conn_complaint;
+ int max_params_num;
+
/* user configuration */
c_psql_query_t **queries;
int queries_num;
query->name = sstrdup (name);
query->query = NULL;
+ query->params = NULL;
+ query->params_num = 0;
+
query->cols = NULL;
query->cols_num = 0;
return query;
sfree (query->name);
sfree (query->query);
+ sfree (query->params);
+ query->params_num = 0;
+
for (i = 0; i < query->cols_num; ++i) {
sfree (query->cols[i].type);
sfree (query->cols[i].type_instance);
db->conn_complaint.last = 0;
db->conn_complaint.interval = 0;
+ db->max_params_num = 0;
+
db->queries = NULL;
db->queries_num = 0;
c_psql_query_t *query;
PGresult *res;
+ char *params[db->max_params_num];
+
int rows, cols;
int i;
query = db->queries[idx];
- res = PQexec (db->conn, query->query);
+ assert (db->max_params_num >= query->params_num);
+
+ for (i = 0; i < query->params_num; ++i) {
+ switch (query->params[i]) {
+ case C_PSQL_PARAM_HOST:
+ params[i] = (NULL == db->host) ? "localhost" : db->host;
+ break;
+ case C_PSQL_PARAM_DB:
+ params[i] = db->database;
+ break;
+ case C_PSQL_PARAM_USER:
+ params[i] = db->user;
+ break;
+ default:
+ assert (0);
+ }
+ }
+
+ res = PQexecParams (db->conn, query->query, query->params_num, NULL,
+ (const char *const *)((0 == query->params_num) ? NULL : params),
+ NULL, NULL, /* return text data */ 0);
if (PGRES_TUPLES_OK != PQresultStatus (res)) {
log_err ("Failed to execute SQL query: %s",
return 0;
} /* config_set */
+static int config_set_param (c_psql_query_t *query, const oconfig_item_t *ci)
+{
+ c_psql_param_t param;
+ char *param_str;
+
+ if ((0 != ci->children_num) || (1 != ci->values_num)
+ || (OCONFIG_TYPE_STRING != ci->values[0].type)) {
+ log_err ("Param expects a single string argument.");
+ return 1;
+ }
+
+ param_str = ci->values[0].value.string;
+ if (0 == strcasecmp (param_str, "hostname"))
+ param = C_PSQL_PARAM_HOST;
+ else if (0 == strcasecmp (param_str, "database"))
+ param = C_PSQL_PARAM_DB;
+ else if (0 == strcasecmp (param_str, "username"))
+ param = C_PSQL_PARAM_USER;
+ else {
+ log_err ("Invalid parameter \"%s\".", param_str);
+ return 1;
+ }
+
+ ++query->params_num;
+ if (NULL == (query->params = (c_psql_param_t *)realloc (query->params,
+ query->params_num * sizeof (*query->params)))) {
+ log_err ("Out of memory.");
+ exit (5);
+ }
+
+ query->params[query->params_num - 1] = param;
+ return 0;
+} /* config_set_param */
+
static int config_set_column (c_psql_query_t *query, const oconfig_item_t *ci)
{
c_psql_col_t *col;
exit (5);
}
+ if (query->params_num > db->max_params_num)
+ db->max_params_num = query->params_num;
+
db->queries[db->queries_num - 1] = query;
return 0;
} /* config_set_query */
if (0 == strcasecmp (c->key, "Query"))
config_set ("Query", &query->query, c);
+ else if (0 == strcasecmp (c->key, "Param"))
+ config_set_param (query, c);
else if (0 == strcasecmp (c->key, "Column"))
config_set_column (query, c);
else