package de.jaschastarke.minecraft.limitedcreative.blockstate; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; import de.jaschastarke.bukkit.lib.chat.ChatFormattings; import de.jaschastarke.bukkit.lib.commands.CommandContext; import de.jaschastarke.bukkit.lib.database.ResultIterator; import de.jaschastarke.database.db.Database; import de.jaschastarke.minecraft.limitedcreative.ModBlockStates; import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source; import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.Cuboid; public class CreativeControlImportThread extends DatabaseMigrationThread { public CreativeControlImportThread(ModBlockStates mod, CommandContext context, Database source, Database target) { super(mod, context, source, target); } @Override public void run() { try { if (!target.isInTransaction()) target.startTransaction(); int rowCount = 0; Connection sourceConnection = source.getConnection(); Connection targetConnection = target.getConnection(); if (mode == Mode.REPLACE) { targetConnection.createStatement().execute("DELETE FROM lc_block_state"); } DBQueries targetDB = new DBQueries(this, target); List<WorldSize> worldBounds = new ArrayList<WorldSize>(); for (World w : mod.getPlugin().getServer().getWorlds()) { try { ResultSet fetchBounds = sourceConnection.createStatement().executeQuery("SELECT MIN(x), MIN(z), MAX(x), MAX(z) FROM crcr_blocks_" + w.getName()); while (fetchBounds.next()) { worldBounds.add(new WorldSize(w, fetchBounds.getInt(1), fetchBounds.getInt(2), fetchBounds.getInt(3), fetchBounds.getInt(4))); } fetchBounds.close(); } catch (SQLException e) { if (isDebug()) mod.getLog().debug("crcr_blocks_" + w.getName() + " not found: " + e.getMessage()); mod.getLog().info("CreativeControl has BlockData for World " + w.getName()); } } for (WorldSize bounds : worldBounds) { World world = mod.getPlugin().getServer().getWorld(bounds.getWorld()); if (world != null) { long time = System.currentTimeMillis(); int itCount = 0; if (mod.isDebug()) mod.getLog().debug("Processing world " + world.getName() + " with bounds: " + bounds); for (int x = bounds.getMinX(); x <= bounds.getMaxX(); x += CHUNK_SIZE + 1) { for (int z = bounds.getMinZ(); z <= bounds.getMaxZ(); z += CHUNK_SIZE + 1) { Cuboid c = new Cuboid(); c.add(new Location(world, x, 0, z)); c.add(new Location(world, x + CHUNK_SIZE, world.getMaxHeight(), z + CHUNK_SIZE)); if (mod.isDebug()) mod.getLog().debug("Fetching Cuboid: " + c.toString()); for (BlockState bs : iterateAllIn(c)) { if (mode == Mode.UPDATE) { BlockState xs = targetDB.find(bs.getLocation()); if (xs == null) { targetDB.insert(bs); } else if (xs.getDate().before(bs.getDate())) { targetDB.update(bs); } } else { targetDB.insert(bs); } rowCount++; itCount++; } Thread.yield(); } } String region = "Region{world = " + world.getName() + ", x = [" + bounds.getMinX() + "; " + (bounds.getMinX() + CHUNK_SIZE) + "], z = [" + bounds.getMinZ() + "; " + (bounds.getMinZ() + CHUNK_SIZE) + "]}"; mod.getLog().info("Migration processed " + itCount + " BlockStates in " + region + " within " + ((System.currentTimeMillis() - time) / 1000.0) + " seconds"); } } target.endTransaction(); context.responseFormatted(ChatFormattings.SUCCESS, L("command.blockstate.migration_finished", rowCount) + " " + context.getFormatter().formatString(ChatFormattings.ERROR, L("command.blockstate.migration_finished_restart"))); } catch (SQLException e) { try { target.revertTransaction(); } catch (SQLException e1) {} context.responseFormatted(ChatFormattings.ERROR, L("command.blockstate.migration_error", e.getMessage())); } } private PreparedStatement findall = null; private Iterable<BlockState> iterateAllIn(final DBModel.Cuboid c) throws SQLException { if (isDebug()) getLog().debug("DBQuery: iterateAllIn: " + c.toString()); if (findall == null) { findall = source.prepare("SELECT * FROM crcr_blocks_" + c.getWorld().getName() + " LEFT JOIN crcr_players ON owner = id WHERE x >= ? AND x <= ? AND y >= ? AND y <= ? AND z >= ? AND z <= ?"); } findall.setInt(1, c.getMinX()); findall.setInt(2, c.getMaxX()); findall.setInt(3, c.getMinY()); findall.setInt(4, c.getMaxY()); findall.setInt(5, c.getMinZ()); findall.setInt(6, c.getMaxZ()); ResultSet rs = findall.executeQuery(); return new ResultIterator<BlockState>(rs) { @Override protected BlockState fetch(ResultSet rs) throws SQLException { BlockState bs = new BlockState(); bs.setLocation(new Location(c.getWorld(), rs.getInt("x"), rs.getInt("y"), rs.getInt("z"))); bs.setDate(new Date(rs.getLong("time"))); bs.setGameMode(GameMode.CREATIVE); bs.setPlayerName(rs.getString("player")); bs.setSource(Source.PLAYER); return bs; } }; } }