static int udb_result_create (const char *query_name, /* {{{ */
    udb_result_t **r_head, oconfig_item_t *ci)
{
  udb_result_t *r;
  int status;
  int i;

  if (ci->values_num != 0)
  {
    WARNING ("db query utils: The `Result' block doesn't accept "
        "any arguments. Ignoring %i argument%s.",
        ci->values_num, (ci->values_num == 1) ? "" : "s");
  }

  r = calloc (1, sizeof (*r));
  if (r == NULL)
  {
    ERROR ("db query utils: calloc failed.");
    return (-1);
  }
  r->type = NULL;
  r->instance_prefix = NULL;
  r->instances = NULL;
  r->values = NULL;
  r->metadata = NULL;
  r->next = NULL;

  /* Fill the `udb_result_t' structure.. */
  status = 0;
  for (i = 0; i < ci->children_num; i++)
  {
    oconfig_item_t *child = ci->children + i;

    if (strcasecmp ("Type", child->key) == 0)
      status = udb_config_set_string (&r->type, child);
    else if (strcasecmp ("InstancePrefix", child->key) == 0)
      status = udb_config_set_string (&r->instance_prefix, child);
    else if (strcasecmp ("InstancesFrom", child->key) == 0)
      status = udb_config_add_string (&r->instances, &r->instances_num, child);
    else if (strcasecmp ("ValuesFrom", child->key) == 0)
      status = udb_config_add_string (&r->values, &r->values_num, child);
    else if (strcasecmp ("MetadataFrom", child->key) == 0)
      status = udb_config_add_string (&r->metadata, &r->metadata_num, child);
    else
    {
      WARNING ("db query utils: Query `%s': Option `%s' not allowed here.",
          query_name, child->key);
      status = -1;
    }

    if (status != 0)
      break;
  }

  /* Check that all necessary options have been given. */
  while (status == 0)
  {
    if (r->type == NULL)
    {
      WARNING ("db query utils: `Type' not given for "
          "result in query `%s'", query_name);
      status = -1;
    }
    if (r->values == NULL)
    {
      WARNING ("db query utils: `ValuesFrom' not given for "
          "result in query `%s'", query_name);
      status = -1;
    }

    break;
  } /* while (status == 0) */

  if (status != 0)
  {
    udb_result_free (r);
    return (-1);
  }

  /* If all went well, add this result to the list of results. */
  if (*r_head == NULL)
  {
    *r_head = r;
  }
  else
  {
    udb_result_t *last;

    last = *r_head;
    while (last->next != NULL)
      last = last->next;

    last->next = r;
  }

  return (0);
} /* }}} int udb_result_create */
/*
 * Query public functions
 */
int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
    size_t *ret_query_list_len, oconfig_item_t *ci,
    udb_query_create_callback_t cb)
{
  udb_query_t **query_list;
  size_t        query_list_len;

  udb_query_t *q;
  int status;
  int i;

  if ((ret_query_list == NULL) || (ret_query_list_len == NULL))
    return (-EINVAL);
  query_list     = *ret_query_list;
  query_list_len = *ret_query_list_len;

  if ((ci->values_num != 1)
      || (ci->values[0].type != OCONFIG_TYPE_STRING))
  {
    WARNING ("db query utils: The `Query' block "
        "needs exactly one string argument.");
    return (-1);
  }

  q = calloc (1, sizeof (*q));
  if (q == NULL)
  {
    ERROR ("db query utils: calloc failed.");
    return (-1);
  }
  q->min_version = 0;
  q->max_version = UINT_MAX;
  q->statement = NULL;
  q->results = NULL;
  q->plugin_instance_from = NULL;

  status = udb_config_set_string (&q->name, ci);
  if (status != 0)
  {
    sfree (q);
    return (status);
  }

  /* Fill the `udb_query_t' structure.. */
  for (i = 0; i < ci->children_num; i++)
  {
    oconfig_item_t *child = ci->children + i;

    if (strcasecmp ("Statement", child->key) == 0)
      status = udb_config_set_string (&q->statement, child);
    else if (strcasecmp ("Result", child->key) == 0)
      status = udb_result_create (q->name, &q->results, child);
    else if (strcasecmp ("MinVersion", child->key) == 0)
      status = udb_config_set_uint (&q->min_version, child);
    else if (strcasecmp ("MaxVersion", child->key) == 0)
      status = udb_config_set_uint (&q->max_version, child);
    else if (strcasecmp ("PluginInstanceFrom", child->key) == 0)
      status = udb_config_set_string (&q->plugin_instance_from, child);

    /* Call custom callbacks */
    else if (cb != NULL)
    {
      status = (*cb) (q, child);
      if (status != 0)
      {
        WARNING ("db query utils: The configuration callback failed "
            "to handle `%s'.", child->key);
      }
    }
    else
    {
      WARNING ("db query utils: Query `%s': Option `%s' not allowed here.",
          q->name, child->key);
      status = -1;
    }

    if (status != 0)
      break;
  }

  /* Check that all necessary options have been given. */
  if (status == 0)
  {
    if (q->statement == NULL)
    {
      WARNING ("db query utils: Query `%s': No `Statement' given.", q->name);
      status = -1;
    }
    if (q->results == NULL)
    {
      WARNING ("db query utils: Query `%s': No (valid) `Result' block given.",
          q->name);
      status = -1;
    }
  } /* if (status == 0) */

  /* If all went well, add this query to the list of queries within the
   * database structure. */
  if (status == 0)
  {
    udb_query_t **temp;

    temp = realloc (query_list,
        sizeof (*query_list) * (query_list_len + 1));
    if (temp == NULL)
    {
      ERROR ("db query utils: realloc failed");
      status = -1;
    }
    else
    {
      query_list = temp;
      query_list[query_list_len] = q;
      query_list_len++;
    }
  }

  if (status != 0)
  {
    udb_query_free_one (q);
    return (-1);
  }

  *ret_query_list     = query_list;
  *ret_query_list_len = query_list_len;

  return (0);
} /* }}} int udb_query_create */
Exemple #3
0
/*
 * Query public functions
 */
int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
    size_t *ret_query_list_len, oconfig_item_t *ci,
    udb_query_create_callback_t cb, int legacy_mode)
{
  udb_query_t **query_list;
  size_t        query_list_len;

  udb_query_t *q;
  int status;
  int i;

  size_t legacy_position;

  if ((ret_query_list == NULL) || (ret_query_list_len == NULL))
    return (-EINVAL);
  query_list     = *ret_query_list;
  query_list_len = *ret_query_list_len;

  if ((ci->values_num != 1)
      || (ci->values[0].type != OCONFIG_TYPE_STRING))
  {
    WARNING ("db query utils: The `Query' block "
        "needs exactly one string argument.");
    return (-1);
  }

  q = (udb_query_t *) malloc (sizeof (*q));
  if (q == NULL)
  {
    ERROR ("db query utils: malloc failed.");
    return (-1);
  }
  memset (q, 0, sizeof (*q));
  q->legacy_mode = legacy_mode;
  q->min_version = 0;
  q->max_version = UINT_MAX;

  legacy_position = 0;

  status = udb_config_set_string (&q->name, ci);
  if (status != 0)
  {
    sfree (q);
    return (status);
  }

  /* Fill the `udb_query_t' structure.. */
  for (i = 0; i < ci->children_num; i++)
  {
    oconfig_item_t *child = ci->children + i;

    if (strcasecmp ("Statement", child->key) == 0)
      status = udb_config_set_string (&q->statement, child);
    else if (strcasecmp ("Result", child->key) == 0)
      status = udb_result_create (q->name, &q->results, child);
    else if (strcasecmp ("MinVersion", child->key) == 0)
      status = udb_config_set_uint (&q->min_version, child);
    else if (strcasecmp ("MaxVersion", child->key) == 0)
      status = udb_config_set_uint (&q->max_version, child);

    /* PostgreSQL compatibility code */
    else if ((strcasecmp ("Query", child->key) == 0)
        && (q->legacy_mode == 1))
    {
      WARNING ("db query utils: Query `%s': The `Query' option is "
          "deprecated. Please use `Statement' instead.",
          q->name);
      status = udb_config_set_string (&q->statement, child);
    }
    else if ((strcasecmp ("Column", child->key) == 0)
        && (q->legacy_mode == 1))
    {
      WARNING ("db query utils: Query `%s': The `Column' option is "
          "deprecated. Please use the new syntax instead.",
          q->name);
      status = udb_legacy_result_create (q->name, &q->results, child,
          legacy_position);
      legacy_position++;
    }
    else if ((strcasecmp ("MinPGVersion", child->key) == 0)
        && (q->legacy_mode == 1))
    {
      WARNING ("db query utils: Query `%s': The `MinPGVersion' option is "
          "deprecated. Please use `MinVersion' instead.",
          q->name);
      status = udb_config_set_uint (&q->min_version, child);
    }
    else if ((strcasecmp ("MaxPGVersion", child->key) == 0)
        && (q->legacy_mode == 1))
    {
      WARNING ("db query utils: Query `%s': The `MaxPGVersion' option is "
          "deprecated. Please use `MaxVersion' instead.",
          q->name);
      status = udb_config_set_uint (&q->max_version, child);
    }

    /* Call custom callbacks */
    else if (cb != NULL)
    {
      status = (*cb) (q, child);
      if (status != 0)
      {
        WARNING ("db query utils: The configuration callback failed "
            "to handle `%s'.", child->key);
      }
    }
    else
    {
      WARNING ("db query utils: Query `%s': Option `%s' not allowed here.",
          q->name, child->key);
      status = -1;
    }

    if (status != 0)
      break;
  }

  /* Check that all necessary options have been given. */
  if (status == 0)
  {
    if (q->statement == NULL)
    {
      WARNING ("db query utils: Query `%s': No `Statement' given.", q->name);
      status = -1;
    }
    if (q->results == NULL)
    {
      WARNING ("db query utils: Query `%s': No (valid) `Result' block given.",
          q->name);
      status = -1;
    }
  } /* if (status == 0) */

  /* If all went well, add this query to the list of queries within the
   * database structure. */
  if (status == 0)
  {
    udb_query_t **temp;

    temp = (udb_query_t **) realloc (query_list,
        sizeof (*query_list) * (query_list_len + 1));
    if (temp == NULL)
    {
      ERROR ("db query utils: realloc failed");
      status = -1;
    }
    else
    {
      query_list = temp;
      query_list[query_list_len] = q;
      query_list_len++;
    }
  }

  if (status != 0)
  {
    udb_query_free_one (q);
    return (-1);
  }

  *ret_query_list     = query_list;
  *ret_query_list_len = query_list_len;

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