X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fpostgresql.c;h=dd53cb4fd2b018fd11dd18a8d1c5788b7cc95a04;hb=ba9b76d4be49c6a45b32a508c48e828a583b6dfc;hp=9e916596e9fc2dc366f23965e35ca516cc326c2b;hpb=5f73b7200633f3e72d1169d6f3f33e2ed8e1188f;p=collectd.git diff --git a/src/postgresql.c b/src/postgresql.c index 9e916596..dd53cb4f 100644 --- a/src/postgresql.c +++ b/src/postgresql.c @@ -2,19 +2,30 @@ * collectd - src/postgresql.c * Copyright (C) 2008, 2009 Sebastian Harl * Copyright (C) 2009 Florian Forster + * All rights reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * * Authors: * Sebastian Harl @@ -102,6 +113,7 @@ typedef struct { int max_params_num; /* user configuration */ + udb_query_preparation_area_t **q_prep_areas; udb_query_t **queries; size_t queries_num; @@ -141,7 +153,7 @@ static c_psql_database_t *c_psql_database_new (const char *name) db = (c_psql_database_t *)malloc (sizeof (*db)); if (NULL == db) { log_err ("Out of memory."); - exit (5); + return NULL; } db->conn = NULL; @@ -153,6 +165,7 @@ static c_psql_database_t *c_psql_database_new (const char *name) db->max_params_num = 0; + db->q_prep_areas = NULL; db->queries = NULL; db->queries_num = 0; @@ -174,11 +187,18 @@ static c_psql_database_t *c_psql_database_new (const char *name) static void c_psql_database_delete (void *data) { + size_t i; + c_psql_database_t *db = data; PQfinish (db->conn); db->conn = NULL; + if (db->q_prep_areas) + for (i = 0; i < db->queries_num; ++i) + udb_query_delete_preparation_area (db->q_prep_areas[i]); + free (db->q_prep_areas); + sfree (db->queries); db->queries_num = 0; @@ -330,7 +350,8 @@ static PGresult *c_psql_exec_query_params (c_psql_database_t *db, NULL, NULL, /* return text data */ 0); } /* c_psql_exec_query_params */ -static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q) +static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q, + udb_query_preparation_area_t *prep_area) { PGresult *res; @@ -413,8 +434,8 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q) else host = db->host; - status = udb_query_prepare_result (q, host, "postgresql", - db->database, column_names, (size_t) column_num); + status = udb_query_prepare_result (q, prep_area, host, "postgresql", + db->database, column_names, (size_t) column_num, db->interval); if (0 != status) { log_err ("udb_query_prepare_result failed with status %i.", status); @@ -437,13 +458,15 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q) if (col < column_num) continue; - status = udb_query_handle_result (q, column_values); + 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 */ @@ -451,6 +474,8 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q) static int c_psql_read (user_data_t *ud) { c_psql_database_t *db; + + int success = 0; int i; if ((ud == NULL) || (ud->data == NULL)) { @@ -467,16 +492,22 @@ static int c_psql_read (user_data_t *ud) for (i = 0; i < db->queries_num; ++i) { + udb_query_preparation_area_t *prep_area; udb_query_t *q; + prep_area = db->q_prep_areas[i]; q = db->queries[i]; if ((0 != db->server_version) && (udb_query_check_version (q, db->server_version) <= 0)) continue; - c_psql_exec_query (db, q); + if (0 == c_psql_exec_query (db, q, prep_area)) + success = 1; } + + if (! success) + return -1; return 0; } /* c_psql_read */ @@ -601,6 +632,8 @@ static int c_psql_config_database (oconfig_item_t *ci) memset (&ud, 0, sizeof (ud)); db = c_psql_database_new (ci->values[0].value.string); + if (db == NULL) + return -1; for (i = 0; i < ci->children_num; ++i) { oconfig_item_t *c = ci->children + i; @@ -629,19 +662,38 @@ static int c_psql_config_database (oconfig_item_t *ci) } /* If no `Query' options were given, add the default queries.. */ - if (db->queries_num == 0) - { + if (db->queries_num == 0) { for (i = 0; i < def_queries_num; i++) udb_query_pick_from_list_by_name (def_queries[i], queries, queries_num, &db->queries, &db->queries_num); } + if (db->queries_num > 0) { + db->q_prep_areas = (udb_query_preparation_area_t **) calloc ( + db->queries_num, sizeof (*db->q_prep_areas)); + + if (db->q_prep_areas == NULL) { + log_err ("Out of memory."); + c_psql_database_delete (db); + return -1; + } + } + for (i = 0; (size_t)i < db->queries_num; ++i) { c_psql_user_data_t *data; data = udb_query_get_user_data (db->queries[i]); if ((data != NULL) && (data->params_num > db->max_params_num)) db->max_params_num = data->params_num; + + db->q_prep_areas[i] + = udb_query_allocate_preparation_area (db->queries[i]); + + if (db->q_prep_areas[i] == NULL) { + log_err ("Out of memory."); + c_psql_database_delete (db); + return -1; + } } ud.data = db;