mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-03-10 05:39:19 +01:00
LargeStoreQueries now stores missing world names as well.
Affects issues: - Fixed #1848
This commit is contained in:
parent
acf15a1e86
commit
599bf4a837
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.djrapitops.plan.delivery.domain;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a world stored in the Plan database.
|
||||||
|
*/
|
||||||
|
public class World {
|
||||||
|
|
||||||
|
private final String worldName;
|
||||||
|
private final ServerUUID serverUUID;
|
||||||
|
|
||||||
|
public World(String worldName, ServerUUID serverUUID) {
|
||||||
|
this.worldName = worldName;
|
||||||
|
this.serverUUID = serverUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorldName() {
|
||||||
|
return worldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerUUID getServerUUID() {
|
||||||
|
return serverUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
World world = (World) o;
|
||||||
|
return Objects.equals(getWorldName(), world.getWorldName()) && Objects.equals(getServerUUID(), world.getServerUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getWorldName(), getServerUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "World{" +
|
||||||
|
"worldName='" + worldName + '\'' +
|
||||||
|
", serverUUID=" + serverUUID +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -17,10 +17,12 @@
|
|||||||
package com.djrapitops.plan.storage.database.queries;
|
package com.djrapitops.plan.storage.database.queries;
|
||||||
|
|
||||||
import com.djrapitops.plan.delivery.domain.Nickname;
|
import com.djrapitops.plan.delivery.domain.Nickname;
|
||||||
|
import com.djrapitops.plan.delivery.domain.World;
|
||||||
import com.djrapitops.plan.delivery.domain.auth.User;
|
import com.djrapitops.plan.delivery.domain.auth.User;
|
||||||
import com.djrapitops.plan.gathering.domain.*;
|
import com.djrapitops.plan.gathering.domain.*;
|
||||||
import com.djrapitops.plan.identification.Server;
|
import com.djrapitops.plan.identification.Server;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
|
import com.djrapitops.plan.storage.database.queries.objects.WorldTimesQueries;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.*;
|
import com.djrapitops.plan.storage.database.sql.tables.*;
|
||||||
import com.djrapitops.plan.storage.database.transactions.ExecBatchStatement;
|
import com.djrapitops.plan.storage.database.transactions.ExecBatchStatement;
|
||||||
import com.djrapitops.plan.storage.database.transactions.Executable;
|
import com.djrapitops.plan.storage.database.transactions.Executable;
|
||||||
@ -29,10 +31,8 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static method class for large storage queries.
|
* Static method class for large storage queries.
|
||||||
@ -292,12 +292,40 @@ public class LargeStoreQueries {
|
|||||||
|
|
||||||
public static Executable storeAllSessionsWithKillAndWorldData(Collection<FinishedSession> sessions) {
|
public static Executable storeAllSessionsWithKillAndWorldData(Collection<FinishedSession> sessions) {
|
||||||
return connection -> {
|
return connection -> {
|
||||||
|
Set<World> existingWorlds = WorldTimesQueries.fetchWorlds().executeWithConnection(connection);
|
||||||
|
storeAllWorldNames(sessions, existingWorlds).execute(connection);
|
||||||
storeAllSessionsWithoutKillOrWorldData(sessions).execute(connection);
|
storeAllSessionsWithoutKillOrWorldData(sessions).execute(connection);
|
||||||
storeSessionKillData(sessions).execute(connection);
|
storeSessionKillData(sessions).execute(connection);
|
||||||
return storeSessionWorldTimeData(sessions).execute(connection);
|
return storeSessionWorldTimeData(sessions).execute(connection);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Executable storeAllWorldNames(Collection<FinishedSession> sessions, Set<World> existingWorlds) {
|
||||||
|
Set<World> worlds = sessions.stream().flatMap(session -> {
|
||||||
|
ServerUUID serverUUID = session.getServerUUID();
|
||||||
|
return session.getExtraData(WorldTimes.class)
|
||||||
|
.map(WorldTimes::getWorldTimes)
|
||||||
|
.map(Map::keySet)
|
||||||
|
.orElseGet(Collections::emptySet)
|
||||||
|
.stream()
|
||||||
|
.map(worldName -> new World(worldName, serverUUID));
|
||||||
|
}).filter(world -> !existingWorlds.contains(world))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (worlds.isEmpty()) return Executable.empty();
|
||||||
|
|
||||||
|
return new ExecBatchStatement(WorldTable.INSERT_STATEMENT) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
for (World world : worlds) {
|
||||||
|
statement.setString(1, world.getWorldName());
|
||||||
|
statement.setString(2, world.getServerUUID().toString());
|
||||||
|
statement.addBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static Executable storeSessionKillData(Collection<FinishedSession> sessions) {
|
private static Executable storeSessionKillData(Collection<FinishedSession> sessions) {
|
||||||
if (sessions == null || sessions.isEmpty()) return Executable.empty();
|
if (sessions == null || sessions.isEmpty()) return Executable.empty();
|
||||||
|
|
||||||
|
@ -16,10 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.storage.database.queries.objects;
|
package com.djrapitops.plan.storage.database.queries.objects;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.delivery.domain.World;
|
||||||
import com.djrapitops.plan.gathering.domain.GMTimes;
|
import com.djrapitops.plan.gathering.domain.GMTimes;
|
||||||
import com.djrapitops.plan.gathering.domain.WorldTimes;
|
import com.djrapitops.plan.gathering.domain.WorldTimes;
|
||||||
import com.djrapitops.plan.identification.ServerUUID;
|
import com.djrapitops.plan.identification.ServerUUID;
|
||||||
import com.djrapitops.plan.storage.database.queries.Query;
|
import com.djrapitops.plan.storage.database.queries.Query;
|
||||||
|
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
|
||||||
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
|
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.WorldTable;
|
import com.djrapitops.plan.storage.database.sql.tables.WorldTable;
|
||||||
@ -28,9 +30,7 @@ import com.djrapitops.plan.storage.database.sql.tables.WorldTimesTable;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
||||||
|
|
||||||
@ -198,4 +198,21 @@ public class WorldTimesQueries {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static QueryStatement<Set<World>> fetchWorlds() {
|
||||||
|
String worldNameSql = SELECT + '*' + FROM + WorldTable.TABLE_NAME;
|
||||||
|
return new QueryAllStatement<Set<World>>(worldNameSql) {
|
||||||
|
@Override
|
||||||
|
public Set<World> processResults(ResultSet set) throws SQLException {
|
||||||
|
Set<World> worlds = new HashSet<>();
|
||||||
|
while (set.next()) {
|
||||||
|
worlds.add(new World(
|
||||||
|
set.getString(WorldTable.NAME),
|
||||||
|
ServerUUID.fromString(set.getString(WorldTable.SERVER_UUID))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return worlds;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
@ -31,6 +31,8 @@ import com.djrapitops.plan.storage.database.queries.objects.KillQueries;
|
|||||||
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.WorldTimesQueries;
|
import com.djrapitops.plan.storage.database.queries.objects.WorldTimesQueries;
|
||||||
import com.djrapitops.plan.storage.database.queries.objects.playertable.ServerTablePlayersQuery;
|
import com.djrapitops.plan.storage.database.queries.objects.playertable.ServerTablePlayersQuery;
|
||||||
|
import com.djrapitops.plan.storage.database.sql.tables.WorldTable;
|
||||||
|
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
|
||||||
import com.djrapitops.plan.storage.database.transactions.StoreServerInformationTransaction;
|
import com.djrapitops.plan.storage.database.transactions.StoreServerInformationTransaction;
|
||||||
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
import com.djrapitops.plan.storage.database.transactions.Transaction;
|
||||||
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
|
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
|
||||||
@ -43,6 +45,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import utilities.RandomData;
|
import utilities.RandomData;
|
||||||
import utilities.TestConstants;
|
import utilities.TestConstants;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -152,6 +155,34 @@ public interface SessionQueriesTest extends DatabaseTestPreparer {
|
|||||||
assertEquals(worldTimes, allSessions.get(0).getExtraData(WorldTimes.class).get());
|
assertEquals(worldTimes, allSessions.get(0).getExtraData(WorldTimes.class).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
default void worldTimesAreSavedWithSessionWithoutWorlds() {
|
||||||
|
prepareForSessionSave();
|
||||||
|
// Remove the worlds from the database so that they need to also be saved.
|
||||||
|
execute(new ExecStatement("DELETE FROM " + WorldTable.TABLE_NAME) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) {
|
||||||
|
// Nothing needed
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
WorldTimes worldTimes = RandomData.randomWorldTimes(worlds);
|
||||||
|
FinishedSession session = RandomData.randomSession(serverUUID(), worlds, playerUUID);
|
||||||
|
session.getExtraData().put(WorldTimes.class, worldTimes);
|
||||||
|
List<FinishedSession> sessions = new ArrayList<>();
|
||||||
|
sessions.add(session);
|
||||||
|
db().executeTransaction(new Transaction() {
|
||||||
|
@Override
|
||||||
|
protected void performOperations() {
|
||||||
|
execute(LargeStoreQueries.storeAllSessionsWithKillAndWorldData(sessions));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
List<FinishedSession> allSessions = db().query(SessionQueries.fetchAllSessions());
|
||||||
|
|
||||||
|
assertEquals(worldTimes, allSessions.get(0).getExtraData(WorldTimes.class).get());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
default void playersWorldTimesMatchTotal() {
|
default void playersWorldTimesMatchTotal() {
|
||||||
worldTimesAreSavedWithSession();
|
worldTimesAreSavedWithSession();
|
||||||
|
Loading…
Reference in New Issue
Block a user