void MysqlDbConnection::ActivateObject(const DbObject::Ptr& dbobj)
{
boost::mutex::scoped_lock lock(m_ConnectionMutex);
+ InternalActivateObject(dbobj);
+}
+void MysqlDbConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
+{
if (!m_Connected)
return;
SetReference(dbobj, DbReference());
}
+/* caller must hold m_ConnectionMutex */
bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& value, Value *result)
{
if (key == "instance_id") {
DbReference dbrefcol = GetReference(dbobjcol);
if (!dbrefcol.IsValid()) {
- ActivateObject(dbobjcol);
+ InternalActivateObject(dbobjcol);
dbrefcol = GetReference(dbobjcol);
*result = static_cast<long>(dbrefcol);
} else if (DbValue::IsTimestamp(value)) {
- double ts = DbValue::ExtractValue(value);
+ long ts = DbValue::ExtractValue(value);
std::ostringstream msgbuf;
msgbuf << "FROM_UNIXTIME(" << ts << ")";
*result = Value(msgbuf.str());
Dictionary::Ptr FetchRow(MYSQL_RES *result);
bool FieldToEscapedString(const String& key, const Value& value, Value *result);
+ void InternalActivateObject(const DbObject::Ptr& dbobj);
void TxTimerHandler(void);
void ReconnectTimerHandler(void);
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered;
boost::signals2::signal<void (double, const std::set<DynamicObject::WeakPtr>&)> DynamicObject::OnTransactionClosing;
boost::signals2::signal<void (double, const DynamicObject::Ptr&)> DynamicObject::OnFlushObject;
+boost::signals2::signal<void (const DynamicObject::Ptr&, const std::set<String, string_iless>&)> DynamicObject::OnAttributesChanged;
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
: m_ConfigTx(0), m_LocalTx(0), m_Registered(false)
attrs.swap(object->m_ModifiedAttributes);
}
+ OnAttributesChanged(object, attrs);
+
BOOST_FOREACH(const String& attr, attrs) {
object->OnAttributeChanged(attr);
}
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
static boost::signals2::signal<void (double, const std::set<DynamicObject::WeakPtr>&)> OnTransactionClosing;
static boost::signals2::signal<void (double, const DynamicObject::Ptr&)> OnFlushObject;
+ static boost::signals2::signal<void (const DynamicObject::Ptr&, const std::set<String, string_iless>&)> OnAttributesChanged;
Value InvokeMethod(const String& method, const std::vector<Value>& arguments);
#include "base/dynamictype.h"
#include "base/objectlock.h"
#include "base/utility.h"
+#include "base/logger_fwd.h"
#include <boost/foreach.hpp>
using namespace icinga;
boost::signals2::signal<void (const DbQuery&)> DbObject::OnQuery;
DbObject::DbObject(const shared_ptr<DbType>& type, const String& name1, const String& name2)
- : m_Name1(name1), m_Name2(name2), m_Type(type)
+ : m_Name1(name1), m_Name2(name2), m_Type(type), m_LastConfigUpdate(0), m_LastStatusUpdate(0)
{ }
void DbObject::StaticInitialize(void)
{
DynamicObject::OnRegistered.connect(boost::bind(&DbObject::ObjectRegisteredHandler, _1));
DynamicObject::OnUnregistered.connect(boost::bind(&DbObject::ObjectUnregisteredHandler, _1));
-// DynamicObject::OnTransactionClosing.connect(boost::bind(&DbObject::TransactionClosingHandler, _1, _2));
-// DynamicObject::OnFlushObject.connect(boost::bind(&DbObject::FlushObjectHandler, _1, _2));
+ DynamicObject::OnAttributesChanged.connect(boost::bind(&DbObject::AttributesChangedHandler, _1, _2));
}
void DbObject::SetObject(const DynamicObject::Ptr& object)
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.Fields->Set("config_type", 1);
OnQuery(query2);
+
+ m_LastConfigUpdate = Utility::GetTime();
}
void DbObject::SendStatusUpdate(void)
query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query2.Fields->Set("status_update_time", Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", Utility::GetTime()));
OnQuery(query2);
+
+ m_LastStatusUpdate = Utility::GetTime();
+}
+
+double DbObject::GetLastConfigUpdate(void) const
+{
+ return m_LastConfigUpdate;
+}
+
+double DbObject::GetLastStatusUpdate(void) const
+{
+ return m_LastStatusUpdate;
+}
+
+bool DbObject::IsConfigAttribute(const String& attribute) const
+{
+ DynamicObject::Ptr object = GetObject();
+ ObjectLock olock(object);
+ DynamicObject::AttributeConstIterator it;
+
+ it = object->GetAttributes().find(attribute);
+
+ if (it == object->GetAttributes().end())
+ return false;
+
+ return (it->second.GetType() == Attribute_Config);
+}
+
+bool DbObject::IsStatusAttribute(const String&) const
+{
+ return false;
}
DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
name1 = object->GetName();
}
- dbobj = dbtype->GetOrCreateObjectByName(object->GetName(), String());
+ dbobj = dbtype->GetOrCreateObjectByName(name1, name2);
{
ObjectLock olock(object);
}
}
-//void DbObject::TransactionClosingHandler(double tx, const std::set<DynamicObject::WeakPtr>& modifiedObjects)
-//{
-// BOOST_FOREACH(const DynamicObject::WeakPtr& wobject, modifiedObjects) {
-// DynamicObject::Ptr object = wobject.lock();
-//
-// if (!object)
-// continue;
-//
-// FlushObjectHandler(tx, object);
-// }
-//}
-//
-//void DbObject::FlushObjectHandler(double tx, const DynamicObject::Ptr& object)
-//{
-// DbObject::Ptr dbobj = GetOrCreateByObject(object);
-//
-// if (!dbobj)
-// return;
-//
-// dbobj->SendUpdate();
-//}
+void DbObject::AttributesChangedHandler(const DynamicObject::Ptr& object, const std::set<String, string_iless>& attributes)
+{
+ DbObject::Ptr dbobj = GetOrCreateByObject(object);
+
+ if (!dbobj)
+ return;
+
+ bool configUpdate = false, statusUpdate = false;
+
+ BOOST_FOREACH(const String& attribute, attributes) {
+ if (!configUpdate && dbobj->IsConfigAttribute(attribute))
+ configUpdate = true;
+
+ if (!statusUpdate && dbobj->IsStatusAttribute(attribute))
+ statusUpdate = true;
+ }
+
+ if (configUpdate)
+ dbobj->SendConfigUpdate();
+
+ if (statusUpdate)
+ dbobj->SendStatusUpdate();
+}
void SendConfigUpdate(void);
void SendStatusUpdate(void);
+ double GetLastConfigUpdate(void) const;
+ double GetLastStatusUpdate(void) const;
+
protected:
DbObject(const boost::shared_ptr<DbType>& type, const String& name1, const String& name2);
+ virtual bool IsConfigAttribute(const String& attribute) const;
+ virtual bool IsStatusAttribute(const String& attribute) const;
+
private:
String m_Name1;
String m_Name2;
boost::shared_ptr<DbType> m_Type;
DynamicObject::Ptr m_Object;
+ double m_LastConfigUpdate;
+ double m_LastStatusUpdate;
friend boost::shared_ptr<DbObject> boost::make_shared<>(const icinga::String&, const icinga::String&);
static void ObjectRegisteredHandler(const DynamicObject::Ptr& object);
static void ObjectUnregisteredHandler(const DynamicObject::Ptr& object);
+ static void AttributesChangedHandler(const DynamicObject::Ptr& object, const std::set<String, string_iless>& attributes);
//static void TransactionClosingHandler(double tx, const std::set<DynamicObject::WeakPtr>& modifiedObjects);
//static void FlushObjectHandler(double tx, const DynamicObject::Ptr& object);
return fields;
+}
+
+bool ServiceDbObject::IsStatusAttribute(const String& attribute) const
+{
+ return (attribute == "last_result");
}
\ No newline at end of file
virtual Dictionary::Ptr GetConfigFields(void) const;
virtual Dictionary::Ptr GetStatusFields(void) const;
+
+ virtual bool IsStatusAttribute(const String& attribute) const;
};
}