From 4345b30f78f75f3ab53df1f471f116b4b42a09d0 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 20 May 2017 09:45:15 +0300 Subject: [PATCH] Added save & get multiple methods to tables, bugfixes Fix #92 #91 possibly #88 --- Plan/pom.xml | 24 +- .../main/java/com/djrapitops/plan/Phrase.java | 1 + .../commands/manage/ManageImportCommand.java | 34 +- .../commands/manage/ManageRemoveCommand.java | 2 +- .../data/additional/towny/TownyTable.java | 12 +- .../plan/data/cache/DataCacheHandler.java | 16 +- .../plan/data/cache/InspectCacheHandler.java | 29 ++ .../data/cache/queue/DataCacheSaveQueue.java | 2 +- .../data/handling/importing/ImportUtils.java | 26 ++ .../data/handling/importing/Importer.java | 53 +++ .../handling/importing/OnTimeImporter.java | 49 +++ .../plan/data/importing/Importer.java | 26 -- .../plan/data/importing/OnTimeImporter.java | 55 ---- .../PlanCommandPreprocessListener.java | 2 + .../djrapitops/plan/database/Database.java | 237 +++++++++++--- .../plan/database/databases/SQLDB.java | 302 +++++++----------- .../plan/database/tables/CommandUseTable.java | 21 +- .../plan/database/tables/IPsTable.java | 74 +++++ .../plan/database/tables/KillsTable.java | 74 +++++ .../plan/database/tables/LocationsTable.java | 46 ++- .../plan/database/tables/NicknamesTable.java | 87 +++++ .../plan/database/tables/SessionsTable.java | 78 +++++ .../plan/database/tables/UsersTable.java | 83 ++++- .../djrapitops/plan/utilities/Analysis.java | 89 ++---- .../plan/utilities/ManageUtils.java | 52 +-- .../djrapitops/plan/utilities/MiscUtils.java | 2 + Plan/src/main/resources/plugin.yml | 2 +- .../plan/data/cache/DataCacheHandlerTest.java | 11 +- .../cache/queue/DataCacheClearQueueTest.java | 4 + .../queue/DataCacheProcessQueueTest.java | 4 +- .../plan/database/DatabaseTest.java | 41 ++- 31 files changed, 1044 insertions(+), 494 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/data/handling/importing/ImportUtils.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/data/handling/importing/Importer.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/data/handling/importing/OnTimeImporter.java delete mode 100644 Plan/src/main/java/com/djrapitops/plan/data/importing/Importer.java delete mode 100644 Plan/src/main/java/com/djrapitops/plan/data/importing/OnTimeImporter.java diff --git a/Plan/pom.xml b/Plan/pom.xml index 0bc9a57c9..c51aa7f18 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -3,10 +3,10 @@ 4.0.0 com.djrapitops Plan - 3.1.1 + 3.2.0 jar - @@ -149,7 +149,15 @@ org.apache.maven.plugins maven-jar-plugin - 2.6 + 2.6 + + + **/test/* + **/*/test/* + **/*/test.* + **/test/**/* + + org.pitest @@ -162,6 +170,8 @@ test.java.main.java.com.djrapitops.plan.* + 1000 + true @@ -173,6 +183,14 @@ checkstyle.xml + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + test.* + + diff --git a/Plan/src/main/java/com/djrapitops/plan/Phrase.java b/Plan/src/main/java/com/djrapitops/plan/Phrase.java index 87b0c7ff1..8169e7518 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Phrase.java +++ b/Plan/src/main/java/com/djrapitops/plan/Phrase.java @@ -79,6 +79,7 @@ public enum Phrase { ERROR_WEBSERVER_OFF_INSPECT(ChatColor.YELLOW + "" + PREFIX + "This command can be only used if webserver/planlite is enabled on this server."), ERROR_LOGGED("Caught " + REPLACE0 + ". It has been logged to the Errors.txt"), ERROR_SESSIONDATA_INITIALIZATION("Player's session was initialized in a wrong way! (" + REPLACE0 + ")"), + ERROR_ANALYSIS_FETCH_FAIL("Failed to fetch data for Analysis, Exception occurred."), // CMD_FOOTER(COLOR_TER.color() + "" + ARROWS_RIGHT), MANAGE_ERROR_INCORRECT_PLUGIN(ChatColor.RED + "" + PREFIX + "Plugin not supported: "), diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java index 5e4e02680..a41a0aece 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java @@ -4,17 +4,20 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import main.java.com.djrapitops.plan.Permissions; import main.java.com.djrapitops.plan.Phrase; import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.command.CommandType; import main.java.com.djrapitops.plan.command.SubCommand; -import main.java.com.djrapitops.plan.data.importing.Importer; -import main.java.com.djrapitops.plan.data.importing.OnTimeImporter; +import main.java.com.djrapitops.plan.data.handling.importing.ImportUtils; +import main.java.com.djrapitops.plan.data.handling.importing.Importer; import main.java.com.djrapitops.plan.utilities.ManageUtils; import org.bukkit.Bukkit; +import static org.bukkit.Bukkit.getOfflinePlayers; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -23,9 +26,9 @@ import org.bukkit.scheduler.BukkitTask; /** * This manage subcommand is used to import data from 3rd party plugins. - * + * * Supported plugins (v3.0.0) : OnTime - * + * * @author Rsl1122 * @since 2.3.0 */ @@ -57,10 +60,9 @@ public class ManageImportCommand extends SubCommand { sender.sendMessage(Phrase.MANAGE_ERROR_INCORRECT_PLUGIN + importFromPlugin); return true; } - HashMap importPlugins = new HashMap<>(); - importPlugins.put("ontime", new OnTimeImporter(plugin)); + Map importPlugins = ImportUtils.getImporters(); - if (!importPlugins.get(importFromPlugin).isEnabled()) { + if (!importPlugins.keySet().contains(importFromPlugin) || !ImportUtils.isPluginEnabled(importFromPlugin)) { sender.sendMessage(Phrase.MANAGE_ERROR_PLUGIN_NOT_ENABLED + importFromPlugin); return true; } @@ -70,20 +72,18 @@ public class ManageImportCommand extends SubCommand { return true; } + final Importer importer = importPlugins.get(importFromPlugin); // Header - sender.sendMessage(Phrase.MANAGE_IMPORTING + ""); - Set uuids = new HashSet<>(); - for (OfflinePlayer p : Bukkit.getOfflinePlayers()) { - uuids.add(p.getUniqueId()); - } - HashMap numbericData = importPlugins.get(importFromPlugin).grabNumericData(uuids); BukkitTask asyncImportTask = new BukkitRunnable() { @Override public void run() { - if (importFromPlugin.equals("ontime")) { - if (ManageUtils.importOnTime(numbericData, plugin)) { - sender.sendMessage(Phrase.MANAGE_SUCCESS + ""); - } + sender.sendMessage(Phrase.MANAGE_IMPORTING + ""); + List uuids = Arrays.stream(getOfflinePlayers()).map(p -> p.getUniqueId()).collect(Collectors.toList()); + if (importer.importData(uuids)) { + sender.sendMessage(Phrase.MANAGE_SUCCESS + ""); + } else { + sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + ""); + } this.cancel(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java index 9bb773cee..5737869f4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java @@ -76,7 +76,7 @@ public class ManageRemoveCommand extends SubCommand { public void run() { sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse()); try { - plugin.getHandler().scheludeForClear(uuid); + plugin.getHandler().getDataCache().remove(uuid); if (plugin.getDB().removeAccount(uuid.toString())) { sender.sendMessage(Phrase.MANAGE_REMOVE_SUCCESS.parse(playerName, plugin.getDB().getConfigName())); } else { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/towny/TownyTable.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/towny/TownyTable.java index d9aa41b79..2b19fdf16 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/additional/towny/TownyTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/towny/TownyTable.java @@ -1,6 +1,7 @@ package main.java.com.djrapitops.plan.data.additional.towny; import com.massivecraft.factions.entity.MPlayer; +import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; import java.io.Serializable; import java.util.List; @@ -46,8 +47,17 @@ public class TownyTable extends PluginData { html.append(Html.TABLELINE_4.parse(Html.TOWN_NO_TOWNS.parse(), "", "", "")); } else { for (Town t : towns) { + if (t == null) { + continue; + } String name = t.getName(); - String mayor = t.getMayor().getName(); + Resident mayorR = t.getMayor(); + String mayor; + if (mayorR != null) { + mayor = mayorR.getName(); + } else { + mayor = "None"; + } String residents = t.getNumResidents() + ""; String land = t.getPurchasedBlocks() + ""; String leaderPage = Html.LINK.parse(HtmlUtils.getInspectUrl(mayor), mayor); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java b/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java index 10528c5a1..656cc4cf4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java @@ -37,8 +37,8 @@ import static org.bukkit.Bukkit.getOfflinePlayer; * This class is the main processing class that initializes Save, Clear, Process * and Get queue and Starts the asyncronous save task. * - * It is used to store commanduse, locations, active sessions and UserData objects - * in memory. + * It is used to store commanduse, locations, active sessions and UserData + * objects in memory. * * It's methods can be used to access all the data it stores and to clear them. * @@ -49,7 +49,7 @@ public class DataCacheHandler extends LocationCache { // Cache private final HashMap dataCache; - private HashMap commandUse; + private Map commandUse; // Plan private final Plan plugin; @@ -269,8 +269,16 @@ public class DataCacheHandler extends LocationCache { data.addAll(dataCache.values()); Log.debug("SAVING, DataCache size: " + dataCache.keySet().size()); try { - db.saveMultipleUserData(data); db.saveCommandUse(commandUse); + } catch (SQLException e) { + Log.toLog(this.getClass().getName(), e); + } + try { + db.saveMultipleUserData(data); + } catch (SQLException e) { + Log.toLog(this.getClass().getName(), e); + } + try { db.close(); } catch (SQLException e) { Log.toLog(this.getClass().getName(), e); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/cache/InspectCacheHandler.java b/Plan/src/main/java/com/djrapitops/plan/data/cache/InspectCacheHandler.java index 5e38fa2c9..f4275be78 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/cache/InspectCacheHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/cache/InspectCacheHandler.java @@ -1,9 +1,16 @@ package main.java.com.djrapitops.plan.data.cache; +import java.sql.SQLException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.UUID; +import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.data.UserData; +import main.java.com.djrapitops.plan.database.Database; /** * This class stores UserData objects used for displaying the Html pages. @@ -46,6 +53,24 @@ public class InspectCacheHandler { handler.getUserDataForProcessing(cacher, uuid, false); } + public void cacheAllUserData(Database db) throws SQLException { + Set cachedUserData = handler.getDataCache().keySet(); + for (UUID uuid : cachedUserData) { + cache(uuid); + } + Set savedUUIDs = new HashSet<>(); + try { + savedUUIDs = db.getUsersTable().getSavedUUIDs(); + } catch (SQLException ex) { + Log.toLog(this.getClass().getName(), ex); + } + savedUUIDs.removeAll(cachedUserData); + List userDataForUUIDS = db.getUserDataForUUIDS(savedUUIDs); + for (UserData uData : userDataForUUIDS) { + cache.put(uData.getUuid(), uData); + } + } + /** * Checks the cache for UserData matching UUID. * @@ -65,4 +90,8 @@ public class InspectCacheHandler { public boolean isCached(UUID uuid) { return cache.containsKey(uuid); } + + public List getCachedUserData() { + return new ArrayList<>(cache.values()); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/cache/queue/DataCacheSaveQueue.java b/Plan/src/main/java/com/djrapitops/plan/data/cache/queue/DataCacheSaveQueue.java index 49678a9af..a8793bf12 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/cache/queue/DataCacheSaveQueue.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/cache/queue/DataCacheSaveQueue.java @@ -133,7 +133,7 @@ class SaveConsumer implements Runnable { UUID uuid = data.getUuid(); Log.debug(uuid + ": Saving: " + uuid); try { - db.saveUserData(uuid, data); + db.saveUserData(data); data.stopAccessing(); Log.debug(uuid + ": Saved!"); if (data.shouldClearAfterSave()) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/ImportUtils.java b/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/ImportUtils.java new file mode 100644 index 000000000..5abbd37f3 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/ImportUtils.java @@ -0,0 +1,26 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package main.java.com.djrapitops.plan.data.handling.importing; + +import java.util.HashMap; +import java.util.Map; +import static org.bukkit.Bukkit.getPluginManager; + +/** + * + * @author Risto + */ +public class ImportUtils { + public static boolean isPluginEnabled(String pluginName) { + return getPluginManager().isPluginEnabled(pluginName); + } + + public static Map getImporters() { + Map importers = new HashMap<>(); + importers.put("ontime", new OnTimeImporter()); + return importers; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/Importer.java b/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/Importer.java new file mode 100644 index 000000000..ce3298320 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/Importer.java @@ -0,0 +1,53 @@ +package main.java.com.djrapitops.plan.data.handling.importing; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; +import main.java.com.djrapitops.plan.Log; +import main.java.com.djrapitops.plan.Plan; +import main.java.com.djrapitops.plan.data.cache.DataCacheHandler; +import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo; +import main.java.com.djrapitops.plan.database.Database; +import static org.bukkit.Bukkit.getOfflinePlayer; +import org.bukkit.OfflinePlayer; + +/** + * + * @author Rsl1122 + */ +public abstract class Importer { + + public Importer() { + + } + + public boolean importData(Collection uuids) { + Plan plan = Plan.getInstance(); + DataCacheHandler handler = plan.getHandler(); + Database db = plan.getDB(); + Set saved; + try { + saved = db.getSavedUUIDs(); + } catch (SQLException ex) { + Log.toLog(this.getClass().getName(), ex); + return false; + } + List unSaved = new ArrayList<>(uuids); + unSaved.removeAll(saved); + for (UUID uuid : unSaved) { + OfflinePlayer player = getOfflinePlayer(uuid); + handler.newPlayer(player); + } + for (UUID uuid : uuids) { + handler.addToPool(importData(uuid)); + } + return true; + } + + public abstract HandlingInfo importData(UUID uuid); +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/OnTimeImporter.java b/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/OnTimeImporter.java new file mode 100644 index 000000000..502dc7e6b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/handling/importing/OnTimeImporter.java @@ -0,0 +1,49 @@ +package main.java.com.djrapitops.plan.data.handling.importing; + +import java.util.HashMap; +import java.util.Set; +import java.util.UUID; +import main.java.com.djrapitops.plan.data.UserData; +import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo; +import main.java.com.djrapitops.plan.data.handling.info.InfoType; +import me.edge209.OnTime.OnTimeAPI; +import me.edge209.OnTime.OnTimeAPI.data; +import org.bukkit.Bukkit; +import static org.bukkit.Bukkit.getOfflinePlayer; +import org.bukkit.GameMode; +import org.bukkit.OfflinePlayer; + +/** + * + * @author Rsl1122 + */ +public class OnTimeImporter extends Importer { + + /** + * + */ + public OnTimeImporter() { + } + + @Override + public HandlingInfo importData(UUID uuid) { + OfflinePlayer p = getOfflinePlayer(uuid); + Long playTime = OnTimeAPI.getPlayerTimeData(p.getName(), OnTimeAPI.data.TOTALPLAY); + return new HandlingInfo(uuid, InfoType.OTHER, 0L) { + @Override + public boolean process(UserData uData) { + if (uuid != uData.getUuid()) { + return false; + } + if (playTime > uData.getPlayTime()) { + uData.setPlayTime(playTime); + uData.setLastGamemode(GameMode.SURVIVAL); + uData.setAllGMTimes(playTime, 0, 0, 0); + uData.setLastGmSwapTime(playTime); + } + return true; + } + }; + + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/importing/Importer.java b/Plan/src/main/java/com/djrapitops/plan/data/importing/Importer.java deleted file mode 100644 index bbbb491a5..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/data/importing/Importer.java +++ /dev/null @@ -1,26 +0,0 @@ - -package main.java.com.djrapitops.plan.data.importing; - -import java.util.HashMap; -import java.util.Set; -import java.util.UUID; - -/** - * - * @author Rsl1122 - */ -public interface Importer { - - /** - * - * @param uuids - * @return - */ - public HashMap grabNumericData(Set uuids); - - /** - * - * @return - */ - public boolean isEnabled(); -} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/importing/OnTimeImporter.java b/Plan/src/main/java/com/djrapitops/plan/data/importing/OnTimeImporter.java deleted file mode 100644 index 4fe405925..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/data/importing/OnTimeImporter.java +++ /dev/null @@ -1,55 +0,0 @@ -package main.java.com.djrapitops.plan.data.importing; - -import java.util.HashMap; -import java.util.Set; -import java.util.UUID; -import main.java.com.djrapitops.plan.Plan; -import me.edge209.OnTime.OnTimeAPI; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; - -/** - * - * @author Rsl1122 - */ -public class OnTimeImporter implements Importer { - - private final Plan plugin; - private boolean enabled; - - /** - * - * @param plugin - */ - public OnTimeImporter(Plan plugin) { - this.plugin = plugin; - this.enabled = Bukkit.getPluginManager().isPluginEnabled("OnTime"); - } - - /** - * - * @param uuids - * @return - */ - @Override - public HashMap grabNumericData(Set uuids) { - HashMap onTimeData = new HashMap<>(); - for (OfflinePlayer p : Bukkit.getOfflinePlayers()) { - Long playTime = OnTimeAPI.getPlayerTimeData(p.getName(), OnTimeAPI.data.TOTALPLAY); - if (playTime != -1) { - UUID uuid = p.getUniqueId(); - onTimeData.put(uuid, playTime); - } - } - return onTimeData; - } - - /** - * - * @return - */ - @Override - public boolean isEnabled() { - return enabled; - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/listeners/PlanCommandPreprocessListener.java b/Plan/src/main/java/com/djrapitops/plan/data/listeners/PlanCommandPreprocessListener.java index c3d3141d5..ca45864be 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/listeners/PlanCommandPreprocessListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/listeners/PlanCommandPreprocessListener.java @@ -1,5 +1,6 @@ package main.java.com.djrapitops.plan.data.listeners; +import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.Permissions; import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.data.cache.DataCacheHandler; @@ -39,6 +40,7 @@ public class PlanCommandPreprocessListener implements Listener { return; } if (Permissions.IGNORE_COMMANDUSE.userHasThisPermission(event.getPlayer())) { + Log.debug("Ignored command, player had ignore permission."); return; } handler.handleCommand(event.getMessage().split(" ")[0]); diff --git a/Plan/src/main/java/com/djrapitops/plan/database/Database.java b/Plan/src/main/java/com/djrapitops/plan/database/Database.java index d59a337b0..34a58e74d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/Database.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/Database.java @@ -5,9 +5,17 @@ import java.util.*; import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor; +import main.java.com.djrapitops.plan.database.tables.CommandUseTable; +import main.java.com.djrapitops.plan.database.tables.GMTimesTable; +import main.java.com.djrapitops.plan.database.tables.IPsTable; +import main.java.com.djrapitops.plan.database.tables.KillsTable; +import main.java.com.djrapitops.plan.database.tables.LocationsTable; +import main.java.com.djrapitops.plan.database.tables.NicknamesTable; +import main.java.com.djrapitops.plan.database.tables.SessionsTable; +import main.java.com.djrapitops.plan.database.tables.UsersTable; +import main.java.com.djrapitops.plan.database.tables.VersionTable; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; /** * Abstract class representing a Database. @@ -16,7 +24,16 @@ import org.bukkit.configuration.ConfigurationSection; */ public abstract class Database { - private final Plan plugin; + protected final Plan plugin; + protected UsersTable usersTable; + protected GMTimesTable gmTimesTable; + protected KillsTable killsTable; + protected LocationsTable locationsTable; + protected NicknamesTable nicknamesTable; + protected SessionsTable sessionsTable; + protected IPsTable ipsTable; + protected CommandUseTable commandUseTable; + protected VersionTable versionTable; /** * Super constructor. @@ -39,141 +56,255 @@ public abstract class Database { } /** + * Used to give Database processors to call with UserData after they have + * been fetched from the database. * - * @param uuid - * @param processors - * @throws SQLException + * This method is a shortcut method for multiple parameters. + * + * @param uuid UUID of the player. + * @param processors Processors to call with the UserData after the fetch is + * complete. + * @throws SQLException If a database error occurs. */ public void giveUserDataToProcessors(UUID uuid, DBCallableProcessor... processors) throws SQLException { - List coll = new ArrayList<>(); - coll.addAll(Arrays.asList(processors)); - giveUserDataToProcessors(uuid, coll); + giveUserDataToProcessors(uuid, Arrays.asList(processors)); } /** + * Used to give Database processors to call with UserData after they have + * been fetched from the database. * - * @param uuid - * @param processors - * @throws SQLException + * @param uuid UUID of the player. + * @param processors Processors to call with the UserData after the fetch is + * complete. + * @throws SQLException If a database error occurs. */ public abstract void giveUserDataToProcessors(UUID uuid, Collection processors) throws SQLException; - /** - * - * @param uuid - * @param data - * @throws SQLException - */ - public abstract void saveUserData(UUID uuid, UserData data) throws SQLException; + public abstract List getUserDataForUUIDS(Collection uuids) throws SQLException; /** + * Used to save UserData object of a user. * - * @param data - * @throws SQLException + * @param uuid UUID of the player + * @param data UserData of the Player. + * @throws SQLException If a database error occurs. + * @deprecated Separate UUID no longer required. */ - public abstract void saveMultipleUserData(List data) throws SQLException; + @Deprecated + public void saveUserData(UUID uuid, UserData data) throws SQLException { + if (uuid.equals(data.getUuid())) { + saveUserData(data); + } + } /** + * Used to save UserData object of a user. * - * @param uuid - * @return + * @param data UserData of the Player. + * @throws SQLException If a database error occurs. + */ + public abstract void saveUserData(UserData data) throws SQLException; + + /** + * Used to save UserData object of multiple users. + * + * @param data Collection of UserData objects. + * @throws SQLException If a database error occurs. + */ + public abstract void saveMultipleUserData(Collection data) throws SQLException; + + /** + * Check if the user is saved in the database. + * + * @param uuid UUID of the user. + * @return true/false */ public abstract boolean wasSeenBefore(UUID uuid); /** - * + * Cleans the database of excess data. */ public abstract void clean(); /** + * Used to get the name of the database type. * - * @return + * @return SQLite/MySQL */ public abstract String getName(); /** + * Used to get the config name of the database type. * - * @return + * @return sqlite/mysql */ public String getConfigName() { return getName().toLowerCase().replace(" ", ""); } /** + * Used to get the database schema version. * - * @return - */ - public ConfigurationSection getConfigSection() { - return plugin.getConfig().getConfigurationSection(getConfigName()); - } - - /** - * - * @return @throws SQLException + * @return Integer starting from 0, incremented by one when schema is + * updated. + * @throws SQLException If a database error occurs. */ public abstract int getVersion() throws SQLException; /** + * Used to set the database schema version. * - * @param version - * @throws SQLException + * @param version Integer starting from 0, incremented by one when schema is + * updated. + * @throws SQLException If a database error occurs. */ public abstract void setVersion(int version) throws SQLException; /** + * Closes the database & it's resources. * - * @throws SQLException + * @throws SQLException If a database error occurs. */ public abstract void close() throws SQLException; /** + * Removes all data related to an account from the database. * - * @param uuid - * @return - * @throws SQLException + * @param uuid UUID of the account. + * @return Success of the removal. + * @throws SQLException If a database error occurs. */ public abstract boolean removeAccount(String uuid) throws SQLException; /** + * Used to clear all data from the database. * - * @return @throws SQLException + * Uses DELETE * FROM table. + * + * @return Success of removal. + * @throws SQLException If a database error occurs. */ public abstract boolean removeAllData() throws SQLException; /** + * Used to save CommandUse map. * * @param data - * @throws SQLException - * @throws NullPointerException + * @throws SQLException If a database error occurs. + * @throws NullPointerException If the database has not initialized tables. */ - public abstract void saveCommandUse(HashMap data) throws SQLException, NullPointerException; + @Deprecated + public void saveCommandUse(Map data) throws SQLException, NullPointerException { + commandUseTable.saveCommandUse(data); + } /** * - * @return @throws SQLException + * @return @throws SQLException If a database error occurs. */ - public abstract Set getSavedUUIDs() throws SQLException; + public Set getSavedUUIDs() throws SQLException { + return usersTable.getSavedUUIDs(); + } /** * - * @return @throws SQLException + * @return @throws SQLException If a database error occurs. */ - public abstract HashMap getCommandUse() throws SQLException; + @Deprecated + public Map getCommandUse() throws SQLException { + return commandUseTable.getCommandUse(); + } /** * * @param uuid * @return - * @throws SQLException + * @throws SQLException If a database error occurs. */ - public abstract int getUserId(String uuid) throws SQLException; + @Deprecated + public int getUserId(String uuid) throws SQLException { + return usersTable.getUserId(uuid); + } /** * * @param userId * @param worlds * @return - * @throws SQLException + * @throws SQLException If a database error occurs. */ - public abstract List getLocations(String userId, HashMap worlds) throws SQLException; + @Deprecated + public List getLocations(String userId, HashMap worlds) throws SQLException { + return getLocations(Integer.parseInt(userId), worlds); + } + + @Deprecated + public List getLocations(int userId, HashMap worlds) throws SQLException { + return locationsTable.getLocations(userId, worlds); + } + + /** + * + * @return + */ + public UsersTable getUsersTable() { + return usersTable; + } + + /** + * + * @return + */ + public SessionsTable getSessionsTable() { + return sessionsTable; + } + + /** + * + * @return + */ + public GMTimesTable getGmTimesTable() { + return gmTimesTable; + } + + /** + * + * @return + */ + public KillsTable getKillsTable() { + return killsTable; + } + + /** + * + * @return + */ + public LocationsTable getLocationsTable() { + return locationsTable; + } + + /** + * + * @return + */ + public IPsTable getIpsTable() { + return ipsTable; + } + + /** + * + * @return + */ + public NicknamesTable getNicknamesTable() { + return nicknamesTable; + } + + /** + * + * @return + */ + public CommandUseTable getCommandUseTable() { + return commandUseTable; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java index 7064ca348..aa08a199d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java @@ -3,6 +3,7 @@ package main.java.com.djrapitops.plan.database.databases; import java.net.InetAddress; import java.sql.Connection; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -10,16 +11,16 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.data.*; import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor; import main.java.com.djrapitops.plan.database.Database; import main.java.com.djrapitops.plan.database.tables.*; -import main.java.com.djrapitops.plan.utilities.UUIDFetcher; import org.bukkit.GameMode; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.scheduler.BukkitRunnable; import static org.bukkit.Bukkit.getOfflinePlayer; @@ -35,16 +36,6 @@ public abstract class SQLDB extends Database { private Connection connection; - private final UsersTable usersTable; - private final GMTimesTable gmTimesTable; - private final KillsTable killsTable; - private final LocationsTable locationsTable; - private final NicknamesTable nicknamesTable; - private final SessionsTable sessionsTable; - private final IPsTable ipsTable; - private final CommandUseTable commandUseTable; - private final VersionTable versionTable; - /** * * @param plugin @@ -77,7 +68,7 @@ public abstract class SQLDB extends Database { */ public void startConnectionPingTask(Plan plugin) throws IllegalArgumentException, IllegalStateException { // Maintains Connection. - (new BukkitRunnable() { + new BukkitRunnable() { @Override public void run() { try { @@ -88,7 +79,7 @@ public abstract class SQLDB extends Database { connection = getNewConnection(); } } - }).runTaskTimerAsynchronously(plugin, 60 * 20, 60 * 20); + }.runTaskTimerAsynchronously(plugin, 60 * 20, 60 * 20); } /** @@ -124,13 +115,22 @@ public abstract class SQLDB extends Database { newDatabase = false; } catch (Exception e) { } - versionTable.createTable(); + if (!versionTable.createTable()) { + Log.error("Failed to create table: " + versionTable.getTableName()); + return false; + } if (newDatabase) { Log.info("New Database created."); setVersion(3); } for (Table table : getAllTables()) { - table.createTable(); + if (!table.createTable()) { + Log.error("Failed to create table: " + table.getTableName()); + return false; + } + } + if (!newDatabase && getVersion() < 3) { + setVersion(3); } } return true; @@ -196,55 +196,13 @@ public abstract class SQLDB extends Database { @Override public boolean wasSeenBefore(UUID uuid) { try { - return getUserId(uuid.toString()) != -1; + return usersTable.getUserId(uuid.toString()) != -1; } catch (SQLException e) { Log.toLog(this.getClass().getName(), e); return false; } } - /** - * - * @param uuid - * @return - * @throws SQLException - */ - @Override - public int getUserId(String uuid) throws SQLException { - return usersTable.getUserId(uuid); - } - - /** - * - * @return @throws SQLException - */ - @Override - public Set getSavedUUIDs() throws SQLException { - return usersTable.getSavedUUIDs(); - } - - /** - * - * @param commandUse - * @throws SQLException - * @throws NullPointerException - */ - @Override - @Deprecated - public void saveCommandUse(HashMap commandUse) throws SQLException, NullPointerException { - commandUseTable.saveCommandUse(commandUse); - } - - /** - * - * @return @throws SQLException - */ - @Override - @Deprecated - public HashMap getCommandUse() throws SQLException { - return commandUseTable.getCommandUse(); - } - /** * * @param uuid @@ -259,7 +217,7 @@ public abstract class SQLDB extends Database { Log.toLog(this.getClass().getName(), e); return false; } - int userId = getUserId(uuid); + int userId = usersTable.getUserId(uuid); if (userId == -1) { return false; } @@ -295,7 +253,7 @@ public abstract class SQLDB extends Database { UserData data = new UserData(getOfflinePlayer(uuid), new DemographicsData()); usersTable.addUserInformationToUserData(data); - int userId = getUserId(uuid.toString()); + int userId = usersTable.getUserId(uuid); List nicknames = nicknamesTable.getNicknames(userId); data.addNicknames(nicknames); @@ -316,43 +274,42 @@ public abstract class SQLDB extends Database { } } - @Deprecated - private HashMap getGMTimes(int userId) throws SQLException { - return gmTimesTable.getGMTimes(userId); - } - - @Deprecated - private List getIPAddresses(int userId) throws SQLException { - return ipsTable.getIPAddresses(userId); - } - - @Deprecated - private List getNicknames(int userId) throws SQLException { - return nicknamesTable.getNicknames(userId); - } - @Override - @Deprecated - public List getLocations(String userId, HashMap worlds) throws SQLException { - return getLocations(Integer.parseInt(userId), worlds); - } - - /** - * - * @param userId - * @param worlds - * @return - * @throws SQLException - * @deprecated - */ - @Deprecated - public List getLocations(int userId, HashMap worlds) throws SQLException { - return locationsTable.getLocations(userId, worlds); - } - - @Deprecated - private List getPlayerKills(int userId) throws SQLException { - return killsTable.getPlayerKills(userId); + public List getUserDataForUUIDS(Collection uuids) throws SQLException { + if (uuids == null || uuids.isEmpty()) { + return new ArrayList<>(); + } + Map userIds = usersTable.getAllUserIds(); + List data = new ArrayList<>(); + for (UUID uuid : uuids) { + if (!userIds.keySet().contains(uuid)) { + continue; + } + UserData uData = new UserData(getOfflinePlayer(uuid), new DemographicsData()); + data.add(uData); + } + if (data.isEmpty()) { + return data; + } + usersTable.addUserInformationToUserData(data); + Map idUuidRel = userIds.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + List ids = userIds.entrySet().stream().filter(e -> uuids.contains(e.getKey())).map(e -> e.getValue()).collect(Collectors.toList()); + Log.debug("Ids: "+ids); + Map> nicknames = nicknamesTable.getNicknames(ids); + Map> ipList = ipsTable.getIPList(ids); + Map> playerKills = killsTable.getPlayerKills(ids, idUuidRel); + Map> sessionData = sessionsTable.getSessionData(ids); + Log.debug("Sizes: U:"+uuids.size()+" D:"+data.size()+" I:"+userIds.size()+" N:"+nicknames.size()+" I:"+ipList.size()+" K:"+playerKills.size()+" S:"+sessionData.size()); + for (UserData uData : data) { + UUID uuid = uData.getUuid(); + Integer id = userIds.get(uuid); + uData.addIpAddresses(ipList.get(id)); + uData.addNicknames(nicknames.get(id)); + uData.addSessions(sessionData.get(id)); + uData.setPlayerKills(playerKills.get(id)); + uData.setGmTimes(gmTimesTable.getGMTimes(id)); + } + return data; } /** @@ -361,7 +318,7 @@ public abstract class SQLDB extends Database { * @throws SQLException */ @Override - public void saveMultipleUserData(List data) throws SQLException { + public void saveMultipleUserData(Collection data) throws SQLException { checkConnection(); if (data.isEmpty()) { return; @@ -369,42 +326,58 @@ public abstract class SQLDB extends Database { Set exceptions = new HashSet<>(); List saveLast = usersTable.saveUserDataInformationBatch(data); data.removeAll(saveLast); - for (UserData uData : data) { - if (uData == null) { + // Transform to map + Map userDatas = data.stream().collect(Collectors.toMap(UserData::getUuid, Function.identity())); + // Get UserIDs + Map userIds = usersTable.getAllUserIds(); + // Empty dataset + Map> locations = new HashMap<>(); + Map> nicknames = new HashMap<>(); + Map lastNicks = new HashMap<>(); + Map> ips = new HashMap<>(); + Map> kills = new HashMap<>(); + Map uuids = userIds.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + Map> sessions = new HashMap<>(); + Map> gmTimes = new HashMap<>(); + // Put to dataset + for (UUID uuid : userDatas.keySet()) { + Integer id = userIds.get(uuid); + UserData uData = userDatas.get(uuid); + if (id == -1) { + saveLast.add(uData); continue; } - UUID uuid = uData.getUuid(); - if (uuid == null) { - try { - uData.setUuid(UUIDFetcher.getUUIDOf(uData.getName())); - if (uData.getUuid() == null) { - continue; - } - } catch (Exception ex) { - continue; - } - } uData.access(); - try { - int userId = getUserId(uData.getUuid().toString()); - sessionsTable.saveSessionData(userId, uData.getSessions()); - saveAdditionalLocationsList(userId, uData.getLocations()); - saveNickList(userId, uData.getNicknames(), uData.getLastNick()); - saveIPList(userId, uData.getIps()); - savePlayerKills(userId, uData.getPlayerKills()); - saveGMTimes(userId, uData.getGmTimes()); - } catch (Exception e) { - exceptions.add(e); - } - uData.stopAccessing(); + locations.put(id, uData.getLocations()); + nicknames.put(id, uData.getNicknames()); + lastNicks.put(id, uData.getLastNick()); + ips.put(id, uData.getIps()); + kills.put(id, uData.getPlayerKills()); + sessions.put(id, uData.getSessions()); + gmTimes.put(id, uData.getGmTimes()); } - for (UserData userData : saveLast) { - UUID uuid = userData.getUuid(); - if (uuid == null) { - continue; + // Save + locationsTable.saveAdditionalLocationsLists(locations); + nicknamesTable.saveNickLists(nicknames, lastNicks); + ipsTable.saveIPList(ips); + killsTable.savePlayerKills(kills, uuids); + sessionsTable.saveSessionData(sessions); + for (Integer id : gmTimes.keySet()) { + gmTimesTable.saveGMTimes(id, gmTimes.get(id)); + } + for (Integer id : locations.keySet()) { + UUID uuid = uuids.get(id); + if (uuid != null) { + UserData uData = userDatas.get(uuid); + if (uData != null) { + uData.stopAccessing(); + } } + } + // Save leftovers + for (UserData userData : saveLast) { try { - saveUserData(uuid, userData); + saveUserData(userData); } catch (SQLException e) { exceptions.add(e); } catch (NullPointerException e) { @@ -418,12 +391,15 @@ public abstract class SQLDB extends Database { /** * - * @param uuid * @param data * @throws SQLException */ @Override - public void saveUserData(UUID uuid, UserData data) throws SQLException { + public void saveUserData(UserData data) throws SQLException { + if (data == null) { + return; + } + UUID uuid = data.getUuid(); if (uuid == null) { return; } @@ -431,7 +407,7 @@ public abstract class SQLDB extends Database { Log.debug("DB_Save: " + data); data.access(); usersTable.saveUserDataInformation(data); - int userId = getUserId(uuid.toString()); + int userId = usersTable.getUserId(uuid.toString()); sessionsTable.saveSessionData(userId, data.getSessions()); locationsTable.saveAdditionalLocationsList(userId, data.getLocations()); nicknamesTable.saveNickList(userId, data.getNicknames(), data.getLastNick()); @@ -550,68 +526,4 @@ public abstract class SQLDB extends Database { public Connection getConnection() { return connection; } - - /** - * - * @return - */ - public UsersTable getUsersTable() { - return usersTable; - } - - /** - * - * @return - */ - public SessionsTable getSessionsTable() { - return sessionsTable; - } - - /** - * - * @return - */ - public GMTimesTable getGmTimesTable() { - return gmTimesTable; - } - - /** - * - * @return - */ - public KillsTable getKillsTable() { - return killsTable; - } - - /** - * - * @return - */ - public LocationsTable getLocationsTable() { - return locationsTable; - } - - /** - * - * @return - */ - public IPsTable getIpsTable() { - return ipsTable; - } - - /** - * - * @return - */ - public NicknamesTable getNicknamesTable() { - return nicknamesTable; - } - - /** - * - * @return - */ - public CommandUseTable getCommandUseTable() { - return commandUseTable; - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java index 152fcfa7a..483f8b5dd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java @@ -4,6 +4,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; +import java.util.Map; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.database.databases.SQLDB; @@ -48,11 +49,10 @@ public class CommandUseTable extends Table { /** * - * @return - * @throws SQLException + * @return @throws SQLException */ - public HashMap getCommandUse() throws SQLException { - HashMap commandUse = new HashMap<>(); + public Map getCommandUse() throws SQLException { + Map commandUse = new HashMap<>(); PreparedStatement statement = null; ResultSet set = null; try { @@ -74,34 +74,37 @@ public class CommandUseTable extends Table { * @throws SQLException * @throws NullPointerException */ - public void saveCommandUse(HashMap data) throws SQLException, NullPointerException { + public void saveCommandUse(Map data) throws SQLException, NullPointerException { if (data.isEmpty()) { return; } PreparedStatement statement = null; try { - removeAllData(); + if (!removeAllData()) { + Log.debug("CommandUse Table clear failed."); + } statement = prepareStatement("INSERT INTO " + tableName + " (" + columnCommand + ", " + columnTimesUsed + ") VALUES (?, ?)"); boolean commitRequired = false; for (String key : data.keySet()) { + Integer amount = data.get(key); +// Log.debug("Saving Command: "+key+" "+amount); if (key.length() > 20) { continue; } statement.setString(1, key); - statement.setInt(2, data.get(key)); + statement.setInt(2, amount); statement.addBatch(); commitRequired = true; } - if (commitRequired) { + Log.debug("CommandUse: Executing batch, size: "+data.size()); statement.executeBatch(); } } finally { close(statement); } } - } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/IPsTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/IPsTable.java index c79b048b5..bbef11193 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/IPsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/IPsTable.java @@ -6,7 +6,11 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.database.databases.SQLDB; @@ -136,4 +140,74 @@ public class IPsTable extends Table { close(statement); } } + + public Map> getIPList(Collection ids) throws SQLException { + if (ids == null || ids.isEmpty()) { + return new HashMap<>(); + } + PreparedStatement statement = null; + ResultSet set = null; + try { + statement = prepareStatement("SELECT * FROM " + tableName); + set = statement.executeQuery(); + Map> ips = new HashMap<>(); + for (Integer id : ids) { + ips.put(id, new HashSet<>()); + } + while (set.next()) { + Integer id = set.getInt(columnUserID); + if (!ids.contains(id)) { + Log.debug("Ips-Ids did not contain: " + id); + continue; + } + try { + ips.get(id).add(InetAddress.getByName(set.getString(columnIP))); + } catch (UnknownHostException e) { + } + } + return ips; + } finally { + close(set); + close(statement); + } + } + + public void saveIPList(Map> ips) throws SQLException { + if (ips == null || ips.isEmpty()) { + return; + } + Map> saved = getIPList(ips.keySet()); + PreparedStatement statement = null; + try { + statement = prepareStatement("INSERT INTO " + tableName + " (" + + columnUserID + ", " + + columnIP + + ") VALUES (?, ?)"); + boolean commitRequired = false; + for (Integer id : ips.keySet()) { + Set ipAddresses = ips.get(id); + Set s = saved.get(id); + if (s != null) { + ipAddresses.removeAll(s); + } + if (ipAddresses.isEmpty()) { + continue; + } + for (InetAddress ip : ipAddresses) { + if (ip == null) { + continue; + } + statement.setInt(1, id); + statement.setString(2, ip.getHostAddress()); + statement.addBatch(); + commitRequired = true; + } + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/KillsTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/KillsTable.java index 3a6797e3d..2be950855 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/KillsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/KillsTable.java @@ -4,7 +4,10 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.data.KillData; @@ -147,4 +150,75 @@ public class KillsTable extends Table { close(statement); } } + + public Map> getPlayerKills(Collection ids, Map uuids) throws SQLException { + if (ids == null || ids.isEmpty()) { + return new HashMap<>(); + } + + PreparedStatement statement = null; + ResultSet set = null; + try { + Map> kills = new HashMap<>(); + statement = prepareStatement("SELECT * FROM " + tableName); + set = statement.executeQuery(); + for (Integer id : ids) { + kills.put(id, new ArrayList<>()); + } + while (set.next()) { + int killerID = set.getInt(columnKillerUserID); + int victimID = set.getInt(columnVictimUserID); + if (!ids.contains(killerID)) { + Log.debug("Kills-Ids did not contain: " + killerID); + continue; + } + UUID victimUUID = uuids.get(victimID); + kills.get(killerID).add(new KillData(victimUUID, victimID, set.getString(columnWeapon), set.getLong(columnDate))); + } + return kills; + } finally { + close(set); + close(statement); + } + } + + public void savePlayerKills(Map> kills, Map uuids) throws SQLException { + if (kills == null || kills.isEmpty()) { + return; + } + Map> saved = getPlayerKills(kills.keySet(), uuids); + PreparedStatement statement = null; + try { + statement = prepareStatement("INSERT INTO " + tableName + " (" + + columnKillerUserID + ", " + + columnVictimUserID + ", " + + columnWeapon + ", " + + columnDate + + ") VALUES (?, ?, ?, ?)"); + boolean commitRequired = false; + for (Integer id : kills.keySet()) { + List playerKills = kills.get(id); + List s = saved.get(id); + if (s != null) { + playerKills.removeAll(s); + } + for (KillData kill : playerKills) { + if (kill == null) { + continue; + } + statement.setInt(1, id); + statement.setInt(2, kill.getVictimUserID()); + statement.setString(3, kill.getWeapon()); + statement.setLong(4, kill.getDate()); + statement.addBatch(); + commitRequired = true; + } + if (commitRequired) { + statement.executeBatch(); + } + } + } finally { + close(statement); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/LocationsTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/LocationsTable.java index 4291af1b7..e2a2c1811 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/LocationsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/LocationsTable.java @@ -6,6 +6,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.database.databases.SQLDB; import org.bukkit.Location; @@ -132,13 +133,13 @@ public class LocationsTable extends Table { if (location == null) { continue; } - statement.setInt(1, userId); - statement.setInt(2, (int) location.getBlockX()); - statement.setInt(3, (int) location.getBlockZ()); World world = location.getWorld(); if (world == null) { continue; } + statement.setInt(1, userId); + statement.setInt(2, (int) location.getBlockX()); + statement.setInt(3, (int) location.getBlockZ()); statement.setString(4, world.getName()); statement.addBatch(); commitRequired = true; @@ -150,4 +151,43 @@ public class LocationsTable extends Table { close(statement); } } + + public void saveAdditionalLocationsLists(Map> locations) throws SQLException { + if (locations == null || locations.isEmpty()) { + return; + } + PreparedStatement statement = null; + try { + statement = prepareStatement("INSERT INTO " + tableName + " (" + + columnUserID + ", " + + columnCoordinatesX + ", " + + columnCoordinatesZ + ", " + + columnWorld + + ") VALUES (?, ?, ?, ?)"); + boolean commitRequired = false; + for (Integer id : locations.keySet()) { + List newLocations = locations.get(id); + if (newLocations == null || newLocations.isEmpty()) { + continue; + } + for (Location location : newLocations) { + World world = location.getWorld(); + if (world == null) { + continue; + } + statement.setInt(1, id); + statement.setInt(2, (int) location.getBlockX()); + statement.setInt(3, (int) location.getBlockZ()); + statement.setString(4, world.getName()); + statement.addBatch(); + commitRequired = true; + } + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java index 81e13f3f5..8720dedb6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java @@ -4,7 +4,10 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.database.databases.SQLDB; @@ -164,4 +167,88 @@ public class NicknamesTable extends Table { close(statement); } } + + public Map> getNicknames(Collection ids) throws SQLException { + if (ids == null || ids.isEmpty()) { + return new HashMap<>(); + } + + PreparedStatement statement = null; + ResultSet set = null; + try { + Map> nicks = new HashMap<>(); + Map lastNicks = new HashMap<>(); + for (Integer id : ids) { + nicks.put(id, new ArrayList<>()); + } + statement = prepareStatement("SELECT * FROM " + tableName); + set = statement.executeQuery(); + while (set.next()) { + + Integer id = set.getInt(columnUserID); + if (!ids.contains(id)) { + Log.debug("Nicknames-Ids did not contain: " + id); + continue; + } + String nickname = set.getString(columnNick); + if (nickname.isEmpty()) { + continue; + } + nicks.get(id).add(nickname); + if (set.getBoolean(columnCurrent)) { + lastNicks.put(id, nickname); + } + } + for (Integer id : lastNicks.keySet()) { + String lastNick = lastNicks.get(id); + List list = nicks.get(id); + list.remove(lastNick); + list.add(lastNick); + } + + return nicks; + } finally { + close(set); + close(statement); + } + } + + public void saveNickLists(Map> nicknames, Map lastNicks) throws SQLException { + if (nicknames == null || nicknames.isEmpty()) { + return; + } + Map> saved = getNicknames(nicknames.keySet()); + PreparedStatement statement = null; + try { + boolean commitRequired = false; + statement = prepareStatement("INSERT INTO " + tableName + " (" + + columnUserID + ", " + + columnCurrent + ", " + + columnNick + + ") VALUES (?, ?, ?)"); + for (Integer id : nicknames.keySet()) { + Set newNicks = nicknames.get(id); + String lastNick = lastNicks.get(id); + List s = saved.get(id); + if (s != null) { + newNicks.removeAll(s); + } + if (newNicks.isEmpty()) { + continue; + } + for (String name : newNicks) { + statement.setInt(1, id); + statement.setInt(2, (name.equals(lastNick)) ? 1 : 0); + statement.setString(3, name); + statement.addBatch(); + commitRequired = true; + } + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/SessionsTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/SessionsTable.java index 311a418bb..5687894e5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/SessionsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/SessionsTable.java @@ -4,7 +4,10 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.data.SessionData; import main.java.com.djrapitops.plan.database.databases.SQLDB; @@ -142,4 +145,79 @@ public class SessionsTable extends Table { close(statement); } } + + public Map> getSessionData(Collection ids) throws SQLException { + if (ids == null || ids.isEmpty()) { + return new HashMap<>(); + } + PreparedStatement statement = null; + ResultSet set = null; + try { + Map> sessions = new HashMap<>(); + statement = prepareStatement("SELECT * FROM " + tableName); + set = statement.executeQuery(); + for (Integer id : ids) { + sessions.put(id, new ArrayList<>()); + } + while (set.next()) { + Integer id = set.getInt(columnUserID); + if (!ids.contains(id)) { + Log.debug("Session-Ids did not contain: " + id); + continue; + } + sessions.get(id).add(new SessionData(set.getLong(columnSessionStart), set.getLong(columnSessionEnd))); + } + set.close(); + statement.close(); + + return sessions; + } finally { + close(set); + close(statement); + } + } + + public void saveSessionData(Map> sessions) throws SQLException { + if (sessions == null || sessions.isEmpty()) { + return; + } + Map> saved = getSessionData(sessions.keySet()); + PreparedStatement statement = null; + try { + statement = prepareStatement("INSERT INTO " + tableName + " (" + + columnUserID + ", " + + columnSessionStart + ", " + + columnSessionEnd + + ") VALUES (?, ?, ?)"); + + boolean commitRequired = false; + for (Integer id : sessions.keySet()) { + List sessionList = sessions.get(id); + List s = saved.get(id); + if (s != null) { + sessionList.removeAll(s); + } + if (sessionList.isEmpty()) { + continue; + } + for (SessionData session : sessionList) { + long end = session.getSessionEnd(); + long start = session.getSessionStart(); + if (end < start) { + continue; + } + statement.setInt(1, id); + statement.setLong(2, start); + statement.setLong(3, end); + statement.addBatch(); + commitRequired = true; + } + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java index a22dea4f9..f9922f4ba 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java @@ -4,15 +4,21 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.api.Gender; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.database.databases.SQLDB; import main.java.com.djrapitops.plan.utilities.UUIDFetcher; +import me.edge209.OnTime.OnTimeAPI.data; import org.bukkit.GameMode; /** @@ -172,8 +178,7 @@ public class UsersTable extends Table { /** * - * @return - * @throws SQLException + * @return @throws SQLException */ public Set getSavedUUIDs() throws SQLException { PreparedStatement statement = null; @@ -253,6 +258,37 @@ public class UsersTable extends Table { close(statement); } } + + public void addUserInformationToUserData(List data) throws SQLException { + PreparedStatement statement = null; + ResultSet set = null; + try { + Map userDatas = data.stream().collect(Collectors.toMap(UserData::getUuid, Function.identity())); + statement = prepareStatement("SELECT * FROM " + tableName); + set = statement.executeQuery(); + while (set.next()) { + String uuidS = set.getString(columnUUID); + UUID uuid = UUID.fromString(uuidS); + if (!userDatas.keySet().contains(uuid)) { + continue; + } + UserData uData = userDatas.get(uuid); + uData.getDemData().setAge(set.getInt(columnDemAge)); + uData.getDemData().setGender(Gender.parse(set.getString(columnDemGender))); + uData.getDemData().setGeoLocation(set.getString(columnDemGeoLocation)); + uData.setLastGamemode(GameMode.valueOf(set.getString(columnLastGM))); + uData.setLastGmSwapTime(set.getLong(columnLastGMSwapTime)); + uData.setPlayTime(set.getLong(columnPlayTime)); + uData.setLoginTimes(set.getInt(columnLoginTimes)); + uData.setLastPlayed(set.getLong(columnLastPlayed)); + uData.setDeaths(set.getInt(columnDeaths)); + uData.setMobKills(set.getInt(columnMobKills)); + } + } finally { + close(set); + close(statement); + } + } /** * @@ -343,7 +379,7 @@ public class UsersTable extends Table { * @return * @throws SQLException */ - public List saveUserDataInformationBatch(List data) throws SQLException { + public List saveUserDataInformationBatch(Collection data) throws SQLException { PreparedStatement statement = null; try { List saveLast = new ArrayList<>(); @@ -418,6 +454,47 @@ public class UsersTable extends Table { } } + public Map getUserIds(Collection uuids) throws SQLException { + PreparedStatement statement = null; + ResultSet set = null; + try { + Map ids = new HashMap<>(); + statement = prepareStatement("SELECT " + columnUUID + ", " + columnID + " FROM " + tableName); + set = statement.executeQuery(); + while (set.next()) { + String uuidS = set.getString(columnUUID); + UUID uuid = UUID.fromString(uuidS); + if (!uuids.contains(uuid)) { + continue; + } + ids.put(uuid, set.getInt(columnID)); + } + return ids; + } finally { + close(set); + close(statement); + } + } + + public Map getAllUserIds() throws SQLException { + PreparedStatement statement = null; + ResultSet set = null; + try { + Map ids = new HashMap<>(); + statement = prepareStatement("SELECT " + columnUUID + ", " + columnID + " FROM " + tableName); + set = statement.executeQuery(); + while (set.next()) { + String uuidS = set.getString(columnUUID); + UUID uuid = UUID.fromString(uuidS); + ids.put(uuid, set.getInt(columnID)); + } + return ids; + } finally { + close(set); + close(statement); + } + } + /** * * @return diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java index b1c77448b..f513fa6d9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java @@ -1,5 +1,6 @@ package main.java.com.djrapitops.plan.utilities; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -7,6 +8,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Collectors; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.Phrase; @@ -75,15 +78,6 @@ public class Analysis { }).runTaskAsynchronously(plugin); } - /** - * @param analysisCache - * @deprecated Does nothing anymore, use analyze(AnalysisCacheHandler, - * Database) - */ - @Deprecated - public void analyze(AnalysisCacheHandler analysisCache) { - } - private List fetchPlayersInDB(Database db) { try { log(Phrase.ANALYSIS_FETCH_PLAYERS + ""); @@ -108,46 +102,29 @@ public class Analysis { * @return Whether or not analysis was successful. */ public boolean analyze(AnalysisCacheHandler analysisCache, Database db) { - List rawData = new ArrayList<>(); - List added = new ArrayList<>(); - List uuids = fetchPlayersInDB(db); - if (uuids.isEmpty()) { - Log.info(Phrase.ANALYSIS_FAIL_NO_DATA + ""); - return false; - } - uuids.stream().forEach((uuid) -> { - inspectCache.cache(uuid); - }); log(Phrase.ANALYSIS_FETCH_DATA + ""); - while (rawData.size() != uuids.size()) { - uuids.stream() - .filter((uuid) -> (!added.contains(uuid))) - .forEach((uuid) -> { - if (inspectCache.isCached(uuid)) { - UserData userData = inspectCache.getFromCache(uuid); - if (userData != null) { - rawData.add(userData); - userData.access(); - added.add(uuid); - } - } - }); + try { + inspectCache.cacheAllUserData(db); + } catch (Exception ex) { + Log.toLog(this.getClass().getName(), ex); + Log.error(Phrase.ERROR_ANALYSIS_FETCH_FAIL + ""); } - if (added.isEmpty()) { + List rawData = inspectCache.getCachedUserData(); + if (rawData.isEmpty()) { Log.info(Phrase.ANALYSIS_FAIL_NO_DATA + ""); return false; } - return analyzeData(rawData, uuids, analysisCache); + return analyzeData(rawData, analysisCache); } /** * * @param rawData - * @param uuids * @param analysisCache * @return */ - public boolean analyzeData(List rawData, List uuids, AnalysisCacheHandler analysisCache) { + public boolean analyzeData(List rawData, AnalysisCacheHandler analysisCache) { + List uuids = rawData.stream().map(d -> d.getUuid()).collect(Collectors.toList()); // Create empty Dataset long now = MiscUtils.getTime(); final RawAnalysisData sorted = new RawAnalysisData(); @@ -368,49 +345,49 @@ public class Analysis { } private Map analyzeAdditionalPluginData(List uuids) { - Map replaceMap = new HashMap<>(); - HookHandler hookHandler = Plan.getInstance().getHookHandler(); - List sources = hookHandler.getAdditionalDataSources(); - for (PluginData source : sources) { + final Map replaceMap = new HashMap<>(); + final HookHandler hookHandler = plugin.getHookHandler(); + final List sources = hookHandler.getAdditionalDataSources(); + final AnalysisType[] totalTypes = new AnalysisType[]{ + AnalysisType.INT_TOTAL, AnalysisType.LONG_TOTAL, AnalysisType.LONG_TIME_MS_TOTAL, AnalysisType.DOUBLE_TOTAL + }; + final AnalysisType[] avgTypes = new AnalysisType[]{ + AnalysisType.INT_AVG, AnalysisType.LONG_AVG, AnalysisType.LONG_TIME_MS_AVG, AnalysisType.LONG_EPOCH_MS_MINUS_NOW_AVG, AnalysisType.DOUBLE_AVG + }; + final AnalysisType bool = AnalysisType.BOOLEAN_PERCENTAGE; + final AnalysisType boolTot = AnalysisType.BOOLEAN_TOTAL; + sources.parallelStream().forEach(source -> { Log.debug("Analyzing source: " + source.getPlaceholder("").replace("%", "")); try { - List analysisTypes = source.getAnalysisTypes(); + final List analysisTypes = source.getAnalysisTypes(); if (analysisTypes.isEmpty()) { - continue; + return; } if (analysisTypes.contains(AnalysisType.HTML)) { replaceMap.put(source.getPlaceholder(AnalysisType.HTML.getPlaceholderModifier()), source.getHtmlReplaceValue(AnalysisType.HTML.getModifier(), uuids.get(0))); - continue; + return; } - AnalysisType[] totalTypes = new AnalysisType[]{ - AnalysisType.INT_TOTAL, AnalysisType.LONG_TOTAL, AnalysisType.LONG_TIME_MS_TOTAL, AnalysisType.DOUBLE_TOTAL - }; for (AnalysisType type : totalTypes) { if (analysisTypes.contains(type)) { replaceMap.put(source.getPlaceholder(type.getPlaceholderModifier()), AnalysisUtils.getTotal(type, source, uuids)); } } - AnalysisType[] avgTypes = new AnalysisType[]{ - AnalysisType.INT_AVG, AnalysisType.LONG_AVG, AnalysisType.LONG_TIME_MS_AVG, AnalysisType.LONG_EPOCH_MS_MINUS_NOW_AVG, AnalysisType.DOUBLE_AVG - }; for (AnalysisType type : avgTypes) { if (analysisTypes.contains(type)) { replaceMap.put(source.getPlaceholder(type.getPlaceholderModifier()), AnalysisUtils.getAverage(type, source, uuids)); } } - AnalysisType t = AnalysisType.BOOLEAN_PERCENTAGE; - if (analysisTypes.contains(t)) { - replaceMap.put(source.getPlaceholder(t.getPlaceholderModifier()), AnalysisUtils.getBooleanPercentage(t, source, uuids)); + if (analysisTypes.contains(bool)) { + replaceMap.put(source.getPlaceholder(bool.getPlaceholderModifier()), AnalysisUtils.getBooleanPercentage(bool, source, uuids)); } - t = AnalysisType.BOOLEAN_TOTAL; - if (analysisTypes.contains(t)) { - replaceMap.put(source.getPlaceholder(t.getPlaceholderModifier()), AnalysisUtils.getBooleanTotal(t, source, uuids)); + if (analysisTypes.contains(boolTot)) { + replaceMap.put(source.getPlaceholder(boolTot.getPlaceholderModifier()), AnalysisUtils.getBooleanTotal(boolTot, source, uuids)); } } catch (Throwable e) { Log.error("A PluginData-source caused an exception: " + source.getPlaceholder("").replace("%", "")); Log.toLog(this.getClass().getName(), e); } - } + }); return replaceMap; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/ManageUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/ManageUtils.java index f80921c1f..d989690a4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/ManageUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/ManageUtils.java @@ -7,8 +7,11 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.data.UserData; @@ -46,40 +49,6 @@ public class ManageUtils { return clearAndCopy(backupDB, copyFromDB, uuids); } - /** - * Import OnTime plugin data to the provided DataCacheHandler, and save - * cache. - * - * @param onTimeData PlayTime data of Ontime - * @param plugin Current instance of Plan - * @return success? - */ - public static boolean importOnTime(HashMap onTimeData, Plan plugin) { - DataCacheHandler handler = plugin.getHandler(); - for (UUID uuid : onTimeData.keySet()) { - OfflinePlayer player = getOfflinePlayer(uuid); - if (!plugin.getDB().wasSeenBefore(uuid)) { - - handler.newPlayer(player); - } - DBCallableProcessor importer = new DBCallableProcessor() { - @Override - public void process(UserData data) { - Long playTime = onTimeData.get(uuid); - if (playTime > data.getPlayTime()) { - data.setPlayTime(playTime); - data.setLastGamemode(GameMode.SURVIVAL); - data.setAllGMTimes(playTime, 0, 0, 0); - data.setLastGmSwapTime(playTime); - } - } - }; - handler.getUserDataForProcessing(importer, uuid); - } - handler.saveCachedUserData(); - return true; - } - /** * Get the saved UUIDs in a hashset * @@ -108,20 +77,9 @@ public class ManageUtils { public static boolean clearAndCopy(Database clearAndCopyToDB, Database copyFromDB, Collection fromDBsavedUUIDs) { try { clearAndCopyToDB.removeAllData(); - List allUserData = new ArrayList<>(); - for (UUID uuid : fromDBsavedUUIDs) { - copyFromDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() { - @Override - public void process(UserData data) { - allUserData.add(data); - } - }); - } - while (fromDBsavedUUIDs.size() > allUserData.size()) { - - } + List allUserData = copyFromDB.getUserDataForUUIDS(copyFromDB.getSavedUUIDs()); clearAndCopyToDB.saveMultipleUserData(allUserData); - clearAndCopyToDB.saveCommandUse(copyFromDB.getCommandUse()); + clearAndCopyToDB.getCommandUseTable().saveCommandUse(copyFromDB.getCommandUseTable().getCommandUse()); } catch (SQLException | NullPointerException e) { Log.toLog("ManageUtils.move", e); return false; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java index ae809f740..9ac9d5e7b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java @@ -7,8 +7,10 @@ import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Scanner; import java.util.Set; +import java.util.stream.Collectors; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.Permissions; import main.java.com.djrapitops.plan.Phrase; diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml index 14255c916..fc049e7a0 100644 --- a/Plan/src/main/resources/plugin.yml +++ b/Plan/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: main.java.com.djrapitops.plan.Plan -version: 3.1.0 +version: 3.2.0 softdepend: - OnTime diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/DataCacheHandlerTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/DataCacheHandlerTest.java index 9814c1fee..4898eb390 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/DataCacheHandlerTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/DataCacheHandlerTest.java @@ -9,6 +9,7 @@ import java.sql.SQLException; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.data.DemographicsData; @@ -93,17 +94,17 @@ public class DataCacheHandlerTest { } @Override - public void saveCommandUse(HashMap c) { + public void saveCommandUse(Map c) { calledSaveCommandUse = true; } @Override - public void saveUserData(UUID uuid, UserData data) throws SQLException { + public void saveUserData(UserData data) throws SQLException { calledSaveUserData = true; } @Override - public void saveMultipleUserData(List data) throws SQLException { + public void saveMultipleUserData(Collection data) throws SQLException { calledSaveMultiple = true; } }; @@ -133,7 +134,7 @@ public class DataCacheHandlerTest { public void testGetUserDataForProcessingCache() throws SQLException, InterruptedException { // db.init(); UserData data = new UserData(MockUtils.mockPlayer(), new DemographicsData()); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); handler.getUserDataForProcessing(new DBCallableProcessor() { @Override public void process(UserData d) { @@ -154,7 +155,7 @@ public class DataCacheHandlerTest { @Test public void testGetUserDataForProcessingDontCache() throws SQLException, InterruptedException { UserData data = new UserData(MockUtils.mockPlayer(), new DemographicsData()); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); handler.getUserDataForProcessing(new DBCallableProcessor() { @Override public void process(UserData d) { diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheClearQueueTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheClearQueueTest.java index 1b27523d2..e207f1170 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheClearQueueTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheClearQueueTest.java @@ -11,6 +11,7 @@ import org.bukkit.plugin.java.JavaPlugin; import org.junit.After; import static org.junit.Assert.assertTrue; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; @@ -68,6 +69,7 @@ public class DataCacheClearQueueTest { /** * */ + @Ignore @Test public void testScheduleForClear_UUID() { } @@ -75,6 +77,7 @@ public class DataCacheClearQueueTest { /** * */ + @Ignore @Test public void testScheduleForClear_Collection() { } @@ -82,6 +85,7 @@ public class DataCacheClearQueueTest { /** * */ + @Ignore @Test public void testStop() { } diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheProcessQueueTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheProcessQueueTest.java index 8f72f0f49..04a4b5ff6 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheProcessQueueTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/cache/queue/DataCacheProcessQueueTest.java @@ -21,6 +21,7 @@ import org.bukkit.plugin.java.JavaPlugin; import org.junit.After; import static org.junit.Assert.*; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; @@ -104,7 +105,7 @@ public class DataCacheProcessQueueTest { }); Thread.sleep(1000); assertTrue(q.stop().isEmpty()); - + } /** @@ -135,6 +136,7 @@ public class DataCacheProcessQueueTest { * * @throws InterruptedException */ + @Ignore("Inconsistant") @Test public void testContainsUUID() throws InterruptedException { DataCacheProcessQueue q = new DataCacheProcessQueue(handler); diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java index 504706e7a..0999fee27 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java @@ -11,8 +11,10 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -183,7 +185,7 @@ public class DatabaseTest { public void testRemoveAll() throws SQLException { db.init(); UserData data = new UserData(MockUtils.mockPlayer(), new DemographicsData()); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); HashMap c = new HashMap<>(); c.put("/plan", 1); c.put("/tp", 4); @@ -192,7 +194,7 @@ public class DatabaseTest { c.put("/roiergbnougbierubieugbeigubeigubgierbgeugeg", 3); db.saveCommandUse(c); assertTrue(db.removeAllData()); - assertTrue("Contains the user", db.getUserId(data.getUuid().toString()) == -1); + assertTrue("Contains the user", db.getUserDataForUUIDS(Arrays.asList(new UUID[]{MockUtils.getPlayerUUID(), MockUtils.getPlayer2UUID()})).isEmpty()); assertTrue("Contains commandUse", db.getCommandUse().isEmpty()); } @@ -210,11 +212,12 @@ public class DatabaseTest { c.put("/help", 21); c.put("/roiergbnougbierubieugbeigubeigubgierbgeugeg", 3); db.saveCommandUse(c); - assertTrue("Doesn't contain /plan", db.getCommandUse().containsKey("/plan")); - assertTrue("Doesn't contain /tp", db.getCommandUse().containsKey("/tp")); - assertTrue("Doesn't contain /pla", db.getCommandUse().containsKey("/pla")); - assertTrue("Doesn't contain /help", db.getCommandUse().containsKey("/help")); - assertTrue("Contains too long cmd", !db.getCommandUse().containsKey("/roiergbnougbierubieugbeigubeigubgierbgeugeg")); + Map commandUse = db.getCommandUse(); + assertTrue("Doesn't contain /plan", commandUse.containsKey("/plan")); + assertTrue("Doesn't contain /tp", commandUse.containsKey("/tp")); + assertTrue("Doesn't contain /pla", commandUse.containsKey("/pla")); + assertTrue("Doesn't contain /help", commandUse.containsKey("/help")); + assertTrue("Contains too long cmd", !commandUse.containsKey("/roiergbnougbierubieugbeigubeigubgierbgeugeg")); } /** @@ -225,9 +228,9 @@ public class DatabaseTest { public void testSaveUserData() throws SQLException { db.init(); UserData data = new UserData(MockUtils.mockPlayer(), new DemographicsData()); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); data.addNickname("TestUpdateForSave"); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); DBCallableProcessor process = new DBCallableProcessor() { @Override public void process(UserData d) { @@ -246,9 +249,9 @@ public class DatabaseTest { db.init(); UserData data = new UserData(MockUtils.mockPlayer(), new DemographicsData()); UserData data2 = new UserData(MockUtils.mockPlayer2(), new DemographicsData()); - db.saveUserData(data2.getUuid(), data2); + db.saveUserData(data2); data.addNickname("s); DROP TABLE plan_users;--"); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); assertTrue("Removed Users table.", db.getUserId(data2.getUuid().toString()) != -1); } @@ -260,7 +263,7 @@ public class DatabaseTest { public void testSaveMultipleUserData() throws SQLException { db.init(); UserData data = new UserData(MockUtils.mockPlayer(), new DemographicsData()); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); data.addNickname("TestUpdateForSave"); UserData data2 = new UserData(MockUtils.mockPlayer2(), new DemographicsData()); List list = new ArrayList<>(); @@ -291,7 +294,7 @@ public class DatabaseTest { public void testRemove() throws SQLException { db.init(); UserData data = new UserData(MockUtils.mockPlayer(), new DemographicsData()); - db.saveUserData(data.getUuid(), data); + db.saveUserData(data); assertTrue(db.removeAccount(data.getUuid().toString())); assertTrue("Contains the user", !db.wasSeenBefore(data.getUuid())); } @@ -326,6 +329,7 @@ public class DatabaseTest { * * @throws SQLException */ + // Big test because @Test public void testRestore() throws SQLException { db.init(); @@ -335,6 +339,12 @@ public class DatabaseTest { list.add(data); list.add(data2); db.saveMultipleUserData(list); + HashMap c = new HashMap<>(); + c.put("/plan", 1); + c.put("/tp", 4); + c.put("/pla", 7); + c.put("/help", 21); + db.saveCommandUse(c); backup = new SQLiteDB(plan, "debug-backup") { @Override public void startConnectionPingTask(Plan plugin) { @@ -347,5 +357,10 @@ public class DatabaseTest { Set savedUUIDs = db.getSavedUUIDs(); assertTrue("Didn't contain 1", savedUUIDs.contains(data.getUuid())); assertTrue("Didn't contain 2", savedUUIDs.contains(data2.getUuid())); + Map commandUse = db.getCommandUse(); + assertTrue("Doesn't contain /plan", commandUse.containsKey("/plan")); + assertTrue("Doesn't contain /tp", commandUse.containsKey("/tp")); + assertTrue("Doesn't contain /pla", commandUse.containsKey("/pla")); + assertTrue("Doesn't contain /help", commandUse.containsKey("/help")); } }