diff --git a/src/ui/3rdparty/sqlite/sqlitestmt.cpp b/src/ui/3rdparty/sqlite/sqlitestmt.cpp index 9c9d864c..17026390 100644 --- a/src/ui/3rdparty/sqlite/sqlitestmt.cpp +++ b/src/ui/3rdparty/sqlite/sqlitestmt.cpp @@ -401,6 +401,11 @@ void SqliteStmt::doList(const SqliteStmtList &stmtList) } } +QVariant SqliteStmt::nullable(int v) +{ + return nullable(v, v == 0); +} + QVariant SqliteStmt::nullable(const QString &v) { return nullable(v, v.isEmpty()); diff --git a/src/ui/3rdparty/sqlite/sqlitestmt.h b/src/ui/3rdparty/sqlite/sqlitestmt.h index 0d9ab299..ccd79ee1 100644 --- a/src/ui/3rdparty/sqlite/sqlitestmt.h +++ b/src/ui/3rdparty/sqlite/sqlitestmt.h @@ -80,6 +80,7 @@ public: { return isNull ? QVariant() : QVariant(v); } + static QVariant nullable(int v); static QVariant nullable(const QString &v); static QVariant nullable(const QDateTime &v); diff --git a/src/ui/conf/app.cpp b/src/ui/conf/app.cpp index 8a16d8e1..fd7a5a8a 100644 --- a/src/ui/conf/app.cpp +++ b/src/ui/conf/app.cpp @@ -25,7 +25,7 @@ bool App::isExtraFlagsEqual(const App &o) const bool App::isOptionsEqual(const App &o) const { - return isFlagsEqual(o) && isZonesEqual(o) && groupIndex == o.groupIndex + return isFlagsEqual(o) && isZonesEqual(o) && groupIndex == o.groupIndex && ruleId == o.ruleId && appOriginPath == o.appOriginPath && appPath == o.appPath && notes == o.notes && scheduleAction == o.scheduleAction && scheduleTime == o.scheduleTime; } diff --git a/src/ui/conf/app.h b/src/ui/conf/app.h index 3e906292..11a88cb2 100644 --- a/src/ui/conf/app.h +++ b/src/ui/conf/app.h @@ -38,7 +38,9 @@ public: qint8 scheduleAction = ScheduleBlock; - int groupIndex = 0; + qint8 groupIndex = 0; + + quint16 ruleId = 0; quint32 acceptZones = 0; quint32 rejectZones = 0; diff --git a/src/ui/conf/confappmanager.cpp b/src/ui/conf/confappmanager.cpp index 0ec118cb..5b9e543d 100644 --- a/src/ui/conf/confappmanager.cpp +++ b/src/ui/conf/confappmanager.cpp @@ -48,6 +48,7 @@ constexpr int APP_END_TIMER_INTERVAL_MAX = 24 * 60 * 60 * 1000; // 1 day " t.kill_process," \ " t.accept_zones," \ " t.reject_zones," \ + " t.rule_id," \ " t.end_action," \ " t.end_time," \ " g.order_index as group_index," \ @@ -81,17 +82,17 @@ const char *const sqlUpsertApp = "INSERT INTO app(app_group_id, origin_path, pat " is_wildcard, use_group_perm, apply_child, kill_child," " lan_only, parked, log_blocked, log_conn," " blocked, kill_process, accept_zones, reject_zones," - " end_action, end_time, creat_time)" + " rule_id, end_action, end_time, creat_time)" " VALUES(?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14," - " ?15, ?16, ?17, ?18, ?19, ?20, ?21)" + " ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22)" " ON CONFLICT(path) DO UPDATE" " SET app_group_id = ?2, origin_path = ?3, name = ?5," " notes = ?6, is_wildcard = ?7, use_group_perm = ?8," " apply_child = ?9, kill_child = ?10, lan_only = ?11," " parked = ?12, log_blocked = ?13, log_conn = ?14," " blocked = ?15, kill_process = ?16," - " accept_zones = ?17, reject_zones = ?18," - " end_action = ?19, end_time = ?20" + " accept_zones = ?17, reject_zones = ?18, rule_id = ?19," + " end_action = ?20, end_time = ?21" " RETURNING app_id;"; const char *const sqlUpdateApp = "UPDATE app" @@ -100,8 +101,8 @@ const char *const sqlUpdateApp = "UPDATE app" " apply_child = ?9, kill_child = ?10, lan_only = ?11," " parked = ?12, log_blocked = ?13, log_conn = ?14," " blocked = ?15, kill_process = ?16," - " accept_zones = ?17, reject_zones = ?18," - " end_action = ?19, end_time = ?20" + " accept_zones = ?17, reject_zones = ?18, rule_id = ?19," + " end_action = ?20, end_time = ?21" " WHERE app_id = ?1" " RETURNING app_id;"; @@ -213,6 +214,7 @@ void ConfAppManager::beginAddOrUpdateApp( app.killProcess, app.acceptZones, app.rejectZones, + SqliteStmt::nullable(app.ruleId), app.scheduleAction, SqliteStmt::nullable(app.scheduleTime), SqliteStmt::nullable(DateUtil::now(), onlyUpdate), @@ -623,10 +625,11 @@ void ConfAppManager::fillApp(App &app, const SqliteStmt &stmt) app.killProcess = stmt.columnBool(14); app.acceptZones = stmt.columnUInt(15); app.rejectZones = stmt.columnUInt(16); - app.scheduleAction = stmt.columnInt(17); - app.scheduleTime = stmt.columnDateTime(18); - app.groupIndex = stmt.columnInt(19); - app.alerted = stmt.columnBool(20); + app.ruleId = stmt.columnUInt(17); + app.scheduleAction = stmt.columnInt(18); + app.scheduleTime = stmt.columnDateTime(19); + app.groupIndex = stmt.columnInt(20); + app.alerted = stmt.columnBool(21); } bool ConfAppManager::updateDriverDeleteApp(const QString &appPath) diff --git a/src/ui/conf/confmanager.cpp b/src/ui/conf/confmanager.cpp index fd9e1686..891910c7 100644 --- a/src/ui/conf/confmanager.cpp +++ b/src/ui/conf/confmanager.cpp @@ -33,7 +33,7 @@ namespace { const QLoggingCategory LC("conf"); -constexpr int DATABASE_USER_VERSION = 37; +constexpr int DATABASE_USER_VERSION = 38; const char *const sqlSelectAddressGroups = "SELECT addr_group_id, include_all, exclude_all," " include_zones, exclude_zones," diff --git a/src/ui/conf/confrulemanager.cpp b/src/ui/conf/confrulemanager.cpp index f241f427..2b1d1278 100644 --- a/src/ui/conf/confrulemanager.cpp +++ b/src/ui/conf/confrulemanager.cpp @@ -36,12 +36,10 @@ const char *const sqlSelectRuleIds = "SELECT rule_id FROM rule" const char *const sqlDeleteRule = "DELETE FROM rule WHERE rule_id = ?1;"; const char *const sqlDeleteAppRule = "UPDATE app" - " SET app_rules = app_rules & ~?1" - " WHERE (app_rules & ?1) <> 0;"; + " SET rule_id = NULL" + " WHERE rule_id = ?1;"; -const char *const sqlDeletePresetRule = "UPDATE rule" - " SET preset_rules = preset_rules & ~?1" - " WHERE (preset_rules & ?1) <> 0;"; +const char *const sqlDeleteRuleSet = "DELETE rule_set WHERE rule_id = ?1;"; const char *const sqlUpdateRuleName = "UPDATE rule SET name = ?2 WHERE rule_id = ?1;"; @@ -155,7 +153,7 @@ bool ConfRuleManager::deleteRule(int ruleId) } break; case Rule::PresetRule: { // Delete the Preset Rule from Rules - DbUtil(sqliteDb(), &ok).sql(sqlDeletePresetRule).vars(vars).executeOk(); + DbUtil(sqliteDb(), &ok).sql(sqlDeleteRuleSet).vars(vars).executeOk(); } break; } } diff --git a/src/ui/conf/migrations/1.sql b/src/ui/conf/migrations/1.sql index 40275718..a32d1274 100644 --- a/src/ui/conf/migrations/1.sql +++ b/src/ui/conf/migrations/1.sql @@ -70,7 +70,7 @@ CREATE TABLE app( kill_process BOOLEAN NOT NULL DEFAULT 0, accept_zones INTEGER NOT NULL DEFAULT 0, -- zone ids bit mask reject_zones INTEGER NOT NULL DEFAULT 0, -- zone ids bit mask - app_rules INTEGER NOT NULL DEFAULT 0, -- rule ids bit mask + rule_id INTEGER, creat_time INTEGER NOT NULL, end_action INTEGER NOT NULL DEFAULT 0, end_time INTEGER @@ -79,6 +79,7 @@ CREATE TABLE app( CREATE INDEX app_app_group_id_idx ON app(app_group_id); CREATE UNIQUE INDEX app_path_uk ON app(path); CREATE INDEX app_name_idx ON app(name); +CREATE INDEX app_rule_idx ON app(rule_id); CREATE INDEX app_end_time_idx ON app(end_time); CREATE TABLE app_alert( @@ -96,12 +97,20 @@ CREATE TABLE rule( rule_type INTEGER NOT NULL, -- app rules, global before/after apps, preset rules accept_zones INTEGER NOT NULL DEFAULT 0, -- zone ids bit mask reject_zones INTEGER NOT NULL DEFAULT 0, -- zone ids bit mask - preset_rules INTEGER NOT NULL DEFAULT 0, -- rule ids bit mask mod_time INTEGER NOT NULL ); CREATE INDEX rule_rule_type_name_idx ON rule(rule_type, lower(name)); +CREATE TABLE rule_set( + rule_set_id INTEGER PRIMARY KEY, + rule_id INTEGER NOT NULL, + sub_rule_id INTEGER NOT NULL, + order_index INTEGER NOT NULL +); + +CREATE INDEX rule_set_rule_id_idx ON rule_set(rule_id); + CREATE TABLE task( task_id INTEGER PRIMARY KEY, name TEXT NOT NULL, diff --git a/src/ui/model/applistmodel.cpp b/src/ui/model/applistmodel.cpp index 49411d55..4da77aa2 100644 --- a/src/ui/model/applistmodel.cpp +++ b/src/ui/model/applistmodel.cpp @@ -420,11 +420,12 @@ bool AppListModel::updateAppRow(const QString &sql, const QVariantHash &vars, Ap appRow.killProcess = stmt.columnBool(14); appRow.acceptZones = stmt.columnUInt(15); appRow.rejectZones = stmt.columnUInt(16); - appRow.scheduleAction = stmt.columnInt(17); - appRow.scheduleTime = stmt.columnDateTime(18); - appRow.creatTime = stmt.columnDateTime(19); - appRow.groupIndex = stmt.columnInt(20); - appRow.alerted = stmt.columnBool(21); + appRow.ruleId = stmt.columnUInt(17); + appRow.scheduleAction = stmt.columnInt(18); + appRow.scheduleTime = stmt.columnDateTime(19); + appRow.creatTime = stmt.columnDateTime(20); + appRow.groupIndex = stmt.columnInt(21); + appRow.alerted = stmt.columnBool(22); return true; } @@ -484,6 +485,7 @@ QString AppListModel::sqlBase() const " t.kill_process," " t.accept_zones," " t.reject_zones," + " t.rule_id," " t.end_action," " t.end_time," " t.creat_time," diff --git a/src/ui/model/rulelistmodel.cpp b/src/ui/model/rulelistmodel.cpp index fe8721f5..ca4ba070 100644 --- a/src/ui/model/rulelistmodel.cpp +++ b/src/ui/model/rulelistmodel.cpp @@ -348,7 +348,6 @@ QString RuleListModel::sqlBase() const " rule_type," " accept_zones," " reject_zones," - " preset_rules," " mod_time" " FROM rule t" " WHERE rule_type = :type"; diff --git a/src/ui/rpc/confappmanagerrpc.cpp b/src/ui/rpc/confappmanagerrpc.cpp index b715ceb8..e06cb091 100644 --- a/src/ui/rpc/confappmanagerrpc.cpp +++ b/src/ui/rpc/confappmanagerrpc.cpp @@ -127,8 +127,8 @@ QVariantList ConfAppManagerRpc::appToVarList(const App &app) { return { app.isWildcard, app.useGroupPerm, app.applyChild, app.killChild, app.lanOnly, app.parked, app.logBlocked, app.logConn, app.blocked, app.killProcess, app.groupIndex, - app.acceptZones, app.rejectZones, app.appId, app.appOriginPath, app.appPath, app.appName, - app.notes, app.scheduleAction, app.scheduleTime }; + app.acceptZones, app.rejectZones, app.ruleId, app.appId, app.appOriginPath, app.appPath, + app.appName, app.notes, app.scheduleAction, app.scheduleTime }; } App ConfAppManagerRpc::varListToApp(const QVariantList &v) @@ -147,13 +147,14 @@ App ConfAppManagerRpc::varListToApp(const QVariantList &v) app.groupIndex = v.value(10).toInt(); app.acceptZones = v.value(11).toUInt(); app.rejectZones = v.value(12).toUInt(); - app.appId = v.value(13).toLongLong(); - app.appOriginPath = v.value(14).toString(); - app.appPath = v.value(15).toString(); - app.appName = v.value(16).toString(); - app.notes = v.value(17).toString(); - app.scheduleAction = v.value(18).toInt(); - app.scheduleTime = v.value(19).toDateTime(); + app.ruleId = v.value(13).toUInt(); + app.appId = v.value(14).toLongLong(); + app.appOriginPath = v.value(15).toString(); + app.appPath = v.value(16).toString(); + app.appName = v.value(17).toString(); + app.notes = v.value(18).toString(); + app.scheduleAction = v.value(19).toInt(); + app.scheduleTime = v.value(20).toDateTime(); return app; }