]> granicus.if.org Git - icinga2/commitdiff
Implement support for timestamps.
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 23 Jul 2013 09:02:47 +0000 (11:02 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 23 Jul 2013 09:02:47 +0000 (11:02 +0200)
components/ido_mysql/mysqldbconnection.cpp
components/ido_mysql/mysqldbconnection.h
lib/ido/Makefile.am
lib/ido/dbobject.cpp
lib/ido/dbquery.cpp [new file with mode: 0644]
lib/ido/dbquery.h [new file with mode: 0644]
lib/ido/dbvalue.cpp [new file with mode: 0644]
lib/ido/dbvalue.h [new file with mode: 0644]
lib/ido/hostdbobject.cpp
lib/ido/servicedbobject.cpp

index 9c842495ad90daf21c1a481b27b059e037974b38..2e79ec0c241bba4a68e446c2cd46f4700a60a586 100644 (file)
@@ -22,6 +22,7 @@
 #include "base/convert.h"
 #include "base/utility.h"
 #include "ido/dbtype.h"
+#include "ido/dbvalue.h"
 #include "ido_mysql/mysqldbconnection.h"
 #include <boost/tuple/tuple.hpp>
 #include <boost/smart_ptr/make_shared.hpp>
@@ -136,9 +137,9 @@ void MysqlDbConnection::ReconnectTimerHandler(void)
 
                Query("UPDATE icinga_objects SET is_active = 0");
 
-               std::ostringstream qbuf;
-               qbuf << "SELECT object_id, objecttype_id, name1, name2 FROM icinga_objects WHERE instance_id = " << static_cast<long>(m_InstanceID);
-               rows = Query(qbuf.str());
+               std::ostringstream q1buf;
+               q1buf << "SELECT object_id, objecttype_id, name1, name2 FROM icinga_objects WHERE instance_id = " << static_cast<long>(m_InstanceID);
+               rows = Query(q1buf.str());
 
                ObjectLock olock(rows);
                BOOST_FOREACH(const Dictionary::Ptr& row, rows) {
@@ -151,6 +152,11 @@ void MysqlDbConnection::ReconnectTimerHandler(void)
                        SetReference(dbobj, DbReference(row->Get("object_id")));
                }
 
+               // TODO: Use a timer, move to libido
+               std::ostringstream q2buf;
+               q2buf << "REPLACE INTO icinga_programstatus (instance_id, status_update_time) VALUES (" << static_cast<long>(m_InstanceID) << ", NOW())";
+               Query(q2buf.str());
+
                Query("BEGIN");
        }
 
@@ -276,9 +282,12 @@ void MysqlDbConnection::DeactivateObject(const DbObject::Ptr& dbobj)
        SetReference(dbobj, DbReference());
 }
 
-bool MysqlDbConnection::FieldToString(const String& key, const Value& value, Value *result)
+bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& value, Value *result)
 {
-       *result = value;
+       if (key == "instance_id") {
+               *result = static_cast<long>(m_InstanceID);
+               return true;
+       }
 
        if (value.IsObjectType<DynamicObject>()) {
                DbObject::Ptr dbobjcol = DbObject::GetOrCreateByObject(value);
@@ -300,16 +309,27 @@ bool MysqlDbConnection::FieldToString(const String& key, const Value& value, Val
                }
 
                *result = static_cast<long>(dbrefcol);
+       } else if (DbValue::IsTimestamp(value)) {
+               double ts = DbValue::ExtractValue(value);
+               std::ostringstream msgbuf;
+               msgbuf << "FROM_UNIXTIME(" << ts << ")";
+               *result = Value(msgbuf.str());
+       } else if (DbValue::IsTimestampNow(value)) {
+               *result = "NOW()";
+       } else {
+               *result = "'" + Escape(DbValue::ExtractValue(value)) + "'";
        }
 
-       if (key == "instance_id")
-               *result = static_cast<long>(m_InstanceID);
-
        return true;
 }
 
 void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
 {
+       boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+       if (!m_Connected)
+               return;
+
        std::ostringstream qbuf;
 
        switch (query.Type) {
@@ -336,7 +356,7 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
                Value value;
                bool first = true;
                BOOST_FOREACH(boost::tie(key, value), query.Fields) {
-                       if (!FieldToString(key, value, &value))
+                       if (!FieldToEscapedString(key, value, &value))
                                return;
 
                        if (query.Type == DbQueryInsert) {
@@ -346,12 +366,12 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
                                }
 
                                cols += key;
-                               values += "'" + Convert::ToString(value) + "'";
+                               values += Convert::ToString(value);
                        } else {
                                if (!first)
                                        qbuf << ", ";
 
-                               qbuf << " " << key << " = '" << Escape(value) << "'";
+                               qbuf << " " << key << " = " << value;
                        }
 
                        if (first)
@@ -371,7 +391,7 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
                Value value;
                bool first = true;
                BOOST_FOREACH(boost::tie(key, value), query.WhereCriteria) {
-                       if (!FieldToString(Empty, value, &value))
+                       if (!FieldToEscapedString(Empty, value, &value))
                                return;
 
                        if (!first)
@@ -384,6 +404,5 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
                }
        }
 
-       boost::mutex::scoped_lock lock(m_ConnectionMutex);
        Query(qbuf.str());
 }
index bc3b2b0189234cf333144db65065b6bbc2a1d56a..6384ffb48ffcf5c6ec7da452cbb9c60d38ea6470 100644 (file)
@@ -73,7 +73,7 @@ private:
        String Escape(const String& s);
        Dictionary::Ptr FetchRow(MYSQL_RES *result);
 
-       bool FieldToString(const String& key, const Value& value, Value *result);
+       bool FieldToEscapedString(const String& key, const Value& value, Value *result);
 
        void TxTimerHandler(void);
        void ReconnectTimerHandler(void);
index 51d27cbfcdde65aa30f6a4c852df2d68bffb02da..0867fa24667ba3c380bd40ff9ba09854bb42a807 100644 (file)
@@ -20,6 +20,8 @@ libido_la_SOURCES = \
        dbreference.h \
        dbtype.cpp \
        dbtype.h \
+       dbvalue.cpp \
+       dbvalue.h \
        hostdbobject.cpp \
        hostdbobject.h \
        ido-type.cpp \
index 9da69bc50239c2e2cb8523992e13b62c2098d45c..4d1e9920cfb054719b2ff6657d896fdd48bc0521 100644 (file)
@@ -88,6 +88,7 @@ void DbObject::SendConfigUpdate(void)
 
        query2.Fields->Set(GetType()->GetTable() + "_object_id", GetObject());
        query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+       query2.Fields->Set("config_type", 1);
        OnQuery(query2);
 }
 
diff --git a/lib/ido/dbquery.cpp b/lib/ido/dbquery.cpp
new file mode 100644 (file)
index 0000000..6e9dee8
--- /dev/null
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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 "ido/dbquery.h"
+
+using namespace icinga;
diff --git a/lib/ido/dbquery.h b/lib/ido/dbquery.h
new file mode 100644 (file)
index 0000000..223dcc5
--- /dev/null
@@ -0,0 +1,45 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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 DBQUERY_H
+#define DBQUERY_H
+
+#include "base/dictionary.h"
+
+namespace icinga
+{
+
+enum DbQueryType
+{
+       DbQueryInsert,
+       DbQueryUpdate,
+       DbQueryDelete
+};
+
+struct DbQuery
+{
+       DbQueryType Type;
+       String Table;
+       Dictionary::Ptr Fields;
+       Dictionary::Ptr WhereCriteria;
+};
+
+}
+
+#endif /* DBQUERY_H */
diff --git a/lib/ido/dbvalue.cpp b/lib/ido/dbvalue.cpp
new file mode 100644 (file)
index 0000000..6a6034a
--- /dev/null
@@ -0,0 +1,81 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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 "ido/dbvalue.h"
+
+using namespace icinga;
+
+DbValue::DbValue(DbValueType type, const Value& value)
+       : m_Type(type), m_Value(value)
+{ }
+
+Value DbValue::FromTimestamp(const Value& ts)
+{
+       if (ts.IsEmpty() || ts == 0)
+               return Empty;
+
+       return boost::make_shared<DbValue>(DbValueTimestamp, ts);
+}
+
+Value DbValue::FromTimestampNow(void)
+{
+       return boost::make_shared<DbValue>(DbValueTimestampNow, Empty);
+}
+
+Value DbValue::FromValue(const Value& value)
+{
+       return value;
+}
+
+bool DbValue::IsTimestamp(const Value& value)
+{
+       if (!value.IsObjectType<DbValue>())
+               return false;
+
+       DbValue::Ptr dbv = value;
+       return dbv->GetType() == DbValueTimestamp;
+}
+
+bool DbValue::IsTimestampNow(const Value& value)
+{
+       if (!value.IsObjectType<DbValue>())
+               return false;
+
+       DbValue::Ptr dbv = value;
+       return dbv->GetType() == DbValueTimestampNow;
+}
+
+Value DbValue::ExtractValue(const Value& value)
+{
+       if (!value.IsObjectType<DbValue>())
+               return value;
+
+       DbValue::Ptr dbv = value;
+       return dbv->GetValue();
+}
+
+DbValueType DbValue::GetType(void) const
+{
+       return m_Type;
+}
+
+Value DbValue::GetValue(void) const
+{
+       return m_Value;
+}
diff --git a/lib/ido/dbvalue.h b/lib/ido/dbvalue.h
new file mode 100644 (file)
index 0000000..526fbc0
--- /dev/null
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 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 DBVALUE_H
+#define DBVALUE_H
+
+#include "base/object.h"
+#include "base/value.h"
+#include <boost/smart_ptr/make_shared.hpp>
+
+namespace icinga
+{
+
+enum DbValueType
+{
+       DbValueTimestamp,
+       DbValueTimestampNow,
+};
+
+/**
+ * A database value.
+ *
+ * @ingroup ido
+ */
+struct DbValue : public Object
+{
+public:
+       DECLARE_PTR_TYPEDEFS(DbValue);
+
+       static Value FromTimestamp(const Value& ts);
+       static Value FromTimestampNow(void);
+       static Value FromValue(const Value& value);
+
+       static bool IsTimestamp(const Value& value);
+       static bool IsTimestampNow(const Value& value);
+       static Value ExtractValue(const Value& value);
+
+       DbValueType GetType(void) const;
+       Value GetValue(void) const;
+
+protected:
+       DbValue(DbValueType type, const Value& value);
+
+private:
+       DbValueType m_Type;
+       Value m_Value;
+
+       friend boost::shared_ptr<DbValue> boost::make_shared<>(const icinga::DbValueType&, const double&);
+       friend boost::shared_ptr<DbValue> boost::make_shared<>(const icinga::DbValueType&, const icinga::Value&);
+};
+
+}
+
+#endif /* DBVALUE_H */
index f8b14bf349bdee628f802be2edc36695f3d04a8e..7b2f17a8c3c72b3a2c69915a661c20b48e9b677c 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "ido/hostdbobject.h"
 #include "ido/dbtype.h"
+#include "ido/dbvalue.h"
 #include "icinga/host.h"
 #include "icinga/service.h"
 #include "icinga/checkcommand.h"
@@ -133,14 +134,14 @@ Dictionary::Ptr HostDbObject::GetStatusFields(void) const
        fields->Set("output", attrs->Get("plugin_output"));
        fields->Set("long_output", attrs->Get("long_plugin_output"));
        fields->Set("perfdata", attrs->Get("performance_data"));
-       fields->Set("last_check", attrs->Get("last_check"));
-       fields->Set("next_check", attrs->Get("next_check"));
+       fields->Set("last_check", DbValue::FromTimestamp(attrs->Get("last_check")));
+       fields->Set("next_check", DbValue::FromTimestamp(attrs->Get("next_check")));
        fields->Set("current_check_attempt", attrs->Get("current_attempt"));
        fields->Set("max_check_attempts", attrs->Get("max_attempts"));
-       fields->Set("last_state_change", attrs->Get("last_state_change"));
-       fields->Set("last_hard_state_change", attrs->Get("last_hard_state_change"));
-       fields->Set("last_time_up", attrs->Get("last_time_up"));
-       fields->Set("last_time_down", attrs->Get("last_time_down"));
+       fields->Set("last_state_change", DbValue::FromTimestamp(attrs->Get("last_state_change")));
+       fields->Set("last_hard_state_change", DbValue::FromTimestamp(attrs->Get("last_hard_state_change")));
+       fields->Set("last_time_up", DbValue::FromTimestamp(attrs->Get("last_time_up")));
+       fields->Set("last_time_down", DbValue::FromTimestamp(attrs->Get("last_time_down")));
        fields->Set("last_time_unreachable", attrs->Get("last_time_unreachable"));
        //fields->Set("last_update", attrs->Get("last_update"));
        fields->Set("notifications_enabled", attrs->Get("notifications_enabled"));
@@ -153,8 +154,8 @@ Dictionary::Ptr HostDbObject::GetStatusFields(void) const
        fields->Set("acknowledgement_type", attrs->Get("acknowledgement_type"));
        //fields->Set("acknowledgement_end_time", attrs->Get("acknowledgement_end_time"));
        fields->Set("scheduled_downtime_depth", attrs->Get("scheduled_downtime_depth"));
-       fields->Set("last_notification", attrs->Get("last_notification"));
-       fields->Set("next_notification", attrs->Get("next_notification"));
+       fields->Set("last_notification", DbValue::FromTimestamp(attrs->Get("last_notification")));
+       fields->Set("next_notification", DbValue::FromTimestamp(attrs->Get("next_notification")));
        fields->Set("current_notification_number", attrs->Get("current_notification_number"));
 
 
index 364b888c0da16b540e341cc2fe97de66c3d649a9..7d61bd9a6731a2508a43ae56dd9f82962228bc58 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "ido/servicedbobject.h"
 #include "ido/dbtype.h"
+#include "ido/dbvalue.h"
 #include "base/objectlock.h"
 #include "icinga/service.h"
 #include "icinga/checkcommand.h"
@@ -37,6 +38,12 @@ Dictionary::Ptr ServiceDbObject::GetConfigFields(void) const
        Dictionary::Ptr fields = boost::make_shared<Dictionary>();
        Service::Ptr service = static_pointer_cast<Service>(GetObject());
 
+       Host::Ptr host = service->GetHost();
+
+       if (!host)
+               return Dictionary::Ptr();
+
+       fields->Set("host_object_id", host);
        fields->Set("display_name", service->GetDisplayName());
        fields->Set("check_command_object_id", service->GetCheckCommand());
        fields->Set("check_command_args", Empty);
@@ -45,8 +52,8 @@ Dictionary::Ptr ServiceDbObject::GetConfigFields(void) const
        fields->Set("notification_timeperiod_object_id", Empty);
        fields->Set("check_timeperiod_object_id", Empty);
        fields->Set("failure_prediction_options", Empty);
-       fields->Set("check_interval", service->GetCheckInterval() * 60);
-       fields->Set("retry_interval", service->GetRetryInterval() * 60);
+       fields->Set("check_interval", service->GetCheckInterval() / 60);
+       fields->Set("retry_interval", service->GetRetryInterval() / 60);
        fields->Set("max_check_attempts", service->GetMaxCheckAttempts());
        fields->Set("first_notification_delay", Empty);
        fields->Set("notification_interval", Empty);
@@ -111,16 +118,16 @@ Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const
        fields->Set("output", attrs->Get("plugin_output"));
        fields->Set("long_output", attrs->Get("long_plugin_output"));
        fields->Set("perfdata", attrs->Get("performance_data"));
-       fields->Set("last_check", attrs->Get("last_check"));
-       fields->Set("next_check", attrs->Get("next_check"));
+       fields->Set("last_check", DbValue::FromTimestamp(attrs->Get("last_check")));
+       fields->Set("next_check", DbValue::FromTimestamp(attrs->Get("next_check")));
        fields->Set("current_check_attempt", attrs->Get("current_attempt"));
        fields->Set("max_check_attempts", attrs->Get("max_attempts"));
-       fields->Set("last_state_change", attrs->Get("last_state_change"));
-       fields->Set("last_hard_state_change", attrs->Get("last_hard_state_change"));
-       fields->Set("last_time_ok", attrs->Get("last_time_ok"));
-       fields->Set("last_time_warning", attrs->Get("last_time_warn"));
-       fields->Set("last_time_critical", attrs->Get("last_time_critical"));
-       fields->Set("last_time_unknown", attrs->Get("last_time_unknown"));
+       fields->Set("last_state_change", DbValue::FromTimestamp(attrs->Get("last_state_change")));
+       fields->Set("last_hard_state_change", DbValue::FromTimestamp(attrs->Get("last_hard_state_change")));
+       fields->Set("last_time_ok", DbValue::FromTimestamp(attrs->Get("last_time_ok")));
+       fields->Set("last_time_warning", DbValue::FromTimestamp(attrs->Get("last_time_warn")));
+       fields->Set("last_time_critical", DbValue::FromTimestamp(attrs->Get("last_time_critical")));
+       fields->Set("last_time_unknown", DbValue::FromTimestamp(attrs->Get("last_time_unknown")));
        //fields->Set("last_update", attrs->Get("last_update"));
        fields->Set("notifications_enabled", attrs->Get("notifications_enabled"));
        fields->Set("active_checks_enabled", attrs->Get("active_checks_enabled"));
@@ -132,8 +139,8 @@ Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const
        fields->Set("acknowledgement_type", attrs->Get("acknowledgement_type"));
        //fields->Set("acknowledgement_end_time", attrs->Get("acknowledgement_end_time"));
        fields->Set("scheduled_downtime_depth", attrs->Get("scheduled_downtime_depth"));
-       fields->Set("last_notification", attrs->Get("last_notification"));
-       fields->Set("next_notification", attrs->Get("next_notification"));
+       fields->Set("last_notification", DbValue::FromTimestamp(attrs->Get("last_notification")));
+       fields->Set("next_notification", DbValue::FromTimestamp(attrs->Get("next_notification")));
        fields->Set("current_notification_number", attrs->Get("current_notification_number"));