]> granicus.if.org Git - icinga2/commitdiff
Implement support for re-ordering groups of IDO queries
authorMichael Friedrich <michael.friedrich@netways.de>
Tue, 15 Dec 2015 14:29:48 +0000 (15:29 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Tue, 23 Feb 2016 08:14:04 +0000 (09:14 +0100)
fixes #10855

lib/db_ido/dbconnection.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 754cf36455c4f8797351007d0f81a60aa2a41221..81fb681ed14c874e20d42c169b13d6e6c9c496ae 100644 (file)
@@ -395,7 +395,7 @@ void DbConnection::PrepareDatabase(void)
         */
 
        //ClearConfigTable("commands");
-       ClearConfigTable("comments");
+       //ClearConfigTable("comments");
        ClearConfigTable("contact_addresses");
        ClearConfigTable("contact_notificationcommands");
        ClearConfigTable("contactgroup_members");
@@ -414,7 +414,7 @@ void DbConnection::PrepareDatabase(void)
        //ClearConfigTable("hostgroups");
        //ClearConfigTable("hosts");
        //ClearConfigTable("hoststatus");
-       ClearConfigTable("scheduleddowntime");
+       //ClearConfigTable("scheduleddowntime");
        ClearConfigTable("service_contactgroups");
        ClearConfigTable("service_contacts");
        ClearConfigTable("servicedependencies");
index 4c9fe094cf273f8ff71a9ef2a892dc0649b5dbfe..b18c5be9d36efdf286f6d022e562f0db3befb2ab 100644 (file)
@@ -754,18 +754,59 @@ void IdoMysqlConnection::ExecuteQuery(const DbQuery& query)
 {
        ASSERT(query.Category != DbCatInvalid);
 
-       boost::mutex::scoped_lock lock(m_QueryQueueMutex);
        m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority, true);
 }
 
 void IdoMysqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& queries)
 {
-       boost::mutex::scoped_lock lock(m_QueryQueueMutex);
+       ASSERT(!queries.empty());
+
+       m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteMultipleQueries, this, queries), queries[0].Priority, true);
+}
+
+bool IdoMysqlConnection::CanExecuteQuery(const DbQuery& query)
+{
+       if (query.WhereCriteria) {
+               ObjectLock olock(query.WhereCriteria);
+               Value value;
+
+               BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
+                       if (!FieldToEscapedString(kv.first, kv.second, &value))
+                               return false;
+               }
+       }
+
+       if (query.Fields) {
+               ObjectLock olock(query.Fields);
+
+               BOOST_FOREACH(const Dictionary::Pair& kv, query.Fields) {
+                       Value value;
+
+                       if (kv.second.IsEmpty() && !kv.second.IsString())
+                               continue;
+
+                       if (!FieldToEscapedString(kv.first, kv.second, &value))
+                               return false;
+               }
+       }
+
+       return true;
+}
+
+void IdoMysqlConnection::InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries)
+{
+       AssertOnWorkQueue();
 
        BOOST_FOREACH(const DbQuery& query, queries) {
                ASSERT(query.Category != DbCatInvalid);
 
-               m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority, true);
+               if (!CanExecuteQuery(query)) {
+                       m_QueryQueue.Enqueue(boost::bind(&IdoMysqlConnection::InternalExecuteMultipleQueries, this, queries), query.Priority);
+               }
+       }
+
+       BOOST_FOREACH(const DbQuery& query, queries) {
+               InternalExecuteQuery(query, NULL);
        }
 }
 
index 7f1f6dfbda76fe6c9b4b3c678f5e2d79d1be3444..71fbc4a6e0306d33152b80cbdd4ac15c43a9dea8 100644 (file)
@@ -73,7 +73,6 @@ private:
        int m_SessionToken;
 
        WorkQueue m_QueryQueue;
-       boost::mutex m_QueryQueueMutex;
 
        MYSQL m_Connection;
        int m_AffectedRows;
@@ -106,7 +105,11 @@ private:
        void TxTimerHandler(void);
        void ReconnectTimerHandler(void);
 
+       bool CanExecuteQuery(const DbQuery& query);
+
        void InternalExecuteQuery(const DbQuery& query, DbQueryType *typeOverride = NULL);
+       void InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
+
        void FinishExecuteQuery(const DbQuery& query, int type, bool upsert);
        void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
        void InternalNewTransaction(void);
index ae993acfb3079b1da3e53f821494d13c41dbc8ab..fa52eec80341f88248be63e0a72b2dbd88a62458 100644 (file)
@@ -634,18 +634,59 @@ void IdoPgsqlConnection::ExecuteQuery(const DbQuery& query)
 {
        ASSERT(query.Category != DbCatInvalid);
 
-       boost::mutex::scoped_lock lock(m_QueryQueueMutex);
        m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority, true);
 }
 
 void IdoPgsqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& queries)
 {
-       boost::mutex::scoped_lock lock(m_QueryQueueMutex);
+       ASSERT(!queries.empty());
+
+       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteMultipleQueries, this, queries), queries[0].Priority, true);
+}
+
+bool IdoPgsqlConnection::CanExecuteQuery(const DbQuery& query)
+{
+       if (query.WhereCriteria) {
+               ObjectLock olock(query.WhereCriteria);
+               Value value;
+
+               BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
+                       if (!FieldToEscapedString(kv.first, kv.second, &value))
+                               return false;
+               }
+       }
+
+       if (query.Fields) {
+               ObjectLock olock(query.Fields);
+
+               BOOST_FOREACH(const Dictionary::Pair& kv, query.Fields) {
+                       Value value;
+
+                       if (kv.second.IsEmpty() && !kv.second.IsString())
+                               continue;
+
+                       if (!FieldToEscapedString(kv.first, kv.second, &value))
+                               return false;
+               }
+       }
+
+       return true;
+}
+
+void IdoPgsqlConnection::InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries)
+{
+       AssertOnWorkQueue();
 
        BOOST_FOREACH(const DbQuery& query, queries) {
                ASSERT(query.Category != DbCatInvalid);
 
-               m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, (DbQueryType *)NULL), query.Priority, true);
+               if (!CanExecuteQuery(query)) {
+                       m_QueryQueue.Enqueue(boost::bind(&IdoPgsqlConnection::InternalExecuteMultipleQueries, this, queries), query.Priority);
+               }
+       }
+
+       BOOST_FOREACH(const DbQuery& query, queries) {
+               InternalExecuteQuery(query, NULL);
        }
 }
 
index 135a0b1114edcefc981e6387db8c8e6e4ee889ee..d0e2e567316d1eeb8db8044826d201db4cc36475 100644 (file)
@@ -65,7 +65,6 @@ private:
        int m_SessionToken;
 
        WorkQueue m_QueryQueue;
-       boost::mutex m_QueryQueueMutex;
 
        PGconn *m_Connection;
        int m_AffectedRows;
@@ -92,7 +91,10 @@ private:
        void TxTimerHandler(void);
        void ReconnectTimerHandler(void);
 
+       bool CanExecuteQuery(const DbQuery& query);
+
        void InternalExecuteQuery(const DbQuery& query, DbQueryType *typeOverride = NULL);
+       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;