From 264fdf40d5b1fd6344ba434bf720820a9bd5b9bb Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 30 Oct 2013 15:32:33 +0100 Subject: [PATCH] Implement PostgreSQL adapter for IDO. Fixes #4777 --- components/CMakeLists.txt | 1 + components/db_ido_pgsql/CMakeLists.txt | 40 + .../db_ido_pgsql/db_ido_pgsql-type.conf | 31 + .../db_ido_pgsql/idopgsqlconnection.cpp | 601 +++++++ components/db_ido_pgsql/idopgsqlconnection.h | 91 + components/db_ido_pgsql/idopgsqlconnection.ti | 29 + components/db_ido_pgsql/schema/pgsql.sql | 1561 +++++++++++++++++ doc/4.3-object-types.md | 84 +- lib/db_ido/dbconnection.cpp | 1 + lib/db_ido/dbquery.h | 1 + 10 files changed, 2439 insertions(+), 1 deletion(-) create mode 100644 components/db_ido_pgsql/CMakeLists.txt create mode 100644 components/db_ido_pgsql/db_ido_pgsql-type.conf create mode 100644 components/db_ido_pgsql/idopgsqlconnection.cpp create mode 100644 components/db_ido_pgsql/idopgsqlconnection.h create mode 100644 components/db_ido_pgsql/idopgsqlconnection.ti create mode 100644 components/db_ido_pgsql/schema/pgsql.sql diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index ad78975c9..646172121 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -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 index 000000000..0adfc05cb --- /dev/null +++ b/components/db_ido_pgsql/CMakeLists.txt @@ -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 index 000000000..01a7a6b3d --- /dev/null +++ b/components/db_ido_pgsql/db_ido_pgsql-type.conf @@ -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 index 000000000..6f318c081 --- /dev/null +++ b/components/db_ido_pgsql/idopgsqlconnection.cpp @@ -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 +#include +#include +#include + +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(); + m_TxTimer->SetInterval(5); + m_TxTimer->OnTimerExpired.connect(boost::bind(&IdoPgsqlConnection::TxTimerHandler, this)); + m_TxTimer->Start(); + + m_ReconnectTimer = boost::make_shared(); + 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(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(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(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(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(); + + 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(); + + 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(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(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(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(m_InstanceID); + return true; + } + if (key == "notification_id") { + *result = static_cast(m_LastNotificationID); + return true; + } + + Value rawvalue = DbValue::ExtractValue(value); + + if (rawvalue.IsObjectType()) { + 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(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(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(m_InstanceID)) + " AND " + time_column + + " < TO_TIMESTAMP(" + Convert::ToString(static_cast(max_age)) + ")"); +} diff --git a/components/db_ido_pgsql/idopgsqlconnection.h b/components/db_ido_pgsql/idopgsqlconnection.h new file mode 100644 index 000000000..61583ce89 --- /dev/null +++ b/components/db_ido_pgsql/idopgsqlconnection.h @@ -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 + +namespace icinga +{ + +/** + * An IDO pgSQL database connection. + * + * @ingroup ido + */ +class IdoPgsqlConnection : public ReflectionObjectImpl +{ +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 index 000000000..39f600945 --- /dev/null +++ b/components/db_ido_pgsql/idopgsqlconnection.ti @@ -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 index 000000000..8d02a95e1 --- /dev/null +++ b/components/db_ido_pgsql/schema/pgsql.sql @@ -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 +-- +-- -------------------------------------------------------- + +-- +-- 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'); + diff --git a/doc/4.3-object-types.md b/doc/4.3-object-types.md index 4916abc55..58f3e59da 100644 --- a/doc/4.3-object-types.md +++ b/doc/4.3-object-types.md @@ -504,7 +504,7 @@ Attributes: ### 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. +### 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. + ### LiveStatusListener Livestatus API interface available as TCP or UNIX socket. diff --git a/lib/db_ido/dbconnection.cpp b/lib/db_ido/dbconnection.cpp index d9f819446..78dc98791 100644 --- a/lib/db_ido/dbconnection.cpp +++ b/lib/db_ido/dbconnection.cpp @@ -80,6 +80,7 @@ void DbConnection::ProgramStatusHandler(void) DbQuery query2; query2.Table = "programstatus"; + query2.IdColumn = "programstatus_id"; query2.Type = DbQueryInsert; query2.Category = DbCatProgramStatus; diff --git a/lib/db_ido/dbquery.h b/lib/db_ido/dbquery.h index fc434b943..dad43fa2c 100644 --- a/lib/db_ido/dbquery.h +++ b/lib/db_ido/dbquery.h @@ -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 Object;