Explorar o código

sqlite->mysql query compatibility; table engine InnoDB; image from mariadb:lts

Christian Kahlau %!s(int64=2) %!d(string=hai) anos
pai
achega
7587443f57
Modificáronse 3 ficheiros con 128 adicións e 127 borrados
  1. 1 1
      server/mysql/Dockerfile
  2. 7 7
      server/mysql/init-db.sql
  3. 120 119
      server/src/ctrl/mariadb-database.class.ts

+ 1 - 1
server/mysql/Dockerfile

@@ -1,3 +1,3 @@
-FROM mariadb:11.0.2
+FROM mariadb:lts
 
 COPY ./init-db.sql /docker-entrypoint-initdb.d/init-db.sql

+ 7 - 7
server/mysql/init-db.sql

@@ -15,7 +15,7 @@ CREATE TABLE `Server` (
   `FQDN` VARCHAR(512) NOT NULL,
   UNIQUE INDEX UQ_Server_Title (`Title`),
   UNIQUE INDEX UQ_Server_FQDN (`FQDN`)
-);
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 CREATE TABLE `HealthCheckConfig` (
   `ID` INT PRIMARY KEY AUTO_INCREMENT,
@@ -24,7 +24,7 @@ CREATE TABLE `HealthCheckConfig` (
   `Title` VARCHAR(512) NOT NULL,
   CONSTRAINT FK_HealthCheckConfig_Server FOREIGN KEY(`ServerID`) REFERENCES `Server`(`ID`) ON DELETE CASCADE,
   UNIQUE INDEX UQ_HealthCheckConfig_1 (`ServerID`, `Type`, `Title`)
-);
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 CREATE TABLE `HealthCheckParams` (
   `ID` INT PRIMARY KEY AUTO_INCREMENT,
@@ -33,7 +33,7 @@ CREATE TABLE `HealthCheckParams` (
   `Key` VARCHAR(32) NOT NULL,
   `Value` TEXT NOT NULL,
   CONSTRAINT FK_HealthCheckParams_HealthCheckConfig FOREIGN KEY(`ConfigID`) REFERENCES `HealthCheckConfig`(`ID`) ON DELETE CASCADE
-);
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 CREATE TABLE `HealthCheckDataEntry` (
   `ID` BIGINT PRIMARY KEY AUTO_INCREMENT,
@@ -42,7 +42,7 @@ CREATE TABLE `HealthCheckDataEntry` (
   `Status` SMALLINT NOT NULL,
   `Message` TEXT,
   CONSTRAINT FK_HealthCheckDataEntry_HealthCheckConfig FOREIGN KEY(`ConfigID`) REFERENCES `HealthCheckConfig`(`ID`) ON DELETE CASCADE
-);
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 CREATE TABLE `ServerConfig` (
   `ID` INT PRIMARY KEY AUTO_INCREMENT,
@@ -51,7 +51,7 @@ CREATE TABLE `ServerConfig` (
   `Value` TEXT NOT NULL,
   CONSTRAINT FK_ServerConfig_Server FOREIGN KEY(`ServerID`) REFERENCES `Server`(`ID`) ON DELETE CASCADE,
   UNIQUE INDEX UQ_ServerConfig_1(`ServerID`, `Key`)
-);
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 CREATE TABLE `ServerDataEntry` (
   `ID` BIGINT PRIMARY KEY AUTO_INCREMENT,
@@ -59,7 +59,7 @@ CREATE TABLE `ServerDataEntry` (
   `Timestamp` TIMESTAMP NOT NULL,
   CONSTRAINT FK_ServerDataEntry_Server FOREIGN KEY(`ServerID`) REFERENCES `Server`(`ID`) ON DELETE CASCADE,
   UNIQUE INDEX UQ_ServerDataEntry_1(`ServerID`, `Timestamp`)
-);
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 CREATE TABLE `ServerDataValue` (
   `ID` BIGINT PRIMARY KEY AUTO_INCREMENT,
@@ -69,7 +69,7 @@ CREATE TABLE `ServerDataValue` (
   `Value` DOUBLE NOT NULL,
   CONSTRAINT FK_ServerDataValue_ServerDataEntry FOREIGN KEY(`EntryID`) REFERENCES `ServerDataEntry`(`ID`) ON DELETE CASCADE,
   UNIQUE INDEX UQ_ServerDataValue_1(`EntryID`, `Type`, `Key`)
-);
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 COMMIT;
 SET AUTOCOMMIT = 1;

+ 120 - 119
server/src/ctrl/mariadb-database.class.ts

@@ -24,7 +24,7 @@ export class MariaDBDatabase implements DataProvider {
     try {
       await this.db.connect();
 
-      Logger.info('[INFO] Opened MariaDB Connection');
+      Logger.debug('[DEBUG] Opened MariaDB Connection');
 
       if (migrate) {
         //TODO: RUN DB MIGRATIONS
@@ -41,12 +41,12 @@ export class MariaDBDatabase implements DataProvider {
   public async getAllServerConfigs(): Promise<Server[]> {
     const res = await this.db.query(
       `SELECT 
-        Server.*,
-        ServerConfig.Key,
-        ServerConfig.Value
-        FROM Server
-        LEFT OUTER JOIN ServerConfig ON Server.ID = ServerConfig.ServerID
-        ORDER BY Server.Title, ServerConfig.Key`,
+        \`Server\`.*,
+        \`ServerConfig\`.\`Key\`,
+        \`ServerConfig\`.\`Value\`
+        FROM \`Server\`
+        LEFT OUTER JOIN \`ServerConfig\` ON \`Server\`.\`ID\` = \`ServerConfig\`.\`ServerID\`
+        ORDER BY \`Server\`.\`Title\`, \`ServerConfig\`.\`Key\``,
       []
     );
 
@@ -75,9 +75,9 @@ export class MariaDBDatabase implements DataProvider {
     try {
       for (const entry of data) {
         const result = await this.db.query(
-          `INSERT INTO ServerDataEntry(ServerID, Timestamp) VALUES(?, ?);
-          SELECT LAST_INSERT_ID() as ID;`,
-          [serverID, entry.time.getTime()]
+          `INSERT INTO \`ServerDataEntry\`(\`ServerID\`, \`Timestamp\`) VALUES(?, ?);
+          SELECT LAST_INSERT_ID() as 'ID';`,
+          [serverID, entry.time]
         );
 
         if (!result || result.length < 2) throw new DatabaseException('Unexpected result during insertServerData');
@@ -86,7 +86,7 @@ export class MariaDBDatabase implements DataProvider {
 
         for (const type of Object.keys(entry).filter(t => !['time', 'hdd'].includes(t))) {
           for (const key of Object.keys((entry as any)[type])) {
-            await this.db.query('INSERT INTO ServerDataValue(EntryID, Type, Key, Value) VALUES(?, ?, ?, ?);', [
+            await this.db.query('INSERT INTO `ServerDataValue`(`EntryID`, `Type`, `Key`, `Value`) VALUES(?, ?, ?, ?);', [
               entryID,
               type,
               key,
@@ -98,7 +98,7 @@ export class MariaDBDatabase implements DataProvider {
         if (entry.hdd) {
           for (const mount of Object.keys(entry.hdd)) {
             for (const key of Object.keys(entry.hdd[mount])) {
-              await this.db.query('INSERT INTO ServerDataValue(EntryID, Type, Key, Value) VALUES(?, ?, ?, ?);', [
+              await this.db.query('INSERT INTO `ServerDataValue`(`EntryID`, `Type`, `Key`, `Value`) VALUES(?, ?, ?, ?);', [
                 entryID,
                 `hdd:${mount}`,
                 key,
@@ -119,12 +119,12 @@ export class MariaDBDatabase implements DataProvider {
     const results: any[] = await this.db.query(
       `
       SELECT
-        ServerDataValue.Type 
-      FROM ServerDataEntry
-      JOIN ServerDataValue ON ServerDataEntry.ID = ServerDataValue.EntryID
-      WHERE ServerDataEntry.ServerID = ?
-      GROUP BY ServerDataValue.Type
-      ORDER BY ServerDataValue.Type;
+        \`ServerDataValue\`.\`Type\` 
+      FROM \`ServerDataEntry\`
+      JOIN \`ServerDataValue\` ON \`ServerDataEntry\`.\`ID\` = \`ServerDataValue\`.\`EntryID\`
+      WHERE \`ServerDataEntry\`.\`ServerID\` = ?
+      GROUP BY \`ServerDataValue\`.\`Type\`
+      ORDER BY \`ServerDataValue\`.\`Type\`;
     `,
       [serverID]
     );
@@ -152,28 +152,28 @@ export class MariaDBDatabase implements DataProvider {
     const result: any[] = await this.db.query(
       `
       SELECT 
-        CEIL(Timestamp / ?) * ? as 'Timegroup',
-        AVG(VALUE_AVG.Value) as 'avg',
-        MAX(VALUE_PEAK.Value) as 'peak'${
+        CEIL(UNIX_TIMESTAMP(\`Timestamp\`) * 1000 / ?) * ? as 'Timegroup',
+        AVG(\`VALUE_AVG\`.\`Value\`) as 'avg',
+        MAX(\`VALUE_PEAK\`.\`Value\`) as 'peak'${
           select_max
             ? `,
-        MAX(VALUE_MAX.Value) as 'max'`
+        MAX(\`VALUE_MAX\`.\`Value\`) as 'max'`
             : ''
         }
-      FROM ServerDataEntry
-      JOIN ServerDataValue AS VALUE_AVG ON ServerDataEntry.ID = VALUE_AVG.EntryID AND VALUE_AVG.Type = ? AND VALUE_AVG.Key = 'avg'
-      JOIN ServerDataValue AS VALUE_PEAK ON ServerDataEntry.ID = VALUE_PEAK.EntryID AND VALUE_PEAK.Type = ? AND VALUE_PEAK.Key = 'peak'
+      FROM \`ServerDataEntry\`
+      JOIN \`ServerDataValue\` AS \`VALUE_AVG\` ON \`ServerDataEntry\`.\`ID\` = \`VALUE_AVG\`.\`EntryID\` AND \`VALUE_AVG\`.\`Type\` = ? AND \`VALUE_AVG\`.\`Key\` = 'avg'
+      JOIN \`ServerDataValue\` AS \`VALUE_PEAK\` ON \`ServerDataEntry\`.\`ID\` = \`VALUE_PEAK\`.\`EntryID\` AND \`VALUE_PEAK\`.\`Type\` = ? AND \`VALUE_PEAK\`.\`Key\` = 'peak'
       ${
         select_max
-          ? "JOIN ServerDataValue AS VALUE_MAX ON ServerDataEntry.ID = VALUE_MAX.EntryID AND VALUE_MAX.Type = ? AND VALUE_MAX.Key = 'max'"
+          ? "JOIN `ServerDataValue` AS `VALUE_MAX` ON `ServerDataEntry`.`ID` = `VALUE_MAX`.`EntryID` AND `VALUE_MAX`.`Type` = ? AND `VALUE_MAX`.`Key` = 'max'"
           : ''
       }
-      WHERE ServerDataEntry.ServerID = ?
-      AND ServerDataEntry.Timestamp BETWEEN ? AND ?
-      GROUP BY Timegroup
-      ORDER BY Timegroup;
+      WHERE \`ServerDataEntry\`.\`ServerID\` = ?
+      AND \`ServerDataEntry\`.\`Timestamp\` BETWEEN ? AND ?
+      GROUP BY \`Timegroup\`
+      ORDER BY \`Timegroup\`;
     `,
-      [sectionMs, sectionMs, ...select_types, serverID, from.getTime(), to.getTime()]
+      [sectionMs, sectionMs, ...select_types, serverID, from, to]
     );
 
     return result.map(r => ({ time: new Date(r.Timegroup), avg: r.avg, peak: r.peak, max: r.max }));
@@ -185,25 +185,25 @@ export class MariaDBDatabase implements DataProvider {
     const result: any[] = await this.db.query(
       `
       SELECT 
-        AVG(VALUE_AVG.Value) as 'avg',
-        AVG(VALUE_PEAK.Value) as 'peak'${
+        AVG(\`VALUE_AVG\`.\`Value\`) as 'avg',
+        AVG(\`VALUE_PEAK\`.\`Value\`) as 'peak'${
           select_max
             ? `,
-        MAX(VALUE_MAX.Value) as 'max'`
+        MAX(\`VALUE_MAX\`.\`Value\`) as 'max'`
             : ''
         }
-      FROM ServerDataEntry
-      JOIN ServerDataValue AS VALUE_AVG ON ServerDataEntry.ID = VALUE_AVG.EntryID AND VALUE_AVG.Type = ? AND VALUE_AVG.Key = 'avg'
-      JOIN ServerDataValue AS VALUE_PEAK ON ServerDataEntry.ID = VALUE_PEAK.EntryID AND VALUE_PEAK.Type = ? AND VALUE_PEAK.Key = 'peak'
+      FROM \`ServerDataEntry\`
+      JOIN \`ServerDataValue\` AS \`VALUE_AVG\` ON \`ServerDataEntry\`.\`ID\` = \`VALUE_AVG\`.\`EntryID\` AND \`VALUE_AVG\`.\`Type\` = ? AND \`VALUE_AVG\`.\`Key\` = 'avg'
+      JOIN \`ServerDataValue\` AS \`VALUE_PEAK\` ON \`ServerDataEntry\`.\`ID\` = \`VALUE_PEAK\`.\`EntryID\` AND \`VALUE_PEAK\`.\`Type\` = ? AND \`VALUE_PEAK\`.\`Key\` = 'peak'
       ${
         select_max
-          ? "JOIN ServerDataValue AS VALUE_MAX ON ServerDataEntry.ID = VALUE_MAX.EntryID AND VALUE_MAX.Type = ? AND VALUE_MAX.Key = 'max'"
+          ? "JOIN `ServerDataValue` AS `VALUE_MAX` ON `ServerDataEntry`.`ID` = `VALUE_MAX`.`EntryID` AND `VALUE_MAX`.`Type` = ? AND `VALUE_MAX`.`Key` = 'max'"
           : ''
       }
-      WHERE ServerDataEntry.ServerID = ?
-      AND ServerDataEntry.Timestamp BETWEEN ? AND ?;
+      WHERE \`ServerDataEntry\`.\`ServerID\` = ?
+      AND \`ServerDataEntry\`.\`Timestamp\` BETWEEN ? AND ?;
     `,
-      [...select_types, serverID, from.getTime(), to.getTime()]
+      [...select_types, serverID, from, to]
     );
 
     const row = result[0];
@@ -223,15 +223,15 @@ export class MariaDBDatabase implements DataProvider {
   private async getHealthCheckConfigs(serverID?: number, type = 'http') {
     const res: any[] = await this.db.query(
       `SELECT 
-        HealthCheckConfig.*,
-        HealthCheckParams.Type as '_ParamType',
-        HealthCheckParams.Key as '_ParamKey',
-        HealthCheckParams.Value as '_ParamValue'
-        FROM HealthCheckConfig
-        LEFT OUTER JOIN HealthCheckParams ON HealthCheckConfig.ID = HealthCheckParams.ConfigID
-        WHERE HealthCheckConfig.Type = ?
-        ${!!serverID ? 'AND HealthCheckConfig.ServerID = ?' : ''}
-        ORDER BY HealthCheckConfig.Title, _ParamType, _ParamKey`,
+        \`HealthCheckConfig\`.*,
+        \`HealthCheckParams\`.\`Type\` as '_ParamType',
+        \`HealthCheckParams\`.\`Key\` as '_ParamKey',
+        \`HealthCheckParams\`.\`Value\` as '_ParamValue'
+        FROM \`HealthCheckConfig\`
+        LEFT OUTER JOIN \`HealthCheckParams\` ON \`HealthCheckConfig\`.\`ID\` = \`HealthCheckParams\`.\`ConfigID\`
+        WHERE \`HealthCheckConfig\`.\`Type\` = ?
+        ${!!serverID ? 'AND `HealthCheckConfig`.`ServerID` = ?' : ''}
+        ORDER BY \`HealthCheckConfig\`.\`Title\`, _ParamType, _ParamKey`,
       [type, serverID]
     );
 
@@ -247,15 +247,15 @@ export class MariaDBDatabase implements DataProvider {
 
     const res: any[] = await this.db.query(
       `SELECT 
-        HealthCheckConfig.*,
-        HealthCheckParams.Type as '_ParamType',
-        HealthCheckParams.Key as '_ParamKey',
-        HealthCheckParams.Value as '_ParamValue'
-        FROM HealthCheckConfig
-        LEFT OUTER JOIN HealthCheckParams ON HealthCheckConfig.ID = HealthCheckParams.ConfigID
-        WHERE HealthCheckConfig.ID = ?
-        AND HealthCheckConfig.ServerID = ?
-        ORDER BY HealthCheckConfig.Title, _ParamType, _ParamKey`,
+        \`HealthCheckConfig\`.*,
+        \`HealthCheckParams\`.\`Type\` as '_ParamType',
+        \`HealthCheckParams\`.\`Key\` as '_ParamKey',
+        \`HealthCheckParams\`.\`Value\` as '_ParamValue'
+        FROM \`HealthCheckConfig\`
+        LEFT OUTER JOIN \`HealthCheckParams\` ON \`HealthCheckConfig\`.\`ID\` = \`HealthCheckParams\`.\`ConfigID\`
+        WHERE \`HealthCheckConfig\`.\`ID\` = ?
+        AND \`HealthCheckConfig\`.\`ServerID\` = ?
+        ORDER BY \`HealthCheckConfig\`.\`Title\`, _ParamType, _ParamKey`,
       [configID, serverID]
     );
 
@@ -284,7 +284,7 @@ export class MariaDBDatabase implements DataProvider {
         // UPDATE
         Logger.debug('[DEBUG] Updating HealthCheckConfig', conf.title, `(${oldConf.id})`);
         if (oldConf.title !== conf.title) {
-          await this.db.query('UPDATE HealthCheckConfig SET Title = ? WHERE ID = ?', [conf.title, oldConf.id]);
+          await this.db.query('UPDATE `HealthCheckConfig` SET `Title` = ? WHERE `ID` = ?', [conf.title, oldConf.id]);
         }
 
         let updValues: any[][] = [];
@@ -303,11 +303,11 @@ export class MariaDBDatabase implements DataProvider {
           updValues.push([conf.notifyThreshold ?? defaults.serviceChecks.notifyThreshold, conf.id, 'notifyThreshold']);
         if (updValues.length) {
           for (const data of updValues) {
-            await this.db.query(`UPDATE HealthCheckParams SET Value = ? WHERE ConfigID = ? AND Key = ?;`, data);
+            await this.db.query('UPDATE `HealthCheckParams` SET `Value` = ? WHERE `ConfigID` = ? AND `Key` = ?;', data);
           }
         }
 
-        const res = await this.db.query('SELECT * FROM HealthCheckParams WHERE ConfigID = ? and Key = "check";', [conf.id]);
+        const res = await this.db.query('SELECT * FROM `HealthCheckParams` WHERE `ConfigID` = ? and `Key` = "check";', [conf.id]);
         updValues = [];
         const delIDs: number[] = [];
         res.forEach((row: any, i) => {
@@ -319,26 +319,26 @@ export class MariaDBDatabase implements DataProvider {
         });
 
         if (delIDs.length) {
-          const delSql = `DELETE FROM HealthCheckParams WHERE ID IN (${delIDs.map(() => '?').join(',')});`;
+          const delSql = `DELETE FROM \`HealthCheckParams\` WHERE \`ID\` IN (${delIDs.map(() => '?').join(',')});`;
           await this.db.query(delSql, delIDs);
         }
 
         if (updValues.length) {
           for (const data of updValues) {
-            await this.db.query('UPDATE HealthCheckParams SET Value = ? WHERE ID = ?;', data);
+            await this.db.query('UPDATE `HealthCheckParams` SET `Value` = ? WHERE `ID` = ?;', data);
           }
         }
         const insValues = conf.checks.filter((c, i) => i > res.length - 1).map(c => [conf.id, 'regexp', 'check', JSON.stringify(c)]);
         if (insValues.length) {
           for (const data of insValues) {
-            await this.db.query('INSERT INTO HealthCheckParams(ConfigID, Type, Key, Value) VALUES(?, ?, ?, ?);', data);
+            await this.db.query('INSERT INTO `HealthCheckParams`(`ConfigID`, `Type`, `Key`, `Value`) VALUES(?, ?, ?, ?);', data);
           }
         }
       } else {
         // INSERT
         Logger.debug('[DEBUG] Inserting new HealthCheckConfig', conf.title);
         const res = await this.db.query(
-          `INSERT INTO HealthCheckConfig(ServerID, Type, Title) VALUES(?, ?, ?);
+          `INSERT INTO \`HealthCheckConfig\`(\`ServerID\`, \`Type\`, \`Title\`) VALUES(?, ?, ?);
           SELECT LAST_INSERT_ID() as ID;`,
           [serverID, 'http', conf.title]
         );
@@ -352,7 +352,7 @@ export class MariaDBDatabase implements DataProvider {
 
         const insCheckValues = conf.checks.map(c => [conf.id, 'regexp', 'check', c]);
         await this.db.query(
-          `INSERT INTO HealthCheckParams(ConfigID, Type, Key, Value) VALUES
+          `INSERT INTO \`HealthCheckParams\`(\`ConfigID\`, \`Type\`, \`Key\`, \`Value\`) VALUES
           (?, ?, ?, ?),
           (?, ?, ?, ?),
           (?, ?, ?, ?),
@@ -383,15 +383,15 @@ export class MariaDBDatabase implements DataProvider {
     const conf = await this.getHealthCheckConfigByID(serverID, confID);
     if (!conf) return false;
 
-    await this.db.query('DELETE FROM HealthCheckConfig WHERE ID = ?;', [confID]);
+    await this.db.query('DELETE FROM `HealthCheckConfig` WHERE `ID` = ?;', [confID]);
     return true;
   }
 
   async insertHealthCheckData(confID: number, time: Date, status: HttpCheckStatus, message: string) {
     const res = await this.db.query(
-      `INSERT INTO HealthCheckDataEntry(ConfigID, Timestamp, Status, Message) VALUES(?, ?, ?, ?);
+      `INSERT INTO \`HealthCheckDataEntry\`(\`ConfigID\`, \`Timestamp\`, \`Status\`, \`Message\`) VALUES(?, ?, ?, ?);
       SELECT LAST_INSERT_ID() as ID;`,
-      [confID, time.getTime(), status, message]
+      [confID, time, status, message]
     );
 
     if (!res || res.length < 2) throw new DatabaseException('Unexpected result during insertHealthCheckData');
@@ -409,56 +409,56 @@ export class MariaDBDatabase implements DataProvider {
   async queryServiceCheckData(serverID: number, confID: number, from: Date, to: Date) {
     const result = await this.db.query(
       `
-      SELECT DataEntryChanges.*
-      FROM HealthCheckConfig
+      SELECT \`DataEntryChanges\`.*
+      FROM \`HealthCheckConfig\`
       JOIN (
         SELECT * FROM (
           SELECT 
             *
-          FROM HealthCheckDataEntry
-          WHERE ConfigID = ?
-          AND Timestamp BETWEEN ? AND ?
-          ORDER BY ID
+          FROM \`HealthCheckDataEntry\`
+          WHERE \`ConfigID\` = ?
+          AND \`Timestamp\` BETWEEN ? AND ?
+          ORDER BY \`ID\`
           LIMIT 0, 1
-        ) AS FIRST_STATE
+        ) AS \`FIRST_STATE\`
 
         UNION
 
         SELECT 
-          ID,
-          ConfigID,
-          Timestamp,
-          Status,
-          Message
+          \`ID\`,
+          \`ConfigID\`,
+          \`Timestamp\`,
+          \`Status\`,
+          \`Message\`
         FROM
         (
           SELECT 
-            HealthCheckDataEntry.*, 
-            LAG(Status) OVER (ORDER BY ConfigID, Timestamp) AS previous_state, 
-            LAG(Message) OVER (ORDER BY ConfigID, Timestamp) AS previous_msg
-          FROM HealthCheckDataEntry
-          WHERE ConfigID = ?
-        )
-        WHERE Status <> previous_state
-        AND Message <> previous_msg
+            \`HealthCheckDataEntry\`.*, 
+            LAG(\`Status\`) OVER (ORDER BY \`ConfigID\`, \`Timestamp\`) AS previous_state, 
+            LAG(\`Message\`) OVER (ORDER BY \`ConfigID\`, \`Timestamp\`) AS previous_msg
+          FROM \`HealthCheckDataEntry\`
+          WHERE \`ConfigID\` = ?
+        ) AS HCDE2
+        WHERE \`Status\` != previous_state
+        AND \`Message\` != previous_msg
         
         UNION
         
         SELECT * FROM (
           SELECT 
             *
-          FROM HealthCheckDataEntry
-          WHERE ConfigID = ?
-          AND Timestamp BETWEEN ? AND ?
+          FROM \`HealthCheckDataEntry\`
+          WHERE \`ConfigID\` = ?
+          AND \`Timestamp\` BETWEEN ? AND ?
           ORDER BY ID DESC
           LIMIT 0, 1
-        ) AS LAST_STATE
-        ORDER BY ConfigID, Timestamp
-      ) AS DataEntryChanges ON DataEntryChanges.ConfigID = HealthCheckConfig.ID
-      WHERE HealthCheckConfig.ServerID = ?
-        AND DataEntryChanges.Timestamp BETWEEN ? AND ?
-      ORDER BY Timestamp, ID;`,
-      [confID, from.getTime(), to.getTime(), confID, confID, from.getTime(), to.getTime(), serverID, from.getTime(), to.getTime()]
+        ) AS \`LAST_STATE\`
+        ORDER BY \`ConfigID\`, \`Timestamp\`
+      ) AS \`DataEntryChanges\` ON \`DataEntryChanges\`.\`ConfigID\` = \`HealthCheckConfig\`.\`ID\`
+      WHERE \`HealthCheckConfig\`.\`ServerID\` = ?
+        AND \`DataEntryChanges\`.\`Timestamp\` BETWEEN ? AND ?
+      ORDER BY \`Timestamp\`, \`ID\`;`,
+      [confID, from, to, confID, confID, from, to, serverID, from, to]
     );
 
     const mapByTimestamp = this.mapServiceCheckDataByTimestamp(result);
@@ -476,14 +476,14 @@ export class MariaDBDatabase implements DataProvider {
   public async queryServiceCheckLogs(serverID: number, confID: number, from: Date, to: Date) {
     const result = await this.db.query(
       `
-      SELECT HealthCheckDataEntry.*
-      FROM HealthCheckConfig
-      JOIN HealthCheckDataEntry ON HealthCheckDataEntry.ConfigID = HealthCheckConfig.ID
-      WHERE HealthCheckConfig.ID = ?
-        AND HealthCheckConfig.ServerID = ?
-        AND HealthCheckDataEntry.Timestamp BETWEEN ? AND ?
-      ORDER BY Timestamp, ConfigID;`,
-      [confID, serverID, from.getTime(), to.getTime()]
+      SELECT \`HealthCheckDataEntry\`.*
+      FROM \`HealthCheckConfig\`
+      JOIN \`HealthCheckDataEntry\` ON \`HealthCheckDataEntry\`.\`ConfigID\` = \`HealthCheckConfig\`.\`ID\`
+      WHERE \`HealthCheckConfig\`.\`ID\` = ?
+        AND \`HealthCheckConfig\`.\`ServerID\` = ?
+        AND \`HealthCheckDataEntry\`.\`Timestamp\` BETWEEN ? AND ?
+      ORDER BY \`Timestamp\`, \`ConfigID\`;`,
+      [confID, serverID, from, to]
     );
 
     const mapByTimestamp = this.mapServiceCheckDataByTimestamp(result);
@@ -500,18 +500,19 @@ export class MariaDBDatabase implements DataProvider {
 
   public async getLastErrors(confID: number, threshold: number) {
     const result = await this.db.query(
-      `SELECT * FROM HealthCheckDataEntry
-        WHERE ConfigID = ?
-        AND Timestamp IN (
-          SELECT Timestamp 
-          FROM HealthCheckDataEntry
-          WHERE ConfigID = ?
-          GROUP BY Timestamp
-          ORDER BY Timestamp DESC
+      `SELECT HCDE1.* 
+        FROM \`HealthCheckDataEntry\` as HCDE1
+        INNER JOIN (
+          SELECT \`Timestamp\` 
+          FROM \`HealthCheckDataEntry\`
+          WHERE \`ConfigID\` = ?
+          GROUP BY \`Timestamp\`
+          ORDER BY \`Timestamp\` DESC
           LIMIT 0, ?
-        )
-        ORDER BY Timestamp DESC, ID DESC`,
-      [confID, confID, threshold]
+        ) AS HCDE2 ON HCDE1.\`Timestamp\` = HCDE2.\`Timestamp\`
+        WHERE \`ConfigID\` = ?
+        ORDER BY HCDE1.\`Timestamp\` DESC, HCDE1.\`ID\` DESC`,
+      [confID, threshold, confID]
     );
 
     const mapByTimestamp = this.mapServiceCheckDataByTimestamp(result);