contrib/migrate-4-5.px: Add options parsing and help output.
[collectd.git] / src / oracle.c
index b008e5c..0356749 100644 (file)
@@ -62,6 +62,7 @@ struct o_database_s
   char *username;
   char *password;
 
+  udb_query_preparation_area_t **q_prep_areas;
   udb_query_t **queries;
   size_t        queries_num;
 
@@ -121,6 +122,8 @@ static void o_report_error (const char *where, /* {{{ */
 
 static void o_database_free (o_database_t *db) /* {{{ */
 {
+  size_t i;
+
   if (db == NULL)
     return;
 
@@ -130,6 +133,11 @@ static void o_database_free (o_database_t *db) /* {{{ */
   sfree (db->password);
   sfree (db->queries);
 
+  if (db->q_prep_areas != NULL)
+    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);
 } /* }}} void o_database_free */
 
@@ -256,6 +264,34 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
     break;
   } /* while (status == 0) */
 
+  while ((status == 0) && (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)
+    {
+      WARNING ("oracle plugin: malloc failed");
+      status = -1;
+      break;
+    }
+
+    for (i = 0; i < db->queries_num; ++i)
+    {
+      db->q_prep_areas[i]
+        = udb_query_allocate_preparation_area (db->queries[i]);
+
+      if (db->q_prep_areas[i] == NULL)
+      {
+        WARNING ("oracle plugin: udb_query_allocate_preparation_area failed");
+        status = -1;
+        break;
+      }
+    }
+
+    break;
+  }
+
   /* If all went well, add this query to the list of queries within the
    * database structure. */
   if (status == 0)
@@ -349,7 +385,7 @@ static int o_init (void) /* {{{ */
 } /* }}} int o_init */
 
 static int o_read_database_query (o_database_t *db, /* {{{ */
-    udb_query_t *q)
+    udb_query_t *q, udb_query_preparation_area_t *prep_area)
 {
   char **column_names;
   char **column_values;
@@ -497,7 +533,7 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
   for (i = 0; i < column_num; i++) /* {{{ */
   {
     char *column_name;
-    size_t column_name_length;
+    ub4 column_name_length;
     OCIParam *oci_param;
 
     oci_param = NULL;
@@ -533,8 +569,8 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
     column_names[i][column_name_length] = 0;
 
     DEBUG ("oracle plugin: o_read_database_query: column_names[%zu] = %s; "
-        "column_name_length = %zu;",
-        i, column_names[i], column_name_length);
+        "column_name_length = %"PRIu32";",
+        i, column_names[i], (uint32_t) column_name_length);
 
     status = OCIDefineByPos (oci_statement,
         &oci_defines[i], oci_error, (ub4) (i + 1),
@@ -548,8 +584,9 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
   } /* for (j = 1; j <= param_counter; j++) */
   /* }}} End of the ``define'' stuff. */
 
-  status = udb_query_prepare_result (q, hostname_g, /* plugin = */ "oracle",
-      db->name, column_names, column_num);
+  status = udb_query_prepare_result (q, prep_area, hostname_g,
+      /* plugin = */ "oracle", db->name, column_names, column_num,
+      /* interval = */ 0);
   if (status != 0)
   {
     ERROR ("oracle plugin: o_read_database_query (%s, %s): "
@@ -576,7 +613,7 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
       break;
     }
 
-    status = udb_query_handle_result (q, column_values);
+    status = udb_query_handle_result (q, prep_area, column_values);
     if (status != 0)
     {
       WARNING ("oracle plugin: o_read_database_query (%s, %s): "
@@ -598,6 +635,47 @@ static int o_read_database (o_database_t *db) /* {{{ */
   size_t i;
   int status;
 
+  if (db->oci_service_context != NULL)
+  {
+    OCIServer *server_handle;
+    ub4 connection_status;
+
+    server_handle = NULL;
+    status = OCIAttrGet ((void *) db->oci_service_context, OCI_HTYPE_SVCCTX, 
+        (void *) &server_handle, /* size pointer = */ NULL,
+        OCI_ATTR_SERVER, oci_error);
+    if (status != OCI_SUCCESS)
+    {
+      o_report_error ("o_read_database", "OCIAttrGet", oci_error);
+      return (-1);
+    }
+
+    if (server_handle == NULL)
+    {
+      connection_status = OCI_SERVER_NOT_CONNECTED;
+    }
+    else /* if (server_handle != NULL) */
+    {
+      connection_status = 0;
+      status = OCIAttrGet ((void *) server_handle, OCI_HTYPE_SERVER,
+          (void *) &connection_status, /* size pointer = */ NULL,
+          OCI_ATTR_SERVER_STATUS, oci_error);
+      if (status != OCI_SUCCESS)
+      {
+        o_report_error ("o_read_database", "OCIAttrGet", oci_error);
+        return (-1);
+      }
+    }
+
+    if (connection_status != OCI_SERVER_NORMAL)
+    {
+      INFO ("oracle plugin: Connection to %s lost. Trying to reconnect.",
+          db->name);
+      OCIHandleFree (db->oci_service_context, OCI_HTYPE_SVCCTX);
+      db->oci_service_context = NULL;
+    }
+  } /* if (db->oci_service_context != NULL) */
+
   if (db->oci_service_context == NULL)
   {
     status = OCILogon (oci_env, oci_error,
@@ -620,7 +698,7 @@ static int o_read_database (o_database_t *db) /* {{{ */
       db->connect_id, db->oci_service_context);
 
   for (i = 0; i < db->queries_num; i++)
-    o_read_database_query (db, db->queries[i]);
+    o_read_database_query (db, db->queries[i], db->q_prep_areas[i]);
 
   return (0);
 } /* }}} int o_read_database */