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");
constexpr int DATABASE_USER_VERSION = 39;
constexpr int DATABASE_USER_VERSION = 40;
const char *const sqlSelectAddressGroups = "SELECT addr_group_id, include_all, exclude_all,"
" 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"
" 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 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 ok = true;

View File

@ -27,6 +27,8 @@ public:
void loadRuleSet(Rule &rule, QStringList &ruleSetNames);
void saveRuleSet(Rule &rule);
bool checkRuleSetLoop(int ruleId, int subRuleId);
virtual bool addOrUpdateRule(Rule &rule);
virtual bool deleteRule(int ruleId);
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_sub_rule_id_idx ON rule_set(sub_rule_id);
CREATE TABLE task(
task_id INTEGER PRIMARY KEY,

View File

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

View File

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