/* * PostgreSQL plugin. * $Id$ */ #define IN_PLUGIN #include "../../echoping.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef POSTGRESQL_PREFIX #include #else #include #endif const char *request = NULL; int readall = FALSE; int connect_each_time = FALSE; poptContext postgresql_poptcon; PGconn *conn; PGresult *res; char *conninfo; echoping_options global_options; void postgresql_usage (const char *msg) { if (msg) { printf ("PostgreSQL plugin error: %s\n", msg); } poptPrintUsage (postgresql_poptcon, stdout, 0); fprintf (stderr, " [SQL-request]\n"); exit (1); } char * init (const int argc, const char **argv, const echoping_options global_external_options) { int value; char *msg = malloc (256); char *rest; /* popt variables */ struct poptOption options[] = { {"conninfo", 'c', POPT_ARG_STRING, &conninfo, 0, "Connection information for the Postgresql server. Something like 'host=foo dbname=bar''", ""}, {"readall", 'a', POPT_ARG_NONE, &readall, 0, "Read all the data sent by the Postgresql server", ""}, {"connect-each-time", 'e', POPT_ARG_NONE, &connect_each_time, 0, "(Re)Connect to the Postgresql server at each iteration", ""}, POPT_AUTOHELP POPT_TABLEEND }; global_options = global_external_options; if (global_options.udp) err_quit ("UDP makes no sense for a PostgreSQL connection"); postgresql_poptcon = poptGetContext (NULL, argc, argv, options, POPT_CONTEXT_POSIXMEHARDER); while ((value = poptGetNextOpt (postgresql_poptcon)) > 0) { } if (value < -1) { sprintf (msg, "%s: %s", poptBadOption (postgresql_poptcon, POPT_BADOPTION_NOALIAS), poptStrerror (value)); postgresql_usage (msg); } request = poptGetArg (postgresql_poptcon); if (request == NULL) request = "SELECT now()"; rest = poptGetArg (postgresql_poptcon); if (rest != NULL) postgresql_usage ("Erroneous additional arguments"); if (conninfo == NULL) conninfo = ""; return NULL; /* We only use the conninfo, echoping does not see our hostname or port */ } void start_raw () { if (!connect_each_time) { conn = PQconnectdb (conninfo); if (conn == NULL) { err_quit ("Cannot create connection\n"); } if (PQstatus (conn) == CONNECTION_BAD) { err_quit ("Connection failed: %s\n", PQerrorMessage (conn)); } } } int execute () { unsigned int row, column; char *result; if (connect_each_time) { conn = PQconnectdb (conninfo); if (conn == NULL) { err_ret ("Cannot create connection\n"); return -1; } if (PQstatus (conn) == CONNECTION_BAD) { err_ret ("Connection failed: %s\n", PQerrorMessage (conn)); return -1; } } res = PQexec (conn, request); if (PQresultStatus (res) != PGRES_TUPLES_OK) { err_ret ("Cannot run \"%s\": %s\n", request, PQresultErrorMessage (res)); return -1; } if (global_options.verbose) printf ("%d tuples returned\n", PQntuples (res)); if (readall) { for (row = 0; row < PQntuples (res); row++) { for (column = 0; column < PQnfields (res); column++) { result = PQgetvalue (res, row, column); if (result == NULL) { err_ret ("Cannot retrieve value [%d,%d]\n", row, column); return -1; } /* else { printf ("DEBUG: [%d,%d] %s\n", row, column, result); } */ } } } if (connect_each_time) PQfinish (conn); return 0; } void terminate () { if (!connect_each_time) PQfinish (conn); }