]> granicus.if.org Git - icinga2/commitdiff
ido: Keep track of insert IDs.
authorGunnar Beutner <gunnar.beutner@netways.de>
Fri, 2 Aug 2013 06:56:36 +0000 (08:56 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 2 Aug 2013 06:59:19 +0000 (08:59 +0200)
components/ido_mysql/mysqldbconnection.cpp
components/ido_mysql/mysqldbconnection.h
lib/ido/dbconnection.cpp
lib/ido/dbconnection.h
lib/ido/dbobject.cpp
lib/ido/dbquery.h

index 449d8eacc83a294f70861566143fd8d1b671c894..f59216aa9aaf5bfed80fdf7e15fd4af8758fecbc 100644 (file)
@@ -125,7 +125,7 @@ void MysqlDbConnection::ReconnectTimerHandler(void)
 
                if (rows->GetLength() == 0) {
                        Query("INSERT INTO " + GetTablePrefix() + "instances (instance_name, instance_description) VALUES ('" + Escape(instanceName) + "', '" + m_InstanceDescription + "')");
-                       m_InstanceID = GetInsertID();
+                       m_InstanceID = GetLastInsertID();
                } else {
                        Dictionary::Ptr row = rows->Get(0);
                        m_InstanceID = DbReference(row->Get("instance_id"));
@@ -149,7 +149,7 @@ void MysqlDbConnection::ReconnectTimerHandler(void)
                                continue;
 
                        DbObject::Ptr dbobj = dbtype->GetOrCreateObjectByName(row->Get("name1"), row->Get("name2"));
-                       SetReference(dbobj, DbReference(row->Get("object_id")));
+                       SetObjectID(dbobj, DbReference(row->Get("object_id")));
                }
 
                Query("BEGIN");
@@ -190,7 +190,7 @@ Array::Ptr MysqlDbConnection::Query(const String& query)
        return rows;
 }
 
-DbReference MysqlDbConnection::GetInsertID(void)
+DbReference MysqlDbConnection::GetLastInsertID(void)
 {
        return DbReference(mysql_insert_id(&m_Connection));
 }
@@ -251,7 +251,7 @@ void MysqlDbConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
        if (!m_Connected)
                return;
 
-       DbReference dbref = GetReference(dbobj);
+       DbReference dbref = GetObjectID(dbobj);
        std::ostringstream qbuf;
 
        if (!dbref.IsValid()) {
@@ -259,7 +259,7 @@ void MysqlDbConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
                      << static_cast<long>(m_InstanceID) << ", " << dbobj->GetType()->GetTypeID() << ", "
                      << "'" << Escape(dbobj->GetName1()) << "', '" << Escape(dbobj->GetName2()) << "', 1)";
                Query(qbuf.str());
-               SetReference(dbobj, GetInsertID());
+               SetObjectID(dbobj, GetLastInsertID());
        } else {
                qbuf << "UPDATE " + GetTablePrefix() + "objects SET is_active = 1 WHERE object_id = " << static_cast<long>(dbref);
                Query(qbuf.str());
@@ -273,7 +273,7 @@ void MysqlDbConnection::DeactivateObject(const DbObject::Ptr& dbobj)
        if (!m_Connected)
                return;
 
-       DbReference dbref = GetReference(dbobj);
+       DbReference dbref = GetObjectID(dbobj);
 
        if (!dbref.IsValid())
                return;
@@ -299,12 +299,12 @@ bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& val
                        return true;
                }
 
-               DbReference dbrefcol = GetReference(dbobjcol);
+               DbReference dbrefcol = GetObjectID(dbobjcol);
 
                if (!dbrefcol.IsValid()) {
                        InternalActivateObject(dbobjcol);
 
-                       dbrefcol = GetReference(dbobjcol);
+                       dbrefcol = GetObjectID(dbobjcol);
 
                        if (!dbrefcol.IsValid())
                                return false;
@@ -332,14 +332,51 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
        if (!m_Connected)
                return;
 
-       std::ostringstream qbuf;
+       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)
+                               qbuf << " AND ";
+
+                       where << key << " = " << value;
+
+                       if (first)
+                               first = false;
+               }
+       }
+
+       if ((query.Type & DbQueryInsert) && (query.Type & DbQueryUpdate)) {
+               assert(query.Object);
+
+               if (GetInsertID(query.Object).IsValid())
+                       type = DbQueryUpdate;
+               else {
+                       if (query.WhereCriteria)
+                               Query("DELETE FROM " + GetTablePrefix() + query.Table + where.str());
 
-       switch (query.Type) {
+                       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";
+                       qbuf << "UPDATE " << GetTablePrefix() << query.Table << " SET";
                        break;
                case DbQueryDelete:
                        qbuf << "DELETE FROM " << GetTablePrefix() << query.Table;
@@ -348,7 +385,7 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
                        ASSERT(!"Invalid query type.");
        }
 
-       if (query.Type == DbQueryInsert || query.Type == DbQueryUpdate) {
+       if (type == DbQueryInsert || type == DbQueryUpdate) {
                String cols;
                String values;
 
@@ -361,7 +398,7 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
                        if (!FieldToEscapedString(key, value, &value))
                                return;
 
-                       if (query.Type == DbQueryInsert) {
+                       if (type == DbQueryInsert) {
                                if (!first) {
                                        cols += ", ";
                                        values += ", ";
@@ -380,31 +417,15 @@ void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
                                first = false;
                }
 
-               if (query.Type == DbQueryInsert)
+               if (type == DbQueryInsert)
                        qbuf << " (" << cols << ") VALUES (" << values << ")";
        }
 
-       if (query.WhereCriteria) {
-               qbuf << " 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)
-                               qbuf << " AND ";
-
-                       qbuf << key << " = " << value;
-
-                       if (first)
-                               first = false;
-               }
-       }
+       if (type != DbQueryInsert)
+               qbuf << where.str();
 
        Query(qbuf.str());
+
+       if (type == DbQueryInsert && query.Object)
+               SetInsertID(query.Object, GetLastInsertID());
 }
index 62861558222bd212d0a764ab3acf7ae57a4cc5ac..5d71dc2e4738f3ff0d38b6c08100312b2646c85f 100644 (file)
@@ -69,7 +69,7 @@ private:
        Timer::Ptr m_TxTimer;
 
        Array::Ptr Query(const String& query);
-       DbReference GetInsertID(void);
+       DbReference GetLastInsertID(void);
        String Escape(const String& s);
        Dictionary::Ptr FetchRow(MYSQL_RES *result);
 
index 408d5270ca5fbb833d06911006749f017dd3055f..35768e53f94d7e31810d2295fe935b1d45191572 100644 (file)
@@ -91,26 +91,47 @@ void DbConnection::ProgramStatusHandler(void)
        DbObject::OnQuery(query2);
 }
 
-void DbConnection::SetReference(const DbObject::Ptr& dbobj, const DbReference& dbref)
+void DbConnection::SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref)
 {
        if (dbref.IsValid())
-               m_References[dbobj] = dbref;
+               m_ObjectIDs[dbobj] = dbref;
        else
-               m_References.erase(dbobj);
+               m_ObjectIDs.erase(dbobj);
 }
 
-DbReference DbConnection::GetReference(const DbObject::Ptr& dbobj) const
+DbReference DbConnection::GetObjectID(const DbObject::Ptr& dbobj) const
 {
        std::map<DbObject::Ptr, DbReference>::const_iterator it;
 
-       it = m_References.find(dbobj);
+       it = m_ObjectIDs.find(dbobj);
 
-       if (it == m_References.end())
+       if (it == m_ObjectIDs.end())
                return DbReference();
 
        return it->second;
 }
 
+void DbConnection::SetInsertID(const DbObject::Ptr& dbobj, const DbReference& dbref)
+{
+       if (dbref.IsValid())
+               m_InsertIDs[dbobj] = dbref;
+       else
+               m_InsertIDs.erase(dbobj);
+}
+
+DbReference DbConnection::GetInsertID(const DbObject::Ptr& dbobj) const
+{
+       std::map<DbObject::Ptr, DbReference>::const_iterator it;
+
+       it = m_InsertIDs.find(dbobj);
+
+       if (it == m_InsertIDs.end())
+               return DbReference();
+
+       return it->second;
+}
+
+
 void DbConnection::ExecuteQuery(const DbQuery&)
 {
        /* Default handler does nothing. */
index 7aa2163b241049d46b8f35a8dab7212cb6bcc2e2..0a7949ca4b5373340b635faa8822a7a56e0740b4 100644 (file)
@@ -42,8 +42,11 @@ public:
 
        static void StaticInitialize(void);
 
-       void SetReference(const DbObject::Ptr& dbobj, const DbReference& dbref);
-       DbReference GetReference(const DbObject::Ptr& dbobj) const;
+       void SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref);
+       DbReference GetObjectID(const DbObject::Ptr& dbobj) const;
+
+       void SetInsertID(const DbObject::Ptr& dbobj, const DbReference& dbref);
+       DbReference GetInsertID(const DbObject::Ptr& dbobj) const;
 
        String GetTablePrefix(void) const;
 
@@ -59,7 +62,8 @@ protected:
 private:
        Attribute<String> m_TablePrefix;
 
-       std::map<DbObject::Ptr, DbReference> m_References;
+       std::map<DbObject::Ptr, DbReference> m_ObjectIDs;
+       std::map<DbObject::Ptr, DbReference> m_InsertIDs;
        static Timer::Ptr m_ProgramStatusTimer;
 
        static void ProgramStatusHandler(void);
index 11d27204aa2746248be4a734f464a8077f1f5572..d8b3a9ca41bfdf1281e2d357b124640c63a1a6cf 100644 (file)
@@ -79,21 +79,17 @@ void DbObject::SendConfigUpdate(void)
        if (!fields)
                return;
 
-       DbQuery query1;
-       query1.Table = GetType()->GetTable() + "s";
-       query1.Type = DbQueryDelete;
-       query1.WhereCriteria = boost::make_shared<Dictionary>();
-       query1.WhereCriteria->Set(GetType()->GetIDColumn(), GetObject());
-       OnQuery(query1);
-
-       DbQuery query2;
-       query2.Table = GetType()->GetTable() + "s";
-       query2.Type = DbQueryInsert;
-       query2.Fields = fields;
-       query2.Fields->Set(GetType()->GetIDColumn(), GetObject());
-       query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
-       query2.Fields->Set("config_type", 1);
-       OnQuery(query2);
+       DbQuery query;
+       query.Table = GetType()->GetTable() + "s";
+       query.Type = DbQueryInsert | DbQueryUpdate;
+       query.Fields = fields;
+       query.Fields->Set(GetType()->GetIDColumn(), GetObject());
+       query.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+       query.Fields->Set("config_type", 1);
+       query.WhereCriteria = boost::make_shared<Dictionary>();
+       query.WhereCriteria->Set(GetType()->GetIDColumn(), GetObject());
+       query.Object = GetSelf();
+       OnQuery(query);
 
        m_LastConfigUpdate = Utility::GetTime();
 
@@ -107,21 +103,17 @@ void DbObject::SendStatusUpdate(void)
        if (!fields)
                return;
 
-       DbQuery query1;
-       query1.Table = GetType()->GetTable() + "status";
-       query1.Type = DbQueryDelete;
-       query1.WhereCriteria = boost::make_shared<Dictionary>();
-       query1.WhereCriteria->Set(GetType()->GetIDColumn(), GetObject());
-       OnQuery(query1);
-
-       DbQuery query2;
-       query2.Table = GetType()->GetTable() + "status";
-       query2.Type = DbQueryInsert;
-       query2.Fields = fields;
-       query2.Fields->Set(GetType()->GetIDColumn(), GetObject());
-       query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
-       query2.Fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
-       OnQuery(query2);
+       DbQuery query;
+       query.Table = GetType()->GetTable() + "status";
+       query.Type = DbQueryInsert | DbQueryUpdate;
+       query.Fields = fields;
+       query.Fields->Set(GetType()->GetIDColumn(), GetObject());
+       query.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+       query.Fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
+       query.WhereCriteria = boost::make_shared<Dictionary>();
+       query.WhereCriteria->Set(GetType()->GetIDColumn(), GetObject());
+       query.Object = GetSelf();
+       OnQuery(query);
 
        m_LastStatusUpdate = Utility::GetTime();
 
index 223dcc50e11e4efe6d59d27f313df3ce356893ef..7f2c78050646606ca3522259f3307248756ee8d5 100644 (file)
@@ -27,17 +27,20 @@ namespace icinga
 
 enum DbQueryType
 {
-       DbQueryInsert,
-       DbQueryUpdate,
-       DbQueryDelete
+       DbQueryInsert = 1,
+       DbQueryUpdate = 2,
+       DbQueryDelete = 4
 };
 
+class DbObject;
+
 struct DbQuery
 {
-       DbQueryType Type;
+       int Type;
        String Table;
        Dictionary::Ptr Fields;
        Dictionary::Ptr WhereCriteria;
+       boost::shared_ptr<DbObject> Object;
 };
 
 }