From 776fa3327f610c2efd44439510e683588be495f2 Mon Sep 17 00:00:00 2001 From: Aurora Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Mon, 13 Feb 2023 18:23:38 +0200 Subject: [PATCH] Fixed issues with peak player count query optimization --- .../database/queries/objects/TPSQueries.java | 9 +- .../identification/ServerServerInfoTest.java | 105 ++++++++++++++++++ 2 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 Plan/common/src/test/java/com/djrapitops/plan/identification/ServerServerInfoTest.java diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/TPSQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/TPSQueries.java index ecd737399..b9d35eb7b 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/TPSQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/queries/objects/TPSQueries.java @@ -216,16 +216,17 @@ public class TPSQueries { } public static Query>> fetchPeakPlayerCount(ServerUUID serverUUID, long afterDate) { - String subQuery = '(' + SELECT + DATE + ",MAX(" + PLAYERS_ONLINE + ") as " + PLAYERS_ONLINE + FROM + TABLE_NAME + + String subQuery = '(' + SELECT + "MAX(" + PLAYERS_ONLINE + ") as " + PLAYERS_ONLINE + FROM + TABLE_NAME + WHERE + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID + - AND + DATE + ">= ?)"; + AND + DATE + ">= ?" + + GROUP_BY + SERVER_ID + ")"; String sql = SELECT + "t." + DATE + ',' + "t." + PLAYERS_ONLINE + FROM + TABLE_NAME + " t" + - INNER_JOIN + subQuery + " max on t." + DATE + "=max." + DATE + AND + "t." + PLAYERS_ONLINE + "=max." + PLAYERS_ONLINE + + INNER_JOIN + subQuery + " max on t." + PLAYERS_ONLINE + "=max." + PLAYERS_ONLINE + WHERE + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID + AND + "t." + DATE + ">= ?" + - ORDER_BY + DATE + " DESC LIMIT 1"; + ORDER_BY + "t." + DATE + " DESC LIMIT 1"; return new QueryStatement<>(sql) { @Override diff --git a/Plan/common/src/test/java/com/djrapitops/plan/identification/ServerServerInfoTest.java b/Plan/common/src/test/java/com/djrapitops/plan/identification/ServerServerInfoTest.java new file mode 100644 index 000000000..dd3ef0cc8 --- /dev/null +++ b/Plan/common/src/test/java/com/djrapitops/plan/identification/ServerServerInfoTest.java @@ -0,0 +1,105 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package com.djrapitops.plan.identification; + +import com.djrapitops.plan.delivery.webserver.Addresses; +import com.djrapitops.plan.exceptions.database.DBOpException; +import com.djrapitops.plan.identification.properties.ServerProperties; +import com.djrapitops.plan.identification.storage.ServerDBLoader; +import com.djrapitops.plan.identification.storage.ServerFileLoader; +import com.djrapitops.plan.processing.Processing; +import com.djrapitops.plan.settings.config.PlanConfig; +import com.djrapitops.plan.settings.locale.Locale; +import com.djrapitops.plan.storage.database.DBSystem; +import net.playeranalytics.plugin.server.PluginLogger; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; +import utilities.TestConstants; +import utilities.TestErrorLogger; +import utilities.TestPluginLogger; +import utilities.mocks.TestProcessing; + +import java.util.Optional; +import java.util.concurrent.CompletionException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +/** + * @author AuroraLS3 + */ +@ExtendWith(MockitoExtension.class) +class ServerServerInfoTest { + + @Mock + DBSystem dbSystem; + @InjectMocks + @Spy + ServerDBLoader fromDatabase; + + @Mock + ServerProperties serverProperties; + @Mock + ServerFileLoader fromFile; + @Mock + PlanConfig config; + @Mock + Addresses addresses; + @Mock + Locale locale; + @Spy + PluginLogger logger = new TestPluginLogger(); + @Spy + Processing processing = new TestProcessing(() -> locale, logger, new TestErrorLogger()); + + ServerServerInfo underTest; + + @BeforeEach + void setUp() { + TestErrorLogger.throwErrors(false); + underTest = new ServerServerInfo( + TestConstants.VERSION, + serverProperties, fromFile, fromDatabase, processing, config, addresses, locale, logger + ); + when(fromFile.load(any())).thenReturn(Optional.of(new Server(1, TestConstants.SERVER_UUID, TestConstants.SERVER_NAME, "", false, TestConstants.VERSION))); + } + + @AfterEach + void tearDown() { + for (Throwable throwable : TestErrorLogger.getCaught()) { + Logger.getGlobal().log(Level.WARNING, "test", throwable); + } + + TestErrorLogger.throwErrors(true); + } + + @Test + void databaseThrowsErrorOnSave() { + doThrow(new CompletionException(new DBOpException("Test exception"))) + .when(fromDatabase).save(any()); + underTest.loadServerInfo(); + verify(fromFile, times(0)).save(any()); + } +} \ No newline at end of file