Implement support for re-ordering groups of IDO queries

fixes #10855
This commit is contained in:
Michael Friedrich 2015-12-15 15:29:48 +01:00
parent 96fa29793c
commit 5b48559d75
5 changed files with 97 additions and 10 deletions

View 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");

View 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);
}
}

View 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);

View 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);
}
}

View 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;