mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-25 22:54:57 +02:00
Fix problem with duplicate INSERTs for the same key columns
fixes #12461 fixes #12458
This commit is contained in:
parent
b26b3a4f65
commit
4c54cddec8
@ -314,7 +314,6 @@ void DbObject::SendVarsStatusUpdate(void)
|
|||||||
query.WhereCriteria = new Dictionary();
|
query.WhereCriteria = new Dictionary();
|
||||||
query.WhereCriteria->Set("object_id", obj);
|
query.WhereCriteria->Set("object_id", obj);
|
||||||
query.WhereCriteria->Set("varname", kv.first);
|
query.WhereCriteria->Set("varname", kv.first);
|
||||||
query.Object = this;
|
|
||||||
|
|
||||||
queries.push_back(query);
|
queries.push_back(query);
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ void IdoMysqlConnection::ExecuteQuery(const DbQuery& query)
|
|||||||
{
|
{
|
||||||
ASSERT(query.Category != DbCatInvalid);
|
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)
|
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) {
|
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();
|
AssertOnWorkQueue();
|
||||||
|
|
||||||
@ -911,7 +911,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
|
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
|
BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
|
||||||
if (!FieldToEscapedString(kv.first, kv.second, &value)) {
|
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;
|
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;
|
bool upsert = false;
|
||||||
|
|
||||||
@ -945,6 +945,14 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
type = DbQueryUpdate;
|
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) {
|
switch (type) {
|
||||||
case DbQueryInsert:
|
case DbQueryInsert:
|
||||||
qbuf << "INSERT INTO " << GetTablePrefix() << query.Table;
|
qbuf << "INSERT INTO " << GetTablePrefix() << query.Table;
|
||||||
@ -975,7 +983,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!FieldToEscapedString(kv.first, kv.second, &value)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,8 +1019,7 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
void IdoMysqlConnection::FinishExecuteQuery(const DbQuery& query, int type, bool upsert)
|
void IdoMysqlConnection::FinishExecuteQuery(const DbQuery& query, int type, bool upsert)
|
||||||
{
|
{
|
||||||
if (upsert && GetAffectedRows() == 0) {
|
if (upsert && GetAffectedRows() == 0) {
|
||||||
DbQueryType to = DbQueryInsert;
|
InternalExecuteQuery(query, DbQueryDelete | DbQueryInsert);
|
||||||
InternalExecuteQuery(query, &to);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ private:
|
|||||||
|
|
||||||
bool CanExecuteQuery(const DbQuery& query);
|
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 InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
|
||||||
|
|
||||||
void FinishExecuteQuery(const DbQuery& query, int type, bool upsert);
|
void FinishExecuteQuery(const DbQuery& query, int type, bool upsert);
|
||||||
|
@ -667,7 +667,7 @@ void IdoPgsqlConnection::ExecuteQuery(const DbQuery& query)
|
|||||||
{
|
{
|
||||||
ASSERT(query.Category != DbCatInvalid);
|
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)
|
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) {
|
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();
|
AssertOnWorkQueue();
|
||||||
|
|
||||||
@ -768,7 +768,7 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
|
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
|
BOOST_FOREACH(const Dictionary::Pair& kv, query.WhereCriteria) {
|
||||||
if (!FieldToEscapedString(kv.first, kv.second, &value)) {
|
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;
|
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;
|
bool upsert = false;
|
||||||
|
|
||||||
@ -802,6 +802,14 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
type = DbQueryUpdate;
|
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) {
|
switch (type) {
|
||||||
case DbQueryInsert:
|
case DbQueryInsert:
|
||||||
qbuf << "INSERT INTO " << GetTablePrefix() << query.Table;
|
qbuf << "INSERT INTO " << GetTablePrefix() << query.Table;
|
||||||
@ -831,7 +839,7 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!FieldToEscapedString(kv.first, kv.second, &value)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,8 +872,7 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, DbQueryType
|
|||||||
Query(qbuf.str());
|
Query(qbuf.str());
|
||||||
|
|
||||||
if (upsert && GetAffectedRows() == 0) {
|
if (upsert && GetAffectedRows() == 0) {
|
||||||
DbQueryType to = DbQueryInsert;
|
InternalExecuteQuery(query, DbQueryDelete | DbQueryInsert);
|
||||||
InternalExecuteQuery(query, &to);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ private:
|
|||||||
|
|
||||||
bool CanExecuteQuery(const DbQuery& query);
|
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 InternalExecuteMultipleQueries(const std::vector<DbQuery>& queries);
|
||||||
void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
|
void InternalCleanUpExecuteQuery(const String& table, const String& time_key, double time_value);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user