return result;
}
+void Array::Sort(void)
+{
+ ObjectLock olock(this);
+ std::sort(m_Data.begin(), m_Data.end());
+}
+
String Array::ToString(void) const
{
std::ostringstream msgbuf;
Array::Ptr Reverse(void) const;
+ void Sort(void);
+
virtual String ToString(void) const override;
virtual Value GetFieldByName(const String& field, bool sandboxed, const DebugInfo& debugInfo) const override;
/* Default handler does nothing. */
}
+void DbConnection::SetConfigHash(const DbObject::Ptr& dbobj, const String& hash)
+{
+ SetConfigHash(dbobj->GetType(), GetObjectID(dbobj), hash);
+}
+
+void DbConnection::SetConfigHash(const DbType::Ptr& type, const DbReference& objid, const String& hash)
+{
+ if (!objid.IsValid())
+ return;
+
+ if (!hash.IsEmpty())
+ m_ConfigHashes[std::make_pair(type, objid)] = hash;
+ else
+ m_ConfigHashes.erase(std::make_pair(type, objid));
+}
+
+String DbConnection::GetConfigHash(const DbObject::Ptr& dbobj) const
+{
+ return GetConfigHash(dbobj->GetType(), GetObjectID(dbobj));
+}
+
+String DbConnection::GetConfigHash(const DbType::Ptr& type, const DbReference& objid) const
+{
+ if (!objid.IsValid())
+ return String();
+
+ std::map<std::pair<DbType::Ptr, DbReference>, String>::const_iterator it;
+
+ it = m_ConfigHashes.find(std::make_pair(type, objid));
+
+ if (it == m_ConfigHashes.end())
+ return String();
+
+ return it->second;
+}
+
void DbConnection::SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref)
{
if (dbref.IsValid())
m_ActiveObjects.clear();
m_ConfigUpdates.clear();
m_StatusUpdates.clear();
+ m_ConfigHashes.clear();
}
void DbConnection::SetConfigUpdate(const DbObject::Ptr& dbobj, bool hasupdate)
if (!dbActive)
ActivateObject(dbobj);
- dbobj->SendConfigUpdate();
- dbobj->SendStatusUpdate();
+ Dictionary::Ptr configFields = dbobj->GetConfigFields();
+ String configHash = dbobj->CalculateConfigHash(configFields);
+ configFields->Set("config_hash", configHash);
+
+ String cachedHash = GetConfigHash(dbobj);
+
+ if (cachedHash != configHash) {
+ dbobj->SendConfigUpdateHeavy(configFields);
+ dbobj->SendStatusUpdate();
+ } else {
+ dbobj->SendConfigUpdateLight();
+ }
} else if (!active) {
/* Deactivate the deleted object no matter
* which state it had in the database.
void DbConnection::PrepareDatabase(void)
{
- /*
- * only clear tables on reconnect which
- * cannot be updated by their existing ids
- * for details check https://dev.icinga.org/issues/5565
- */
-
- //ClearConfigTable("commands");
- //ClearConfigTable("comments");
- ClearConfigTable("contact_addresses");
- ClearConfigTable("contact_notificationcommands");
- //ClearConfigTable("contactgroup_members");
- //ClearConfigTable("contactgroups");
- //ClearConfigTable("contacts");
- //ClearConfigTable("contactstatus");
- //ClearConfigTable("customvariables");
- //ClearConfigTable("customvariablestatus");
- //ClearConfigTable("endpoints");
- //ClearConfigTable("endpointstatus");
- ClearConfigTable("host_contactgroups");
- ClearConfigTable("host_contacts");
- ClearConfigTable("host_parenthosts");
- ClearConfigTable("hostdependencies");
- //ClearConfigTable("hostgroup_members");
- //ClearConfigTable("hostgroups");
- //ClearConfigTable("hosts");
- //ClearConfigTable("hoststatus");
- //ClearConfigTable("scheduleddowntime");
- ClearConfigTable("service_contactgroups");
- ClearConfigTable("service_contacts");
- ClearConfigTable("servicedependencies");
- //ClearConfigTable("servicegroup_members");
- //ClearConfigTable("servicegroups");
- //ClearConfigTable("services");
- //ClearConfigTable("servicestatus");
- ClearConfigTable("timeperiod_timeranges");
- //ClearConfigTable("timeperiods");
-
BOOST_FOREACH(const DbType::Ptr& type, DbType::GetAllTypes()) {
FillIDCache(type);
}
static void InitializeDbTimer(void);
+ void SetConfigHash(const DbObject::Ptr& dbobj, const String& hash);
+ void SetConfigHash(const DbType::Ptr& type, const DbReference& objid, const String& hash);
+ String GetConfigHash(const DbObject::Ptr& dbobj) const;
+ String GetConfigHash(const DbType::Ptr& type, const DbReference& objid) const;
+
void SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref);
DbReference GetObjectID(const DbObject::Ptr& dbobj) const;
private:
bool m_IDCacheValid;
+ std::map<std::pair<DbType::Ptr, DbReference>, String> m_ConfigHashes;
std::map<DbObject::Ptr, DbReference> m_ObjectIDs;
std::map<std::pair<DbType::Ptr, DbReference>, DbReference> m_InsertIDs;
std::set<DbObject::Ptr> m_ActiveObjects;
void CleanUpHandler(void);
- virtual void ClearConfigTable(const String& table) = 0;
-
static Timer::Ptr m_ProgramStatusTimer;
static boost::once_flag m_OnceFlag;
#include "base/configobject.hpp"
#include "base/configtype.hpp"
#include "base/json.hpp"
+#include "base/serializer.hpp"
+#include "base/json.hpp"
#include "base/convert.hpp"
#include "base/objectlock.hpp"
#include "base/utility.hpp"
return m_Type;
}
-void DbObject::SendConfigUpdate(void)
+String DbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const
+{
+ Dictionary::Ptr configFieldsDup = configFields->ShallowClone();
+
+ {
+ ObjectLock olock(configFieldsDup);
+
+ BOOST_FOREACH(const Dictionary::Pair& kv, configFieldsDup) {
+ if (kv.second.IsObjectType<ConfigObject>()) {
+ ConfigObject::Ptr obj = kv.second;
+ configFieldsDup->Set(kv.first, obj->GetName());
+ }
+ }
+ }
+
+ Array::Ptr data = new Array();
+ data->Add(configFieldsDup);
+
+ CustomVarObject::Ptr custom_var_object = dynamic_pointer_cast<CustomVarObject>(GetObject());
+
+ if (custom_var_object)
+ data->Add(custom_var_object->GetVars());
+
+ return HashValue(data);
+}
+
+String DbObject::HashValue(const Value& value)
+{
+ Value temp;
+
+ Type::Ptr type = value.GetReflectionType();
+
+ if (ConfigObject::TypeInstance->IsAssignableFrom(type))
+ temp = Serialize(value, FAConfig);
+ else
+ temp = value;
+
+ return SHA256(JsonEncode(temp));
+}
+
+void DbObject::SendConfigUpdateHeavy(const Dictionary::Ptr& configFields)
{
/* update custom var config and status */
- SendVarsConfigUpdate();
+ SendVarsConfigUpdateHeavy();
SendVarsStatusUpdate();
/* config attributes */
- Dictionary::Ptr fields = GetConfigFields();
-
- if (!fields)
+ if (!configFields)
return;
+ ASSERT(configFields->Contains("config_hash"));
+
+ ConfigObject::Ptr object = GetObject();
+
DbQuery query;
query.Table = GetType()->GetTable() + "s";
query.Type = DbQueryInsert | DbQueryUpdate;
query.Category = DbCatConfig;
- query.Fields = fields;
- query.Fields->Set(GetType()->GetIDColumn(), GetObject());
+ query.Fields = configFields;
+ query.Fields->Set(GetType()->GetIDColumn(), object);
query.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query.Fields->Set("config_type", 1);
query.WhereCriteria = new Dictionary();
- query.WhereCriteria->Set(GetType()->GetIDColumn(), GetObject());
+ query.WhereCriteria->Set(GetType()->GetIDColumn(), object);
query.Object = this;
query.ConfigUpdate = true;
OnQuery(query);
m_LastConfigUpdate = Utility::GetTime();
- OnConfigUpdate();
+ OnConfigUpdateHeavy();
+}
+
+void DbObject::SendConfigUpdateLight(void)
+{
+ OnConfigUpdateLight();
}
void DbObject::SendStatusUpdate(void)
OnStatusUpdate();
}
-void DbObject::SendVarsConfigUpdate(void)
+void DbObject::SendVarsConfigUpdateHeavy(void)
{
ConfigObject::Ptr obj = GetObject();
if (!custom_var_object)
return;
+ std::vector<DbQuery> queries;
+
+ DbQuery query1;
+ query1.Table = "customvariables";
+ query1.Type = DbQueryDelete;
+ query1.Category = DbCatConfig;
+ query1.WhereCriteria = new Dictionary();
+ query1.WhereCriteria->Set("object_id", obj);
+
+ queries.push_back(query1);
+
+ DbQuery query2;
+ query2.Table = "customvariablestatus";
+ query2.Type = DbQueryDelete;
+ query2.Category = DbCatConfig;
+ query2.WhereCriteria = new Dictionary();
+ query2.WhereCriteria->Set("object_id", obj);
+
+ queries.push_back(query2);
+
Dictionary::Ptr vars = CompatUtility::GetCustomAttributeConfig(custom_var_object);
if (vars) {
- std::vector<DbQuery> queries;
ObjectLock olock (vars);
BOOST_FOREACH(const Dictionary::Pair& kv, vars) {
fields->Set("varvalue", value);
fields->Set("is_json", is_json);
fields->Set("config_type", 1);
- fields->Set("session_token", 0); /* DbConnection class fills in real ID */
fields->Set("object_id", obj);
fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
- DbQuery query;
- query.Table = "customvariables";
- query.Type = DbQueryInsert | DbQueryUpdate;
- query.Category = DbCatConfig;
- query.Fields = fields;
+ DbQuery query3;
+ query3.Table = "customvariables";
+ query3.Type = DbQueryInsert;
+ query3.Category = DbCatConfig;
+ query3.Fields = fields;
- query.WhereCriteria = new Dictionary();
- query.WhereCriteria->Set("object_id", obj);
- query.WhereCriteria->Set("varname", kv.first);
- query.Object = this;
+ query3.WhereCriteria = new Dictionary();
+ query3.WhereCriteria->Set("object_id", obj);
+ query3.WhereCriteria->Set("varname", kv.first);
+ query3.Object = this;
- queries.push_back(query);
+ queries.push_back(query3);
}
-
- OnMultipleQueries(queries);
}
+
+ OnMultipleQueries(queries);
}
void DbObject::SendVarsStatusUpdate(void)
fields->Set("varvalue", value);
fields->Set("is_json", is_json);
fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
- fields->Set("session_token", 0); /* DbConnection class fills in real ID */
fields->Set("object_id", obj);
fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
return m_LastStatusUpdate;
}
-void DbObject::OnConfigUpdate(void)
+void DbObject::OnConfigUpdateHeavy(void)
+{
+ /* Default handler does nothing. */
+}
+
+void DbObject::OnConfigUpdateLight(void)
{
/* Default handler does nothing. */
}
DbObject::Ptr dbobj = DbObject::GetOrCreateByObject(object);
if (dbobj) {
- dbobj->SendConfigUpdate();
+ Dictionary::Ptr configFields = dbobj->GetConfigFields();
+ String configHash = dbobj->CalculateConfigHash(configFields);
+ configFields->Set("config_hash", configHash);
+
+ dbobj->SendConfigUpdateHeavy(configFields);
dbobj->SendStatusUpdate();
}
}
static boost::signals2::signal<void (const DbQuery&)> OnQuery;
static boost::signals2::signal<void (const std::vector<DbQuery>&)> OnMultipleQueries;
- void SendConfigUpdate(void);
+ void SendConfigUpdateHeavy(const Dictionary::Ptr& configFields);
+ void SendConfigUpdateLight(void);
void SendStatusUpdate(void);
- void SendVarsConfigUpdate(void);
+ void SendVarsConfigUpdateHeavy(void);
void SendVarsStatusUpdate(void);
double GetLastConfigUpdate(void) const;
double GetLastStatusUpdate(void) const;
+ virtual String CalculateConfigHash(const Dictionary::Ptr& configFields) const;
+
protected:
DbObject(const intrusive_ptr<DbType>& type, const String& name1, const String& name2);
- virtual void OnConfigUpdate(void);
+ virtual void OnConfigUpdateHeavy(void);
+ virtual void OnConfigUpdateLight(void);
virtual void OnStatusUpdate(void);
+ static String HashValue(const Value& value);
+
private:
String m_Name1;
String m_Name2;
return fields;
}
-void HostDbObject::OnConfigUpdate(void)
+void HostDbObject::OnConfigUpdateHeavy(void)
{
Host::Ptr host = static_pointer_cast<Host>(GetObject());
/* groups */
Array::Ptr groups = host->GetGroups();
+ std::vector<DbQuery> queries;
+
+ DbQuery query1;
+ query1.Table = DbType::GetByName("HostGroup")->GetTable() + "_members";
+ query1.Type = DbQueryDelete;
+ query1.Category = DbCatConfig;
+ query1.WhereCriteria = new Dictionary();
+ query1.WhereCriteria->Set("host_object_id", host);
+
+ queries.push_back(query1);
+
if (groups) {
ObjectLock olock(groups);
BOOST_FOREACH(const String& groupName, groups) {
HostGroup::Ptr group = HostGroup::GetByName(groupName);
- DbQuery query1;
- query1.Table = DbType::GetByName("HostGroup")->GetTable() + "_members";
- query1.Type = DbQueryInsert | DbQueryUpdate;
- query1.Category = DbCatConfig;
- query1.Fields = new Dictionary();
- query1.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
- query1.Fields->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
- query1.Fields->Set("host_object_id", host);
- query1.Fields->Set("session_token", 0); /* DbConnection class fills in real ID */
- query1.WhereCriteria = new Dictionary();
- query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
- query1.WhereCriteria->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
- query1.WhereCriteria->Set("host_object_id", host);
-
- DbObject::OnQuery(query1);
+ DbQuery query2;
+ query2.Table = DbType::GetByName("HostGroup")->GetTable() + "_members";
+ query2.Type = DbQueryInsert;
+ query2.Category = DbCatConfig;
+ query2.Fields = new Dictionary();
+ query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ query2.Fields->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
+ query2.Fields->Set("host_object_id", host);
+ query2.WhereCriteria = new Dictionary();
+ query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ query2.WhereCriteria->Set("hostgroup_id", DbValue::FromObjectInsertID(group));
+ query2.WhereCriteria->Set("host_object_id", host);
+
+ queries.push_back(query2);
}
}
+ DbObject::OnMultipleQueries(queries);
+
+ queries.clear();
+
+ DbQuery query2;
+ query2.Table = GetType()->GetTable() + "_parenthosts";
+ query2.Type = DbQueryDelete;
+ query2.Category = DbCatConfig;
+ query2.WhereCriteria = new Dictionary();
+ query2.WhereCriteria->Set(GetType()->GetTable() + "_id", DbValue::FromObjectInsertID(GetObject()));
+
+ queries.push_back(query2);
+
/* parents */
BOOST_FOREACH(const Checkable::Ptr& checkable, host->GetParents()) {
Host::Ptr parent = dynamic_pointer_cast<Host>(checkable);
query1.Type = DbQueryInsert;
query1.Category = DbCatConfig;
query1.Fields = fields1;
- OnQuery(query1);
+
+ queries.push_back(query1);
}
+ DbObject::OnMultipleQueries(queries);
+
/* host dependencies */
Log(LogDebug, "HostDbObject")
<< "host dependencies for '" << host->GetName() << "'";
+ queries.clear();
+
+ DbQuery query3;
+ query3.Table = GetType()->GetTable() + "dependencies";
+ query3.Type = DbQueryDelete;
+ query3.Category = DbCatConfig;
+ query3.WhereCriteria = new Dictionary();
+ query3.WhereCriteria->Set("dependent_host_object_id", host);
+
+ queries.push_back(query3);
+
BOOST_FOREACH(const Dependency::Ptr& dep, host->GetDependencies()) {
Checkable::Ptr parent = dep->GetParent();
query2.Type = DbQueryInsert;
query2.Category = DbCatConfig;
query2.Fields = fields2;
- OnQuery(query2);
+
+ queries.push_back(query2);
}
+ DbObject::OnMultipleQueries(queries);
+
Log(LogDebug, "HostDbObject")
<< "host contacts: " << host->GetName();
+ queries.clear();
+
+ DbQuery query4;
+ query4.Table = GetType()->GetTable() + "_contacts";
+ query4.Type = DbQueryDelete;
+ query4.Category = DbCatConfig;
+ query4.WhereCriteria = new Dictionary();
+ query4.WhereCriteria->Set("host_id", DbValue::FromObjectInsertID(host));
+
+ queries.push_back(query4);
+
BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(host)) {
Log(LogDebug, "HostDbObject")
<< "host contacts: " << user->GetName();
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
- OnQuery(query_contact);
+
+ queries.push_back(query_contact);
}
+ DbObject::OnMultipleQueries(queries);
+
Log(LogDebug, "HostDbObject")
<< "host contactgroups: " << host->GetName();
+ queries.clear();
+
+ DbQuery query5;
+ query5.Table = GetType()->GetTable() + "_contactgroups";
+ query5.Type = DbQueryDelete;
+ query5.Category = DbCatConfig;
+ query5.WhereCriteria = new Dictionary();
+ query5.WhereCriteria->Set("host_id", DbValue::FromObjectInsertID(host));
+
+ queries.push_back(query5);
+
BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(host)) {
Log(LogDebug, "HostDbObject")
<< "host contactgroups: " << usergroup->GetName();
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
- OnQuery(query_contact);
+
+ queries.push_back(query_contact);
}
+ DbObject::OnMultipleQueries(queries);
+
+ DoCommonConfigUpdate();
+}
+
+void HostDbObject::OnConfigUpdateLight(void)
+{
+ DoCommonConfigUpdate();
+}
+
+void HostDbObject::DoCommonConfigUpdate(void)
+{
+ Host::Ptr host = static_pointer_cast<Host>(GetObject());
+
/* update comments and downtimes on config change */
DbEvents::AddComments(host);
DbEvents::AddDowntimes(host);
}
-void HostDbObject::OnStatusUpdate(void)
+String HostDbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const
{
+ String hashData = DbObject::CalculateConfigHash(configFields);
+
+ Host::Ptr host = static_pointer_cast<Host>(GetObject());
+
+ Array::Ptr parents = new Array();
+
+ /* parents */
+ BOOST_FOREACH(const Checkable::Ptr& checkable, host->GetParents()) {
+ Host::Ptr parent = dynamic_pointer_cast<Host>(checkable);
+
+ if (!parent)
+ continue;
+
+ parents->Add(parent->GetName());
+ }
+
+ parents->Sort();
+
+ hashData += DbObject::HashValue(parents);
+
+ Array::Ptr dependencies = new Array();
+
+ /* dependencies */
+ BOOST_FOREACH(const Dependency::Ptr& dep, host->GetDependencies()) {
+ Checkable::Ptr parent = dep->GetParent();
+
+ if (!parent)
+ continue;
+
+ int state_filter = dep->GetStateFilter();
+
+ Array::Ptr depInfo = new Array();
+ depInfo->Add(parent->GetName());
+ depInfo->Add(dep->GetStateFilter());
+ depInfo->Add(dep->GetPeriodRaw());
+
+ dependencies->Add(depInfo);
+ }
+
+ dependencies->Sort();
+
+ hashData += DbObject::HashValue(dependencies);
+
+ Array::Ptr users = new Array();
+
+ BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(host)) {
+ users->Add(user->GetName());
+ }
+
+ users->Sort();
+
+ hashData += DbObject::HashValue(users);
+
+ Array::Ptr userGroups = new Array();
+
+ BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(host)) {
+ userGroups->Add(usergroup->GetName());
+ }
+
+ userGroups->Sort();
+
+ hashData += DbObject::HashValue(userGroups);
+
+ return SHA256(hashData);
}
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
+ virtual void OnConfigUpdateHeavy(void) override;
+ virtual void OnConfigUpdateLight(void) override;
+
+ virtual String CalculateConfigHash(const Dictionary::Ptr& configFields) const;
+
private:
- virtual void OnConfigUpdate(void) override;
- virtual void OnStatusUpdate(void) override;
+ void DoCommonConfigUpdate(void);
};
}
return fields;
}
-void ServiceDbObject::OnConfigUpdate(void)
+void ServiceDbObject::OnConfigUpdateHeavy(void)
{
Service::Ptr service = static_pointer_cast<Service>(GetObject());
/* groups */
Array::Ptr groups = service->GetGroups();
+ std::vector<DbQuery> queries;
+
+ DbQuery query1;
+ query1.Table = DbType::GetByName("ServiceGroup")->GetTable() + "_members";
+ query1.Type = DbQueryDelete;
+ query1.Category = DbCatConfig;
+ query1.WhereCriteria = new Dictionary();
+ query1.WhereCriteria->Set("service_object_id", service);
+
+ queries.push_back(query1);
+
if (groups) {
ObjectLock olock(groups);
BOOST_FOREACH(const String& groupName, groups) {
ServiceGroup::Ptr group = ServiceGroup::GetByName(groupName);
- DbQuery query1;
- query1.Table = DbType::GetByName("ServiceGroup")->GetTable() + "_members";
- query1.Type = DbQueryInsert | DbQueryUpdate;
- query1.Category = DbCatConfig;
- query1.Fields = new Dictionary();
- query1.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
- query1.Fields->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
- query1.Fields->Set("service_object_id", service);
- query1.Fields->Set("session_token", 0); /* DbConnection class fills in real ID */
- query1.WhereCriteria = new Dictionary();
- query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
- query1.WhereCriteria->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
- query1.WhereCriteria->Set("service_object_id", service);
-
- DbObject::OnQuery(query1);
+ DbQuery query2;
+ query2.Table = DbType::GetByName("ServiceGroup")->GetTable() + "_members";
+ query2.Type = DbQueryInsert;
+ query2.Category = DbCatConfig;
+ query2.Fields = new Dictionary();
+ query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ query2.Fields->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
+ query2.Fields->Set("service_object_id", service);
+ query2.WhereCriteria = new Dictionary();
+ query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ query2.WhereCriteria->Set("servicegroup_id", DbValue::FromObjectInsertID(group));
+ query2.WhereCriteria->Set("service_object_id", service);
+
+ queries.push_back(query2);
}
}
+ DbObject::OnMultipleQueries(queries);
+
/* service dependencies */
Log(LogDebug, "ServiceDbObject")
<< "service dependencies for '" << service->GetName() << "'";
+ queries.clear();
+
+ DbQuery query2;
+ query2.Table = GetType()->GetTable() + "dependencies";
+ query2.Type = DbQueryDelete;
+ query2.Category = DbCatConfig;
+ query2.WhereCriteria = new Dictionary();
+ query2.WhereCriteria->Set("dependent_service_object_id", service);
+
+ queries.push_back(query2);
+
BOOST_FOREACH(const Dependency::Ptr& dep, service->GetDependencies()) {
Checkable::Ptr parent = dep->GetParent();
query1.Type = DbQueryInsert;
query1.Category = DbCatConfig;
query1.Fields = fields1;
- OnQuery(query1);
+
+ queries.push_back(query1);
}
+ DbObject::OnMultipleQueries(queries);
+
/* service contacts, contactgroups */
Log(LogDebug, "ServiceDbObject")
<< "service contacts: " << service->GetName();
+ queries.clear();
+
+ DbQuery query3;
+ query3.Table = GetType()->GetTable() + "_contacts";
+ query3.Type = DbQueryDelete;
+ query3.Category = DbCatConfig;
+ query3.WhereCriteria = new Dictionary();
+ query3.WhereCriteria->Set("service_id", DbValue::FromObjectInsertID(service));
+
+ queries.push_back(query3);
+
BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) {
Log(LogDebug, "ServiceDbObject")
<< "service contacts: " << user->GetName();
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
- OnQuery(query_contact);
+
+ queries.push_back(query_contact);
}
+ DbObject::OnMultipleQueries(queries);
+
Log(LogDebug, "ServiceDbObject")
<< "service contactgroups: " << service->GetName();
+ queries.clear();
+
+ DbQuery query4;
+ query4.Table = GetType()->GetTable() + "_contactgroups";
+ query4.Type = DbQueryDelete;
+ query4.Category = DbCatConfig;
+ query4.WhereCriteria = new Dictionary();
+ query4.WhereCriteria->Set("service_id", DbValue::FromObjectInsertID(service));
+
+ queries.push_back(query4);
+
BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(service)) {
Log(LogDebug, "ServiceDbObject")
<< "service contactgroups: " << usergroup->GetName();
query_contact.Type = DbQueryInsert;
query_contact.Category = DbCatConfig;
query_contact.Fields = fields_contact;
- OnQuery(query_contact);
+
+ queries.push_back(query_contact);
}
+ DbObject::OnMultipleQueries(queries);
+
+ DoCommonConfigUpdate();
+}
+
+void ServiceDbObject::OnConfigUpdateLight(void)
+{
+ DoCommonConfigUpdate();
+}
+
+void ServiceDbObject::DoCommonConfigUpdate(void)
+{
+ Service::Ptr service = static_pointer_cast<Service>(GetObject());
+
/* update comments and downtimes on config change */
DbEvents::AddComments(service);
DbEvents::AddDowntimes(service);
}
-void ServiceDbObject::OnStatusUpdate(void)
+String ServiceDbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const
{
+ String hashData = DbObject::CalculateConfigHash(configFields);
+
+ Service::Ptr service = static_pointer_cast<Service>(GetObject());
+
+ Array::Ptr dependencies = new Array();
+
+ /* dependencies */
+ BOOST_FOREACH(const Dependency::Ptr& dep, service->GetDependencies()) {
+ Checkable::Ptr parent = dep->GetParent();
+
+ if (!parent)
+ continue;
+
+ int state_filter = dep->GetStateFilter();
+
+ Array::Ptr depInfo = new Array();
+ depInfo->Add(parent->GetName());
+ depInfo->Add(dep->GetStateFilter());
+ depInfo->Add(dep->GetPeriodRaw());
+
+ dependencies->Add(depInfo);
+ }
+
+ dependencies->Sort();
+
+ hashData += DbObject::HashValue(dependencies);
+
+ Array::Ptr users = new Array();
+
+ BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) {
+ users->Add(user->GetName());
+ }
+
+ users->Sort();
+
+ hashData += DbObject::HashValue(users);
+
+ Array::Ptr userGroups = new Array();
+
+ BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(service)) {
+ userGroups->Add(usergroup->GetName());
+ }
+
+ userGroups->Sort();
+
+ hashData += DbObject::HashValue(userGroups);
+
+ return SHA256(hashData);
}
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
-protected:
- virtual void OnConfigUpdate(void) override;
- virtual void OnStatusUpdate(void) override;
+ virtual void OnConfigUpdateHeavy(void) override;
+ virtual void OnConfigUpdateLight(void) override;
+
+ virtual String CalculateConfigHash(const Dictionary::Ptr& configFields) const;
+
+private:
+ void DoCommonConfigUpdate(void);
};
}
return Empty;
}
-void TimePeriodDbObject::OnConfigUpdate(void)
+void TimePeriodDbObject::OnConfigUpdateHeavy(void)
{
TimePeriod::Ptr tp = static_pointer_cast<TimePeriod>(GetObject());
TimePeriodDbObject(const DbType::Ptr& type, const String& name1, const String& name2);
+protected:
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
- virtual void OnConfigUpdate(void) override;
+
+ virtual void OnConfigUpdateHeavy(void) override;
};
}
return fields;
}
-void UserDbObject::OnConfigUpdate(void)
+void UserDbObject::OnConfigUpdateHeavy(void)
{
- Dictionary::Ptr fields = new Dictionary();
User::Ptr user = static_pointer_cast<User>(GetObject());
/* groups */
Array::Ptr groups = user->GetGroups();
+ std::vector<DbQuery> queries;
+
+ DbQuery query1;
+ query1.Table = DbType::GetByName("UserGroup")->GetTable() + "_members";
+ query1.Type = DbQueryDelete;
+ query1.Category = DbCatConfig;
+ query1.WhereCriteria = new Dictionary();
+ query1.WhereCriteria->Set("contact_object_id", user);
+
+ queries.push_back(query1);
+
if (groups) {
ObjectLock olock(groups);
BOOST_FOREACH(const String& groupName, groups) {
UserGroup::Ptr group = UserGroup::GetByName(groupName);
- DbQuery query1;
- query1.Table = DbType::GetByName("UserGroup")->GetTable() + "_members";
- query1.Type = DbQueryInsert | DbQueryUpdate;
- query1.Category = DbCatConfig;
- query1.Fields = new Dictionary();
- query1.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
- query1.Fields->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
- query1.Fields->Set("contact_object_id", user);
- query1.Fields->Set("session_token", 0); /* DbConnection class fills in real ID */
- query1.WhereCriteria = new Dictionary();
- query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
- query1.WhereCriteria->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
- query1.WhereCriteria->Set("contact_object_id", user);
-
- OnQuery(query1);
+ DbQuery query2;
+ query2.Table = DbType::GetByName("UserGroup")->GetTable() + "_members";
+ query2.Type = DbQueryInsert | DbQueryUpdate;
+ query2.Category = DbCatConfig;
+ query2.Fields = new Dictionary();
+ query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ query2.Fields->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
+ query2.Fields->Set("contact_object_id", user);
+ query2.WhereCriteria = new Dictionary();
+ query2.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ query2.WhereCriteria->Set("contactgroup_id", DbValue::FromObjectInsertID(group));
+ query2.WhereCriteria->Set("contact_object_id", user);
+
+ queries.push_back(query2);
}
}
- /* contact addresses */
- Log(LogDebug, "UserDbObject")
- << "contact addresses for '" << user->GetName() << "'";
+ DbObject::OnMultipleQueries(queries);
+
+ queries.clear();
+
+ DbQuery query2;
+ query2.Table = "contact_addresses";
+ query2.Type = DbQueryDelete;
+ query2.Category = DbCatConfig;
+ query2.WhereCriteria = new Dictionary();
+ query2.WhereCriteria->Set("contact_id", DbValue::FromObjectInsertID(user));
+
+ queries.push_back(query2);
Dictionary::Ptr vars = user->GetVars();
if (vars) { /* This is sparta. */
for (int i = 1; i <= 6; i++) {
+ Dictionary::Ptr fields = new Dictionary();
+
String key = "address" + Convert::ToString(i);
if (!vars->Contains(key))
query.Table = "contact_addresses";
query.Category = DbCatConfig;
query.Fields = fields;
- OnQuery(query);
+
+ queries.push_back(query);
}
}
+
+ DbObject::OnMultipleQueries(queries);
}
UserDbObject(const DbType::Ptr& type, const String& name1, const String& name2);
+protected:
virtual Dictionary::Ptr GetConfigFields(void) const override;
virtual Dictionary::Ptr GetStatusFields(void) const override;
- virtual void OnConfigUpdate(void) override;
+ virtual void OnConfigUpdateHeavy(void) override;
};
}
void IdoMysqlConnection::ClearTablesBySession(void)
{
- /* delete all customvariables and group members without current session token */
- ClearTableBySession("customvariables");
- ClearTableBySession("customvariablestatus");
- ClearTableBySession("hostgroup_members");
- ClearTableBySession("servicegroup_members");
- ClearTableBySession("contactgroup_members");
+ /* delete all comments and downtimes without current session token */
ClearTableBySession("comments");
ClearTableBySession("scheduleddowntime");
}
Convert::ToString(GetSessionToken()));
}
-void IdoMysqlConnection::ClearConfigTable(const String& table)
-{
- Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " + Convert::ToString(static_cast<long>(m_InstanceID)));
-}
-
void IdoMysqlConnection::AsyncQuery(const String& query, const boost::function<void (const IdoMysqlResult&)>& callback)
{
AssertOnWorkQueue();
void IdoMysqlConnection::FillIDCache(const DbType::Ptr& type)
{
- String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id FROM " + GetTablePrefix() + type->GetTable() + "s";
+ String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id, config_hash FROM " + GetTablePrefix() + type->GetTable() + "s";
IdoMysqlResult result = Query(query);
Dictionary::Ptr row;
while ((row = FetchRow(result))) {
- SetInsertID(type, DbReference(row->Get("object_id")), DbReference(row->Get(type->GetTable() + "_id")));
+ DbReference dbref(row->Get("object_id"));
+ SetInsertID(type, dbref, DbReference(row->Get(type->GetTable() + "_id")));
+ SetConfigHash(type, dbref, row->Get("config_hash"));
}
}
void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
void InternalNewTransaction(void);
- virtual void ClearConfigTable(const String& table) override;
void ClearTableBySession(const String& table);
void ClearTablesBySession(void);
config_type smallint default 0,
object_id bigint unsigned default 0,
command_line TEXT character set latin1 default '',
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (command_id),
UNIQUE KEY instance_id (instance_id,object_id,config_type)
) ENGINE=InnoDB COMMENT='Command definitions';
config_type smallint default 0,
contactgroup_object_id bigint unsigned default 0,
alias varchar(255) character set latin1 default '',
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (contactgroup_id),
UNIQUE KEY instance_id (instance_id,config_type,contactgroup_object_id)
) ENGINE=InnoDB COMMENT='Contactgroup definitions';
instance_id bigint unsigned default 0,
contactgroup_id bigint unsigned default 0,
contact_object_id bigint unsigned default 0,
- session_token int default NULL,
PRIMARY KEY (contactgroup_member_id)
) ENGINE=InnoDB COMMENT='Contactgroup members';
notify_host_unreachable smallint default 0,
notify_host_flapping smallint default 0,
notify_host_downtime smallint default 0,
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (contact_id),
UNIQUE KEY instance_id (instance_id,config_type,contact_object_id)
) ENGINE=InnoDB COMMENT='Contact definitions';
varname varchar(255) character set latin1 collate latin1_general_cs default NULL,
varvalue TEXT character set latin1 default '',
is_json smallint default 0,
- session_token int default NULL,
PRIMARY KEY (customvariable_id),
UNIQUE KEY object_id_2 (object_id,config_type,varname),
KEY varname (varname)
varname varchar(255) character set latin1 collate latin1_general_cs default NULL,
varvalue TEXT character set latin1 default '',
is_json smallint default 0,
- session_token int default NULL,
PRIMARY KEY (customvariablestatus_id),
UNIQUE KEY object_id_2 (object_id,varname),
KEY varname (varname)
notes TEXT character set latin1 default NULL,
notes_url TEXT character set latin1 default NULL,
action_url TEXT character set latin1 default NULL,
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (hostgroup_id),
UNIQUE KEY instance_id (instance_id,hostgroup_object_id)
) ENGINE=InnoDB COMMENT='Hostgroup definitions';
instance_id bigint unsigned default 0,
hostgroup_id bigint unsigned default 0,
host_object_id bigint unsigned default 0,
- session_token int default NULL,
PRIMARY KEY (hostgroup_member_id)
) ENGINE=InnoDB COMMENT='Hostgroup members';
x_3d double default '0',
y_3d double default '0',
z_3d double default '0',
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (host_id),
UNIQUE KEY instance_id (instance_id,config_type,host_object_id),
KEY host_object_id (host_object_id)
notes TEXT character set latin1 default NULL,
notes_url TEXT character set latin1 default NULL,
action_url TEXT character set latin1 default NULL,
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (servicegroup_id),
UNIQUE KEY instance_id (instance_id,config_type,servicegroup_object_id)
) ENGINE=InnoDB COMMENT='Servicegroup definitions';
instance_id bigint unsigned default 0,
servicegroup_id bigint unsigned default 0,
service_object_id bigint unsigned default 0,
- session_token int default NULL,
PRIMARY KEY (servicegroup_member_id)
) ENGINE=InnoDB COMMENT='Servicegroup members';
action_url TEXT character set latin1 default '',
icon_image TEXT character set latin1 default '',
icon_image_alt TEXT character set latin1 default '',
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (service_id),
UNIQUE KEY instance_id (instance_id,config_type,service_object_id),
KEY service_object_id (service_object_id)
config_type smallint default 0,
timeperiod_object_id bigint unsigned default 0,
alias varchar(255) character set latin1 default '',
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (timeperiod_id),
UNIQUE KEY instance_id (instance_id,config_type,timeperiod_object_id)
) ENGINE=InnoDB COMMENT='Timeperiod definitions';
config_type smallint(6) DEFAULT '0',
identity varchar(255) DEFAULT NULL,
node varchar(255) DEFAULT NULL,
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (endpoint_id)
) ENGINE=InnoDB COMMENT='Endpoint configuration';
config_type smallint(6) DEFAULT '0',
parent_zone_object_id bigint(20) unsigned DEFAULT '0',
is_global smallint(6),
+ config_hash varchar(64) DEFAULT NULL,
PRIMARY KEY (zone_id)
) ENGINE=InnoDB COMMENT='Zone configuration';
CREATE INDEX idx_zonestatus_parent_object_id on icinga_zonestatus(parent_zone_object_id);
-- #12210
-CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
-CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
-CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
-
-CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
-CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
-
CREATE INDEX idx_comments_session_del ON icinga_comments (instance_id, session_token);
CREATE INDEX idx_downtimes_session_del ON icinga_scheduleddowntime (instance_id, session_token);
-- #12107
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
+-- #12435
+CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
+CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
+CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
+CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
+CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
+CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
+CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
+CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
+
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------
-- -----------------------------------------
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
--- -----------------------------------------
--- #12210
--- -----------------------------------------
-
-ALTER TABLE icinga_hostgroup_members ADD COLUMN session_token int default NULL;
-ALTER TABLE icinga_servicegroup_members ADD COLUMN session_token int default NULL;
-ALTER TABLE icinga_contactgroup_members ADD COLUMN session_token int default NULL;
-
-CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
-CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
-CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
-
-DROP INDEX cv_session_del_idx ON icinga_customvariables;
-DROP INDEX cvs_session_del_idx ON icinga_customvariablestatus;
-
-CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
-CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
-
-- -----------------------------------------
-- #12258
-- -----------------------------------------
CREATE INDEX idx_comments_session_del ON icinga_comments (instance_id, session_token);
CREATE INDEX idx_downtimes_session_del ON icinga_scheduleddowntime (instance_id, session_token);
+-- -----------------------------------------
+-- #12435
+-- -----------------------------------------
+ALTER TABLE icinga_commands ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_contactgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_contacts ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_hostgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_hosts ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_servicegroups ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_services ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_timeperiods ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_endpoints ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_zones ADD config_hash VARCHAR(64) DEFAULT NULL;
+
+ALTER TABLE icinga_customvariables DROP session_token;
+ALTER TABLE icinga_customvariablestatus DROP session_token;
+
+CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
+CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
+CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
+CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
+CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
+CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
+CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
+CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
+
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------
void IdoPgsqlConnection::ClearTablesBySession(void)
{
- /* delete all customvariables and group members without current session token */
- ClearTableBySession("customvariables");
- ClearTableBySession("customvariablestatus");
- ClearTableBySession("hostgroup_members");
- ClearTableBySession("servicegroup_members");
- ClearTableBySession("contactgroup_members");
+ /* delete all comments and downtimes without current session token */
ClearTableBySession("comments");
ClearTableBySession("scheduleddowntime");
}
Convert::ToString(GetSessionToken()));
}
-void IdoPgsqlConnection::ClearConfigTable(const String& table)
-{
- Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " + Convert::ToString(static_cast<long>(m_InstanceID)));
-}
-
IdoPgsqlResult IdoPgsqlConnection::Query(const String& query)
{
AssertOnWorkQueue();
void IdoPgsqlConnection::FillIDCache(const DbType::Ptr& type)
{
- String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id FROM " + GetTablePrefix() + type->GetTable() + "s";
+ String query = "SELECT " + type->GetIDColumn() + " AS object_id, " + type->GetTable() + "_id, config_hash FROM " + GetTablePrefix() + type->GetTable() + "s";
IdoPgsqlResult result = Query(query);
Dictionary::Ptr row;
int index = 0;
while ((row = FetchRow(result, index))) {
index++;
- SetInsertID(type, DbReference(row->Get("object_id")), DbReference(row->Get(type->GetTable() + "_id")));
+ DbReference dbref(row->Get("object_id"));
+ SetInsertID(type, dbref, DbReference(row->Get(type->GetTable() + "_id")));
+ SetConfigHash(type, dbref, row->Get("config_hash"));
}
}
void InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
- virtual void ClearConfigTable(const String& table) override;
void ClearTableBySession(const String& table);
void ClearTablesBySession(void);
config_type INTEGER default 0,
object_id bigint default 0,
command_line TEXT default '',
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_command_id PRIMARY KEY (command_id) ,
CONSTRAINT UQ_commands UNIQUE (instance_id,object_id,config_type)
) ;
config_type INTEGER default 0,
contactgroup_object_id bigint default 0,
alias TEXT default '',
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_contactgroup_id PRIMARY KEY (contactgroup_id) ,
CONSTRAINT UQ_contactgroups UNIQUE (instance_id,config_type,contactgroup_object_id)
);
notify_host_unreachable INTEGER default 0,
notify_host_flapping INTEGER default 0,
notify_host_downtime INTEGER default 0,
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_contact_id PRIMARY KEY (contact_id) ,
CONSTRAINT UQ_contacts UNIQUE (instance_id,config_type,contact_object_id)
) ;
notes TEXT default NULL,
notes_url TEXT default NULL,
action_url TEXT default NULL,
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_hostgroup_id PRIMARY KEY (hostgroup_id) ,
CONSTRAINT UQ_hostgroups UNIQUE (instance_id,hostgroup_object_id)
) ;
x_3d double precision default 0,
y_3d double precision default 0,
z_3d double precision default 0,
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_host_id PRIMARY KEY (host_id) ,
CONSTRAINT UQ_hosts UNIQUE (instance_id,config_type,host_object_id)
) ;
notes TEXT default NULL,
notes_url TEXT default NULL,
action_url TEXT default NULL,
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_servicegroup_id PRIMARY KEY (servicegroup_id) ,
CONSTRAINT UQ_servicegroups UNIQUE (instance_id,config_type,servicegroup_object_id)
) ;
action_url TEXT default '',
icon_image TEXT default '',
icon_image_alt TEXT default '',
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_service_id PRIMARY KEY (service_id) ,
CONSTRAINT UQ_services UNIQUE (instance_id,config_type,service_object_id)
) ;
config_type INTEGER default 0,
timeperiod_object_id bigint default 0,
alias TEXT default '',
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_timeperiod_id PRIMARY KEY (timeperiod_id) ,
CONSTRAINT UQ_timeperiods UNIQUE (instance_id,config_type,timeperiod_object_id)
) ;
config_type integer default 0,
identity text DEFAULT NULL,
node text DEFAULT NULL,
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_endpoint_id PRIMARY KEY (endpoint_id) ,
CONSTRAINT UQ_endpoints UNIQUE (instance_id,config_type,endpoint_object_id)
) ;
parent_zone_object_id bigint default 0,
config_type integer default 0,
is_global integer default 0,
+ config_hash varchar(64) DEFAULT NULL,
CONSTRAINT PK_zone_id PRIMARY KEY (zone_id) ,
CONSTRAINT UQ_zones UNIQUE (instance_id,config_type,zone_object_id)
) ;
CREATE INDEX idx_zonestatus_parent_object_id on icinga_zonestatus(parent_zone_object_id);
-- #12210
-CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
-CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
-CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
-
CREATE INDEX idx_comments_session_del ON icinga_comments (instance_id, session_token);
CREATE INDEX idx_downtimes_session_del ON icinga_scheduleddowntime (instance_id, session_token);
-CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
-CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
-
-- #12107
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
+-- #12435
+CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
+CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
+CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
+CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
+CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
+CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
+CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
+CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
+
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------
CREATE INDEX idx_zones_parent_object_id on icinga_zones(parent_zone_object_id);
CREATE INDEX idx_zonestatus_parent_object_id on icinga_zonestatus(parent_zone_object_id);
--- -----------------------------------------
--- #12210
--- -----------------------------------------
-
-ALTER TABLE icinga_hostgroup_members ADD COLUMN session_token INTEGER default NULL;
-ALTER TABLE icinga_servicegroup_members ADD COLUMN session_token INTEGER default NULL;
-ALTER TABLE icinga_contactgroup_members ADD COLUMN session_token INTEGER default NULL;
-
-CREATE INDEX idx_hg_session_del ON icinga_hostgroup_members (instance_id, session_token);
-CREATE INDEX idx_sg_session_del ON icinga_servicegroup_members (instance_id, session_token);
-CREATE INDEX idx_cg_session_del ON icinga_contactgroup_members (instance_id, session_token);
-
-DROP INDEX cv_session_del_idx;
-DROP INDEX cvs_session_del_idx;
-
-CREATE INDEX idx_cv_session_del ON icinga_customvariables (instance_id, session_token);
-CREATE INDEX idx_cvs_session_del ON icinga_customvariablestatus (instance_id, session_token);
-
-- -----------------------------------------
-- #12258
-- -----------------------------------------
-- -----------------------------------------
CREATE INDEX idx_statehistory_cleanup on icinga_statehistory(instance_id, state_time);
+-- -----------------------------------------
+-- #12435
+-- -----------------------------------------
+ALTER TABLE icinga_commands ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_contactgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_contacts ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_hostgroups ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_hosts ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_servicegroups ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_services ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_timeperiods ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_endpoints ADD config_hash VARCHAR(64) DEFAULT NULL;
+ALTER TABLE icinga_zones ADD config_hash VARCHAR(64) DEFAULT NULL;
+
+ALTER TABLE icinga_customvariables DROP session_token;
+ALTER TABLE icinga_customvariablestatus DROP session_token;
+
+CREATE INDEX idx_customvariables_object_id on icinga_customvariables(object_id);
+CREATE INDEX idx_contactgroup_members_object_id on icinga_contactgroup_members(contact_object_id);
+CREATE INDEX idx_hostgroup_members_object_id on icinga_hostgroup_members(host_object_id);
+CREATE INDEX idx_servicegroup_members_object_id on icinga_servicegroup_members(service_object_id);
+CREATE INDEX idx_servicedependencies_dependent_service_object_id on icinga_servicedependencies(dependent_service_object_id);
+CREATE INDEX idx_hostdependencies_dependent_host_object_id on icinga_hostdependencies(dependent_host_object_id);
+CREATE INDEX idx_service_contacts_service_id on icinga_service_contacts(service_id);
+CREATE INDEX idx_host_contacts_host_id on icinga_host_contacts(host_id);
+
-- -----------------------------------------
-- set dbversion
-- -----------------------------------------