]> granicus.if.org Git - icinga2/commitdiff
Fix problem with duplicate INSERTs for the same key columns
authorGunnar Beutner <gunnar.beutner@netways.de>
Wed, 17 Aug 2016 11:24:18 +0000 (13:24 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Wed, 17 Aug 2016 11:35:10 +0000 (13:35 +0200)
fixes #12461
fixes #12458

lib/db_ido/dbobject.cpp
lib/db_ido_mysql/idomysqlconnection.cpp
lib/db_ido_mysql/idomysqlconnection.hpp
lib/db_ido_pgsql/idopgsqlconnection.cpp
lib/db_ido_pgsql/idopgsqlconnection.hpp

index 555ec5edeb4adc1eb9d12805763a423e847860a7..e00691aed8a804bdf73d4f338c68b57a39a09059 100644 (file)
@@ -314,7 +314,6 @@ void DbObject::SendVarsStatusUpdate(void)
                        query.WhereCriteria = new Dictionary();
                        query.WhereCriteria->Set("object_id", obj);
                        query.WhereCriteria->Set("varname", kv.first);
-                       query.Object = this;
 
                        queries.push_back(query);
                }
index f46bbabfe01339b633880e15ed773f1605acfe3c..486a816bdbbf360f01ee4f28f1c933e97cb1dfef 100644 (file)
@@ -810,7 +810,7 @@ void IdoMysqlConnection::ExecuteQuery(const DbQuery& query)
 {
        ASSERT(query.Category != DbCatInvalid);
 
-       m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority, true);
+       m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, -1), query.Priority, true);
 }
 
 void IdoMysqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& queries)
@@ -870,11 +870,11 @@ void IdoMysqlConnection::InternalExecuteMultipleQueries(const std::vector<DbQuer
        }
 
        BOOST_FOREACH(const DbQuery& query, queries) {
-               InternalExecuteQuery(query, NULL);
+               InternalExecuteQuery(query);
        }
 }
 
-void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType *typeOverride)
+void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, int typeOverride)
 {
        AssertOnWorkQueue();
 
@@ -911,7 +911,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
 
                BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
                        if (!FieldToEscapedString(kv.first, kv.second, &value)) {
-                               m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority);
+                               m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, -1), query.Priority);
                                return;
                        }
 
@@ -925,7 +925,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                }
        }
 
-       type = typeOverride ? *typeOverride : query.Type;
+       type = (typeOverride != -1) ? typeOverride : query.Type;
 
        bool upsert = false;
 
@@ -945,6 +945,14 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                type = DbQueryUpdate;
        }
 
+       if ((type & DbQueryInsert) && (type & DbQueryDelete)) {
+               std::ostringstream qdel;
+               qdel << "DELETE FROM " << GetTablePrefix() << query.Table << where.str();
+               AsyncQuery(qdel.str());
+
+               type = DbQueryInsert;
+       }
+
        switch (type) {
                case DbQueryInsert:
                        qbuf << "INSERT INTO " << GetTablePrefix() << query.Table;
@@ -975,7 +983,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                                continue;
 
                        if (!FieldToEscapedString(kv.first, kv.second, &value)) {
-                               m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority);
+                               m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, -1), query.Priority);
                                return;
                        }
 
@@ -1011,8 +1019,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
 void IdoMysqlConnection::FinishExecuteQuery(const DbQuery& query, int type, bool upsert)
 {
        if (upsert && GetAffectedRows() == 0) {
-               DbQueryType to = DbQueryInsert;
-               InternalExecuteQuery(query, &to);
+               InternalExecuteQuery(query, DbQueryDelete | DbQueryInsert);
 
                return;
        }
index 53209cd8bd558b0ae95a160f55ad44dab36af418..5920de67b5876e11b6f48be05f7e05795891ec0a 100644 (file)
@@ -107,7 +107,7 @@ private:
 
        bool CanExecuteQuery(const DbQuery& query);
 
-       void InternalExecuteQuery(const DbQuery& query, DbQueryType *typeOverride = NULL);
+       void InternalExecuteQuery(const DbQuery& query, int typeOverride = -1);
        void InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
 
        void FinishExecuteQuery(const DbQuery& query, int type, bool upsert);
index 2a9ec50c2c1da659d3d1aa9f80a5bc4bfb41224e..51526f2005f3dc53b390743c4e9e87119118bdcc 100644 (file)
@@ -667,7 +667,7 @@ void IdoPgsqlConnection::ExecuteQuery(const DbQuery& query)
 {
        ASSERT(query.Category != DbCatInvalid);
 
-       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority, true);
+       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, -1), query.Priority, true);
 }
 
 void IdoPgsqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& queries)
@@ -727,11 +727,11 @@ void IdoPgsqlConnection::InternalExecuteMultipleQueries(const std::vector<DbQuer
        }
 
        BOOST_FOREACH(const DbQuery& query, queries) {
-               InternalExecuteQuery(query, NULL);
+               InternalExecuteQuery(query);
        }
 }
 
-void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType *typeOverride)
+void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, int typeOverride)
 {
        AssertOnWorkQueue();
 
@@ -768,7 +768,7 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
 
                BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
                        if (!FieldToEscapedString(kv.first, kv.second, &value)) {
-                               m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority);
+                               m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, -1), query.Priority);
                                return;
                        }
 
@@ -782,7 +782,7 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                }
        }
 
-       type = typeOverride ? *typeOverride : query.Type;
+       type = (typeOverride != -1) ? typeOverride : query.Type;
 
        bool upsert = false;
 
@@ -802,6 +802,14 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                type = DbQueryUpdate;
        }
 
+       if ((type & DbQueryInsert) && (type & DbQueryDelete)) {
+               std::ostringstream qdel;
+               qdel << "DELETE FROM " << GetTablePrefix() << query.Table << where.str();
+               Query(qdel.str());
+
+               type = DbQueryInsert;
+       }
+
        switch (type) {
                case DbQueryInsert:
                        qbuf << "INSERT INTO " << GetTablePrefix() << query.Table;
@@ -831,7 +839,7 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
                                continue;
 
                        if (!FieldToEscapedString(kv.first, kv.second, &value)) {
-                               m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority);
+                               m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, -1), query.Priority);
                                return;
                        }
 
@@ -864,8 +872,7 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
        Query(qbuf.str());
 
        if (upsert && GetAffectedRows() == 0) {
-               DbQueryType to = DbQueryInsert;
-               InternalExecuteQuery(query, &to);
+               InternalExecuteQuery(query, DbQueryDelete | DbQueryInsert);
 
                return;
        }
index 2c4c46547e5c3d1883f37344d4802a33716eeab5..5ddb699202cb7ab26838bac6a63f5ffe9a0c6645 100644 (file)
@@ -95,7 +95,7 @@ private:
 
        bool CanExecuteQuery(const DbQuery& query);
 
-       void InternalExecuteQuery(const DbQuery& query, DbQueryType *typeOverride = NULL);
+       void InternalExecuteQuery(const DbQuery& query, int typeOverride = -1);
        void InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
        void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);