UI: RuleEdit: Check for Preset Rule loops

This commit is contained in:
Nodir Temirkhodjaev 2024-04-02 19:45:12 +03:00
parent 9e7c136d67
commit 23eeca9ed9
6 changed files with 56 additions and 4 deletions

View File

@ -34,7 +34,7 @@ namespace {
const QLoggingCategory LC("conf"); const QLoggingCategory LC("conf");
constexpr int DATABASE_USER_VERSION = 39; constexpr int DATABASE_USER_VERSION = 40;
const char *const sqlSelectAddressGroups = "SELECT addr_group_id, include_all, exclude_all," const char *const sqlSelectAddressGroups = "SELECT addr_group_id, include_all, exclude_all,"
" include_zones, exclude_zones," " include_zones, exclude_zones,"

View File

@ -60,6 +60,25 @@ const char *const sqlSelectRuleSet = "SELECT t.sub_rule_id, r.name"
" WHERE t.rule_id = ?1" " WHERE t.rule_id = ?1"
" ORDER BY t.order_index;"; " ORDER BY t.order_index;";
const char *const sqlSelectRuleSetLoop = "WITH RECURSIVE"
" parents(rule_id) AS ("
" VALUES(?1)"
" UNION ALL"
" SELECT t.rule_id"
" FROM rule_set t"
" JOIN parents p ON p.rule_id = t.sub_rule_id"
" ),"
" children(rule_id) AS ("
" VALUES(?2)"
" UNION ALL"
" SELECT t.sub_rule_id"
" FROM rule_set t"
" JOIN children c ON c.rule_id = t.rule_id"
" )"
"SELECT p.rule_id"
" FROM parents p"
" JOIN children c ON c.rule_id = p.rule_id;";
const char *const sqlUpdateRuleName = "UPDATE rule SET name = ?2 WHERE rule_id = ?1;"; const char *const sqlUpdateRuleName = "UPDATE rule SET name = ?2 WHERE rule_id = ?1;";
const char *const sqlUpdateRuleEnabled = "UPDATE rule SET enabled = ?2 WHERE rule_id = ?1;"; const char *const sqlUpdateRuleEnabled = "UPDATE rule SET enabled = ?2 WHERE rule_id = ?1;";
@ -142,6 +161,16 @@ void ConfRuleManager::saveRuleSet(Rule &rule)
} }
} }
bool ConfRuleManager::checkRuleSetLoop(int ruleId, int subRuleId)
{
return DbQuery(sqliteDb())
.sql(sqlSelectRuleSetLoop)
.vars({ ruleId, subRuleId })
.execute()
.toInt()
> 0;
}
bool ConfRuleManager::addOrUpdateRule(Rule &rule) bool ConfRuleManager::addOrUpdateRule(Rule &rule)
{ {
bool ok = true; bool ok = true;

View File

@ -27,6 +27,8 @@ public:
void loadRuleSet(Rule &rule, QStringList &ruleSetNames); void loadRuleSet(Rule &rule, QStringList &ruleSetNames);
void saveRuleSet(Rule &rule); void saveRuleSet(Rule &rule);
bool checkRuleSetLoop(int ruleId, int subRuleId);
virtual bool addOrUpdateRule(Rule &rule); virtual bool addOrUpdateRule(Rule &rule);
virtual bool deleteRule(int ruleId); virtual bool deleteRule(int ruleId);
virtual bool updateRuleName(int ruleId, const QString &ruleName); virtual bool updateRuleName(int ruleId, const QString &ruleName);

View File

@ -114,6 +114,7 @@ CREATE TABLE rule_set(
); );
CREATE INDEX rule_set_rule_id_idx ON rule_set(rule_id); CREATE INDEX rule_set_rule_id_idx ON rule_set(rule_id);
CREATE INDEX rule_set_sub_rule_id_idx ON rule_set(sub_rule_id);
CREATE TABLE task( CREATE TABLE task(
task_id INTEGER PRIMARY KEY, task_id INTEGER PRIMARY KEY,

View File

@ -1,10 +1,18 @@
#include "rulesetmodel.h" #include "rulesetmodel.h"
#include <QLoggingCategory>
#include <conf/confrulemanager.h> #include <conf/confrulemanager.h>
#include <util/ioc/ioccontainer.h> #include <util/ioc/ioccontainer.h>
#include "rulelistmodel.h" #include "rulelistmodel.h"
namespace {
const QLoggingCategory LC("model.ruleSet");
}
RuleSetModel::RuleSetModel(QObject *parent) : StringListModel(parent) { } RuleSetModel::RuleSetModel(QObject *parent) : StringListModel(parent) { }
ConfRuleManager *RuleSetModel::confRuleManager() const ConfRuleManager *RuleSetModel::confRuleManager() const
@ -16,6 +24,7 @@ void RuleSetModel::initialize(const RuleRow &ruleRow, const QStringList &ruleSet
{ {
setEdited(false); setEdited(false);
m_ruleId = ruleRow.ruleId;
m_ruleSet = ruleRow.ruleSet; m_ruleSet = ruleRow.ruleSet;
setList(ruleSetNames); setList(ruleSetNames);
@ -23,10 +32,19 @@ void RuleSetModel::initialize(const RuleRow &ruleRow, const QStringList &ruleSet
void RuleSetModel::addRule(const RuleRow &ruleRow) void RuleSetModel::addRule(const RuleRow &ruleRow)
{ {
if (m_ruleSet.contains(ruleRow.ruleId)) const int subRuleId = ruleRow.ruleId;
return;
m_ruleSet.append(ruleRow.ruleId); if (m_ruleSet.contains(subRuleId)) {
qCDebug(LC) << "Sub-Rule already exists";
return;
}
if (confRuleManager()->checkRuleSetLoop(m_ruleId, subRuleId)) {
qCDebug(LC) << "Rule Set loop detected";
return;
}
m_ruleSet.append(subRuleId);
insert(ruleRow.ruleName); insert(ruleRow.ruleName);

View File

@ -30,6 +30,8 @@ public slots:
private: private:
bool m_edited = false; bool m_edited = false;
int m_ruleId = 0;
RuleSetList m_ruleSet; RuleSetList m_ruleSet;
}; };