Refactor event and session column names to camelCase

- Updated test cases to reflect new column names (eve_MAC -> eveMac, eve_DateTime -> eveDateTime, etc.) across various test files.
- Modified SQL table definitions in the database cleanup and migration tests to use camelCase naming conventions.
- Implemented migration tests to ensure legacy column names are correctly renamed to camelCase equivalents.
- Ensured that existing data is preserved during the migration process and that views referencing old column names are dropped before renaming.
- Verified that the migration function is idempotent, allowing for safe re-execution without data loss.
This commit is contained in:
Jokob @NetAlertX
2026-03-16 10:11:22 +00:00
parent 0bb6db155b
commit c7399215ec
109 changed files with 2403 additions and 1967 deletions

View File

@@ -157,7 +157,7 @@ def ensure_views(sql) -> bool:
sql.execute(""" CREATE VIEW Events_Devices AS
SELECT *
FROM Events
LEFT JOIN Devices ON eve_MAC = devMac;
LEFT JOIN Devices ON eveMac = devMac;
""")
sql.execute(""" DROP VIEW IF EXISTS LatestEventsPerMAC;""")
@@ -165,7 +165,7 @@ def ensure_views(sql) -> bool:
WITH RankedEvents AS (
SELECT
e.*,
ROW_NUMBER() OVER (PARTITION BY e.eve_MAC ORDER BY e.eve_DateTime DESC) AS row_num
ROW_NUMBER() OVER (PARTITION BY e.eveMac ORDER BY e.eveDateTime DESC) AS row_num
FROM Events AS e
)
SELECT
@@ -173,43 +173,43 @@ def ensure_views(sql) -> bool:
d.*,
c.*
FROM RankedEvents AS e
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.scanMac
LEFT JOIN Devices AS d ON e.eveMac = d.devMac
INNER JOIN CurrentScan AS c ON e.eveMac = c.scanMac
WHERE e.row_num = 1;""")
sql.execute(""" DROP VIEW IF EXISTS Sessions_Devices;""")
sql.execute(
"""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;"""
"""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON sesMac = devMac;"""
)
# handling the Convert_Events_to_Sessions / Sessions screens
sql.execute("""DROP VIEW IF EXISTS Convert_Events_to_Sessions;""")
sql.execute("""CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eve_MAC,
EVE1.eve_IP,
EVE1.eve_EventType AS eve_EventTypeConnection,
EVE1.eve_DateTime AS eve_DateTimeConnection,
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') OR
EVE2.eve_EventType IS NULL THEN EVE2.eve_EventType ELSE '<missing event>' END AS eve_EventTypeDisconnection,
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') THEN EVE2.eve_DateTime ELSE NULL END AS eve_DateTimeDisconnection,
CASE WHEN EVE2.eve_EventType IS NULL THEN 1 ELSE 0 END AS eve_StillConnected,
EVE1.eve_AdditionalInfo
sql.execute("""CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eveMac,
EVE1.eveIp,
EVE1.eveEventType AS eveEventTypeConnection,
EVE1.eveDateTime AS eveDateTimeConnection,
CASE WHEN EVE2.eveEventType IN ('Disconnected', 'Device Down') OR
EVE2.eveEventType IS NULL THEN EVE2.eveEventType ELSE '<missing event>' END AS eveEventTypeDisconnection,
CASE WHEN EVE2.eveEventType IN ('Disconnected', 'Device Down') THEN EVE2.eveDateTime ELSE NULL END AS eveDateTimeDisconnection,
CASE WHEN EVE2.eveEventType IS NULL THEN 1 ELSE 0 END AS eveStillConnected,
EVE1.eveAdditionalInfo
FROM Events AS EVE1
LEFT JOIN
Events AS EVE2 ON EVE1.eve_PairEventRowID = EVE2.RowID
WHERE EVE1.eve_EventType IN ('New Device', 'Connected','Down Reconnected')
Events AS EVE2 ON EVE1.evePairEventRowid = EVE2.RowID
WHERE EVE1.eveEventType IN ('New Device', 'Connected','Down Reconnected')
UNION
SELECT eve_MAC,
eve_IP,
'<missing event>' AS eve_EventTypeConnection,
NULL AS eve_DateTimeConnection,
eve_EventType AS eve_EventTypeDisconnection,
eve_DateTime AS eve_DateTimeDisconnection,
0 AS eve_StillConnected,
eve_AdditionalInfo
SELECT eveMac,
eveIp,
'<missing event>' AS eveEventTypeConnection,
NULL AS eveDateTimeConnection,
eveEventType AS eveEventTypeDisconnection,
eveDateTime AS eveDateTimeDisconnection,
0 AS eveStillConnected,
eveAdditionalInfo
FROM Events AS EVE1
WHERE (eve_EventType = 'Device Down' OR
eve_EventType = 'Disconnected') AND
EVE1.eve_PairEventRowID IS NULL;
WHERE (eveEventType = 'Device Down' OR
eveEventType = 'Disconnected') AND
EVE1.evePairEventRowid IS NULL;
""")
sql.execute(""" DROP VIEW IF EXISTS LatestDeviceScan;""")
@@ -316,10 +316,10 @@ def ensure_views(sql) -> bool:
WHEN EXISTS (
SELECT 1
FROM Events e
WHERE LOWER(e.eve_MAC) = LOWER(Devices.devMac)
AND e.eve_EventType IN ('Connected','Disconnected','Device Down','Down Reconnected')
AND e.eve_DateTime >= datetime('now', '-{FLAP_WINDOW_HOURS} hours')
GROUP BY e.eve_MAC
WHERE LOWER(e.eveMac) = LOWER(Devices.devMac)
AND e.eveEventType IN ('Connected','Disconnected','Device Down','Down Reconnected')
AND e.eveDateTime >= datetime('now', '-{FLAP_WINDOW_HOURS} hours')
GROUP BY e.eveMac
HAVING COUNT(*) >= {FLAP_THRESHOLD}
)
THEN 1
@@ -360,10 +360,10 @@ def ensure_Indexes(sql) -> bool:
SELECT MIN(rowid)
FROM Events
GROUP BY
eve_MAC,
eve_IP,
eve_EventType,
eve_DateTime
eveMac,
eveIp,
eveEventType,
eveDateTime
);
"""
@@ -373,32 +373,32 @@ def ensure_Indexes(sql) -> bool:
# Sessions
(
"idx_ses_mac_date",
"CREATE INDEX idx_ses_mac_date ON Sessions(ses_MAC, ses_DateTimeConnection, ses_DateTimeDisconnection, ses_StillConnected)",
"CREATE INDEX idx_ses_mac_date ON Sessions(sesMac, sesDateTimeConnection, sesDateTimeDisconnection, sesStillConnected)",
),
# Events
(
"idx_eve_mac_date_type",
"CREATE INDEX idx_eve_mac_date_type ON Events(eve_MAC, eve_DateTime, eve_EventType)",
"CREATE INDEX idx_eve_mac_date_type ON Events(eveMac, eveDateTime, eveEventType)",
),
(
"idx_eve_alert_pending",
"CREATE INDEX idx_eve_alert_pending ON Events(eve_PendingAlertEmail)",
"CREATE INDEX idx_eve_alert_pending ON Events(evePendingAlertEmail)",
),
(
"idx_eve_mac_datetime_desc",
"CREATE INDEX idx_eve_mac_datetime_desc ON Events(eve_MAC, eve_DateTime DESC)",
"CREATE INDEX idx_eve_mac_datetime_desc ON Events(eveMac, eveDateTime DESC)",
),
(
"idx_eve_pairevent",
"CREATE INDEX idx_eve_pairevent ON Events(eve_PairEventRowID)",
"CREATE INDEX idx_eve_pairevent ON Events(evePairEventRowid)",
),
(
"idx_eve_type_date",
"CREATE INDEX idx_eve_type_date ON Events(eve_EventType, eve_DateTime)",
"CREATE INDEX idx_eve_type_date ON Events(eveEventType, eveDateTime)",
),
(
"idx_events_unique",
"CREATE UNIQUE INDEX idx_events_unique ON Events (eve_MAC, eve_IP, eve_EventType, eve_DateTime)",
"CREATE UNIQUE INDEX idx_events_unique ON Events (eveMac, eveIp, eveEventType, eveDateTime)",
),
# Devices
("idx_dev_mac", "CREATE INDEX idx_dev_mac ON Devices(devMac)"),
@@ -436,15 +436,15 @@ def ensure_Indexes(sql) -> bool:
# Plugins_Objects
(
"idx_plugins_plugin_mac_ip",
"CREATE INDEX idx_plugins_plugin_mac_ip ON Plugins_Objects(Plugin, Object_PrimaryID, Object_SecondaryID)",
"CREATE INDEX idx_plugins_plugin_mac_ip ON Plugins_Objects(plugin, objectPrimaryId, objectSecondaryId)",
), # Issue #1251: Optimize name resolution lookup
# Plugins_History: covers both the db_cleanup window function
# (PARTITION BY Plugin ORDER BY DateTimeChanged DESC) and the
# API query (SELECT * … ORDER BY DateTimeChanged DESC).
# (PARTITION BY plugin ORDER BY dateTimeChanged DESC) and the
# API query (SELECT * … ORDER BY dateTimeChanged DESC).
# Without this, both ops do a full 48k-row table sort on every cycle.
(
"idx_plugins_history_plugin_dt",
"CREATE INDEX idx_plugins_history_plugin_dt ON Plugins_History(Plugin, DateTimeChanged DESC)",
"CREATE INDEX idx_plugins_history_plugin_dt ON Plugins_History(plugin, dateTimeChanged DESC)",
),
]
@@ -547,94 +547,295 @@ def ensure_plugins_tables(sql) -> bool:
# Plugin state
sql_Plugins_Objects = """ CREATE TABLE IF NOT EXISTS Plugins_Objects(
"Index" INTEGER,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
DateTimeChanged TEXT NOT NULL,
Watched_Value1 TEXT NOT NULL,
Watched_Value2 TEXT NOT NULL,
Watched_Value3 TEXT NOT NULL,
Watched_Value4 TEXT NOT NULL,
Status TEXT NOT NULL,
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
ObjectGUID TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
plugin TEXT NOT NULL,
objectPrimaryId TEXT NOT NULL,
objectSecondaryId TEXT NOT NULL,
dateTimeCreated TEXT NOT NULL,
dateTimeChanged TEXT NOT NULL,
watchedValue1 TEXT NOT NULL,
watchedValue2 TEXT NOT NULL,
watchedValue3 TEXT NOT NULL,
watchedValue4 TEXT NOT NULL,
"status" TEXT NOT NULL,
extra TEXT NOT NULL,
userData TEXT NOT NULL,
foreignKey TEXT NOT NULL,
syncHubNodeName TEXT,
helpVal1 TEXT,
helpVal2 TEXT,
helpVal3 TEXT,
helpVal4 TEXT,
objectGuid TEXT,
PRIMARY KEY("index" AUTOINCREMENT)
); """
sql.execute(sql_Plugins_Objects)
# Plugin execution results
sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events(
"Index" INTEGER,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
DateTimeChanged TEXT NOT NULL,
Watched_Value1 TEXT NOT NULL,
Watched_Value2 TEXT NOT NULL,
Watched_Value3 TEXT NOT NULL,
Watched_Value4 TEXT NOT NULL,
Status TEXT NOT NULL,
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
plugin TEXT NOT NULL,
objectPrimaryId TEXT NOT NULL,
objectSecondaryId TEXT NOT NULL,
dateTimeCreated TEXT NOT NULL,
dateTimeChanged TEXT NOT NULL,
watchedValue1 TEXT NOT NULL,
watchedValue2 TEXT NOT NULL,
watchedValue3 TEXT NOT NULL,
watchedValue4 TEXT NOT NULL,
"status" TEXT NOT NULL,
extra TEXT NOT NULL,
userData TEXT NOT NULL,
foreignKey TEXT NOT NULL,
syncHubNodeName TEXT,
helpVal1 TEXT,
helpVal2 TEXT,
helpVal3 TEXT,
helpVal4 TEXT,
objectGuid TEXT,
PRIMARY KEY("index" AUTOINCREMENT)
); """
sql.execute(sql_Plugins_Events)
# Plugin execution history
sql_Plugins_History = """ CREATE TABLE IF NOT EXISTS Plugins_History(
"Index" INTEGER,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
DateTimeChanged TEXT NOT NULL,
Watched_Value1 TEXT NOT NULL,
Watched_Value2 TEXT NOT NULL,
Watched_Value3 TEXT NOT NULL,
Watched_Value4 TEXT NOT NULL,
Status TEXT NOT NULL,
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
plugin TEXT NOT NULL,
objectPrimaryId TEXT NOT NULL,
objectSecondaryId TEXT NOT NULL,
dateTimeCreated TEXT NOT NULL,
dateTimeChanged TEXT NOT NULL,
watchedValue1 TEXT NOT NULL,
watchedValue2 TEXT NOT NULL,
watchedValue3 TEXT NOT NULL,
watchedValue4 TEXT NOT NULL,
"status" TEXT NOT NULL,
extra TEXT NOT NULL,
userData TEXT NOT NULL,
foreignKey TEXT NOT NULL,
syncHubNodeName TEXT,
helpVal1 TEXT,
helpVal2 TEXT,
helpVal3 TEXT,
helpVal4 TEXT,
objectGuid TEXT,
PRIMARY KEY("index" AUTOINCREMENT)
); """
sql.execute(sql_Plugins_History)
# Dynamically generated language strings
sql.execute("DROP TABLE IF EXISTS Plugins_Language_Strings;")
sql.execute(""" CREATE TABLE IF NOT EXISTS Plugins_Language_Strings(
"Index" INTEGER,
Language_Code TEXT NOT NULL,
String_Key TEXT NOT NULL,
String_Value TEXT NOT NULL,
Extra TEXT NOT NULL,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
languageCode TEXT NOT NULL,
stringKey TEXT NOT NULL,
stringValue TEXT NOT NULL,
extra TEXT NOT NULL,
PRIMARY KEY("index" AUTOINCREMENT)
); """)
return True
# ===============================================================================
# CamelCase Column Migration
# ===============================================================================
# Mapping of (table_name, old_column_name) → new_column_name.
# Only entries where the name actually changes are listed.
# Columns like "Index" → "index" are cosmetic case changes handled
# implicitly by SQLite's case-insensitive matching.
_CAMELCASE_COLUMN_MAP = {
"Events": {
"eve_MAC": "eveMac",
"eve_IP": "eveIp",
"eve_DateTime": "eveDateTime",
"eve_EventType": "eveEventType",
"eve_AdditionalInfo": "eveAdditionalInfo",
"eve_PendingAlertEmail": "evePendingAlertEmail",
"eve_PairEventRowid": "evePairEventRowid",
"eve_PairEventRowID": "evePairEventRowid",
},
"Sessions": {
"ses_MAC": "sesMac",
"ses_IP": "sesIp",
"ses_EventTypeConnection": "sesEventTypeConnection",
"ses_DateTimeConnection": "sesDateTimeConnection",
"ses_EventTypeDisconnection": "sesEventTypeDisconnection",
"ses_DateTimeDisconnection": "sesDateTimeDisconnection",
"ses_StillConnected": "sesStillConnected",
"ses_AdditionalInfo": "sesAdditionalInfo",
},
"Online_History": {
"Index": "index",
"Scan_Date": "scanDate",
"Online_Devices": "onlineDevices",
"Down_Devices": "downDevices",
"All_Devices": "allDevices",
"Archived_Devices": "archivedDevices",
"Offline_Devices": "offlineDevices",
},
"Plugins_Objects": {
"Index": "index",
"Plugin": "plugin",
"Object_PrimaryID": "objectPrimaryId",
"Object_SecondaryID": "objectSecondaryId",
"DateTimeCreated": "dateTimeCreated",
"DateTimeChanged": "dateTimeChanged",
"Watched_Value1": "watchedValue1",
"Watched_Value2": "watchedValue2",
"Watched_Value3": "watchedValue3",
"Watched_Value4": "watchedValue4",
"Status": "status",
"Extra": "extra",
"UserData": "userData",
"ForeignKey": "foreignKey",
"SyncHubNodeName": "syncHubNodeName",
"HelpVal1": "helpVal1",
"HelpVal2": "helpVal2",
"HelpVal3": "helpVal3",
"HelpVal4": "helpVal4",
"ObjectGUID": "objectGuid",
},
"Plugins_Events": {
"Index": "index",
"Plugin": "plugin",
"Object_PrimaryID": "objectPrimaryId",
"Object_SecondaryID": "objectSecondaryId",
"DateTimeCreated": "dateTimeCreated",
"DateTimeChanged": "dateTimeChanged",
"Watched_Value1": "watchedValue1",
"Watched_Value2": "watchedValue2",
"Watched_Value3": "watchedValue3",
"Watched_Value4": "watchedValue4",
"Status": "status",
"Extra": "extra",
"UserData": "userData",
"ForeignKey": "foreignKey",
"SyncHubNodeName": "syncHubNodeName",
"HelpVal1": "helpVal1",
"HelpVal2": "helpVal2",
"HelpVal3": "helpVal3",
"HelpVal4": "helpVal4",
"ObjectGUID": "objectGuid",
},
"Plugins_History": {
"Index": "index",
"Plugin": "plugin",
"Object_PrimaryID": "objectPrimaryId",
"Object_SecondaryID": "objectSecondaryId",
"DateTimeCreated": "dateTimeCreated",
"DateTimeChanged": "dateTimeChanged",
"Watched_Value1": "watchedValue1",
"Watched_Value2": "watchedValue2",
"Watched_Value3": "watchedValue3",
"Watched_Value4": "watchedValue4",
"Status": "status",
"Extra": "extra",
"UserData": "userData",
"ForeignKey": "foreignKey",
"SyncHubNodeName": "syncHubNodeName",
"HelpVal1": "helpVal1",
"HelpVal2": "helpVal2",
"HelpVal3": "helpVal3",
"HelpVal4": "helpVal4",
"ObjectGUID": "objectGuid",
},
"Plugins_Language_Strings": {
"Index": "index",
"Language_Code": "languageCode",
"String_Key": "stringKey",
"String_Value": "stringValue",
"Extra": "extra",
},
"AppEvents": {
"Index": "index",
"GUID": "guid",
"AppEventProcessed": "appEventProcessed",
"DateTimeCreated": "dateTimeCreated",
"ObjectType": "objectType",
"ObjectGUID": "objectGuid",
"ObjectPlugin": "objectPlugin",
"ObjectPrimaryID": "objectPrimaryId",
"ObjectSecondaryID": "objectSecondaryId",
"ObjectForeignKey": "objectForeignKey",
"ObjectIndex": "objectIndex",
"ObjectIsNew": "objectIsNew",
"ObjectIsArchived": "objectIsArchived",
"ObjectStatusColumn": "objectStatusColumn",
"ObjectStatus": "objectStatus",
"AppEventType": "appEventType",
"Helper1": "helper1",
"Helper2": "helper2",
"Helper3": "helper3",
"Extra": "extra",
},
"Notifications": {
"Index": "index",
"GUID": "guid",
"DateTimeCreated": "dateTimeCreated",
"DateTimePushed": "dateTimePushed",
"Status": "status",
"JSON": "json",
"Text": "text",
"HTML": "html",
"PublishedVia": "publishedVia",
"Extra": "extra",
},
}
def migrate_to_camelcase(sql) -> bool:
"""
Detects legacy (underscore/PascalCase) column names and renames them
to camelCase using ALTER TABLE … RENAME COLUMN (SQLite ≥ 3.25.0).
Idempotent: columns already matching the new name are silently skipped.
"""
# Quick probe: if Events table has 'eveMac' we're already on the new schema
sql.execute('PRAGMA table_info("Events")')
events_cols = {row[1] for row in sql.fetchall()}
if "eveMac" in events_cols:
mylog("verbose", ["[db_upgrade] Schema already uses camelCase — skipping migration"])
return True
if "eve_MAC" not in events_cols:
# Events table doesn't exist or has unexpected schema — skip silently
mylog("verbose", ["[db_upgrade] Events table missing/unrecognised — skipping camelCase migration"])
return True
mylog("none", ["[db_upgrade] Starting camelCase column migration …"])
# Drop views first — ALTER TABLE RENAME COLUMN will fail if a view
# references the old column name and the view SQL cannot be rewritten.
for view_name in ("Events_Devices", "LatestEventsPerMAC", "Sessions_Devices",
"Convert_Events_to_Sessions", "LatestDeviceScan", "DevicesView"):
sql.execute(f"DROP VIEW IF EXISTS {view_name};")
renamed_count = 0
for table, column_map in _CAMELCASE_COLUMN_MAP.items():
# Check table exists
sql.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table,))
if not sql.fetchone():
mylog("verbose", [f"[db_upgrade] Table '{table}' does not exist — skipping"])
continue
# Get current column names (case-preserved)
sql.execute(f'PRAGMA table_info("{table}")')
current_cols = {row[1] for row in sql.fetchall()}
for old_name, new_name in column_map.items():
if old_name in current_cols and new_name not in current_cols:
sql.execute(f'ALTER TABLE "{table}" RENAME COLUMN "{old_name}" TO "{new_name}"')
renamed_count += 1
mylog("verbose", [f"[db_upgrade] {table}.{old_name}{new_name}"])
mylog("none", [f"[db_upgrade] ✓ camelCase migration complete — {renamed_count} columns renamed"])
return True
# ===============================================================================
# UTC Timestamp Migration (added 2026-02-10)
# ===============================================================================
@@ -817,17 +1018,18 @@ def migrate_timestamps_to_utc(sql) -> bool:
mylog("verbose", f"[db_upgrade] Starting UTC timestamp migration (offset: {offset_hours} hours)")
# List of tables and their datetime columns
# List of tables and their datetime columns (camelCase names —
# migrate_to_camelcase() runs before this function).
timestamp_columns = {
'Devices': ['devFirstConnection', 'devLastConnection', 'devLastNotification'],
'Events': ['eve_DateTime'],
'Sessions': ['ses_DateTimeConnection', 'ses_DateTimeDisconnection'],
'Notifications': ['DateTimeCreated', 'DateTimePushed'],
'Online_History': ['Scan_Date'],
'Plugins_Objects': ['DateTimeCreated', 'DateTimeChanged'],
'Plugins_Events': ['DateTimeCreated', 'DateTimeChanged'],
'Plugins_History': ['DateTimeCreated', 'DateTimeChanged'],
'AppEvents': ['DateTimeCreated'],
'Events': ['eveDateTime'],
'Sessions': ['sesDateTimeConnection', 'sesDateTimeDisconnection'],
'Notifications': ['dateTimeCreated', 'dateTimePushed'],
'Online_History': ['scanDate'],
'Plugins_Objects': ['dateTimeCreated', 'dateTimeChanged'],
'Plugins_Events': ['dateTimeCreated', 'dateTimeChanged'],
'Plugins_History': ['dateTimeCreated', 'dateTimeChanged'],
'AppEvents': ['dateTimeCreated'],
}
for table, columns in timestamp_columns.items():

View File

@@ -1,14 +1,14 @@
CREATE TABLE Events (eve_MAC STRING (50) NOT NULL COLLATE NOCASE, eve_IP STRING (50) NOT NULL COLLATE NOCASE, eve_DateTime DATETIME NOT NULL, eve_EventType STRING (30) NOT NULL COLLATE NOCASE, eve_AdditionalInfo STRING (250) DEFAULT (''), eve_PendingAlertEmail BOOLEAN NOT NULL CHECK (eve_PendingAlertEmail IN (0, 1)) DEFAULT (1), eve_PairEventRowid INTEGER);
CREATE TABLE Sessions (ses_MAC STRING (50) COLLATE NOCASE, ses_IP STRING (50) COLLATE NOCASE, ses_EventTypeConnection STRING (30) COLLATE NOCASE, ses_DateTimeConnection DATETIME, ses_EventTypeDisconnection STRING (30) COLLATE NOCASE, ses_DateTimeDisconnection DATETIME, ses_StillConnected BOOLEAN, ses_AdditionalInfo STRING (250));
CREATE TABLE IF NOT EXISTS "Online_History" (
"Index" INTEGER,
"Scan_Date" TEXT,
"Online_Devices" INTEGER,
"Down_Devices" INTEGER,
"All_Devices" INTEGER,
"Archived_Devices" INTEGER,
"Offline_Devices" INTEGER,
PRIMARY KEY("Index" AUTOINCREMENT)
CREATE TABLE Events (eveMac STRING (50) NOT NULL COLLATE NOCASE, eveIp STRING (50) NOT NULL COLLATE NOCASE, eveDateTime DATETIME NOT NULL, eveEventType STRING (30) NOT NULL COLLATE NOCASE, eveAdditionalInfo STRING (250) DEFAULT (''), evePendingAlertEmail BOOLEAN NOT NULL CHECK (evePendingAlertEmail IN (0, 1)) DEFAULT (1), evePairEventRowid INTEGER);
CREATE TABLE Sessions (sesMac STRING (50) COLLATE NOCASE, sesIp STRING (50) COLLATE NOCASE, sesEventTypeConnection STRING (30) COLLATE NOCASE, sesDateTimeConnection DATETIME, sesEventTypeDisconnection STRING (30) COLLATE NOCASE, sesDateTimeDisconnection DATETIME, sesStillConnected BOOLEAN, sesAdditionalInfo STRING (250));
CREATE TABLE IF NOT EXISTS Online_History (
"index" INTEGER,
scanDate TEXT,
onlineDevices INTEGER,
downDevices INTEGER,
allDevices INTEGER,
archivedDevices INTEGER,
offlineDevices INTEGER,
PRIMARY KEY("index" AUTOINCREMENT)
);
CREATE TABLE Devices (
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
@@ -57,96 +57,98 @@ CREATE TABLE Devices (
devParentPortSource TEXT,
devParentRelTypeSource TEXT,
devVlanSource TEXT,
"devCustomProps" TEXT);
CREATE TABLE IF NOT EXISTS "Settings" (
"setKey" TEXT,
"setName" TEXT,
"setDescription" TEXT,
"setType" TEXT,
"setOptions" TEXT,
"setGroup" TEXT,
"setValue" TEXT,
"setEvents" TEXT,
"setOverriddenByEnv" INTEGER
devCustomProps TEXT);
CREATE TABLE IF NOT EXISTS Settings (
setKey TEXT,
setName TEXT,
setDescription TEXT,
setType TEXT,
setOptions TEXT,
setGroup TEXT,
setValue TEXT,
setEvents TEXT,
setOverriddenByEnv INTEGER
);
CREATE TABLE IF NOT EXISTS "Parameters" (
"parID" TEXT PRIMARY KEY,
"parValue" TEXT
CREATE TABLE IF NOT EXISTS Parameters (
parID TEXT PRIMARY KEY,
parValue TEXT
);
CREATE TABLE Plugins_Objects(
"Index" INTEGER,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
DateTimeChanged TEXT NOT NULL,
Watched_Value1 TEXT NOT NULL,
Watched_Value2 TEXT NOT NULL,
Watched_Value3 TEXT NOT NULL,
Watched_Value4 TEXT NOT NULL,
Status TEXT NOT NULL,
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
ObjectGUID TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
plugin TEXT NOT NULL,
objectPrimaryId TEXT NOT NULL,
objectSecondaryId TEXT NOT NULL,
dateTimeCreated TEXT NOT NULL,
dateTimeChanged TEXT NOT NULL,
watchedValue1 TEXT NOT NULL,
watchedValue2 TEXT NOT NULL,
watchedValue3 TEXT NOT NULL,
watchedValue4 TEXT NOT NULL,
"status" TEXT NOT NULL,
extra TEXT NOT NULL,
userData TEXT NOT NULL,
foreignKey TEXT NOT NULL,
syncHubNodeName TEXT,
helpVal1 TEXT,
helpVal2 TEXT,
helpVal3 TEXT,
helpVal4 TEXT,
objectGuid TEXT,
PRIMARY KEY("index" AUTOINCREMENT)
);
CREATE TABLE Plugins_Events(
"Index" INTEGER,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
DateTimeChanged TEXT NOT NULL,
Watched_Value1 TEXT NOT NULL,
Watched_Value2 TEXT NOT NULL,
Watched_Value3 TEXT NOT NULL,
Watched_Value4 TEXT NOT NULL,
Status TEXT NOT NULL,
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT, "ObjectGUID" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
plugin TEXT NOT NULL,
objectPrimaryId TEXT NOT NULL,
objectSecondaryId TEXT NOT NULL,
dateTimeCreated TEXT NOT NULL,
dateTimeChanged TEXT NOT NULL,
watchedValue1 TEXT NOT NULL,
watchedValue2 TEXT NOT NULL,
watchedValue3 TEXT NOT NULL,
watchedValue4 TEXT NOT NULL,
"status" TEXT NOT NULL,
extra TEXT NOT NULL,
userData TEXT NOT NULL,
foreignKey TEXT NOT NULL,
syncHubNodeName TEXT,
helpVal1 TEXT,
helpVal2 TEXT,
helpVal3 TEXT,
helpVal4 TEXT,
objectGuid TEXT,
PRIMARY KEY("index" AUTOINCREMENT)
);
CREATE TABLE Plugins_History(
"Index" INTEGER,
Plugin TEXT NOT NULL,
Object_PrimaryID TEXT NOT NULL,
Object_SecondaryID TEXT NOT NULL,
DateTimeCreated TEXT NOT NULL,
DateTimeChanged TEXT NOT NULL,
Watched_Value1 TEXT NOT NULL,
Watched_Value2 TEXT NOT NULL,
Watched_Value3 TEXT NOT NULL,
Watched_Value4 TEXT NOT NULL,
Status TEXT NOT NULL,
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT, "ObjectGUID" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
plugin TEXT NOT NULL,
objectPrimaryId TEXT NOT NULL,
objectSecondaryId TEXT NOT NULL,
dateTimeCreated TEXT NOT NULL,
dateTimeChanged TEXT NOT NULL,
watchedValue1 TEXT NOT NULL,
watchedValue2 TEXT NOT NULL,
watchedValue3 TEXT NOT NULL,
watchedValue4 TEXT NOT NULL,
"status" TEXT NOT NULL,
extra TEXT NOT NULL,
userData TEXT NOT NULL,
foreignKey TEXT NOT NULL,
syncHubNodeName TEXT,
helpVal1 TEXT,
helpVal2 TEXT,
helpVal3 TEXT,
helpVal4 TEXT,
objectGuid TEXT,
PRIMARY KEY("index" AUTOINCREMENT)
);
CREATE TABLE Plugins_Language_Strings(
"Index" INTEGER,
Language_Code TEXT NOT NULL,
String_Key TEXT NOT NULL,
String_Value TEXT NOT NULL,
Extra TEXT NOT NULL,
PRIMARY KEY("Index" AUTOINCREMENT)
"index" INTEGER,
languageCode TEXT NOT NULL,
stringKey TEXT NOT NULL,
stringValue TEXT NOT NULL,
extra TEXT NOT NULL,
PRIMARY KEY("index" AUTOINCREMENT)
);
CREATE TABLE CurrentScan (
scanMac STRING(50) NOT NULL COLLATE NOCASE,
@@ -165,50 +167,50 @@ CREATE TABLE CurrentScan (
scanType STRING(250),
UNIQUE(scanMac)
);
CREATE TABLE IF NOT EXISTS "AppEvents" (
"Index" INTEGER PRIMARY KEY AUTOINCREMENT,
"GUID" TEXT UNIQUE,
"AppEventProcessed" BOOLEAN,
"DateTimeCreated" TEXT,
"ObjectType" TEXT,
"ObjectGUID" TEXT,
"ObjectPlugin" TEXT,
"ObjectPrimaryID" TEXT,
"ObjectSecondaryID" TEXT,
"ObjectForeignKey" TEXT,
"ObjectIndex" TEXT,
"ObjectIsNew" BOOLEAN,
"ObjectIsArchived" BOOLEAN,
"ObjectStatusColumn" TEXT,
"ObjectStatus" TEXT,
"AppEventType" TEXT,
"Helper1" TEXT,
"Helper2" TEXT,
"Helper3" TEXT,
"Extra" TEXT
CREATE TABLE IF NOT EXISTS AppEvents (
"index" INTEGER PRIMARY KEY AUTOINCREMENT,
guid TEXT UNIQUE,
appEventProcessed BOOLEAN,
dateTimeCreated TEXT,
objectType TEXT,
objectGuid TEXT,
objectPlugin TEXT,
objectPrimaryId TEXT,
objectSecondaryId TEXT,
objectForeignKey TEXT,
objectIndex TEXT,
objectIsNew BOOLEAN,
objectIsArchived BOOLEAN,
objectStatusColumn TEXT,
objectStatus TEXT,
appEventType TEXT,
helper1 TEXT,
helper2 TEXT,
helper3 TEXT,
extra TEXT
);
CREATE TABLE IF NOT EXISTS "Notifications" (
"Index" INTEGER,
"GUID" TEXT UNIQUE,
"DateTimeCreated" TEXT,
"DateTimePushed" TEXT,
"Status" TEXT,
"JSON" TEXT,
"Text" TEXT,
"HTML" TEXT,
"PublishedVia" TEXT,
"Extra" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
CREATE TABLE IF NOT EXISTS Notifications (
"index" INTEGER,
guid TEXT UNIQUE,
dateTimeCreated TEXT,
dateTimePushed TEXT,
"status" TEXT,
"json" TEXT,
"text" TEXT,
html TEXT,
publishedVia TEXT,
extra TEXT,
PRIMARY KEY("index" AUTOINCREMENT)
);
CREATE INDEX IDX_eve_DateTime ON Events (eve_DateTime);
CREATE INDEX IDX_eve_EventType ON Events (eve_EventType COLLATE NOCASE);
CREATE INDEX IDX_eve_MAC ON Events (eve_MAC COLLATE NOCASE);
CREATE INDEX IDX_eve_PairEventRowid ON Events (eve_PairEventRowid);
CREATE INDEX IDX_ses_EventTypeDisconnection ON Sessions (ses_EventTypeDisconnection COLLATE NOCASE);
CREATE INDEX IDX_ses_EventTypeConnection ON Sessions (ses_EventTypeConnection COLLATE NOCASE);
CREATE INDEX IDX_ses_DateTimeDisconnection ON Sessions (ses_DateTimeDisconnection);
CREATE INDEX IDX_ses_MAC ON Sessions (ses_MAC COLLATE NOCASE);
CREATE INDEX IDX_ses_DateTimeConnection ON Sessions (ses_DateTimeConnection);
CREATE INDEX IDX_eve_DateTime ON Events (eveDateTime);
CREATE INDEX IDX_eve_EventType ON Events (eveEventType COLLATE NOCASE);
CREATE INDEX IDX_eve_MAC ON Events (eveMac COLLATE NOCASE);
CREATE INDEX IDX_eve_PairEventRowid ON Events (evePairEventRowid);
CREATE INDEX IDX_ses_EventTypeDisconnection ON Sessions (sesEventTypeDisconnection COLLATE NOCASE);
CREATE INDEX IDX_ses_EventTypeConnection ON Sessions (sesEventTypeConnection COLLATE NOCASE);
CREATE INDEX IDX_ses_DateTimeDisconnection ON Sessions (sesDateTimeDisconnection);
CREATE INDEX IDX_ses_MAC ON Sessions (sesMac COLLATE NOCASE);
CREATE INDEX IDX_ses_DateTimeConnection ON Sessions (sesDateTimeConnection);
CREATE INDEX IDX_dev_PresentLastScan ON Devices (devPresentLastScan);
CREATE INDEX IDX_dev_FirstConnection ON Devices (devFirstConnection);
CREATE INDEX IDX_dev_AlertDeviceDown ON Devices (devAlertDown);
@@ -220,21 +222,20 @@ CREATE INDEX IDX_dev_NewDevice ON Devices (devIsNew);
CREATE INDEX IDX_dev_Archived ON Devices (devIsArchived);
CREATE UNIQUE INDEX IF NOT EXISTS idx_events_unique
ON Events (
eve_MAC,
eve_IP,
eve_EventType,
eve_DateTime
eveMac,
eveIp,
eveEventType,
eveDateTime
);
CREATE VIEW Events_Devices AS
SELECT *
FROM Events
LEFT JOIN Devices ON eve_MAC = devMac
/* Events_Devices(eve_MAC,eve_IP,eve_DateTime,eve_EventType,eve_AdditionalInfo,eve_PendingAlertEmail,eve_PairEventRowid,devMac,devName,devOwner,devType,devVendor,devFavorite,devGroup,devComments,devFirstConnection,devLastConnection,devLastIP,devStaticIP,devScan,devLogEvents,devAlertEvents,devAlertDown,devSkipRepeated,devLastNotification,devPresentLastScan,devIsNew,devLocation,devIsArchived,devParentMAC,devParentPort,devIcon,devGUID,devSite,devSSID,devSyncHubNode,devSourcePlugin,devCustomProps) */;
LEFT JOIN Devices ON eveMac = devMac;
CREATE VIEW LatestEventsPerMAC AS
WITH RankedEvents AS (
SELECT
e.*,
ROW_NUMBER() OVER (PARTITION BY e.eve_MAC ORDER BY e.eve_DateTime DESC) AS row_num
ROW_NUMBER() OVER (PARTITION BY e.eveMac ORDER BY e.eveDateTime DESC) AS row_num
FROM Events AS e
)
SELECT
@@ -242,192 +243,33 @@ CREATE VIEW LatestEventsPerMAC AS
d.*,
c.*
FROM RankedEvents AS e
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.scanMac
WHERE e.row_num = 1
/* LatestEventsPerMAC(eve_MAC,eve_IP,eve_DateTime,eve_EventType,eve_AdditionalInfo,eve_PendingAlertEmail,eve_PairEventRowid,row_num,devMac,devName,devOwner,devType,devVendor,devFavorite,devGroup,devComments,devFirstConnection,devLastConnection,devLastIP,devStaticIP,devScan,devLogEvents,devAlertEvents,devAlertDown,devSkipRepeated,devLastNotification,devPresentLastScan,devIsNew,devLocation,devIsArchived,devParentMAC,devParentPort,devIcon,devGUID,devSite,devSSID,devSyncHubNode,devSourcePlugin,devCustomProps,scanMac,scanLastIP,scanVendor,scanSourcePlugin,scanName,scanLastQuery,scanLastConnection,scanSyncHubNode,scanSite,scanSSID,scanParentMAC,scanParentPort,scanType) */;
CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac
/* Sessions_Devices(ses_MAC,ses_IP,ses_EventTypeConnection,ses_DateTimeConnection,ses_EventTypeDisconnection,ses_DateTimeDisconnection,ses_StillConnected,ses_AdditionalInfo,devMac,devName,devOwner,devType,devVendor,devFavorite,devGroup,devComments,devFirstConnection,devLastConnection,devLastIP,devStaticIP,devScan,devLogEvents,devAlertEvents,devAlertDown,devSkipRepeated,devLastNotification,devPresentLastScan,devIsNew,devLocation,devIsArchived,devParentMAC,devParentPort,devIcon,devGUID,devSite,devSSID,devSyncHubNode,devSourcePlugin,devCustomProps) */;
CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eve_MAC,
EVE1.eve_IP,
EVE1.eve_EventType AS eve_EventTypeConnection,
EVE1.eve_DateTime AS eve_DateTimeConnection,
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') OR
EVE2.eve_EventType IS NULL THEN EVE2.eve_EventType ELSE '<missing event>' END AS eve_EventTypeDisconnection,
CASE WHEN EVE2.eve_EventType IN ('Disconnected', 'Device Down') THEN EVE2.eve_DateTime ELSE NULL END AS eve_DateTimeDisconnection,
CASE WHEN EVE2.eve_EventType IS NULL THEN 1 ELSE 0 END AS eve_StillConnected,
EVE1.eve_AdditionalInfo
LEFT JOIN Devices AS d ON e.eveMac = d.devMac
INNER JOIN CurrentScan AS c ON e.eveMac = c.scanMac
WHERE e.row_num = 1;
CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN Devices ON sesMac = devMac;
CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eveMac,
EVE1.eveIp,
EVE1.eveEventType AS eveEventTypeConnection,
EVE1.eveDateTime AS eveDateTimeConnection,
CASE WHEN EVE2.eveEventType IN ('Disconnected', 'Device Down') OR
EVE2.eveEventType IS NULL THEN EVE2.eveEventType ELSE '<missing event>' END AS eveEventTypeDisconnection,
CASE WHEN EVE2.eveEventType IN ('Disconnected', 'Device Down') THEN EVE2.eveDateTime ELSE NULL END AS eveDateTimeDisconnection,
CASE WHEN EVE2.eveEventType IS NULL THEN 1 ELSE 0 END AS eveStillConnected,
EVE1.eveAdditionalInfo
FROM Events AS EVE1
LEFT JOIN
Events AS EVE2 ON EVE1.eve_PairEventRowID = EVE2.RowID
WHERE EVE1.eve_EventType IN ('New Device', 'Connected','Down Reconnected')
Events AS EVE2 ON EVE1.evePairEventRowid = EVE2.RowID
WHERE EVE1.eveEventType IN ('New Device', 'Connected','Down Reconnected')
UNION
SELECT eve_MAC,
eve_IP,
'<missing event>' AS eve_EventTypeConnection,
NULL AS eve_DateTimeConnection,
eve_EventType AS eve_EventTypeDisconnection,
eve_DateTime AS eve_DateTimeDisconnection,
0 AS eve_StillConnected,
eve_AdditionalInfo
SELECT eveMac,
eveIp,
'<missing event>' AS eveEventTypeConnection,
NULL AS eveDateTimeConnection,
eveEventType AS eveEventTypeDisconnection,
eveDateTime AS eveDateTimeDisconnection,
0 AS eveStillConnected,
eveAdditionalInfo
FROM Events AS EVE1
WHERE (eve_EventType = 'Device Down' OR
eve_EventType = 'Disconnected') AND
EVE1.eve_PairEventRowID IS NULL
/* Convert_Events_to_Sessions(eve_MAC,eve_IP,eve_EventTypeConnection,eve_DateTimeConnection,eve_EventTypeDisconnection,eve_DateTimeDisconnection,eve_StillConnected,eve_AdditionalInfo) */;
CREATE TRIGGER "trg_insert_devices"
AFTER INSERT ON "Devices"
WHEN NOT EXISTS (
SELECT 1 FROM AppEvents
WHERE AppEventProcessed = 0
AND ObjectType = 'Devices'
AND ObjectGUID = NEW.devGUID
AND ObjectStatus = CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END
AND AppEventType = 'insert'
)
BEGIN
INSERT INTO "AppEvents" (
"GUID",
"DateTimeCreated",
"AppEventProcessed",
"ObjectType",
"ObjectGUID",
"ObjectPrimaryID",
"ObjectSecondaryID",
"ObjectStatus",
"ObjectStatusColumn",
"ObjectIsNew",
"ObjectIsArchived",
"ObjectForeignKey",
"ObjectPlugin",
"AppEventType"
)
VALUES (
lower(
hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
substr(hex( randomblob(2)), 2) || '-' ||
substr('AB89', 1 + (abs(random()) % 4) , 1) ||
substr(hex(randomblob(2)), 2) || '-' ||
hex(randomblob(6))
)
,
DATETIME('now'),
FALSE,
'Devices',
NEW.devGUID, -- ObjectGUID
NEW.devMac, -- ObjectPrimaryID
NEW.devLastIP, -- ObjectSecondaryID
CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END, -- ObjectStatus
'devPresentLastScan', -- ObjectStatusColumn
NEW.devIsNew, -- ObjectIsNew
NEW.devIsArchived, -- ObjectIsArchived
NEW.devGUID, -- ObjectForeignKey
'DEVICES', -- ObjectForeignKey
'insert'
);
END;
CREATE TRIGGER "trg_update_devices"
AFTER UPDATE ON "Devices"
WHEN NOT EXISTS (
SELECT 1 FROM AppEvents
WHERE AppEventProcessed = 0
AND ObjectType = 'Devices'
AND ObjectGUID = NEW.devGUID
AND ObjectStatus = CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END
AND AppEventType = 'update'
)
BEGIN
INSERT INTO "AppEvents" (
"GUID",
"DateTimeCreated",
"AppEventProcessed",
"ObjectType",
"ObjectGUID",
"ObjectPrimaryID",
"ObjectSecondaryID",
"ObjectStatus",
"ObjectStatusColumn",
"ObjectIsNew",
"ObjectIsArchived",
"ObjectForeignKey",
"ObjectPlugin",
"AppEventType"
)
VALUES (
lower(
hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
substr(hex( randomblob(2)), 2) || '-' ||
substr('AB89', 1 + (abs(random()) % 4) , 1) ||
substr(hex(randomblob(2)), 2) || '-' ||
hex(randomblob(6))
)
,
DATETIME('now'),
FALSE,
'Devices',
NEW.devGUID, -- ObjectGUID
NEW.devMac, -- ObjectPrimaryID
NEW.devLastIP, -- ObjectSecondaryID
CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END, -- ObjectStatus
'devPresentLastScan', -- ObjectStatusColumn
NEW.devIsNew, -- ObjectIsNew
NEW.devIsArchived, -- ObjectIsArchived
NEW.devGUID, -- ObjectForeignKey
'DEVICES', -- ObjectForeignKey
'update'
);
END;
CREATE TRIGGER "trg_delete_devices"
AFTER DELETE ON "Devices"
WHEN NOT EXISTS (
SELECT 1 FROM AppEvents
WHERE AppEventProcessed = 0
AND ObjectType = 'Devices'
AND ObjectGUID = OLD.devGUID
AND ObjectStatus = CASE WHEN OLD.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END
AND AppEventType = 'delete'
)
BEGIN
INSERT INTO "AppEvents" (
"GUID",
"DateTimeCreated",
"AppEventProcessed",
"ObjectType",
"ObjectGUID",
"ObjectPrimaryID",
"ObjectSecondaryID",
"ObjectStatus",
"ObjectStatusColumn",
"ObjectIsNew",
"ObjectIsArchived",
"ObjectForeignKey",
"ObjectPlugin",
"AppEventType"
)
VALUES (
lower(
hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
substr(hex( randomblob(2)), 2) || '-' ||
substr('AB89', 1 + (abs(random()) % 4) , 1) ||
substr(hex(randomblob(2)), 2) || '-' ||
hex(randomblob(6))
)
,
DATETIME('now'),
FALSE,
'Devices',
OLD.devGUID, -- ObjectGUID
OLD.devMac, -- ObjectPrimaryID
OLD.devLastIP, -- ObjectSecondaryID
CASE WHEN OLD.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END, -- ObjectStatus
'devPresentLastScan', -- ObjectStatusColumn
OLD.devIsNew, -- ObjectIsNew
OLD.devIsArchived, -- ObjectIsArchived
OLD.devGUID, -- ObjectForeignKey
'DEVICES', -- ObjectForeignKey
'delete'
);
END;
WHERE (eveEventType = 'Device Down' OR
eveEventType = 'Disconnected') AND
EVE1.evePairEventRowid IS NULL;

View File

@@ -29,10 +29,10 @@ class SafeConditionBuilder:
# Whitelist of allowed column names for filtering
ALLOWED_COLUMNS = {
"eve_MAC",
"eve_DateTime",
"eve_IP",
"eve_EventType",
"eveMac",
"eveDateTime",
"eveIp",
"eveEventType",
"devName",
"devComments",
"devLastIP",
@@ -43,15 +43,15 @@ class SafeConditionBuilder:
"devPresentLastScan",
"devFavorite",
"devIsNew",
"Plugin",
"Object_PrimaryId",
"Object_SecondaryId",
"DateTimeChanged",
"Watched_Value1",
"Watched_Value2",
"Watched_Value3",
"Watched_Value4",
"Status",
"plugin",
"objectPrimaryId",
"objectSecondaryId",
"dateTimeChanged",
"watchedValue1",
"watchedValue2",
"watchedValue3",
"watchedValue4",
"status",
}
# Whitelist of allowed comparison operators
@@ -413,7 +413,7 @@ class SafeConditionBuilder:
This method handles basic patterns like:
- devName = 'value' (with optional AND/OR prefix)
- devComments LIKE '%value%'
- eve_EventType IN ('type1', 'type2')
- eveEventType IN ('type1', 'type2')
Args:
condition: Single condition string to parse
@@ -648,7 +648,7 @@ class SafeConditionBuilder:
self.parameters[param_name] = event_type
param_names.append(f":{param_name}")
sql_snippet = f"AND eve_EventType IN ({', '.join(param_names)})"
sql_snippet = f"AND eveEventType IN ({', '.join(param_names)})"
return sql_snippet, self.parameters
def get_safe_condition_legacy(