-static void submit (const c_psql_database_t *db, const c_psql_result_t *res,
- char **instances, value_t *values)
-{
- value_list_t vl = VALUE_LIST_INIT;
-
- int instances_num = res->instances_num;
-
- if (NULL != res->instance_prefix)
- ++instances_num;
-
- vl.values = values;
- vl.values_len = res->values_num;
-
- if (C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host)
- || (0 == strcmp (db->host, "localhost")))
- sstrncpy (vl.host, hostname_g, sizeof (vl.host));
- else
- sstrncpy (vl.host, db->host, sizeof (vl.host));
-
- sstrncpy (vl.plugin, "postgresql", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, db->database, sizeof (vl.plugin_instance));
-
- sstrncpy (vl.type, res->type, sizeof (vl.type));
-
- if (0 < instances_num) {
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
- strjoin (vl.type_instance, sizeof (vl.type_instance),
- instances, instances_num, "-");
-
- if ('\0' != vl.type_instance[sizeof (vl.type_instance) - 1]) {
- vl.type_instance[sizeof (vl.type_instance) - 1] = '\0';
- log_warn ("Truncated type instance: %s.", vl.type_instance);
- }
- }
-
- plugin_dispatch_values (&vl);
- return;
-} /* submit */
-
-static int c_psql_get_colnum (PGresult *pgres,
- char **strings, int *numbers, int idx)
-{
- int colnum;
-
- if (0 <= numbers[idx])
- return numbers[idx];
-
- colnum = PQfnumber (pgres, strings[idx]);
- if (0 > colnum)
- log_err ("No such column: %s.", strings[idx]);
-
- numbers[idx] = colnum;
- return colnum;
-} /* c_psql_get_colnum */
-
-static void c_psql_dispatch_row (c_psql_database_t *db, c_psql_query_t *query,
- PGresult *pgres, int row)
-{
- int i;
-
- for (i = 0; i < query->results_num; ++i) {
- c_psql_result_t *res = query->results + i;
-
- char *instances[res->instances_num + 1];
- value_t values[res->values_num];
-
- int offset = 0, status = 0, j;
-
- /* get the instance name */
- if (NULL != res->instance_prefix) {
- instances[0] = res->instance_prefix;
- offset = 1;
- }
-
- for (j = 0; (0 == status) && (j < res->instances_num); ++j) {
- int col = c_psql_get_colnum (pgres,
- res->instances_str, res->instances, j);
-
- if (0 > col) {
- status = -1;
- break;
- }
-
- instances[j + offset] = PQgetvalue (pgres, row, col);
- if (NULL == instances[j + offset])
- instances[j + offset] = "";
- }
-
- /* get the values */
- for (j = 0; (0 == status) && (j < res->values_num); ++j) {
- int col = c_psql_get_colnum (pgres,
- res->values_str, res->values, j);
-
- char *value_str;
- char *endptr = NULL;
-
- if (0 > col) {
- status = -1;
- break;
- }
-
- value_str = PQgetvalue (pgres, row, col);
- if ((NULL == value_str) || ('\0' == *value_str))
- value_str = "0";
-
- if (res->ds_types[j] == DS_TYPE_COUNTER)
- values[j].counter = (counter_t)strtoll (value_str, &endptr, 0);
- else if (res->ds_types[j] == DS_TYPE_GAUGE)
- values[j].gauge = (gauge_t)strtod (value_str, &endptr);
- else {
- log_err ("Invalid type \"%s\" (%i).",
- res->type, res->ds_types[j]);
- }
-
- if (value_str == endptr) {
- log_err ("Failed to parse string as number: %s.", value_str);
- status = -1;
- break;
- }
- else if ((NULL != endptr) && ('\0' != *endptr))
- log_warn ("Ignoring trailing garbage after number: %s.",
- endptr);
- }
-
- if (0 != status)
- continue;
-
- submit (db, res, instances, values);
- }
-} /* c_psql_dispatch_row */
-