]> 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)
committerMichael Friedrich <michael.friedrich@netways.de>
Tue, 15 Dec 2015 14:29:48 +0000 (15:29 +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 d86e87e7e5d3197a2f1e54cf9e447200dcb165fd..67a2368101272dd8778c06f71c1d00e97fa9ba16 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 18b55b4cec8726a467969947481c02167b2c2c43..3b42b828b446b157cd4e748d6143cd7712662dbf 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 636f40d9d17d29941b9ab55a636c1cc0e701e35e..87f84fe256e4ecf6feedd48dde71bd3cd4460e24 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 f1adafb04673bc5f3ea67e267e1c8345da9719c6..0bc4f5eb0ce5408306d5e757b89fd8dbc86762fd 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 078f17e5c8394728a131468f25b24e77c8e062e6..747a6fa04c95c2c5352c18d7119afbf1b03d1c91 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;