]> granicus.if.org Git - icinga2/commitdiff
Implement PostgreSQL adapter for IDO.
authorGunnar Beutner <gunnar.beutner@netways.de>
Wed, 30 Oct 2013 14:32:33 +0000 (15:32 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Mon, 4 Nov 2013 15:05:24 +0000 (16:05 +0100)
Fixes #4777

components/CMakeLists.txt
components/db_ido_pgsql/CMakeLists.txt [new file with mode: 0644]
components/db_ido_pgsql/db_ido_pgsql-type.conf [new file with mode: 0644]
components/db_ido_pgsql/idopgsqlconnection.cpp [new file with mode: 0644]
components/db_ido_pgsql/idopgsqlconnection.h [new file with mode: 0644]
components/db_ido_pgsql/idopgsqlconnection.ti [new file with mode: 0644]
components/db_ido_pgsql/schema/pgsql.sql [new file with mode: 0644]
doc/4.3-object-types.md
lib/db_ido/dbconnection.cpp
lib/db_ido/dbquery.h

index ad78975c9b84e4ee902f4e16f08821debc7b2dfb..646172121bfcd2aaaaf69684154bbc69ed6f5c94 100644 (file)
@@ -2,6 +2,7 @@ add_subdirectory(checker)
 add_subdirectory(cluster)
 add_subdirectory(compat)
 add_subdirectory(db_ido_mysql)
+add_subdirectory(db_ido_pgsql)
 add_subdirectory(demo)
 add_subdirectory(livestatus)
 add_subdirectory(notification)
diff --git a/components/db_ido_pgsql/CMakeLists.txt b/components/db_ido_pgsql/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0adfc05
--- /dev/null
@@ -0,0 +1,40 @@
+# Icinga 2
+# Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/)
+#
+# 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; either version 2
+# of the License, or (at your option) any later version.
+#
+# 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.
+#
+# 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.
+
+find_package(PostgreSQL)
+
+if(PostgreSQL_FOUND)
+    mkclass_target(idopgsqlconnection.ti idopgsqlconnection.th)
+
+    mkembedconfig_target(db_ido_pgsql-type.conf db_ido_pgsql-type.cpp)
+
+    add_library(db_ido_pgsql SHARED idopgsqlconnection.cpp idopgsqlconnection.th db_ido_pgsql-type.cpp)
+
+    include_directories(${PostgreSQL_INCLUDE_DIR})
+    target_link_libraries(db_ido_pgsql ${Boost_LIBRARIES} ${PostgreSQL_LIBRARIES} base config icinga db_ido)
+
+    set_target_properties (
+      db_ido_pgsql PROPERTIES
+      INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
+    )
+
+    install(
+      TARGETS db_ido_pgsql
+      RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
+      LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
+    )
+endif()
diff --git a/components/db_ido_pgsql/db_ido_pgsql-type.conf b/components/db_ido_pgsql/db_ido_pgsql-type.conf
new file mode 100644 (file)
index 0000000..01a7a6b
--- /dev/null
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/)   *
+ *                                                                            *
+ * 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; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * 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.                               *
+ *                                                                            *
+ * 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.             *
+ ******************************************************************************/
+
+type IdoPgsqlConnection inherits DbConnection {
+       %attribute string "host",
+       %attribute number "port",
+
+       %attribute string "user",
+       %attribute string "password",
+
+       %attribute string "database",
+
+       %attribute string "instance_name",
+       %attribute string "instance_description"
+}
diff --git a/components/db_ido_pgsql/idopgsqlconnection.cpp b/components/db_ido_pgsql/idopgsqlconnection.cpp
new file mode 100644 (file)
index 0000000..6f318c0
--- /dev/null
@@ -0,0 +1,601 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/)   *
+ *                                                                            *
+ * 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; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * 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.                               *
+ *                                                                            *
+ * 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.             *
+ ******************************************************************************/
+
+#include "base/logger_fwd.h"
+#include "base/objectlock.h"
+#include "base/convert.h"
+#include "base/utility.h"
+#include "base/application.h"
+#include "base/dynamictype.h"
+#include "db_ido/dbtype.h"
+#include "db_ido/dbvalue.h"
+#include "db_ido_pgsql/idopgsqlconnection.h"
+#include <boost/exception/diagnostic_information.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/foreach.hpp>
+
+using namespace icinga;
+
+REGISTER_TYPE(IdoPgsqlConnection);
+
+#define SCHEMA_VERSION "1.10.0"
+
+void IdoPgsqlConnection::Start(void)
+{
+       DbConnection::Start();
+
+       m_Connection = NULL;
+
+       m_TxTimer = boost::make_shared<Timer>();
+       m_TxTimer->SetInterval(5);
+       m_TxTimer->OnTimerExpired.connect(boost::bind(&IdoPgsqlConnection::TxTimerHandler, this));
+       m_TxTimer->Start();
+
+       m_ReconnectTimer = boost::make_shared<Timer>();
+       m_ReconnectTimer->SetInterval(10);
+       m_ReconnectTimer->OnTimerExpired.connect(boost::bind(&IdoPgsqlConnection::ReconnectTimerHandler, this));
+       m_ReconnectTimer->Start();
+       m_ReconnectTimer->Reschedule(0);
+
+       ASSERT(PQisthreadsafe());
+}
+
+void IdoPgsqlConnection::Stop(void)
+{
+       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::Disconnect, this));
+       m_QueryQueue.Join();
+}
+
+void IdoPgsqlConnection::AssertOnWorkQueue(void)
+{
+       ASSERT(boost::this_thread::get_id() == m_QueryQueue.GetThreadId());
+}
+
+void IdoPgsqlConnection::Disconnect(void)
+{
+       AssertOnWorkQueue();
+
+       boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+       if (!m_Connection)
+               return;
+
+       Query("COMMIT");
+       PQfinish(m_Connection);
+
+       m_Connection = NULL;
+}
+
+void IdoPgsqlConnection::TxTimerHandler(void)
+{
+       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::NewTransaction, this));
+}
+
+void IdoPgsqlConnection::NewTransaction(void)
+{
+       boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+       if (!m_Connection)
+               return;
+
+       Query("COMMIT");
+       Query("BEGIN");
+}
+
+void IdoPgsqlConnection::ReconnectTimerHandler(void)
+{
+       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::Reconnect, this));
+}
+
+void IdoPgsqlConnection::Reconnect(void)
+{
+       AssertOnWorkQueue();
+
+       {
+               boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+               bool reconnect = false;
+
+               if (m_Connection) {
+                       /* Check if we're really still connected */
+                       try {
+                               Query("SELECT 1");
+                               return;
+                       } catch (const std::exception&) {
+                               PQfinish(m_Connection);
+                               m_Connection = NULL;
+                               reconnect = true;
+                       }
+               }
+
+               String ihost, iport, iuser, ipasswd, idb;
+               const char *host, *port, *user , *passwd, *db;
+
+               ihost = GetHost();
+               iport = GetPort();
+               iuser = GetUser();
+               ipasswd = GetPassword();
+               idb = GetDatabase();
+
+               host = (!ihost.IsEmpty()) ? ihost.CStr() : NULL;
+               port = (!iport.IsEmpty()) ? iport.CStr() : NULL;
+               user = (!iuser.IsEmpty()) ? iuser.CStr() : NULL;
+               passwd = (!ipasswd.IsEmpty()) ? ipasswd.CStr() : NULL;
+               db = (!idb.IsEmpty()) ? idb.CStr() : NULL;
+
+               m_Connection = PQsetdbLogin(host, port, NULL, NULL, db, user, passwd);
+
+               if (!m_Connection)
+                       return;
+
+               if (PQstatus(m_Connection) != CONNECTION_OK) {
+                       String message = PQerrorMessage(m_Connection);
+                       PQfinish(m_Connection);
+                       m_Connection = NULL;
+
+                       BOOST_THROW_EXCEPTION(std::runtime_error(message));
+               }
+
+               String dbVersionName = "idoutils";
+               Array::Ptr version_rows = Query("SELECT version FROM " + GetTablePrefix() + "dbversion WHERE name='" + Escape(dbVersionName) + "'");
+
+               if (version_rows->GetLength() == 0)
+                       BOOST_THROW_EXCEPTION(std::runtime_error("Schema does not provide any valid version! Verify your schema installation."));
+
+               Dictionary::Ptr version_row = version_rows->Get(0);
+               String version = version_row->Get("version");
+
+               if (Utility::CompareVersion(SCHEMA_VERSION, version) < 0) {
+                       BOOST_THROW_EXCEPTION(std::runtime_error("Schema version '" + version + "' does not match the required version '" +
+                          SCHEMA_VERSION + "'! Please check the upgrade documentation."));
+               }
+
+               String instanceName = GetInstanceName();
+
+               Array::Ptr rows = Query("SELECT instance_id FROM " + GetTablePrefix() + "instances WHERE instance_name = '" + Escape(instanceName) + "'");
+
+               if (rows->GetLength() == 0) {
+                       Query("INSERT INTO " + GetTablePrefix() + "instances (instance_name, instance_description) VALUES ('" + Escape(instanceName) + "', '" + Escape(GetInstanceDescription()) + "')");
+                       m_InstanceID = GetSequenceValue(GetTablePrefix() + "instances", "instance_id");
+               } else {
+                       Dictionary::Ptr row = rows->Get(0);
+                       m_InstanceID = DbReference(row->Get("instance_id"));
+               }
+
+               std::ostringstream msgbuf;
+               msgbuf << "pgSQL IDO instance id: " << static_cast<long>(m_InstanceID) << " (schema version: '" + version + "')";
+               Log(LogInformation, "db_ido_pgsql", msgbuf.str());
+
+               /* record connection */
+               Query("INSERT INTO " + GetTablePrefix() + "conninfo " +
+                   "(instance_id, connect_time, last_checkin_time, agent_name, agent_version, connect_type, data_start_time) VALUES ("
+                   + Convert::ToString(static_cast<long>(m_InstanceID)) + ", NOW(), NOW(), 'icinga2 db_ido_pgsql', '" + Escape(Application::GetVersion())
+                   + "', '" + (reconnect ? "RECONNECT" : "INITIAL") + "', NOW())");
+
+               /* clear config tables for the initial config dump */
+               ClearConfigTables();
+
+               Query("UPDATE " + GetTablePrefix() + "objects SET is_active = 0");
+
+               std::ostringstream q1buf;
+               q1buf << "SELECT object_id, objecttype_id, name1, name2 FROM " + GetTablePrefix() + "objects WHERE instance_id = " << static_cast<long>(m_InstanceID);
+               rows = Query(q1buf.str());
+
+               ObjectLock olock(rows);
+               BOOST_FOREACH(const Dictionary::Ptr& row, rows) {
+                       DbType::Ptr dbtype = DbType::GetByID(row->Get("objecttype_id"));
+
+                       if (!dbtype)
+                               continue;
+
+                       DbObject::Ptr dbobj = dbtype->GetOrCreateObjectByName(row->Get("name1"), row->Get("name2"));
+                       SetObjectID(dbobj, DbReference(row->Get("object_id")));
+               }
+
+               Query("BEGIN");
+       }
+
+       UpdateAllObjects();
+}
+
+void IdoPgsqlConnection::ClearConfigTables(void)
+{
+       /* TODO make hardcoded table names modular */
+       ClearConfigTable("commands");
+       ClearConfigTable("contact_addresses");
+       ClearConfigTable("contact_notificationcommands");
+       ClearConfigTable("contactgroup_members");
+       ClearConfigTable("contactgroups");
+       ClearConfigTable("contacts");
+       ClearConfigTable("customvariables");
+       ClearConfigTable("host_contactgroups");
+       ClearConfigTable("host_contacts");
+       ClearConfigTable("host_parenthosts");
+       ClearConfigTable("hostdependencies");
+       ClearConfigTable("hostgroup_members");
+       ClearConfigTable("hostgroups");
+       ClearConfigTable("hosts");
+       ClearConfigTable("service_contactgroups");
+       ClearConfigTable("service_contacts");
+       ClearConfigTable("servicedependencies");
+       ClearConfigTable("servicegroup_members");
+       ClearConfigTable("servicegroups");
+       ClearConfigTable("services");
+       ClearConfigTable("timeperiod_timeranges");
+       ClearConfigTable("timeperiods");
+}
+
+void IdoPgsqlConnection::ClearConfigTable(const String& table)
+{
+       Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " + Convert::ToString(static_cast<long>(m_InstanceID)));
+}
+
+Array::Ptr IdoPgsqlConnection::Query(const String& query)
+{
+       AssertOnWorkQueue();
+
+       Log(LogDebug, "db_ido_pgsql", "Query: " + query);
+
+       PGresult *result = PQexec(m_Connection, query.CStr());
+
+       if (!result)
+           BOOST_THROW_EXCEPTION(std::runtime_error("unknown error during pgSQL query"));
+
+       if (PQresultStatus(result) == PGRES_COMMAND_OK)
+               return Array::Ptr();
+
+       if (PQresultStatus(result) != PGRES_TUPLES_OK) {
+               String message = PQresultErrorMessage(result);
+               PQclear(result);
+
+               BOOST_THROW_EXCEPTION(std::runtime_error(message));
+       }
+
+       Array::Ptr rows = boost::make_shared<Array>();
+
+       int rownum = 0;
+
+       for (;;) {
+               Dictionary::Ptr row = FetchRow(result, rownum);
+
+               if (!row)
+                       break;
+
+               rows->Add(row);
+
+               rownum++;
+       }
+
+       PQclear(result);
+
+       return rows;
+}
+
+DbReference IdoPgsqlConnection::GetSequenceValue(const String& table, const String& column)
+{
+       AssertOnWorkQueue();
+
+       Array::Ptr rows = Query("SELECT CURRVAL(pg_get_serial_sequence('" + Escape(table) + "', '" + Escape(column) + "')) AS id");
+
+       ASSERT(rows->GetLength() == 1);
+
+       Dictionary::Ptr row = rows->Get(0);
+
+       return DbReference(Convert::ToLong(row->Get("id")));
+}
+
+String IdoPgsqlConnection::Escape(const String& s)
+{
+       AssertOnWorkQueue();
+
+       ssize_t length = s.GetLength();
+       char *to = new char[s.GetLength() * 2 + 1];
+
+       PQescapeStringConn(m_Connection, to, s.CStr(), length, NULL);
+
+       String result = String(to);
+
+       delete [] to;
+
+       return result;
+}
+
+Dictionary::Ptr IdoPgsqlConnection::FetchRow(PGresult *result, int row)
+{
+       AssertOnWorkQueue();
+
+       if (row >= PQntuples(result))
+               return Dictionary::Ptr();
+
+       int columns = PQnfields(result);
+
+       Dictionary::Ptr dict = boost::make_shared<Dictionary>();
+
+       for (int column = 0; column < columns; column++) {
+               Value value;
+
+               if (!PQgetisnull(result, row, column))
+                       value = PQgetvalue(result, row, column);
+
+               dict->Set(PQfname(result, column), value);
+       }
+
+       return dict;
+}
+
+void IdoPgsqlConnection::ActivateObject(const DbObject::Ptr& dbobj)
+{
+       boost::mutex::scoped_lock lock(m_ConnectionMutex);
+       InternalActivateObject(dbobj);
+}
+
+void IdoPgsqlConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
+{
+       if (!m_Connection)
+               return;
+
+       DbReference dbref = GetObjectID(dbobj);
+       std::ostringstream qbuf;
+
+       if (!dbref.IsValid()) {
+               qbuf << "INSERT INTO " + GetTablePrefix() + "objects (instance_id, objecttype_id, name1, name2, is_active) VALUES ("
+                     << static_cast<long>(m_InstanceID) << ", " << dbobj->GetType()->GetTypeID() << ", "
+                     << "'" << Escape(dbobj->GetName1()) << "', '" << Escape(dbobj->GetName2()) << "', 1)";
+               Query(qbuf.str());
+               SetObjectID(dbobj, GetSequenceValue(GetTablePrefix() + "objects", "object_id"));
+       } else {
+               qbuf << "UPDATE " + GetTablePrefix() + "objects SET is_active = 1 WHERE object_id = " << static_cast<long>(dbref);
+               Query(qbuf.str());
+       }
+}
+
+void IdoPgsqlConnection::DeactivateObject(const DbObject::Ptr& dbobj)
+{
+       boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+       if (!m_Connection)
+               return;
+
+       DbReference dbref = GetObjectID(dbobj);
+
+       if (!dbref.IsValid())
+               return;
+
+       std::ostringstream qbuf;
+       qbuf << "UPDATE " + GetTablePrefix() + "objects SET is_active = 0 WHERE object_id = " << static_cast<long>(dbref);
+       Query(qbuf.str());
+
+       /* Note that we're _NOT_ clearing the db refs via SetReference/SetConfigUpdate/SetStatusUpdate
+        * because the object is still in the database. */
+}
+
+/* caller must hold m_ConnectionMutex */
+bool IdoPgsqlConnection::FieldToEscapedString(const String& key, const Value& value, Value *result)
+{
+       if (key == "instance_id") {
+               *result = static_cast<long>(m_InstanceID);
+               return true;
+       }
+       if (key == "notification_id") {
+               *result = static_cast<long>(m_LastNotificationID);
+               return true;
+       }
+
+       Value rawvalue = DbValue::ExtractValue(value);
+
+       if (rawvalue.IsObjectType<DynamicObject>()) {
+               DbObject::Ptr dbobjcol = DbObject::GetOrCreateByObject(rawvalue);
+
+               if (!dbobjcol) {
+                       *result = 0;
+                       return true;
+               }
+
+               DbReference dbrefcol;
+
+               if (DbValue::IsObjectInsertID(value)) {
+                       dbrefcol = GetInsertID(dbobjcol);
+
+                       ASSERT(dbrefcol.IsValid());
+               } else {
+                       dbrefcol = GetObjectID(dbobjcol);
+
+                       if (!dbrefcol.IsValid()) {
+                               InternalActivateObject(dbobjcol);
+
+                               dbrefcol = GetObjectID(dbobjcol);
+
+                               if (!dbrefcol.IsValid())
+                                       return false;
+                       }
+               }
+
+               *result = static_cast<long>(dbrefcol);
+       } else if (DbValue::IsTimestamp(value)) {
+               long ts = rawvalue;
+               std::ostringstream msgbuf;
+               msgbuf << "TO_TIMESTAMP(" << ts << ")";
+               *result = Value(msgbuf.str());
+       } else if (DbValue::IsTimestampNow(value)) {
+               *result = "NOW()";
+       } else {
+               *result = "'" + Escape(rawvalue) + "'";
+       }
+
+       return true;
+}
+
+void IdoPgsqlConnection::ExecuteQuery(const DbQuery& query)
+{
+       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query));
+}
+
+void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query)
+{
+       boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+       ASSERT(query.Category != DbCatInvalid);
+
+       if ((query.Category & GetCategories()) == 0)
+               return;
+
+       if (!m_Connection)
+               return;
+
+       std::ostringstream qbuf, where;
+       int type;
+
+       if (query.WhereCriteria) {
+               where << " WHERE ";
+
+               ObjectLock olock(query.WhereCriteria);
+               String key;
+               Value value;
+               bool first = true;
+
+               BOOST_FOREACH(boost::tie(key, value), query.WhereCriteria) {
+                       if (!FieldToEscapedString(key, value, &value))
+                               return;
+
+                       if (!first)
+                               where << " AND ";
+
+                       where << key << " = " << value;
+
+                       if (first)
+                               first = false;
+               }
+       }
+
+       if ((query.Type & DbQueryInsert) && (query.Type & DbQueryUpdate)) {
+               bool hasid = false;
+
+               ASSERT(query.Object);
+
+               if (query.ConfigUpdate)
+                       hasid = GetConfigUpdate(query.Object);
+               else if (query.StatusUpdate)
+                       hasid = GetStatusUpdate(query.Object);
+               else
+                       ASSERT(!"Invalid query flags.");
+
+               if (hasid)
+                       type = DbQueryUpdate;
+               else {
+                       if (query.WhereCriteria)
+                               Query("DELETE FROM " + GetTablePrefix() + query.Table + where.str());
+
+                       type = DbQueryInsert;
+               }
+       } else
+               type = query.Type;
+
+       switch (type) {
+               case DbQueryInsert:
+                       qbuf << "INSERT INTO " << GetTablePrefix() << query.Table;
+                       break;
+               case DbQueryUpdate:
+                       qbuf << "UPDATE " << GetTablePrefix() << query.Table << " SET";
+                       break;
+               case DbQueryDelete:
+                       qbuf << "DELETE FROM " << GetTablePrefix() << query.Table;
+                       break;
+               default:
+                       ASSERT(!"Invalid query type.");
+       }
+
+       if (type == DbQueryInsert || type == DbQueryUpdate) {
+               String cols;
+               String values;
+
+               ObjectLock olock(query.Fields);
+
+               String key;
+               Value value;
+               bool first = true;
+               BOOST_FOREACH(boost::tie(key, value), query.Fields) {
+                       if (!FieldToEscapedString(key, value, &value))
+                               return;
+
+                       if (type == DbQueryInsert) {
+                               if (!first) {
+                                       cols += ", ";
+                                       values += ", ";
+                               }
+
+                               cols += key;
+                               values += Convert::ToString(value);
+                       } else {
+                               if (!first)
+                                       qbuf << ", ";
+
+                               qbuf << " " << key << " = " << value;
+                       }
+
+                       if (first)
+                               first = false;
+               }
+
+               if (type == DbQueryInsert)
+                       qbuf << " (" << cols << ") VALUES (" << values << ")";
+       }
+
+       if (type != DbQueryInsert)
+               qbuf << where.str();
+
+       Query(qbuf.str());
+
+       if (query.Object) {
+               if (query.ConfigUpdate)
+                       SetConfigUpdate(query.Object, true);
+               else if (query.StatusUpdate)
+                       SetStatusUpdate(query.Object, true);
+
+               if (type == DbQueryInsert && query.ConfigUpdate) {
+                       String idField = query.IdColumn;
+
+                       if (idField.IsEmpty())
+                               idField = query.Table.SubStr(0, query.Table.GetLength() - 1) + "_id";
+
+                       SetInsertID(query.Object, GetSequenceValue(GetTablePrefix() + query.Table, idField));
+               }
+       }
+       if (type == DbQueryInsert && query.Table == "notifications") { // FIXME remove hardcoded table name
+               m_LastNotificationID = GetSequenceValue(GetTablePrefix() + "notifications", "notification_id");
+               Log(LogDebug, "db_ido", "saving contactnotification notification_id=" + Convert::ToString(static_cast<long>(m_LastNotificationID)));
+       }
+}
+
+void IdoPgsqlConnection::CleanUpExecuteQuery(const String& table, const String& time_column, double max_age)
+{
+       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalCleanUpExecuteQuery, this, table, time_column, max_age));
+}
+
+void IdoPgsqlConnection::InternalCleanUpExecuteQuery(const String& table, const String& time_column, double max_age)
+{
+       boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+       if (!m_Connection)
+               return;
+
+       Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " +
+           Convert::ToString(static_cast<long>(m_InstanceID)) + " AND " + time_column +
+           " < TO_TIMESTAMP(" + Convert::ToString(static_cast<long>(max_age)) + ")");
+}
diff --git a/components/db_ido_pgsql/idopgsqlconnection.h b/components/db_ido_pgsql/idopgsqlconnection.h
new file mode 100644 (file)
index 0000000..61583ce
--- /dev/null
@@ -0,0 +1,91 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/)   *
+ *                                                                            *
+ * 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; either version 2             *
+ * of the License, or (at your option) any later version.                     *
+ *                                                                            *
+ * 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.                               *
+ *                                                                            *
+ * 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.             *
+ ******************************************************************************/
+
+#ifndef IDOPGSQLCONNECTION_H
+#define IDOPGSQLCONNECTION_H
+
+#include "db_ido_pgsql/idopgsqlconnection.th"
+#include "base/array.h"
+#include "base/timer.h"
+#include "base/workqueue.h"
+#include <postgresql/libpq-fe.h>
+
+namespace icinga
+{
+
+/**
+ * An IDO pgSQL database connection.
+ *
+ * @ingroup ido
+ */
+class IdoPgsqlConnection : public ReflectionObjectImpl<IdoPgsqlConnection>
+{
+public:
+       DECLARE_PTR_TYPEDEFS(IdoPgsqlConnection);
+
+       //virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
+
+protected:
+       virtual void Start(void);
+       virtual void Stop(void);
+
+       virtual void ActivateObject(const DbObject::Ptr& dbobj);
+       virtual void DeactivateObject(const DbObject::Ptr& dbobj);
+       virtual void ExecuteQuery(const DbQuery& query);
+        virtual void CleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
+
+private:
+       DbReference m_InstanceID;
+        DbReference m_LastNotificationID;
+
+       WorkQueue m_QueryQueue;
+
+       boost::mutex m_ConnectionMutex;
+       PGconn *m_Connection;
+
+       Timer::Ptr m_ReconnectTimer;
+       Timer::Ptr m_TxTimer;
+
+       Array::Ptr Query(const String& query);
+       DbReference GetSequenceValue(const String& table, const String& column);
+       String Escape(const String& s);
+       Dictionary::Ptr FetchRow(PGresult *result, int row);
+
+       bool FieldToEscapedString(const String& key, const Value& value, Value *result);
+       void InternalActivateObject(const DbObject::Ptr& dbobj);
+
+       void Disconnect(void);
+       void NewTransaction(void);
+       void Reconnect(void);
+
+       void AssertOnWorkQueue(void);
+
+       void TxTimerHandler(void);
+       void ReconnectTimerHandler(void);
+
+       void InternalExecuteQuery(const DbQuery& query);
+        void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
+
+       void ClearConfigTables(void);
+       void ClearConfigTable(const String& table);
+};
+
+}
+
+#endif /* IDOPGSQLCONNECTION_H */
diff --git a/components/db_ido_pgsql/idopgsqlconnection.ti b/components/db_ido_pgsql/idopgsqlconnection.ti
new file mode 100644 (file)
index 0000000..39f6009
--- /dev/null
@@ -0,0 +1,29 @@
+#include "db_ido/dbconnection.h"
+
+namespace icinga
+{
+
+class IdoPgsqlConnection : DbConnection
+{
+       [config] String host {
+               default {{{ return "localhost"; }}}
+       };
+       [config] String port {
+               default {{{ return "5432"; }}}
+       };
+       [config] String user {
+               default {{{ return "icinga"; }}}
+       };
+       [config] String password {
+               default {{{ return "icinga"; }}}
+       };
+       [config] String database {
+               default {{{ return "icinga"; }}}
+       };
+       [config] String instance_name {
+               default {{{ return "default"; }}}
+       };
+       [config] String instance_description;
+};
+
+}
diff --git a/components/db_ido_pgsql/schema/pgsql.sql b/components/db_ido_pgsql/schema/pgsql.sql
new file mode 100644 (file)
index 0000000..8d02a95
--- /dev/null
@@ -0,0 +1,1561 @@
+-- --------------------------------------------------------
+-- pgsql.sql
+-- DB definition for Postgresql
+--
+-- Copyright (c) 2009-2013 Icinga Development Team (http://www.icinga.org)
+--
+-- initial version: 2009-05-13 Markus Manzke
+-- current version: 2012-04-19 Michael Friedrich <michael.friedrich@univie.ac.at>
+--
+-- --------------------------------------------------------
+
+--
+-- Functions
+--
+
+CREATE OR REPLACE FUNCTION from_unixtime(bigint) RETURNS timestamp with time zone AS '
+         SELECT to_timestamp($1) AS result
+' LANGUAGE sql;
+
+CREATE OR REPLACE FUNCTION unix_timestamp(timestamp with time zone) RETURNS bigint AS '
+        SELECT EXTRACT(EPOCH FROM $1)::bigint AS result;
+' LANGUAGE sql;
+
+
+-- -----------------------------------------
+-- set dbversion
+-- -----------------------------------------
+
+CREATE OR REPLACE FUNCTION updatedbversion(version_i TEXT) RETURNS void AS $$
+BEGIN
+        IF EXISTS( SELECT * FROM icinga_dbversion WHERE name='idoutils')
+        THEN
+                UPDATE icinga_dbversion
+                SET version=version_i, modify_time=NOW()
+               WHERE name='idoutils';
+        ELSE
+                INSERT INTO icinga_dbversion (dbversion_id, name, version, create_time, modify_time) VALUES ('1', 'idoutils', version_i, NOW(), NOW());
+        END IF;
+
+        RETURN;
+END;
+$$ LANGUAGE plpgsql;
+-- HINT: su - postgres; createlang plpgsql icinga;
+
+
+
+--
+-- Database: icinga
+--
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_acknowledgements
+--
+
+CREATE TABLE  icinga_acknowledgements (
+  acknowledgement_id bigserial,
+  instance_id bigint default 0,
+  entry_time timestamp with time zone default '1970-01-01 00:00:00',
+  entry_time_usec INTEGER  default 0,
+  acknowledgement_type INTEGER  default 0,
+  object_id bigint default 0,
+  state INTEGER  default 0,
+  author_name TEXT  default '',
+  comment_data TEXT  default '',
+  is_sticky INTEGER  default 0,
+  persistent_comment INTEGER  default 0,
+  notify_contacts INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  CONSTRAINT PK_acknowledgement_id PRIMARY KEY (acknowledgement_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_commands
+--
+
+CREATE TABLE  icinga_commands (
+  command_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  object_id bigint default 0,
+  command_line TEXT  default '',
+  CONSTRAINT PK_command_id PRIMARY KEY (command_id) ,
+  CONSTRAINT UQ_commands UNIQUE (instance_id,object_id,config_type)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_commenthistory
+--
+
+CREATE TABLE  icinga_commenthistory (
+  commenthistory_id bigserial,
+  instance_id bigint default 0,
+  entry_time timestamp with time zone default '1970-01-01 00:00:00',
+  entry_time_usec INTEGER  default 0,
+  comment_type INTEGER  default 0,
+  entry_type INTEGER  default 0,
+  object_id bigint default 0,
+  comment_time timestamp with time zone default '1970-01-01 00:00:00',
+  internal_comment_id bigint default 0,
+  author_name TEXT  default '',
+  comment_data TEXT  default '',
+  is_persistent INTEGER  default 0,
+  comment_source INTEGER  default 0,
+  expires INTEGER  default 0,
+  expiration_time timestamp with time zone default '1970-01-01 00:00:00',
+  deletion_time timestamp with time zone default '1970-01-01 00:00:00',
+  deletion_time_usec INTEGER  default 0,
+  CONSTRAINT PK_commenthistory_id PRIMARY KEY (commenthistory_id) ,
+  CONSTRAINT UQ_commenthistory UNIQUE (instance_id,object_id,comment_time,internal_comment_id)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_comments
+--
+
+CREATE TABLE  icinga_comments (
+  comment_id bigserial,
+  instance_id bigint default 0,
+  entry_time timestamp with time zone default '1970-01-01 00:00:00',
+  entry_time_usec INTEGER  default 0,
+  comment_type INTEGER  default 0,
+  entry_type INTEGER  default 0,
+  object_id bigint default 0,
+  comment_time timestamp with time zone default '1970-01-01 00:00:00',
+  internal_comment_id bigint default 0,
+  author_name TEXT  default '',
+  comment_data TEXT  default '',
+  is_persistent INTEGER  default 0,
+  comment_source INTEGER  default 0,
+  expires INTEGER  default 0,
+  expiration_time timestamp with time zone default '1970-01-01 00:00:00',
+  CONSTRAINT PK_comment_id PRIMARY KEY (comment_id) ,
+  CONSTRAINT UQ_comments UNIQUE (instance_id,object_id,comment_time,internal_comment_id)
+)  ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_configfiles
+--
+
+CREATE TABLE  icinga_configfiles (
+  configfile_id bigserial,
+  instance_id bigint default 0,
+  configfile_type INTEGER  default 0,
+  configfile_path TEXT  default '',
+  CONSTRAINT PK_configfile_id PRIMARY KEY (configfile_id) ,
+  CONSTRAINT UQ_configfiles UNIQUE (instance_id,configfile_type,configfile_path)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_configfilevariables
+--
+
+CREATE TABLE  icinga_configfilevariables (
+  configfilevariable_id bigserial,
+  instance_id bigint default 0,
+  configfile_id bigint default 0,
+  varname TEXT  default '',
+  varvalue TEXT  default '',
+  CONSTRAINT PK_configfilevariable_id PRIMARY KEY (configfilevariable_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_conninfo
+--
+
+CREATE TABLE  icinga_conninfo (
+  conninfo_id bigserial,
+  instance_id bigint default 0,
+  agent_name TEXT  default '',
+  agent_version TEXT  default '',
+  disposition TEXT  default '',
+  connect_source TEXT  default '',
+  connect_type TEXT  default '',
+  connect_time timestamp with time zone default '1970-01-01 00:00:00',
+  disconnect_time timestamp with time zone default '1970-01-01 00:00:00',
+  last_checkin_time timestamp with time zone default '1970-01-01 00:00:00',
+  data_start_time timestamp with time zone default '1970-01-01 00:00:00',
+  data_end_time timestamp with time zone default '1970-01-01 00:00:00',
+  bytes_processed bigint  default 0,
+  lines_processed bigint  default 0,
+  entries_processed bigint  default 0,
+  CONSTRAINT PK_conninfo_id PRIMARY KEY (conninfo_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contactgroups
+--
+
+CREATE TABLE  icinga_contactgroups (
+  contactgroup_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  contactgroup_object_id bigint default 0,
+  alias TEXT  default '',
+  CONSTRAINT PK_contactgroup_id PRIMARY KEY (contactgroup_id) ,
+  CONSTRAINT UQ_contactgroups UNIQUE (instance_id,config_type,contactgroup_object_id)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contactgroup_members
+--
+
+CREATE TABLE  icinga_contactgroup_members (
+  contactgroup_member_id bigserial,
+  instance_id bigint default 0,
+  contactgroup_id bigint default 0,
+  contact_object_id bigint default 0,
+  CONSTRAINT PK_contactgroup_member_id PRIMARY KEY (contactgroup_member_id)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contactnotificationmethods
+--
+
+CREATE TABLE  icinga_contactnotificationmethods (
+  contactnotificationmethod_id bigserial,
+  instance_id bigint default 0,
+  contactnotification_id bigint default 0,
+  start_time timestamp with time zone default '1970-01-01 00:00:00',
+  start_time_usec INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  end_time_usec INTEGER  default 0,
+  command_object_id bigint default 0,
+  command_args TEXT  default '',
+  CONSTRAINT PK_contactnotificationmethod_id PRIMARY KEY (contactnotificationmethod_id) ,
+  CONSTRAINT UQ_contactnotificationmethods UNIQUE (instance_id,contactnotification_id,start_time,start_time_usec)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contactnotifications
+--
+
+CREATE TABLE  icinga_contactnotifications (
+  contactnotification_id bigserial,
+  instance_id bigint default 0,
+  notification_id bigint default 0,
+  contact_object_id bigint default 0,
+  start_time timestamp with time zone default '1970-01-01 00:00:00',
+  start_time_usec INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  end_time_usec INTEGER  default 0,
+  CONSTRAINT PK_contactnotification_id PRIMARY KEY (contactnotification_id) ,
+  CONSTRAINT UQ_contactnotifications UNIQUE (instance_id,contact_object_id,start_time,start_time_usec)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contacts
+--
+
+CREATE TABLE  icinga_contacts (
+  contact_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  contact_object_id bigint default 0,
+  alias TEXT  default '',
+  email_address TEXT  default '',
+  pager_address TEXT  default '',
+  host_timeperiod_object_id bigint default 0,
+  service_timeperiod_object_id bigint default 0,
+  host_notifications_enabled INTEGER  default 0,
+  service_notifications_enabled INTEGER  default 0,
+  can_submit_commands INTEGER  default 0,
+  notify_service_recovery INTEGER  default 0,
+  notify_service_warning INTEGER  default 0,
+  notify_service_unknown INTEGER  default 0,
+  notify_service_critical INTEGER  default 0,
+  notify_service_flapping INTEGER  default 0,
+  notify_service_downtime INTEGER  default 0,
+  notify_host_recovery INTEGER  default 0,
+  notify_host_down INTEGER  default 0,
+  notify_host_unreachable INTEGER  default 0,
+  notify_host_flapping INTEGER  default 0,
+  notify_host_downtime INTEGER  default 0,
+  CONSTRAINT PK_contact_id PRIMARY KEY (contact_id) ,
+  CONSTRAINT UQ_contacts UNIQUE (instance_id,config_type,contact_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contactstatus
+--
+
+CREATE TABLE  icinga_contactstatus (
+  contactstatus_id bigserial,
+  instance_id bigint default 0,
+  contact_object_id bigint default 0,
+  status_update_time timestamp with time zone default '1970-01-01 00:00:00',
+  host_notifications_enabled INTEGER  default 0,
+  service_notifications_enabled INTEGER  default 0,
+  last_host_notification timestamp with time zone default '1970-01-01 00:00:00',
+  last_service_notification timestamp with time zone default '1970-01-01 00:00:00',
+  modified_attributes INTEGER  default 0,
+  modified_host_attributes INTEGER  default 0,
+  modified_service_attributes INTEGER  default 0,
+  CONSTRAINT PK_contactstatus_id PRIMARY KEY (contactstatus_id) ,
+  CONSTRAINT UQ_contactstatus UNIQUE (contact_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contact_addresses
+--
+
+CREATE TABLE  icinga_contact_addresses (
+  contact_address_id bigserial,
+  instance_id bigint default 0,
+  contact_id bigint default 0,
+  address_number INTEGER  default 0,
+  address TEXT  default '',
+  CONSTRAINT PK_contact_address_id PRIMARY KEY (contact_address_id) ,
+  CONSTRAINT UQ_contact_addresses UNIQUE (contact_id,address_number)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_contact_notificationcommands
+--
+
+CREATE TABLE  icinga_contact_notificationcommands (
+  contact_notificationcommand_id bigserial,
+  instance_id bigint default 0,
+  contact_id bigint default 0,
+  notification_type INTEGER  default 0,
+  command_object_id bigint default 0,
+  command_args TEXT  default '',
+  CONSTRAINT PK_contact_notificationcommand_id PRIMARY KEY (contact_notificationcommand_id) ,
+  CONSTRAINT UQ_contact_notificationcommands UNIQUE (contact_id,notification_type,command_object_id,command_args)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_customvariables
+--
+
+CREATE TABLE  icinga_customvariables (
+  customvariable_id bigserial,
+  instance_id bigint default 0,
+  object_id bigint default 0,
+  config_type INTEGER  default 0,
+  has_been_modified INTEGER  default 0,
+  varname TEXT  default '',
+  varvalue TEXT  default '',
+  CONSTRAINT PK_customvariable_id PRIMARY KEY (customvariable_id) ,
+  CONSTRAINT UQ_customvariables UNIQUE (object_id,config_type,varname)
+) ;
+CREATE INDEX icinga_customvariables_i ON icinga_customvariables(varname);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_customvariablestatus
+--
+
+CREATE TABLE  icinga_customvariablestatus (
+  customvariablestatus_id bigserial,
+  instance_id bigint default 0,
+  object_id bigint default 0,
+  status_update_time timestamp with time zone default '1970-01-01 00:00:00',
+  has_been_modified INTEGER  default 0,
+  varname TEXT  default '',
+  varvalue TEXT  default '',
+  CONSTRAINT PK_customvariablestatus_id PRIMARY KEY (customvariablestatus_id) ,
+  CONSTRAINT UQ_customvariablestatus UNIQUE (object_id,varname)
+) ;
+CREATE INDEX icinga_customvariablestatus_i ON icinga_customvariablestatus(varname);
+
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_dbversion
+--
+
+CREATE TABLE  icinga_dbversion (
+  dbversion_id bigserial,
+  name TEXT  default '',
+  version TEXT  default '',
+  create_time timestamp with time zone default '1970-01-01 00:00:00',
+  modify_time timestamp with time zone default '1970-01-01 00:00:00',
+  CONSTRAINT PK_dbversion_id PRIMARY KEY (dbversion_id) ,
+  CONSTRAINT UQ_dbversion UNIQUE (name)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_downtimehistory
+--
+
+CREATE TABLE  icinga_downtimehistory (
+  downtimehistory_id bigserial,
+  instance_id bigint default 0,
+  downtime_type INTEGER  default 0,
+  object_id bigint default 0,
+  entry_time timestamp with time zone default '1970-01-01 00:00:00',
+  author_name TEXT  default '',
+  comment_data TEXT  default '',
+  internal_downtime_id bigint default 0,
+  triggered_by_id bigint default 0,
+  is_fixed INTEGER  default 0,
+  duration BIGINT  default 0,
+  scheduled_start_time timestamp with time zone default '1970-01-01 00:00:00',
+  scheduled_end_time timestamp with time zone default '1970-01-01 00:00:00',
+  was_started INTEGER  default 0,
+  actual_start_time timestamp with time zone default '1970-01-01 00:00:00',
+  actual_start_time_usec INTEGER  default 0,
+  actual_end_time timestamp with time zone default '1970-01-01 00:00:00',
+  actual_end_time_usec INTEGER  default 0,
+  was_cancelled INTEGER  default 0,
+  is_in_effect INTEGER  default 0,
+  trigger_time timestamp with time zone default '1970-01-01 00:00:00',
+  CONSTRAINT PK_downtimehistory_id PRIMARY KEY (downtimehistory_id) ,
+  CONSTRAINT UQ_downtimehistory UNIQUE (instance_id,object_id,entry_time,internal_downtime_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_eventhandlers
+--
+
+CREATE TABLE  icinga_eventhandlers (
+  eventhandler_id bigserial,
+  instance_id bigint default 0,
+  eventhandler_type INTEGER  default 0,
+  object_id bigint default 0,
+  state INTEGER  default 0,
+  state_type INTEGER  default 0,
+  start_time timestamp with time zone default '1970-01-01 00:00:00',
+  start_time_usec INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  end_time_usec INTEGER  default 0,
+  command_object_id bigint default 0,
+  command_args TEXT  default '',
+  command_line TEXT  default '',
+  timeout INTEGER  default 0,
+  early_timeout INTEGER  default 0,
+  execution_time double precision  default 0,
+  return_code INTEGER  default 0,
+  output TEXT  default '',
+  long_output TEXT  default '',
+  CONSTRAINT PK_eventhandler_id PRIMARY KEY (eventhandler_id) ,
+  CONSTRAINT UQ_eventhandlers UNIQUE (instance_id,object_id,start_time,start_time_usec)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_externalcommands
+--
+
+CREATE TABLE  icinga_externalcommands (
+  externalcommand_id bigserial,
+  instance_id bigint default 0,
+  entry_time timestamp with time zone default '1970-01-01 00:00:00',
+  command_type INTEGER  default 0,
+  command_name TEXT  default '',
+  command_args TEXT  default '',
+  CONSTRAINT PK_externalcommand_id PRIMARY KEY (externalcommand_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_flappinghistory
+--
+
+CREATE TABLE  icinga_flappinghistory (
+  flappinghistory_id bigserial,
+  instance_id bigint default 0,
+  event_time timestamp with time zone default '1970-01-01 00:00:00',
+  event_time_usec INTEGER  default 0,
+  event_type INTEGER  default 0,
+  reason_type INTEGER  default 0,
+  flapping_type INTEGER  default 0,
+  object_id bigint default 0,
+  percent_state_change double precision  default 0,
+  low_threshold double precision  default 0,
+  high_threshold double precision  default 0,
+  comment_time timestamp with time zone default '1970-01-01 00:00:00',
+  internal_comment_id bigint default 0,
+  CONSTRAINT PK_flappinghistory_id PRIMARY KEY (flappinghistory_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hostchecks
+--
+
+CREATE TABLE  icinga_hostchecks (
+  hostcheck_id bigserial,
+  instance_id bigint default 0,
+  host_object_id bigint default 0,
+  check_type INTEGER  default 0,
+  is_raw_check INTEGER  default 0,
+  current_check_attempt INTEGER  default 0,
+  max_check_attempts INTEGER  default 0,
+  state INTEGER  default 0,
+  state_type INTEGER  default 0,
+  start_time timestamp with time zone default '1970-01-01 00:00:00',
+  start_time_usec INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  end_time_usec INTEGER  default 0,
+  command_object_id bigint default 0,
+  command_args TEXT  default '',
+  command_line TEXT  default '',
+  timeout INTEGER  default 0,
+  early_timeout INTEGER  default 0,
+  execution_time double precision  default 0,
+  latency double precision  default 0,
+  return_code INTEGER  default 0,
+  output TEXT  default '',
+  long_output TEXT  default '',
+  perfdata TEXT  default '',
+  CONSTRAINT PK_hostcheck_id PRIMARY KEY (hostcheck_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hostdependencies
+--
+
+CREATE TABLE  icinga_hostdependencies (
+  hostdependency_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  host_object_id bigint default 0,
+  dependent_host_object_id bigint default 0,
+  dependency_type INTEGER  default 0,
+  inherits_parent INTEGER  default 0,
+  timeperiod_object_id bigint default 0,
+  fail_on_up INTEGER  default 0,
+  fail_on_down INTEGER  default 0,
+  fail_on_unreachable INTEGER  default 0,
+  CONSTRAINT PK_hostdependency_id PRIMARY KEY (hostdependency_id) ,
+  CONSTRAINT UQ_hostdependencies UNIQUE (instance_id,config_type,host_object_id,dependent_host_object_id,dependency_type,inherits_parent,fail_on_up,fail_on_down,fail_on_unreachable)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hostescalations
+--
+
+CREATE TABLE  icinga_hostescalations (
+  hostescalation_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  host_object_id bigint default 0,
+  timeperiod_object_id bigint default 0,
+  first_notification INTEGER  default 0,
+  last_notification INTEGER  default 0,
+  notification_interval double precision  default 0,
+  escalate_on_recovery INTEGER  default 0,
+  escalate_on_down INTEGER  default 0,
+  escalate_on_unreachable INTEGER  default 0,
+  CONSTRAINT PK_hostescalation_id PRIMARY KEY (hostescalation_id) ,
+  CONSTRAINT UQ_hostescalations UNIQUE (instance_id,config_type,host_object_id,timeperiod_object_id,first_notification,last_notification)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hostescalation_contactgroups
+--
+
+CREATE TABLE  icinga_hostescalation_contactgroups (
+  hostescalation_contactgroup_id bigserial,
+  instance_id bigint default 0,
+  hostescalation_id bigint default 0,
+  contactgroup_object_id bigint default 0,
+  CONSTRAINT PK_hostescalation_contactgroup_id PRIMARY KEY (hostescalation_contactgroup_id) ,
+  CONSTRAINT UQ_hostescalation_contactgroups UNIQUE (hostescalation_id,contactgroup_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hostescalation_contacts
+--
+
+CREATE TABLE  icinga_hostescalation_contacts (
+  hostescalation_contact_id bigserial,
+  instance_id bigint default 0,
+  hostescalation_id bigint default 0,
+  contact_object_id bigint default 0,
+  CONSTRAINT PK_hostescalation_contact_id PRIMARY KEY (hostescalation_contact_id) ,
+  CONSTRAINT UQ_hostescalation_contacts UNIQUE (instance_id,hostescalation_id,contact_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hostgroups
+--
+
+CREATE TABLE  icinga_hostgroups (
+  hostgroup_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  hostgroup_object_id bigint default 0,
+  alias TEXT  default '',
+  CONSTRAINT PK_hostgroup_id PRIMARY KEY (hostgroup_id) ,
+  CONSTRAINT UQ_hostgroups UNIQUE (instance_id,hostgroup_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hostgroup_members
+--
+
+CREATE TABLE  icinga_hostgroup_members (
+  hostgroup_member_id bigserial,
+  instance_id bigint default 0,
+  hostgroup_id bigint default 0,
+  host_object_id bigint default 0,
+  CONSTRAINT PK_hostgroup_member_id PRIMARY KEY (hostgroup_member_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hosts
+--
+
+CREATE TABLE  icinga_hosts (
+  host_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  host_object_id bigint default 0,
+  alias TEXT  default '',
+  display_name TEXT  default '',
+  address TEXT  default '',
+  address6 TEXT  default '',
+  check_command_object_id bigint default 0,
+  check_command_args TEXT  default '',
+  eventhandler_command_object_id bigint default 0,
+  eventhandler_command_args TEXT  default '',
+  notification_timeperiod_object_id bigint default 0,
+  check_timeperiod_object_id bigint default 0,
+  failure_prediction_options TEXT  default '',
+  check_interval double precision  default 0,
+  retry_interval double precision  default 0,
+  max_check_attempts INTEGER  default 0,
+  first_notification_delay double precision  default 0,
+  notification_interval double precision  default 0,
+  notify_on_down INTEGER  default 0,
+  notify_on_unreachable INTEGER  default 0,
+  notify_on_recovery INTEGER  default 0,
+  notify_on_flapping INTEGER  default 0,
+  notify_on_downtime INTEGER  default 0,
+  stalk_on_up INTEGER  default 0,
+  stalk_on_down INTEGER  default 0,
+  stalk_on_unreachable INTEGER  default 0,
+  flap_detection_enabled INTEGER  default 0,
+  flap_detection_on_up INTEGER  default 0,
+  flap_detection_on_down INTEGER  default 0,
+  flap_detection_on_unreachable INTEGER  default 0,
+  low_flap_threshold double precision  default 0,
+  high_flap_threshold double precision  default 0,
+  process_performance_data INTEGER  default 0,
+  freshness_checks_enabled INTEGER  default 0,
+  freshness_threshold INTEGER  default 0,
+  passive_checks_enabled INTEGER  default 0,
+  event_handler_enabled INTEGER  default 0,
+  active_checks_enabled INTEGER  default 0,
+  retain_status_information INTEGER  default 0,
+  retain_nonstatus_information INTEGER  default 0,
+  notifications_enabled INTEGER  default 0,
+  obsess_over_host INTEGER  default 0,
+  failure_prediction_enabled INTEGER  default 0,
+  notes TEXT  default '',
+  notes_url TEXT  default '',
+  action_url TEXT  default '',
+  icon_image TEXT  default '',
+  icon_image_alt TEXT  default '',
+  vrml_image TEXT  default '',
+  statusmap_image TEXT  default '',
+  have_2d_coords INTEGER  default 0,
+  x_2d INTEGER  default 0,
+  y_2d INTEGER  default 0,
+  have_3d_coords INTEGER  default 0,
+  x_3d double precision  default 0,
+  y_3d double precision  default 0,
+  z_3d double precision  default 0,
+  CONSTRAINT PK_host_id PRIMARY KEY (host_id) ,
+  CONSTRAINT UQ_hosts UNIQUE (instance_id,config_type,host_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_hoststatus
+--
+
+CREATE TABLE  icinga_hoststatus (
+  hoststatus_id bigserial,
+  instance_id bigint default 0,
+  host_object_id bigint default 0,
+  status_update_time timestamp with time zone default '1970-01-01 00:00:00',
+  output TEXT  default '',
+  long_output TEXT  default '',
+  perfdata TEXT  default '',
+  check_source TEXT  default '',
+  current_state INTEGER  default 0,
+  has_been_checked INTEGER  default 0,
+  should_be_scheduled INTEGER  default 0,
+  current_check_attempt INTEGER  default 0,
+  max_check_attempts INTEGER  default 0,
+  last_check timestamp with time zone default '1970-01-01 00:00:00',
+  next_check timestamp with time zone default '1970-01-01 00:00:00',
+  check_type INTEGER  default 0,
+  last_state_change timestamp with time zone default '1970-01-01 00:00:00',
+  last_hard_state_change timestamp with time zone default '1970-01-01 00:00:00',
+  last_hard_state INTEGER  default 0,
+  last_time_up timestamp with time zone default '1970-01-01 00:00:00',
+  last_time_down timestamp with time zone default '1970-01-01 00:00:00',
+  last_time_unreachable timestamp with time zone default '1970-01-01 00:00:00',
+  state_type INTEGER  default 0,
+  last_notification timestamp with time zone default '1970-01-01 00:00:00',
+  next_notification timestamp with time zone default '1970-01-01 00:00:00',
+  no_more_notifications INTEGER  default 0,
+  notifications_enabled INTEGER  default 0,
+  problem_has_been_acknowledged INTEGER  default 0,
+  acknowledgement_type INTEGER  default 0,
+  current_notification_number INTEGER  default 0,
+  passive_checks_enabled INTEGER  default 0,
+  active_checks_enabled INTEGER  default 0,
+  event_handler_enabled INTEGER  default 0,
+  flap_detection_enabled INTEGER  default 0,
+  is_flapping INTEGER  default 0,
+  percent_state_change double precision  default 0,
+  latency double precision  default 0,
+  execution_time double precision  default 0,
+  scheduled_downtime_depth INTEGER  default 0,
+  failure_prediction_enabled INTEGER  default 0,
+  process_performance_data INTEGER  default 0,
+  obsess_over_host INTEGER  default 0,
+  modified_host_attributes INTEGER  default 0,
+  event_handler TEXT  default '',
+  check_command TEXT  default '',
+  normal_check_interval double precision  default 0,
+  retry_check_interval double precision  default 0,
+  check_timeperiod_object_id bigint default 0,
+  CONSTRAINT PK_hoststatus_id PRIMARY KEY (hoststatus_id) ,
+  CONSTRAINT UQ_hoststatus UNIQUE (host_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_host_contactgroups
+--
+
+CREATE TABLE  icinga_host_contactgroups (
+  host_contactgroup_id bigserial,
+  instance_id bigint default 0,
+  host_id bigint default 0,
+  contactgroup_object_id bigint default 0,
+  CONSTRAINT PK_host_contactgroup_id PRIMARY KEY (host_contactgroup_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_host_contacts
+--
+
+CREATE TABLE  icinga_host_contacts (
+  host_contact_id bigserial,
+  instance_id bigint default 0,
+  host_id bigint default 0,
+  contact_object_id bigint default 0,
+  CONSTRAINT PK_host_contact_id PRIMARY KEY (host_contact_id) 
+)  ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_host_parenthosts
+--
+
+CREATE TABLE  icinga_host_parenthosts (
+  host_parenthost_id bigserial,
+  instance_id bigint default 0,
+  host_id bigint default 0,
+  parent_host_object_id bigint default 0,
+  CONSTRAINT PK_host_parenthost_id PRIMARY KEY (host_parenthost_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_instances
+--
+
+CREATE TABLE  icinga_instances (
+  instance_id bigserial,
+  instance_name TEXT  default '',
+  instance_description TEXT  default '',
+  CONSTRAINT PK_instance_id PRIMARY KEY (instance_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_logentries
+--
+
+CREATE TABLE  icinga_logentries (
+  logentry_id bigserial,
+  instance_id bigint default 0,
+  logentry_time timestamp with time zone default '1970-01-01 00:00:00',
+  entry_time timestamp with time zone default '1970-01-01 00:00:00',
+  entry_time_usec INTEGER  default 0,
+  logentry_type INTEGER  default 0,
+  logentry_data TEXT  default '',
+  realtime_data INTEGER  default 0,
+  inferred_data_extracted INTEGER  default 0,
+  object_id bigint default NULL,
+  CONSTRAINT PK_logentry_id PRIMARY KEY (logentry_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_notifications
+--
+
+CREATE TABLE  icinga_notifications (
+  notification_id bigserial,
+  instance_id bigint default 0,
+  notification_type INTEGER  default 0,
+  notification_reason INTEGER  default 0,
+  object_id bigint default 0,
+  start_time timestamp with time zone default '1970-01-01 00:00:00',
+  start_time_usec INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  end_time_usec INTEGER  default 0,
+  state INTEGER  default 0,
+  output TEXT  default '',
+  long_output TEXT  default '',
+  escalated INTEGER  default 0,
+  contacts_notified INTEGER  default 0,
+  CONSTRAINT PK_notification_id PRIMARY KEY (notification_id) ,
+  CONSTRAINT UQ_notifications UNIQUE (instance_id,object_id,start_time,start_time_usec)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_objects
+--
+
+CREATE TABLE  icinga_objects (
+  object_id bigserial,
+  instance_id bigint default 0,
+  objecttype_id bigint default 0,
+  name1 TEXT,
+  name2 TEXT,
+  is_active INTEGER  default 0,
+  CONSTRAINT PK_object_id PRIMARY KEY (object_id) 
+--  UNIQUE (objecttype_id,name1,name2)
+) ;
+CREATE INDEX icinga_objects_i ON icinga_objects(objecttype_id,name1,name2);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_processevents
+--
+
+CREATE TABLE  icinga_processevents (
+  processevent_id bigserial,
+  instance_id bigint default 0,
+  event_type INTEGER  default 0,
+  event_time timestamp with time zone default '1970-01-01 00:00:00',
+  event_time_usec INTEGER  default 0,
+  process_id bigint default 0,
+  program_name TEXT  default '',
+  program_version TEXT  default '',
+  program_date TEXT  default '',
+  CONSTRAINT PK_processevent_id PRIMARY KEY (processevent_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_programstatus
+--
+
+CREATE TABLE  icinga_programstatus (
+  programstatus_id bigserial,
+  instance_id bigint default 0,
+  status_update_time timestamp with time zone default '1970-01-01 00:00:00',
+  program_start_time timestamp with time zone default '1970-01-01 00:00:00',
+  program_end_time timestamp with time zone default '1970-01-01 00:00:00',
+  is_currently_running INTEGER  default 0,
+  process_id bigint default 0,
+  daemon_mode INTEGER  default 0,
+  last_command_check timestamp with time zone default '1970-01-01 00:00:00',
+  last_log_rotation timestamp with time zone default '1970-01-01 00:00:00',
+  notifications_enabled INTEGER  default 0,
+  disable_notif_expire_time timestamp with time zone default '1970-01-01 00:00:00',
+  active_service_checks_enabled INTEGER  default 0,
+  passive_service_checks_enabled INTEGER  default 0,
+  active_host_checks_enabled INTEGER  default 0,
+  passive_host_checks_enabled INTEGER  default 0,
+  event_handlers_enabled INTEGER  default 0,
+  flap_detection_enabled INTEGER  default 0,
+  failure_prediction_enabled INTEGER  default 0,
+  process_performance_data INTEGER  default 0,
+  obsess_over_hosts INTEGER  default 0,
+  obsess_over_services INTEGER  default 0,
+  modified_host_attributes INTEGER  default 0,
+  modified_service_attributes INTEGER  default 0,
+  global_host_event_handler TEXT  default '',
+  global_service_event_handler TEXT  default '',
+  CONSTRAINT PK_programstatus_id PRIMARY KEY (programstatus_id) ,
+  CONSTRAINT UQ_programstatus UNIQUE (instance_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_runtimevariables
+--
+
+CREATE TABLE  icinga_runtimevariables (
+  runtimevariable_id bigserial,
+  instance_id bigint default 0,
+  varname TEXT  default '',
+  varvalue TEXT  default '',
+  CONSTRAINT PK_runtimevariable_id PRIMARY KEY (runtimevariable_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_scheduleddowntime
+--
+
+CREATE TABLE  icinga_scheduleddowntime (
+  scheduleddowntime_id bigserial,
+  instance_id bigint default 0,
+  downtime_type INTEGER  default 0,
+  object_id bigint default 0,
+  entry_time timestamp with time zone default '1970-01-01 00:00:00',
+  author_name TEXT  default '',
+  comment_data TEXT  default '',
+  internal_downtime_id bigint default 0,
+  triggered_by_id bigint default 0,
+  is_fixed INTEGER  default 0,
+  duration BIGINT  default 0,
+  scheduled_start_time timestamp with time zone default '1970-01-01 00:00:00',
+  scheduled_end_time timestamp with time zone default '1970-01-01 00:00:00',
+  was_started INTEGER  default 0,
+  actual_start_time timestamp with time zone default '1970-01-01 00:00:00',
+  actual_start_time_usec INTEGER  default 0,
+  is_in_effect INTEGER  default 0,
+  trigger_time timestamp with time zone default '1970-01-01 00:00:00',
+  CONSTRAINT PK_scheduleddowntime_id PRIMARY KEY (scheduleddowntime_id) ,
+  CONSTRAINT UQ_scheduleddowntime UNIQUE (instance_id,object_id,entry_time,internal_downtime_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_servicechecks
+--
+
+CREATE TABLE  icinga_servicechecks (
+  servicecheck_id bigserial,
+  instance_id bigint default 0,
+  service_object_id bigint default 0,
+  check_type INTEGER  default 0,
+  current_check_attempt INTEGER  default 0,
+  max_check_attempts INTEGER  default 0,
+  state INTEGER  default 0,
+  state_type INTEGER  default 0,
+  start_time timestamp with time zone default '1970-01-01 00:00:00',
+  start_time_usec INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  end_time_usec INTEGER  default 0,
+  command_object_id bigint default 0,
+  command_args TEXT  default '',
+  command_line TEXT  default '',
+  timeout INTEGER  default 0,
+  early_timeout INTEGER  default 0,
+  execution_time double precision  default 0,
+  latency double precision  default 0,
+  return_code INTEGER  default 0,
+  output TEXT  default '',
+  long_output TEXT  default '',
+  perfdata TEXT  default '',
+  CONSTRAINT PK_servicecheck_id PRIMARY KEY (servicecheck_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_servicedependencies
+--
+
+CREATE TABLE  icinga_servicedependencies (
+  servicedependency_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  service_object_id bigint default 0,
+  dependent_service_object_id bigint default 0,
+  dependency_type INTEGER  default 0,
+  inherits_parent INTEGER  default 0,
+  timeperiod_object_id bigint default 0,
+  fail_on_ok INTEGER  default 0,
+  fail_on_warning INTEGER  default 0,
+  fail_on_unknown INTEGER  default 0,
+  fail_on_critical INTEGER  default 0,
+  CONSTRAINT PK_servicedependency_id PRIMARY KEY (servicedependency_id) ,
+  CONSTRAINT UQ_servicedependencies UNIQUE (instance_id,config_type,service_object_id,dependent_service_object_id,dependency_type,inherits_parent,fail_on_ok,fail_on_warning,fail_on_unknown,fail_on_critical)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_serviceescalations
+--
+
+CREATE TABLE  icinga_serviceescalations (
+  serviceescalation_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  service_object_id bigint default 0,
+  timeperiod_object_id bigint default 0,
+  first_notification INTEGER  default 0,
+  last_notification INTEGER  default 0,
+  notification_interval double precision  default 0,
+  escalate_on_recovery INTEGER  default 0,
+  escalate_on_warning INTEGER  default 0,
+  escalate_on_unknown INTEGER  default 0,
+  escalate_on_critical INTEGER  default 0,
+  CONSTRAINT PK_serviceescalation_id PRIMARY KEY (serviceescalation_id) ,
+  CONSTRAINT UQ_serviceescalations UNIQUE (instance_id,config_type,service_object_id,timeperiod_object_id,first_notification,last_notification)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_serviceescalation_contactgroups
+--
+
+CREATE TABLE  icinga_serviceescalation_contactgroups (
+  serviceescalation_contactgroup_id bigserial,
+  instance_id bigint default 0,
+  serviceescalation_id bigint default 0,
+  contactgroup_object_id bigint default 0,
+  CONSTRAINT PK_serviceescalation_contactgroup_id PRIMARY KEY (serviceescalation_contactgroup_id) ,
+  CONSTRAINT UQ_serviceescalation_contactgro UNIQUE (serviceescalation_id,contactgroup_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_serviceescalation_contacts
+--
+
+CREATE TABLE  icinga_serviceescalation_contacts (
+  serviceescalation_contact_id bigserial,
+  instance_id bigint default 0,
+  serviceescalation_id bigint default 0,
+  contact_object_id bigint default 0,
+  CONSTRAINT PK_serviceescalation_contact_id PRIMARY KEY (serviceescalation_contact_id) ,
+  CONSTRAINT UQ_serviceescalation_contacts UNIQUE (instance_id,serviceescalation_id,contact_object_id)
+)  ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_servicegroups
+--
+
+CREATE TABLE  icinga_servicegroups (
+  servicegroup_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  servicegroup_object_id bigint default 0,
+  alias TEXT  default '',
+  CONSTRAINT PK_servicegroup_id PRIMARY KEY (servicegroup_id) ,
+  CONSTRAINT UQ_servicegroups UNIQUE (instance_id,config_type,servicegroup_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_servicegroup_members
+--
+
+CREATE TABLE  icinga_servicegroup_members (
+  servicegroup_member_id bigserial,
+  instance_id bigint default 0,
+  servicegroup_id bigint default 0,
+  service_object_id bigint default 0,
+  CONSTRAINT PK_servicegroup_member_id PRIMARY KEY (servicegroup_member_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_services
+--
+
+CREATE TABLE  icinga_services (
+  service_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  host_object_id bigint default 0,
+  service_object_id bigint default 0,
+  display_name TEXT  default '',
+  check_command_object_id bigint default 0,
+  check_command_args TEXT  default '',
+  eventhandler_command_object_id bigint default 0,
+  eventhandler_command_args TEXT  default '',
+  notification_timeperiod_object_id bigint default 0,
+  check_timeperiod_object_id bigint default 0,
+  failure_prediction_options TEXT  default '',
+  check_interval double precision  default 0,
+  retry_interval double precision  default 0,
+  max_check_attempts INTEGER  default 0,
+  first_notification_delay double precision  default 0,
+  notification_interval double precision  default 0,
+  notify_on_warning INTEGER  default 0,
+  notify_on_unknown INTEGER  default 0,
+  notify_on_critical INTEGER  default 0,
+  notify_on_recovery INTEGER  default 0,
+  notify_on_flapping INTEGER  default 0,
+  notify_on_downtime INTEGER  default 0,
+  stalk_on_ok INTEGER  default 0,
+  stalk_on_warning INTEGER  default 0,
+  stalk_on_unknown INTEGER  default 0,
+  stalk_on_critical INTEGER  default 0,
+  is_volatile INTEGER  default 0,
+  flap_detection_enabled INTEGER  default 0,
+  flap_detection_on_ok INTEGER  default 0,
+  flap_detection_on_warning INTEGER  default 0,
+  flap_detection_on_unknown INTEGER  default 0,
+  flap_detection_on_critical INTEGER  default 0,
+  low_flap_threshold double precision  default 0,
+  high_flap_threshold double precision  default 0,
+  process_performance_data INTEGER  default 0,
+  freshness_checks_enabled INTEGER  default 0,
+  freshness_threshold INTEGER  default 0,
+  passive_checks_enabled INTEGER  default 0,
+  event_handler_enabled INTEGER  default 0,
+  active_checks_enabled INTEGER  default 0,
+  retain_status_information INTEGER  default 0,
+  retain_nonstatus_information INTEGER  default 0,
+  notifications_enabled INTEGER  default 0,
+  obsess_over_service INTEGER  default 0,
+  failure_prediction_enabled INTEGER  default 0,
+  notes TEXT  default '',
+  notes_url TEXT  default '',
+  action_url TEXT  default '',
+  icon_image TEXT  default '',
+  icon_image_alt TEXT  default '',
+  CONSTRAINT PK_service_id PRIMARY KEY (service_id) ,
+  CONSTRAINT UQ_services UNIQUE (instance_id,config_type,service_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_servicestatus
+--
+
+CREATE TABLE  icinga_servicestatus (
+  servicestatus_id bigserial,
+  instance_id bigint default 0,
+  service_object_id bigint default 0,
+  status_update_time timestamp with time zone default '1970-01-01 00:00:00',
+  output TEXT  default '',
+  long_output TEXT  default '',
+  perfdata TEXT  default '',
+  check_source TEXT  default '',
+  current_state INTEGER  default 0,
+  has_been_checked INTEGER  default 0,
+  should_be_scheduled INTEGER  default 0,
+  current_check_attempt INTEGER  default 0,
+  max_check_attempts INTEGER  default 0,
+  last_check timestamp with time zone default '1970-01-01 00:00:00',
+  next_check timestamp with time zone default '1970-01-01 00:00:00',
+  check_type INTEGER  default 0,
+  last_state_change timestamp with time zone default '1970-01-01 00:00:00',
+  last_hard_state_change timestamp with time zone default '1970-01-01 00:00:00',
+  last_hard_state INTEGER  default 0,
+  last_time_ok timestamp with time zone default '1970-01-01 00:00:00',
+  last_time_warning timestamp with time zone default '1970-01-01 00:00:00',
+  last_time_unknown timestamp with time zone default '1970-01-01 00:00:00',
+  last_time_critical timestamp with time zone default '1970-01-01 00:00:00',
+  state_type INTEGER  default 0,
+  last_notification timestamp with time zone default '1970-01-01 00:00:00',
+  next_notification timestamp with time zone default '1970-01-01 00:00:00',
+  no_more_notifications INTEGER  default 0,
+  notifications_enabled INTEGER  default 0,
+  problem_has_been_acknowledged INTEGER  default 0,
+  acknowledgement_type INTEGER  default 0,
+  current_notification_number INTEGER  default 0,
+  passive_checks_enabled INTEGER  default 0,
+  active_checks_enabled INTEGER  default 0,
+  event_handler_enabled INTEGER  default 0,
+  flap_detection_enabled INTEGER  default 0,
+  is_flapping INTEGER  default 0,
+  percent_state_change double precision  default 0,
+  latency double precision  default 0,
+  execution_time double precision  default 0,
+  scheduled_downtime_depth INTEGER  default 0,
+  failure_prediction_enabled INTEGER  default 0,
+  process_performance_data INTEGER  default 0,
+  obsess_over_service INTEGER  default 0,
+  modified_service_attributes INTEGER  default 0,
+  event_handler TEXT  default '',
+  check_command TEXT  default '',
+  normal_check_interval double precision  default 0,
+  retry_check_interval double precision  default 0,
+  check_timeperiod_object_id bigint default 0,
+  CONSTRAINT PK_servicestatus_id PRIMARY KEY (servicestatus_id) ,
+  CONSTRAINT UQ_servicestatus UNIQUE (service_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_service_contactgroups
+--
+
+CREATE TABLE  icinga_service_contactgroups (
+  service_contactgroup_id bigserial,
+  instance_id bigint default 0,
+  service_id bigint default 0,
+  contactgroup_object_id bigint default 0,
+  CONSTRAINT PK_service_contactgroup_id PRIMARY KEY (service_contactgroup_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_service_contacts
+--
+
+CREATE TABLE  icinga_service_contacts (
+  service_contact_id bigserial,
+  instance_id bigint default 0,
+  service_id bigint default 0,
+  contact_object_id bigint default 0,
+  CONSTRAINT PK_service_contact_id PRIMARY KEY (service_contact_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_statehistory
+--
+
+CREATE TABLE  icinga_statehistory (
+  statehistory_id bigserial,
+  instance_id bigint default 0,
+  state_time timestamp with time zone default '1970-01-01 00:00:00',
+  state_time_usec INTEGER  default 0,
+  object_id bigint default 0,
+  state_change INTEGER  default 0,
+  state INTEGER  default 0,
+  state_type INTEGER  default 0,
+  current_check_attempt INTEGER  default 0,
+  max_check_attempts INTEGER  default 0,
+  last_state INTEGER  default '-1',
+  last_hard_state INTEGER  default '-1',
+  output TEXT  default '',
+  long_output TEXT  default '',
+  CONSTRAINT PK_statehistory_id PRIMARY KEY (statehistory_id) 
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_systemcommands
+--
+
+CREATE TABLE  icinga_systemcommands (
+  systemcommand_id bigserial,
+  instance_id bigint default 0,
+  start_time timestamp with time zone default '1970-01-01 00:00:00',
+  start_time_usec INTEGER  default 0,
+  end_time timestamp with time zone default '1970-01-01 00:00:00',
+  end_time_usec INTEGER  default 0,
+  command_line TEXT  default '',
+  timeout INTEGER  default 0,
+  early_timeout INTEGER  default 0,
+  execution_time double precision  default 0,
+  return_code INTEGER  default 0,
+  output TEXT  default '',
+  long_output TEXT  default '',
+  CONSTRAINT PK_systemcommand_id PRIMARY KEY (systemcommand_id) ,
+  CONSTRAINT UQ_systemcommands UNIQUE (instance_id,start_time,start_time_usec)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_timeperiods
+--
+
+CREATE TABLE  icinga_timeperiods (
+  timeperiod_id bigserial,
+  instance_id bigint default 0,
+  config_type INTEGER  default 0,
+  timeperiod_object_id bigint default 0,
+  alias TEXT  default '',
+  CONSTRAINT PK_timeperiod_id PRIMARY KEY (timeperiod_id) ,
+  CONSTRAINT UQ_timeperiods UNIQUE (instance_id,config_type,timeperiod_object_id)
+) ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table icinga_timeperiod_timeranges
+--
+
+CREATE TABLE  icinga_timeperiod_timeranges (
+  timeperiod_timerange_id bigserial,
+  instance_id bigint default 0,
+  timeperiod_id bigint default 0,
+  day INTEGER  default 0,
+  start_sec INTEGER  default 0,
+  end_sec INTEGER  default 0,
+  CONSTRAINT PK_timeperiod_timerange_id PRIMARY KEY (timeperiod_timerange_id)
+) ;
+
+
+-- -----------------------------------------
+-- add index (delete)
+-- -----------------------------------------
+
+-- for periodic delete
+-- instance_id and
+-- TIMEDEVENTS => scheduled_time
+-- SYSTEMCOMMANDS, SERVICECHECKS, HOSTCHECKS, EVENTHANDLERS  => start_time
+-- EXTERNALCOMMANDS => entry_time
+
+-- instance_id
+CREATE INDEX systemcommands_i_id_idx on icinga_systemcommands(instance_id);
+CREATE INDEX servicechecks_i_id_idx on icinga_servicechecks(instance_id);
+CREATE INDEX hostchecks_i_id_idx on icinga_hostchecks(instance_id);
+CREATE INDEX eventhandlers_i_id_idx on icinga_eventhandlers(instance_id);
+CREATE INDEX externalcommands_i_id_idx on icinga_externalcommands(instance_id);
+
+-- time
+CREATE INDEX systemcommands_time_id_idx on icinga_systemcommands(start_time);
+CREATE INDEX servicechecks_time_id_idx on icinga_servicechecks(start_time);
+CREATE INDEX hostchecks_time_id_idx on icinga_hostchecks(start_time);
+CREATE INDEX eventhandlers_time_id_idx on icinga_eventhandlers(start_time);
+CREATE INDEX externalcommands_time_id_idx on icinga_externalcommands(entry_time);
+
+
+-- for starting cleanup - referenced in dbhandler.c:882
+-- instance_id only
+
+-- realtime data
+CREATE INDEX programstatus_i_id_idx on icinga_programstatus(instance_id);
+CREATE INDEX hoststatus_i_id_idx on icinga_hoststatus(instance_id);
+CREATE INDEX servicestatus_i_id_idx on icinga_servicestatus(instance_id);
+CREATE INDEX contactstatus_i_id_idx on icinga_contactstatus(instance_id);
+CREATE INDEX comments_i_id_idx on icinga_comments(instance_id);
+CREATE INDEX scheduleddowntime_i_id_idx on icinga_scheduleddowntime(instance_id);
+CREATE INDEX runtimevariables_i_id_idx on icinga_runtimevariables(instance_id);
+CREATE INDEX customvariablestatus_i_id_idx on icinga_customvariablestatus(instance_id);
+
+-- config data
+CREATE INDEX configfiles_i_id_idx on icinga_configfiles(instance_id);
+CREATE INDEX configfilevariables_i_id_idx on icinga_configfilevariables(instance_id);
+CREATE INDEX customvariables_i_id_idx on icinga_customvariables(instance_id);
+CREATE INDEX commands_i_id_idx on icinga_commands(instance_id);
+CREATE INDEX timeperiods_i_id_idx on icinga_timeperiods(instance_id);
+CREATE INDEX timeperiod_timeranges_i_id_idx on icinga_timeperiod_timeranges(instance_id);
+CREATE INDEX contactgroups_i_id_idx on icinga_contactgroups(instance_id);
+CREATE INDEX contactgroup_members_i_id_idx on icinga_contactgroup_members(instance_id);
+CREATE INDEX hostgroups_i_id_idx on icinga_hostgroups(instance_id);
+CREATE INDEX hostgroup_members_i_id_idx on icinga_hostgroup_members(instance_id);
+CREATE INDEX servicegroups_i_id_idx on icinga_servicegroups(instance_id);
+CREATE INDEX servicegroup_members_i_id_idx on icinga_servicegroup_members(instance_id);
+CREATE INDEX hostesc_i_id_idx on icinga_hostescalations(instance_id);
+CREATE INDEX hostesc_contacts_i_id_idx on icinga_hostescalation_contacts(instance_id);
+CREATE INDEX serviceesc_i_id_idx on icinga_serviceescalations(instance_id);
+CREATE INDEX serviceesc_contacts_i_id_idx on icinga_serviceescalation_contacts(instance_id);
+CREATE INDEX hostdependencies_i_id_idx on icinga_hostdependencies(instance_id);
+CREATE INDEX contacts_i_id_idx on icinga_contacts(instance_id);
+CREATE INDEX contact_addresses_i_id_idx on icinga_contact_addresses(instance_id);
+CREATE INDEX contact_notifcommands_i_id_idx on icinga_contact_notificationcommands(instance_id);
+CREATE INDEX hosts_i_id_idx on icinga_hosts(instance_id);
+CREATE INDEX host_parenthosts_i_id_idx on icinga_host_parenthosts(instance_id);
+CREATE INDEX host_contacts_i_id_idx on icinga_host_contacts(instance_id);
+CREATE INDEX services_i_id_idx on icinga_services(instance_id);
+CREATE INDEX service_contacts_i_id_idx on icinga_service_contacts(instance_id);
+CREATE INDEX service_contactgroups_i_id_idx on icinga_service_contactgroups(instance_id);
+CREATE INDEX host_contactgroups_i_id_idx on icinga_host_contactgroups(instance_id);
+CREATE INDEX hostesc_cgroups_i_id_idx on icinga_hostescalation_contactgroups(instance_id);
+CREATE INDEX serviceesc_cgroups_i_id_idx on icinga_serviceescalation_contactgroups(instance_id);
+
+-- -----------------------------------------
+-- more index stuff (WHERE clauses)
+-- -----------------------------------------
+
+-- hosts
+CREATE INDEX hosts_host_object_id_idx on icinga_hosts(host_object_id);
+
+-- hoststatus
+CREATE INDEX hoststatus_stat_upd_time_idx on icinga_hoststatus(status_update_time);
+CREATE INDEX hoststatus_current_state_idx on icinga_hoststatus(current_state);
+CREATE INDEX hoststatus_check_type_idx on icinga_hoststatus(check_type);
+CREATE INDEX hoststatus_state_type_idx on icinga_hoststatus(state_type);
+CREATE INDEX hoststatus_last_state_chg_idx on icinga_hoststatus(last_state_change);
+CREATE INDEX hoststatus_notif_enabled_idx on icinga_hoststatus(notifications_enabled);
+CREATE INDEX hoststatus_problem_ack_idx on icinga_hoststatus(problem_has_been_acknowledged);
+CREATE INDEX hoststatus_act_chks_en_idx on icinga_hoststatus(active_checks_enabled);
+CREATE INDEX hoststatus_pas_chks_en_idx on icinga_hoststatus(passive_checks_enabled);
+CREATE INDEX hoststatus_event_hdl_en_idx on icinga_hoststatus(event_handler_enabled);
+CREATE INDEX hoststatus_flap_det_en_idx on icinga_hoststatus(flap_detection_enabled);
+CREATE INDEX hoststatus_is_flapping_idx on icinga_hoststatus(is_flapping);
+CREATE INDEX hoststatus_p_state_chg_idx on icinga_hoststatus(percent_state_change);
+CREATE INDEX hoststatus_latency_idx on icinga_hoststatus(latency);
+CREATE INDEX hoststatus_ex_time_idx on icinga_hoststatus(execution_time);
+CREATE INDEX hoststatus_sch_downt_d_idx on icinga_hoststatus(scheduled_downtime_depth);
+
+-- services
+CREATE INDEX services_host_object_id_idx on icinga_services(host_object_id);
+
+--servicestatus
+CREATE INDEX srvcstatus_stat_upd_time_idx on icinga_servicestatus(status_update_time);
+CREATE INDEX srvcstatus_current_state_idx on icinga_servicestatus(current_state);
+CREATE INDEX srvcstatus_check_type_idx on icinga_servicestatus(check_type);
+CREATE INDEX srvcstatus_state_type_idx on icinga_servicestatus(state_type);
+CREATE INDEX srvcstatus_last_state_chg_idx on icinga_servicestatus(last_state_change);
+CREATE INDEX srvcstatus_notif_enabled_idx on icinga_servicestatus(notifications_enabled);
+CREATE INDEX srvcstatus_problem_ack_idx on icinga_servicestatus(problem_has_been_acknowledged);
+CREATE INDEX srvcstatus_act_chks_en_idx on icinga_servicestatus(active_checks_enabled);
+CREATE INDEX srvcstatus_pas_chks_en_idx on icinga_servicestatus(passive_checks_enabled);
+CREATE INDEX srvcstatus_event_hdl_en_idx on icinga_servicestatus(event_handler_enabled);
+CREATE INDEX srvcstatus_flap_det_en_idx on icinga_servicestatus(flap_detection_enabled);
+CREATE INDEX srvcstatus_is_flapping_idx on icinga_servicestatus(is_flapping);
+CREATE INDEX srvcstatus_p_state_chg_idx on icinga_servicestatus(percent_state_change);
+CREATE INDEX srvcstatus_latency_idx on icinga_servicestatus(latency);
+CREATE INDEX srvcstatus_ex_time_idx on icinga_servicestatus(execution_time);
+CREATE INDEX srvcstatus_sch_downt_d_idx on icinga_servicestatus(scheduled_downtime_depth);
+
+-- hostchecks
+CREATE INDEX hostchks_h_obj_id_idx on icinga_hostchecks(host_object_id);
+
+-- servicechecks
+CREATE INDEX servicechks_s_obj_id_idx on icinga_servicechecks(service_object_id);
+
+-- objects
+CREATE INDEX objects_objtype_id_idx ON icinga_objects(objecttype_id);
+CREATE INDEX objects_name1_idx ON icinga_objects(name1);
+CREATE INDEX objects_name2_idx ON icinga_objects(name2);
+CREATE INDEX objects_inst_id_idx ON icinga_objects(instance_id);
+
+-- instances
+-- CREATE INDEX instances_name_idx on icinga_instances(instance_name);
+
+-- logentries
+-- CREATE INDEX loge_instance_id_idx on icinga_logentries(instance_id);
+-- #236
+CREATE INDEX loge_time_idx on icinga_logentries(logentry_time);
+-- CREATE INDEX loge_data_idx on icinga_logentries(logentry_data);
+CREATE INDEX loge_inst_id_time_idx on icinga_logentries (instance_id, logentry_time);
+
+
+-- commenthistory
+-- CREATE INDEX c_hist_instance_id_idx on icinga_logentries(instance_id);
+-- CREATE INDEX c_hist_c_time_idx on icinga_logentries(comment_time);
+-- CREATE INDEX c_hist_i_c_id_idx on icinga_logentries(internal_comment_id);
+
+-- downtimehistory
+-- CREATE INDEX d_t_hist_nstance_id_idx on icinga_downtimehistory(instance_id);
+-- CREATE INDEX d_t_hist_type_idx on icinga_downtimehistory(downtime_type);
+-- CREATE INDEX d_t_hist_object_id_idx on icinga_downtimehistory(object_id);
+-- CREATE INDEX d_t_hist_entry_time_idx on icinga_downtimehistory(entry_time);
+-- CREATE INDEX d_t_hist_sched_start_idx on icinga_downtimehistory(scheduled_start_time);
+-- CREATE INDEX d_t_hist_sched_end_idx on icinga_downtimehistory(scheduled_end_time);
+
+-- scheduleddowntime
+-- CREATE INDEX sched_d_t_downtime_type_idx on icinga_scheduleddowntime(downtime_type);
+-- CREATE INDEX sched_d_t_object_id_idx on icinga_scheduleddowntime(object_id);
+-- CREATE INDEX sched_d_t_entry_time_idx on icinga_scheduleddowntime(entry_time);
+-- CREATE INDEX sched_d_t_start_time_idx on icinga_scheduleddowntime(scheduled_start_time);
+-- CREATE INDEX sched_d_t_end_time_idx on icinga_scheduleddowntime(scheduled_end_time);
+
+-- Icinga Web Notifications
+CREATE INDEX notification_idx ON icinga_notifications(notification_type, object_id, start_time);
+CREATE INDEX notification_object_id_idx ON icinga_notifications(object_id);
+CREATE INDEX contact_notification_idx ON icinga_contactnotifications(notification_id, contact_object_id);
+CREATE INDEX contacts_object_id_idx ON icinga_contacts(contact_object_id);
+CREATE INDEX contact_notif_meth_notif_idx ON icinga_contactnotificationmethods(contactnotification_id, command_object_id);
+CREATE INDEX command_object_idx ON icinga_commands(object_id);                         
+CREATE INDEX services_combined_object_idx ON icinga_services(service_object_id, host_object_id);
+
+-- statehistory
+CREATE INDEX statehist_i_id_o_id_s_ty_s_ti on icinga_statehistory(instance_id, object_id, state_type, state_time);
+--#2274
+create index statehist_state_idx on icinga_statehistory(object_id,state);
+
+-- #2618
+CREATE INDEX cntgrpmbrs_cgid_coid ON icinga_contactgroup_members (contactgroup_id,contact_object_id);
+CREATE INDEX hstgrpmbrs_hgid_hoid ON icinga_hostgroup_members (hostgroup_id,host_object_id);
+CREATE INDEX hstcntgrps_hid_cgoid ON icinga_host_contactgroups (host_id,contactgroup_object_id);
+CREATE INDEX hstprnthsts_hid_phoid ON icinga_host_parenthosts (host_id,parent_host_object_id);
+CREATE INDEX runtimevars_iid_varn ON icinga_runtimevariables (instance_id,varname);
+CREATE INDEX sgmbrs_sgid_soid ON icinga_servicegroup_members (servicegroup_id,service_object_id);
+CREATE INDEX scgrps_sid_cgoid ON icinga_service_contactgroups (service_id,contactgroup_object_id);
+CREATE INDEX tperiod_tid_d_ss_es ON icinga_timeperiod_timeranges (timeperiod_id,day,start_sec,end_sec);
+
+-- #3649
+CREATE INDEX sla_idx_sthist ON icinga_statehistory (object_id, state_time DESC);
+CREATE INDEX sla_idx_dohist ON icinga_downtimehistory (object_id, actual_start_time, actual_end_time);
+CREATE INDEX sla_idx_obj ON icinga_objects (objecttype_id, is_active, name1);
+
+
+-- -----------------------------------------
+-- set dbversion
+-- -----------------------------------------
+
+SELECT updatedbversion('1.10.0');
+
index 4916abc5514268ef79023e62c687521b0f25dab4..58f3e59da62c7d83a7bdbc84073010dab70b2e8d 100644 (file)
@@ -504,7 +504,7 @@ Attributes:
 
 ### <a id="objecttype-idomysqlconnection"></a> IdoMySqlConnection
 
-IDO DB schema compatible output into MySQL database.
+IDO database adapter for MySQL.
 
 Example:
 
@@ -584,6 +584,88 @@ Data Categories:
 
 Multiple categories can be combined using the `|` operator.
 
+### <a id="objecttype-idomysqlconnection"></a> IdoPgSqlConnection
+
+IDO database adapter for PostgreSQL.
+
+Example:
+
+    library "db_ido_pgsql"
+
+    object IdoMysqlConnection "pgsql-ido" {
+      host = "127.0.0.1",
+      port = 5432,
+      user = "icinga",
+      password = "icinga",
+      database = "icinga",
+      table_prefix = "icinga_",
+      instance_name = "icinga2",
+      instance_description = "icinga2 dev instance",
+
+      cleanup = {
+        downtimehistory_age = 48h,
+        logentries_age = 31d,
+      },
+
+      categories = (DbCatConfig | DbCatState)
+    }
+
+Attributes:
+
+  Name            |Description
+  ----------------|----------------
+  host            |**Optional.** PostgreSQL database host address. Defaults to "localhost".
+  port            |**Optional.** PostgreSQL database port. Defaults to "5432".
+  user            |**Optional.** PostgreSQL database user with read/write permission to the icinga database. Defaults to "icinga".
+  password        |**Optional.** PostgreSQL database user's password. Defaults to "icinga".
+  database        |**Optional.** PostgreSQL database name. Defaults to "icinga".
+  table\_prefix   |**Optional.** PostgreSQL database table prefix. Defaults to "icinga\_".
+  instance\_name  |**Optional.** Unique identifier for the local Icinga 2 instance. Defaults to "default".
+  instance\_description|**Optional.** Description for the Icinga 2 instance.
+  cleanup         |**Optional.** Dictionary with items for historical table cleanup.
+  categories      |**Optional.** The types of information that should be written to the database.
+
+Cleanup Items:
+
+  Name            | Description
+  ----------------|----------------
+  acknowledgements_age |**Optional.** Max age for acknowledgements table rows (entry_time). Defaults to 0 (never).
+  commenthistory_age |**Optional.** Max age for commenthistory table rows (entry_time). Defaults to 0 (never).
+  contactnotifications_age |**Optional.** Max age for contactnotifications table rows (start_time). Defaults to 0 (never).
+  contactnotificationmethods_age |**Optional.** Max age for contactnotificationmethods table rows (start_time). Defaults to 0 (never).
+  downtimehistory_age |**Optional.** Max age for downtimehistory table rows (entry_time). Defaults to 0 (never).
+  eventhandlers_age |**Optional.** Max age for eventhandlers table rows (start_time). Defaults to 0 (never).
+  externalcommands_age |**Optional.** Max age for externalcommands table rows (entry_time). Defaults to 0 (never).
+  flappinghistory_age |**Optional.** Max age for flappinghistory table rows (event_time). Defaults to 0 (never).
+  hostchecks_age |**Optional.** Max age for hostchecks table rows (start_time). Defaults to 0 (never).
+  logentries_age |**Optional.** Max age for logentries table rows (logentry_time). Defaults to 0 (never).
+  notifications_age |**Optional.** Max age for notifications table rows (start_time). Defaults to 0 (never).
+  processevents_age |**Optional.** Max age for processevents table rows (event_time). Defaults to 0 (never).
+  statehistory_age |**Optional.** Max age for statehistory table rows (state_time). Defaults to 0 (never).
+  servicechecks_age |**Optional.** Max age for servicechecks table rows (start_time). Defaults to 0 (never).
+  systemcommands_age |**Optional.** Max age for systemcommands table rows (start_time). Defaults to 0 (never).
+
+Data Categories:
+
+  Name                 | Description
+  ---------------------|----------------
+  DbCatConfig          | Configuration data
+  DbCatState           | Current state data
+  DbCatAcknowledgement | Acknowledgements
+  DbCatComment         | Comments
+  DbCatDowntime        | Downtimes
+  DbCatEventHandler    | Event handler data
+  DbCatExternalCommand | External commands
+  DbCatFlapping        | Flap detection data
+  DbCatCheck           | Check results
+  DbCatLog             | Log messages
+  DbCatNotification    | Notifications
+  DbCatProgramStatus   | Program status data
+  DbCatRetention       | Retention data
+  DbCatStateHistory    | Historical state data
+
+Multiple categories can be combined using the `|` operator.
+
 ### <a id="objecttype-livestatuslistener"></a> LiveStatusListener
 
 Livestatus API interface available as TCP or UNIX socket.
index d9f81944604cd78bcfc396fa90f59753cbba034f..78dc98791458ea4fdb1d36b74ba023eba6b9c28a 100644 (file)
@@ -80,6 +80,7 @@ void DbConnection::ProgramStatusHandler(void)
 
        DbQuery query2;
        query2.Table = "programstatus";
+       query2.IdColumn = "programstatus_id";
        query2.Type = DbQueryInsert;
        query2.Category = DbCatProgramStatus;
 
index fc434b9436ef7e8b7b98a597839b74ad7fef3b3d..dad43fa2c2be25d26d68307571e4aa73fd7e7409 100644 (file)
@@ -61,6 +61,7 @@ struct I2_DB_IDO_API DbQuery
        int Type;
        DbQueryCategory Category;
        String Table;
+       String IdColumn;
        Dictionary::Ptr Fields;
        Dictionary::Ptr WhereCriteria;
        boost::shared_ptr<DbObject> Object;