package eu.mhsl.minecraft.pixelblocks; import eu.mhsl.minecraft.pixelblocks.utils.Direction; import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; import org.bukkit.Bukkit; import org.bukkit.Location; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.UUID; public class PixelBlockDatabase { private final Connection db; private final PreparedStatement getAllPixelBlocks; private final PreparedStatement deletePixelBlock; private final PreparedStatement insertNewPixelBlock; private final PreparedStatement updateExistingPixelBlock; public PixelBlockDatabase(String url) { try { Class.forName("org.sqlite.JDBC"); this.db = DriverManager.getConnection(url); this.db.createStatement().execute( "CREATE TABLE IF NOT EXISTS pixelblocks (" + "uuid CHAR(36) PRIMARY KEY, " + "owner CHAR(36), " + "locationWorldName CHAR(36), " + "locationX DOUBLE, " + "locationY DOUBLE, " + "locationZ DOUBLE, " + "entryLocationWorldName CHAR(36), " + "entryLocationX DOUBLE, " + "entryLocationY DOUBLE, " + "entryLocationZ DOUBLE, " + "direction CHAR(36)" + ")" ); this.deletePixelBlock = this.db.prepareStatement("DELETE FROM pixelblocks WHERE uuid = ?"); this.getAllPixelBlocks = this.db.prepareStatement("SELECT * FROM pixelblocks"); this.insertNewPixelBlock = this.db.prepareStatement( "INSERT INTO pixelblocks(uuid, owner, " + "locationWorldName, locationX, locationY, locationZ, " + "entryLocationWorldName, entryLocationX, entryLocationY, entryLocationZ, direction) " + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ); this.updateExistingPixelBlock = this.db.prepareStatement( "UPDATE pixelblocks " + "SET owner=?, locationWorldName=?, locationX=?, locationY=?, locationZ=?," + "entryLocationWorldName=?, entryLocationX=?, entryLocationY=?, entryLocationZ=?, direction=? " + "WHERE uuid=?;" ); } catch (SQLException | RuntimeException | ClassNotFoundException e) { throw new RuntimeException("Failed to load Database", e); } } public void close() throws SQLException { deletePixelBlock.close(); getAllPixelBlocks.close(); insertNewPixelBlock.close(); updateExistingPixelBlock.close(); db.close(); } public void deletePixelBlock(PixelBlock pixelBlock) { Bukkit.getScheduler().runTaskAsynchronously(PixelBlocksPlugin.plugin, () -> { try { this.deletePixelBlock.setString(1, pixelBlock.blockUUID.toString()); this.deletePixelBlock.executeUpdate(); PixelBlocksPlugin.plugin.getLogger().info("DB: Deleted PixelBlock: " + pixelBlock.blockUUID); } catch (SQLException e) { throw new RuntimeException("Failed to delete PixelBlock", e); } }); } public void savePixelBlock(PixelBlock pixelBlock) { Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> { List<UUID> storedPixelBlocks = new ArrayList<>(); try { ResultSet pixelBlocksResult = this.getAllPixelBlocks.executeQuery(); while (pixelBlocksResult.next()) { storedPixelBlocks.add(UUID.fromString(pixelBlocksResult.getString("uuid"))); } } catch (SQLException e) { throw new RuntimeException("Failed to fetch PixelBlock list", e); } if(!storedPixelBlocks.contains(pixelBlock.blockUUID)) { // create new entry if it does not exist try { this.insertNewPixelBlock.setString(1, pixelBlock.blockUUID.toString()); this.insertNewPixelBlock.setString(2, pixelBlock.ownerUUID.toString()); this.insertNewPixelBlock.setString(3, pixelBlock.pixelBlockLocation.getWorld().getName()); this.insertNewPixelBlock.setDouble(4, pixelBlock.pixelBlockLocation.getX()); this.insertNewPixelBlock.setDouble(5, pixelBlock.pixelBlockLocation.getY()); this.insertNewPixelBlock.setDouble(6, pixelBlock.pixelBlockLocation.getZ()); if(pixelBlock.lastEntryLocation != null) { this.insertNewPixelBlock.setString(7, pixelBlock.lastEntryLocation.getWorld().getName()); this.insertNewPixelBlock.setDouble(8, pixelBlock.lastEntryLocation.getX()); this.insertNewPixelBlock.setDouble(9, pixelBlock.lastEntryLocation.getY()); this.insertNewPixelBlock.setDouble(10, pixelBlock.lastEntryLocation.getZ()); } else { this.insertNewPixelBlock.setString(7, Bukkit.getWorlds().getFirst().getName()); this.insertNewPixelBlock.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getX()); this.insertNewPixelBlock.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getY()); this.insertNewPixelBlock.setDouble(10, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ()); } this.insertNewPixelBlock.setString(11, pixelBlock.facingDirection.toString()); this.insertNewPixelBlock.executeUpdate(); PixelBlocksPlugin.plugin.getLogger().info("DB: Created PixelBlock: " + pixelBlock.blockUUID); } catch (SQLException e) { throw new RuntimeException("Failed to save PixelBlock", e); } } else { // update existing entry try { this.updateExistingPixelBlock.setString(1, pixelBlock.ownerUUID.toString()); this.updateExistingPixelBlock.setString(2, pixelBlock.pixelBlockLocation.getWorld().getName()); this.updateExistingPixelBlock.setDouble(3, pixelBlock.pixelBlockLocation.getX()); this.updateExistingPixelBlock.setDouble(4, pixelBlock.pixelBlockLocation.getY()); this.updateExistingPixelBlock.setDouble(5, pixelBlock.pixelBlockLocation.getZ()); if(pixelBlock.lastEntryLocation != null) { this.updateExistingPixelBlock.setString(6, pixelBlock.lastEntryLocation.getWorld().getName()); this.updateExistingPixelBlock.setDouble(7, pixelBlock.lastEntryLocation.getX()); this.updateExistingPixelBlock.setDouble(8, pixelBlock.lastEntryLocation.getY()); this.updateExistingPixelBlock.setDouble(9, pixelBlock.lastEntryLocation.getZ()); } else { this.updateExistingPixelBlock.setString(6, Bukkit.getWorlds().getFirst().getName()); this.updateExistingPixelBlock.setDouble(7, Bukkit.getWorlds().getFirst().getSpawnLocation().getX()); this.updateExistingPixelBlock.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getY()); this.updateExistingPixelBlock.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ()); } this.updateExistingPixelBlock.setString(10, pixelBlock.blockUUID.toString()); this.updateExistingPixelBlock.setString(11, pixelBlock.facingDirection.toString()); this.updateExistingPixelBlock.executeUpdate(); PixelBlocksPlugin.plugin.getLogger().info("DB: Updated PixelBlock: " + pixelBlock.blockUUID); } catch (SQLException e) { throw new RuntimeException("Failed updating PixelBlock", e); } } }); } public void loadPixelBlocks() { try { ResultSet allPixelBlocks = this.getAllPixelBlocks.executeQuery(); while (allPixelBlocks.next()) { Location blockLocation = new Location( Bukkit.getWorld(allPixelBlocks.getString("locationWorldName")), allPixelBlocks.getDouble("locationX"), allPixelBlocks.getDouble("locationY"), allPixelBlocks.getDouble("locationZ") ); Location entryLocation = new Location( Bukkit.getWorld(allPixelBlocks.getString("entryLocationWorldName")), allPixelBlocks.getDouble("entryLocationX"), allPixelBlocks.getDouble("entryLocationY"), allPixelBlocks.getDouble("entryLocationZ") ); PixelBlock block = new PixelBlock( blockLocation, UUID.fromString(allPixelBlocks.getString("owner")), UUID.fromString(allPixelBlocks.getString("uuid")), Direction.valueOf(allPixelBlocks.getString("direction")) ); block.setLastEntryLocation(entryLocation); PixelBlocksPlugin.plugin.getLogger().info("DB: Loaded PixelBlock: " + block.blockUUID); } } catch (SQLException e) { throw new RuntimeException("Failed loading PixelBlocks", e); } } }