Esempio n. 1
0
int udb_query_prepare_result (udb_query_t *q, /* {{{ */
    const char *host, const char *plugin, const char *db_name,
    char **column_names, size_t column_num)
{
  udb_result_t *r;
  int status;

  if (q == NULL)
    return (-EINVAL);

  udb_query_finish_result (q);

  q->column_num = column_num;
  q->host = strdup (host);
  q->plugin = strdup (plugin);
  q->db_name = strdup (db_name);

  if ((q->host == NULL) || (q->plugin == NULL) || (q->db_name == NULL))
  {
    ERROR ("db query utils: Query `%s': Prepare failed: Out of memory.", q->name);
    udb_query_finish_result (q);
    return (-ENOMEM);
  }

#if defined(COLLECT_DEBUG) && COLLECT_DEBUG
  do
  {
    size_t i;

    for (i = 0; i < column_num; i++)
    {
      DEBUG ("db query utils: udb_query_prepare_result: "
          "query = %s; column[%zu] = %s;",
          q->name, i, column_names[i]);
    }
  } while (0);
#endif

  for (r = q->results; r != NULL; r = r->next)
  {
    status = udb_result_prepare_result (r, column_names, column_num);
    if (status != 0)
    {
      udb_query_finish_result (q);
      return (status);
    }
  }

  return (0);
} /* }}} int udb_query_prepare_result */
Esempio n. 2
0
static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q,
		udb_query_preparation_area_t *prep_area)
{
	PGresult *res;

	c_psql_user_data_t *data;

	const char *host;

	char **column_names;
	char **column_values;
	int    column_num;

	int rows_num;
	int status;
	int row, col;

	/* The user data may hold parameter information, but may be NULL. */
	data = udb_query_get_user_data (q);

	/* Versions up to `3' don't know how to handle parameters. */
	if (3 <= db->proto_version)
		res = c_psql_exec_query_params (db, q, data);
	else if ((NULL == data) || (0 == data->params_num))
		res = c_psql_exec_query_noparams (db, q);
	else {
		log_err ("Connection to database \"%s\" (%s) does not support "
				"parameters (protocol version %d) - "
				"cannot execute query \"%s\".",
				db->database, db->instance, db->proto_version,
				udb_query_get_name (q));
		return -1;
	}

	column_names = NULL;
	column_values = NULL;

#define BAIL_OUT(status) \
	sfree (column_names); \
	sfree (column_values); \
	PQclear (res); \
	return status

	if (PGRES_TUPLES_OK != PQresultStatus (res)) {
		log_err ("Failed to execute SQL query: %s",
				PQerrorMessage (db->conn));
		log_info ("SQL query was: %s",
				udb_query_get_statement (q));
		BAIL_OUT (-1);
	}

	rows_num = PQntuples (res);
	if (1 > rows_num) {
		BAIL_OUT (0);
	}

	column_num = PQnfields (res);
	column_names = (char **) calloc (column_num, sizeof (char *));
	if (NULL == column_names) {
		log_err ("calloc failed.");
		BAIL_OUT (-1);
	}

	column_values = (char **) calloc (column_num, sizeof (char *));
	if (NULL == column_values) {
		log_err ("calloc failed.");
		BAIL_OUT (-1);
	}
	
	for (col = 0; col < column_num; ++col) {
		/* Pointers returned by `PQfname' are freed by `PQclear' via
		 * `BAIL_OUT'. */
		column_names[col] = PQfname (res, col);
		if (NULL == column_names[col]) {
			log_err ("Failed to resolve name of column %i.", col);
			BAIL_OUT (-1);
		}
	}

	if (C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host)
			|| (0 == strcmp (db->host, "localhost")))
		host = hostname_g;
	else
		host = db->host;

	status = udb_query_prepare_result (q, prep_area, host, "postgresql",
			db->instance, column_names, (size_t) column_num, db->interval);
	if (0 != status) {
		log_err ("udb_query_prepare_result failed with status %i.",
				status);
		BAIL_OUT (-1);
	}

	for (row = 0; row < rows_num; ++row) {
		for (col = 0; col < column_num; ++col) {
			/* Pointers returned by `PQgetvalue' are freed by `PQclear' via
			 * `BAIL_OUT'. */
			column_values[col] = PQgetvalue (res, row, col);
			if (NULL == column_values[col]) {
				log_err ("Failed to get value at (row = %i, col = %i).",
						row, col);
				break;
			}
		}

		/* check for an error */
		if (col < column_num)
			continue;

		status = udb_query_handle_result (q, prep_area, column_values);
		if (status != 0) {
			log_err ("udb_query_handle_result failed with status %i.",
					status);
		}
	} /* for (row = 0; row < rows_num; ++row) */

	udb_query_finish_result (q, prep_area);

	BAIL_OUT (0);
#undef BAIL_OUT
} /* c_psql_exec_query */
Esempio n. 3
0
static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
    udb_query_t *q, udb_query_preparation_area_t *prep_area)
{
  const char *statement;
  dbi_result res;
  size_t column_num;
  char **column_names;
  char **column_values;
  int status;
  size_t i;

  /* Macro that cleans up dynamically allocated memory and returns the
   * specified status. */
#define BAIL_OUT(status) \
  if (column_names != NULL) { sfree (column_names[0]); sfree (column_names); } \
  if (column_values != NULL) { sfree (column_values[0]); sfree (column_values); } \
  if (res != NULL) { dbi_result_free (res); res = NULL; } \
  return (status)

  column_names = NULL;
  column_values = NULL;

  statement = udb_query_get_statement (q);
  assert (statement != NULL);

  res = dbi_conn_query (db->connection, statement);
  if (res == NULL)
  {
    char errbuf[1024];
    ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
        "dbi_conn_query failed: %s",
        db->name, udb_query_get_name (q),
        cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
    BAIL_OUT (-1);
  }
  else /* Get the number of columns */
  {
    unsigned int db_status;

    db_status = dbi_result_get_numfields (res);
    if (db_status == DBI_FIELD_ERROR)
    {
      char errbuf[1024];
      ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
          "dbi_result_get_numfields failed: %s",
          db->name, udb_query_get_name (q),
          cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
      BAIL_OUT (-1);
    }

    column_num = (size_t) db_status;
    DEBUG ("cdbi_read_database_query (%s, %s): There are %zu columns.",
        db->name, udb_query_get_name (q), column_num);
  }

  /* Allocate `column_names' and `column_values'. {{{ */
  column_names = calloc (column_num, sizeof (*column_names));
  if (column_names == NULL)
  {
    ERROR ("dbi plugin: calloc failed.");
    BAIL_OUT (-1);
  }

  column_names[0] = calloc (column_num, DATA_MAX_NAME_LEN);
  if (column_names[0] == NULL)
  {
    ERROR ("dbi plugin: calloc failed.");
    BAIL_OUT (-1);
  }
  for (i = 1; i < column_num; i++)
    column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;

  column_values = calloc (column_num, sizeof (*column_values));
  if (column_values == NULL)
  {
    ERROR ("dbi plugin: calloc failed.");
    BAIL_OUT (-1);
  }

  column_values[0] = calloc (column_num, DATA_MAX_NAME_LEN);
  if (column_values[0] == NULL)
  {
    ERROR ("dbi plugin: calloc failed.");
    BAIL_OUT (-1);
  }
  for (i = 1; i < column_num; i++)
    column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;
  /* }}} */

  /* Copy the field names to `column_names' */
  for (i = 0; i < column_num; i++) /* {{{ */
  {
    const char *column_name;

    column_name = dbi_result_get_field_name (res, (unsigned int) (i + 1));
    if (column_name == NULL)
    {
      ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
          "Cannot retrieve name of field %zu.",
          db->name, udb_query_get_name (q), i + 1);
      BAIL_OUT (-1);
    }

    sstrncpy (column_names[i], column_name, DATA_MAX_NAME_LEN);
  } /* }}} for (i = 0; i < column_num; i++) */

  udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g),
      /* plugin = */ "dbi", db->name,
      column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0);

  /* 0 = error; 1 = success; */
  status = dbi_result_first_row (res); /* {{{ */
  if (status != 1)
  {
    char errbuf[1024];
    ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
        "dbi_result_first_row failed: %s. Maybe the statement didn't "
        "return any rows?",
        db->name, udb_query_get_name (q),
        cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
    udb_query_finish_result (q, prep_area);
    BAIL_OUT (-1);
  } /* }}} */

  /* Iterate over all rows and call `udb_query_handle_result' with each list of
   * values. */
  while (42) /* {{{ */
  {
    status = 0;
    /* Copy the value of the columns to `column_values' */
    for (i = 0; i < column_num; i++) /* {{{ */
    {
      status = cdbi_result_get_field (res, (unsigned int) (i + 1),
          column_values[i], DATA_MAX_NAME_LEN);

      if (status != 0)
      {
        ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
            "cdbi_result_get_field (%zu) failed.",
            db->name, udb_query_get_name (q), i + 1);
        status = -1;
        break;
      }
    } /* }}} for (i = 0; i < column_num; i++) */

    /* If all values were copied successfully, call `udb_query_handle_result'
     * to dispatch the row to the daemon. */
    if (status == 0) /* {{{ */
    {
      status = udb_query_handle_result (q, prep_area, column_values);
      if (status != 0)
      {
        ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
            "udb_query_handle_result failed.",
            db->name, udb_query_get_name (q));
      }
    } /* }}} */

    /* Get the next row from the database. */
    status = dbi_result_next_row (res); /* {{{ */
    if (status != 1)
    {
      if (dbi_conn_error (db->connection, NULL) != 0)
      {
        char errbuf[1024];
        WARNING ("dbi plugin: cdbi_read_database_query (%s, %s): "
            "dbi_result_next_row failed: %s.",
            db->name, udb_query_get_name (q),
            cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
      }
      break;
    } /* }}} */
  } /* }}} while (42) */

  /* Tell the db query interface that we're done with this query. */
  udb_query_finish_result (q, prep_area);

  /* Clean up and return `status = 0' (success) */
  BAIL_OUT (0);
#undef BAIL_OUT
} /* }}} int cdbi_read_database_query */
Esempio n. 4
0
int udb_query_prepare_result (udb_query_t const *q, /* {{{ */
    udb_query_preparation_area_t *prep_area,
    const char *host, const char *plugin, const char *db_name,
    char **column_names, size_t column_num, cdtime_t interval)
{
  udb_result_preparation_area_t *r_area;
  udb_result_t *r;
  int status;

  if ((q == NULL) || (prep_area == NULL))
    return (-EINVAL);

  udb_query_finish_result (q, prep_area);

  prep_area->column_num = column_num;
  prep_area->host = strdup (host);
  prep_area->plugin = strdup (plugin);
  prep_area->db_name = strdup (db_name);

  prep_area->interval = interval;

  if ((prep_area->host == NULL) || (prep_area->plugin == NULL)
      || (prep_area->db_name == NULL))
  {
    ERROR ("db query utils: Query `%s': Prepare failed: Out of memory.", q->name);
    udb_query_finish_result (q, prep_area);
    return (-ENOMEM);
  }

#if defined(COLLECT_DEBUG) && COLLECT_DEBUG
  do
  {
    size_t i;

    for (i = 0; i < column_num; i++)
    {
      DEBUG ("db query utils: udb_query_prepare_result: "
          "query = %s; column[%zu] = %s;",
          q->name, i, column_names[i]);
    }
  } while (0);
#endif

  /* Determine the position of the PluginInstance column {{{ */
  if (q->plugin_instance_from != NULL)
  {
    size_t i;

    for (i = 0; i < column_num; i++)
    {
      if (strcasecmp (q->plugin_instance_from, column_names[i]) == 0)
      {
        prep_area->plugin_instance_pos = i;
        break;
      }
    }

    if (i >= column_num)
    {
      ERROR ("db query utils: udb_query_prepare_result: "
          "Column `%s' from `PluginInstanceFrom' could not be found.",
          q->plugin_instance_from);
      udb_query_finish_result (q, prep_area);
      return (-ENOENT);
    }
  }
  /* }}} */

  for (r = q->results, r_area = prep_area->result_prep_areas;
      r != NULL; r = r->next, r_area = r_area->next)
  {
    if (! r_area)
    {
      ERROR ("db query utils: Query `%s': Invalid number of result "
          "preparation areas.", q->name);
      udb_query_finish_result (q, prep_area);
      return (-EINVAL);
    }

    status = udb_result_prepare_result (r, r_area, column_names, column_num);
    if (status != 0)
    {
      udb_query_finish_result (q, prep_area);
      return (status);
    }
  }

  return (0);
} /* }}} int udb_query_prepare_result */
Esempio n. 5
0
int udb_query_prepare_result (const udb_query_t const *q, /* {{{ */
    udb_query_preparation_area_t *prep_area,
    const char *host, const char *plugin, const char *db_name,
    char **column_names, size_t column_num, int interval)
{
  udb_result_preparation_area_t *r_area;
  udb_result_t *r;
  int status;

  if ((q == NULL) || (prep_area == NULL))
    return (-EINVAL);

  udb_query_finish_result (q, prep_area);

  prep_area->column_num = column_num;
  prep_area->host = strdup (host);
  prep_area->plugin = strdup (plugin);
  prep_area->db_name = strdup (db_name);

  prep_area->interval = interval;

  if ((prep_area->host == NULL) || (prep_area->plugin == NULL)
      || (prep_area->db_name == NULL))
  {
    ERROR ("db query utils: Query `%s': Prepare failed: Out of memory.", q->name);
    udb_query_finish_result (q, prep_area);
    return (-ENOMEM);
  }

#if defined(COLLECT_DEBUG) && COLLECT_DEBUG
  do
  {
    size_t i;

    for (i = 0; i < column_num; i++)
    {
      DEBUG ("db query utils: udb_query_prepare_result: "
          "query = %s; column[%zu] = %s;",
          q->name, i, column_names[i]);
    }
  } while (0);
#endif

  for (r = q->results, r_area = prep_area->result_prep_areas;
      r != NULL; r = r->next, r_area = r_area->next)
  {
    if (! r_area)
    {
      ERROR ("db query utils: Query `%s': Invalid number of result "
          "preparation areas.", q->name);
      udb_query_finish_result (q, prep_area);
      return (-EINVAL);
    }

    status = udb_result_prepare_result (r, r_area, column_names, column_num);
    if (status != 0)
    {
      udb_query_finish_result (q, prep_area);
      return (status);
    }
  }

  return (0);
} /* }}} int udb_query_prepare_result */