UI: AddressesGroup: Use bit-mask for zones.

This commit is contained in:
Nodir Temirkhodjaev 2020-02-14 13:28:15 +05:00
parent e615df2d89
commit d486debc45
11 changed files with 115 additions and 161 deletions

View File

@ -16,6 +16,13 @@ fort_memcmp (const char *p1, const char *p2, size_t len)
}
#endif
static int
bit_scan_forward (unsigned long mask)
{
unsigned long index;
return _BitScanForward(&index, mask) ? index : -1;
}
static BOOL
is_time_in_period (FORT_TIME time, FORT_PERIOD period)
{

View File

@ -8,6 +8,40 @@ AddressGroup::AddressGroup(QObject *parent) :
{
}
void AddressGroup::addIncludeZone(int zoneId)
{
addZone(m_includeZones, zoneId);
}
void AddressGroup::removeIncludeZone(int zoneId)
{
removeZone(m_includeZones, zoneId);
}
void AddressGroup::addExcludeZone(int zoneId)
{
addZone(m_excludeZones, zoneId);
}
void AddressGroup::removeExcludeZone(int zoneId)
{
removeZone(m_excludeZones, zoneId);
}
void AddressGroup::addZone(quint32 &zones, int zoneId)
{
zones |= (quint32(1) << (zoneId - 1));
setEdited(true);
}
void AddressGroup::removeZone(quint32 &zones, int zoneId)
{
zones &= ~(quint32(1) << (zoneId - 1));
setEdited(true);
}
void AddressGroup::setIncludeAll(bool includeAll)
{
if (m_includeAll != includeAll) {
@ -48,44 +82,6 @@ void AddressGroup::setExcludeText(const QString &excludeText)
}
}
void AddressGroup::addIncludeZone(int zoneId, bool sorting)
{
addZone(m_includeZones, zoneId, sorting);
}
void AddressGroup::removeIncludeZone(int zoneId)
{
removeZone(m_includeZones, zoneId);
}
void AddressGroup::addExcludeZone(int zoneId, bool sorting)
{
addZone(m_excludeZones, zoneId, sorting);
}
void AddressGroup::removeExcludeZone(int zoneId)
{
removeZone(m_excludeZones, zoneId);
}
void AddressGroup::addZone(QVector<int> &zones, int zoneId, bool sorting)
{
zones.append(zoneId);
if (sorting) {
std::sort(zones.begin(), zones.end());
}
setEdited(true);
}
void AddressGroup::removeZone(QVector<int> &zones, int zoneId)
{
zones.removeOne(zoneId);
setEdited(true);
}
void AddressGroup::copy(const AddressGroup &o)
{
m_edited = o.edited();
@ -95,9 +91,9 @@ void AddressGroup::copy(const AddressGroup &o)
m_id = o.id();
m_includeText = o.includeText();
m_excludeText = o.excludeText();
m_includeZones = o.includeZones();
m_excludeZones = o.excludeZones();
m_includeText = o.includeText();
m_excludeText = o.excludeText();
}

View File

@ -28,21 +28,24 @@ public:
qint64 id() const { return m_id; }
void setId(qint64 id) { m_id = id; }
quint32 includeZones() const { return m_includeZones; }
void setIncludeZones(quint32 v) { m_includeZones = v; }
quint32 excludeZones() const { return m_excludeZones; }
void setExcludeZones(quint32 v) { m_excludeZones = v; }
void addIncludeZone(int zoneId);
void removeIncludeZone(int zoneId);
void addExcludeZone(int zoneId);
void removeExcludeZone(int zoneId);
QString includeText() const { return m_includeText; }
void setIncludeText(const QString &includeText);
QString excludeText() const { return m_excludeText; }
void setExcludeText(const QString &excludeText);
const QVector<int> &includeZones() const { return m_includeZones; }
const QVector<int> &excludeZones() const { return m_excludeZones; }
void addIncludeZone(int zoneId, bool sorting = false);
void removeIncludeZone(int zoneId);
void addExcludeZone(int zoneId, bool sorting = false);
void removeExcludeZone(int zoneId);
void copy(const AddressGroup &o);
signals:
@ -52,8 +55,8 @@ signals:
void excludeTextChanged();
private:
void addZone(QVector<int> &zones, int zoneId, bool sorting);
void removeZone(QVector<int> &zones, int zoneId);
void addZone(quint32 &zones, int zoneId);
void removeZone(quint32 &zones, int zoneId);
private:
bool m_edited : 1;
@ -63,11 +66,11 @@ private:
qint64 m_id = 0;
quint32 m_includeZones = 0;
quint32 m_excludeZones = 0;
QString m_includeText;
QString m_excludeText;
QVector<int> m_includeZones;
QVector<int> m_excludeZones;
};
#endif // ADDRESSGROUP_H

View File

@ -36,18 +36,12 @@ const char * const sqlPragmas =
const char * const sqlSelectAddressGroups =
"SELECT addr_group_id, include_all, exclude_all,"
" include_zones, exclude_zones,"
" include_text, exclude_text"
" FROM address_group"
" ORDER BY order_index;"
;
const char * const sqlSelectAddressGroupZones =
"SELECT include, zone_id"
" FROM address_group_zone"
" WHERE addr_group_id = ?1"
" ORDER BY include, zone_id;"
;
const char * const sqlSelectAppGroups =
"SELECT app_group_id, enabled,"
" fragment_packet, period_enabled,"
@ -61,28 +55,21 @@ const char * const sqlSelectAppGroups =
const char * const sqlInsertAddressGroup =
"INSERT INTO address_group(addr_group_id, order_index,"
" include_all, exclude_all, include_text, exclude_text)"
" VALUES(?1, ?2, ?3, ?4, ?5, ?6);"
" include_all, exclude_all,"
" include_zones, exclude_zones,"
" include_text, exclude_text)"
" VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);"
;
const char * const sqlUpdateAddressGroup =
"UPDATE address_group"
" SET order_index = ?2,"
" include_all = ?3, exclude_all = ?4,"
" include_text = ?5, exclude_text = ?6"
" include_zones = ?5, exclude_zones = ?6,"
" include_text = ?7, exclude_text = ?8"
" WHERE addr_group_id = ?1;"
;
const char * const sqlDeleteAddressGroupZones =
"DELETE FROM address_group_zone"
" WHERE addr_group_id = ?1;"
;
const char * const sqlInsertAddressGroupZone =
"INSERT INTO address_group_zone(addr_group_id, zone_id, include)"
" VALUES(?1, ?2, ?3);"
;
const char * const sqlInsertAppGroup =
"INSERT INTO app_group(app_group_id, order_index, enabled,"
" fragment_packet, period_enabled,"
@ -209,7 +196,9 @@ const char * const sqlDeleteZone =
;
const char * const sqlDeleteAddressGroupZone =
"DELETE FROM address_group_zone WHERE zone_id = ?1;"
"UPDATE address_group"
" SET include_zones = include_zones & ?1,"
" exclude_zones = exclude_zones & ?1;"
;
const char * const sqlUpdateZone =
@ -253,56 +242,6 @@ bool migrateFunc(SqliteDb *db, int version, bool isNewDb, void *ctx)
return true;
}
bool loadAddressGroupZones(SqliteDb *db, AddressGroup *addrGroup)
{
SqliteStmt stmt;
if (!db->prepare(stmt, sqlSelectAddressGroupZones, {addrGroup->id()}))
return false;
while (stmt.step() == SqliteStmt::StepRow) {
const bool include = stmt.columnBool(0);
const int zoneId = stmt.columnInt(1);
if (include) {
addrGroup->addIncludeZone(zoneId);
} else {
addrGroup->addExcludeZone(zoneId);
}
}
return true;
}
bool saveAddressGroupZones(SqliteDb *db, AddressGroup *addrGroup)
{
const auto addrGroupId = addrGroup->id();
bool ok;
db->executeEx(sqlDeleteAddressGroupZones, {addrGroupId}, 0, &ok);
if (!ok) return false;
SqliteStmt stmt;
if (!db->prepare(stmt, sqlInsertAddressGroupZone))
return false;
const auto addAddressGroupZone = [&](int zoneId, bool include) -> bool {
return stmt.bindVars({addrGroupId, zoneId, include})
&& stmt.step() == SqliteStmt::StepDone
&& stmt.reset();
};
for (const int zoneId : addrGroup->includeZones()) {
if (!addAddressGroupZone(zoneId, true))
return false;
}
for (const int zoneId : addrGroup->excludeZones()) {
if (!addAddressGroupZone(zoneId, false))
return false;
}
return true;
}
bool loadAddressGroups(SqliteDb *db, const QList<AddressGroup *> &addressGroups,
int &index)
{
@ -318,11 +257,10 @@ bool loadAddressGroups(SqliteDb *db, const QList<AddressGroup *> &addressGroups,
addrGroup->setId(stmt.columnInt64(0));
addrGroup->setIncludeAll(stmt.columnBool(1));
addrGroup->setExcludeAll(stmt.columnBool(2));
addrGroup->setIncludeText(stmt.columnText(3));
addrGroup->setExcludeText(stmt.columnText(4));
if (!loadAddressGroupZones(db, addrGroup))
return false;
addrGroup->setIncludeZones(quint32(stmt.columnInt64(3)));
addrGroup->setExcludeZones(quint32(stmt.columnInt64(4)));
addrGroup->setIncludeText(stmt.columnText(5));
addrGroup->setExcludeText(stmt.columnText(6));
addrGroup->setEdited(false);
@ -344,6 +282,8 @@ bool saveAddressGroup(SqliteDb *db, AddressGroup *addrGroup, int orderIndex)
<< orderIndex
<< addrGroup->includeAll()
<< addrGroup->excludeAll()
<< qint64(addrGroup->includeZones())
<< qint64(addrGroup->excludeZones())
<< addrGroup->includeText()
<< addrGroup->excludeText()
;
@ -358,9 +298,6 @@ bool saveAddressGroup(SqliteDb *db, AddressGroup *addrGroup, int orderIndex)
addrGroup->setId(db->lastInsertRowid());
}
if (!saveAddressGroupZones(db, addrGroup))
return false;
addrGroup->setEdited(false);
return true;
@ -826,12 +763,14 @@ bool ConfManager::deleteZone(int zoneId)
m_sqliteDb->beginTransaction();
const auto vars = QVariantList() << zoneId;
m_sqliteDb->executeEx(sqlDeleteZone, vars, 0, &ok);
m_sqliteDb->executeEx(sqlDeleteZone, {zoneId}, 0, &ok);
if (!ok) goto end;
m_sqliteDb->executeEx(sqlDeleteAddressGroupZone, vars, 0, &ok);
// Delete the Zone frpm Address Groups
{
const qint64 zoneUnMask = ~(quint32(1) << (zoneId - 1));
m_sqliteDb->executeEx(sqlDeleteAddressGroupZone, {zoneUnMask}, 0, &ok);
}
end:
return checkResult(ok, true);

View File

@ -19,16 +19,12 @@ CREATE TABLE address_group(
order_index INTEGER NOT NULL,
include_all BOOLEAN NOT NULL,
exclude_all BOOLEAN NOT NULL,
include_zones INTEGER NOT NULL DEFAULT 0,
exclude_zones INTEGER NOT NULL DEFAULT 0,
include_text TEXT NOT NULL,
exclude_text TEXT NOT NULL
);
CREATE TABLE address_group_zone(
addr_group_id INTEGER NOT NULL,
zone_id INTEGER NOT NULL,
include BOOLEAN NOT NULL
);
CREATE TABLE app_group(
app_group_id INTEGER PRIMARY KEY,
order_index INTEGER NOT NULL,

View File

@ -12,6 +12,7 @@
#include "../../../conf/addressgroup.h"
#include "../../../conf/firewallconf.h"
#include "../../../fortcommon.h"
#include "../../../fortmanager.h"
#include "../../../fortsettings.h"
#include "../../../model/zonelistmodel.h"
@ -251,9 +252,9 @@ void AddressesPage::createZonesMenu()
if (checked) {
if (include) {
addrGroup->addIncludeZone(zoneId, true);
addrGroup->addIncludeZone(zoneId);
} else {
addrGroup->addExcludeZone(zoneId, true);
addrGroup->addExcludeZone(zoneId);
}
} else {
if (include) {
@ -269,14 +270,12 @@ void AddressesPage::createZonesMenu()
};
const int zoneCount = zoneListModel()->rowCount();
for (int zoneId = 1; zoneId <= zoneCount; ++zoneId) {
const auto zoneName = zoneListModel()->zoneNameById(zoneId);
if (zoneName.isEmpty())
continue;
for (int row = 0; row < zoneCount; ++row) {
const auto zoneRow = zoneListModel()->zoneRowAt(row);
auto action = new QAction(zoneName, m_menuZones);
auto action = new QAction(zoneRow.zoneName, m_menuZones);
action->setCheckable(true);
action->setData(zoneId);
action->setData(zoneRow.zoneId);
connect(action, &QAction::triggered, this, onZoneActionTriggered);
@ -294,11 +293,12 @@ void AddressesPage::updateZonesMenu(bool include)
if (actions.isEmpty())
return;
const auto zoneIds = addressGroupZones(include);
const quint32 zonesMask = addressGroupZones(include);
for (auto action : actions) {
const int zoneId = action->data().toInt();
const bool checked = zoneIds.contains(zoneId);
const quint32 zoneMask = (quint32(1) << (zoneId - 1));
const bool checked = (zonesMask & zoneMask) != 0;
action->setChecked(checked);
}
@ -357,7 +357,7 @@ AddressGroup *AddressesPage::addressGroupByIndex(int index) const
return addressGroups().at(index);
}
const QVector<int> &AddressesPage::addressGroupZones(bool include) const
quint32 AddressesPage::addressGroupZones(bool include) const
{
return include ? addressGroup()->includeZones()
: addressGroup()->excludeZones();
@ -365,15 +365,19 @@ const QVector<int> &AddressesPage::addressGroupZones(bool include) const
QString AddressesPage::zonesText(bool include) const
{
const auto zoneIds = addressGroupZones(include);
if (zoneIds.isEmpty())
return QString();
QStringList list;
for (const int zoneId : zoneIds) {
quint32 zonesMask = addressGroupZones(include);
while (zonesMask != 0) {
const int zoneIndex = FortCommon::bitScanForward(zonesMask);
const int zoneId = zoneIndex + 1;
const auto zoneName = zoneListModel()->zoneNameById(zoneId);
list.append(zoneName);
zonesMask ^= (quint32(1) << zoneIndex);
}
return list.join(", ");
}

View File

@ -50,7 +50,7 @@ private:
const QList<AddressGroup *> &addressGroups() const;
AddressGroup *addressGroupByIndex(int index) const;
const QVector<int> &addressGroupZones(bool include) const;
quint32 addressGroupZones(bool include) const;
QString zonesText(bool include) const;

View File

@ -232,6 +232,11 @@ bool FortCommon::isTimeInPeriod(quint8 hour, quint8 minute,
return is_time_in_period(time, period);
}
int FortCommon::bitScanForward(quint32 mask)
{
return bit_scan_forward(mask);
}
void FortCommon::provUnregister()
{
fort_prov_unregister(nullptr);

View File

@ -70,6 +70,8 @@ public:
quint8 fromHour, quint8 fromMinute,
quint8 toHour, quint8 toMinute);
static int bitScanForward(quint32 mask);
static void provUnregister();
};

View File

@ -1,5 +1,6 @@
#include "zonelistmodel.h"
#include <QDebug>
#include <QJsonDocument>
#include <sqlite/sqlitedb.h>

View File

@ -2,6 +2,7 @@
#define JSONUTIL_H
#include <QObject>
#include <QVariant>
class JsonUtil
{