/* * Copyright (C) 2016 eccentric_nz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package me.eccentric_nz.TARDIS.database; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import me.eccentric_nz.TARDIS.TARDIS; import org.bukkit.ChatColor; /** * TARDISes prefer the environment of the Space-Time Vortex to the four * dimensional world. They have Curiosity Circuits to encourage them to leave * the Vortex. * * @author eccentric_nz */ public class TARDISSQLiteDatabaseUpdater { private final List<String> areaupdates = new ArrayList<String>(); private final List<String> blockupdates = new ArrayList<String>(); private final List<String> countupdates = new ArrayList<String>(); private final List<String> destupdates = new ArrayList<String>(); private final List<String> doorupdates = new ArrayList<String>(); private final List<String> gravityupdates = new ArrayList<String>(); private final List<String> portalsupdates = new ArrayList<String>(); private final List<String> prefsupdates = new ArrayList<String>(); private final List<String> tardisupdates = new ArrayList<String>(); private final List<String> inventoryupdates = new ArrayList<String>(); private final List<String> uuidUpdates = Arrays.asList("achievements", "ars", "player_prefs", "storage", "t_count", "tardis", "travellers"); private final long now = System.currentTimeMillis(); private final Statement statement; private final TARDIS plugin; private final String prefix; public TARDISSQLiteDatabaseUpdater(TARDIS plugin, Statement statement) { this.plugin = plugin; this.prefix = this.plugin.getPrefix(); this.statement = statement; areaupdates.add("y INTEGER"); areaupdates.add("parking_distance INTEGER DEFAULT 2"); blockupdates.add("police_box INTEGER DEFAULT 0"); countupdates.add("grace INTEGER DEFAULT 0"); destupdates.add("bind TEXT DEFAULT ''"); destupdates.add("type INTEGER DEFAULT 0"); destupdates.add("direction TEXT DEFAULT ''"); destupdates.add("submarine INTEGER DEFAULT 0"); destupdates.add("slot INTEGER DEFAULT '-1'"); doorupdates.add("locked INTEGER DEFAULT 0"); gravityupdates.add("distance INTEGER DEFAULT 11"); gravityupdates.add("velocity REAL DEFAULT 0.5"); portalsupdates.add("abandoned INTEGER DEFAULT 0"); prefsupdates.add("artron_level INTEGER DEFAULT 0"); prefsupdates.add("auto_on INTEGER DEFAULT 0"); prefsupdates.add("auto_siege_on INTEGER DEFAULT 0"); prefsupdates.add("beacon_on INTEGER DEFAULT 1"); prefsupdates.add("build_on INTEGER DEFAULT 1"); prefsupdates.add("ctm_on INTEGER DEFAULT 0"); prefsupdates.add("difficulty INTEGER DEFAULT 0"); prefsupdates.add("dnd_on INTEGER DEFAULT 0"); prefsupdates.add("eps_message TEXT DEFAULT ''"); prefsupdates.add("eps_on INTEGER DEFAULT 0"); prefsupdates.add("farm_on INTEGER DEFAULT 0"); prefsupdates.add("floor TEXT DEFAULT 'LIGHT_GREY_WOOL'"); prefsupdates.add("flying_mode INTEGER DEFAULT 1"); prefsupdates.add("hads_on INTEGER DEFAULT 1"); prefsupdates.add("hads_type TEXT DEFAULT 'DISPLACEMENT'"); prefsupdates.add("hum TEXT DEFAULT ''"); prefsupdates.add("key TEXT DEFAULT ''"); prefsupdates.add("language TEXT DEFAULT 'AUTO_DETECT'"); prefsupdates.add("lanterns_on INTEGER DEFAULT 0"); prefsupdates.add("minecart_on INTEGER DEFAULT 0"); prefsupdates.add("policebox_textures_on INTEGER DEFAULT 1"); prefsupdates.add("renderer_on INTEGER DEFAULT 1"); prefsupdates.add("siege_floor TEXT DEFAULT 'BLACK_CLAY'"); prefsupdates.add("siege_wall TEXT DEFAULT 'GREY_CLAY'"); prefsupdates.add("sign_on INTEGER DEFAULT 1"); prefsupdates.add("submarine_on INTEGER DEFAULT 0"); prefsupdates.add("telepathy_on INTEGER DEFAULT 0"); prefsupdates.add("texture_in TEXT DEFAULT ''"); prefsupdates.add("texture_on INTEGER DEFAULT 0"); prefsupdates.add("texture_out TEXT DEFAULT 'default'"); prefsupdates.add("travelbar_on INTEGER DEFAULT 0"); prefsupdates.add("wall TEXT DEFAULT 'ORANGE_WOOL'"); prefsupdates.add("wool_lights_on INTEGER DEFAULT 0"); prefsupdates.add("auto_powerup_on INTEGER DEFAULT 0"); tardisupdates.add("abandoned INTEGER DEFAULT 0"); tardisupdates.add("adapti_on INTEGER DEFAULT 0"); tardisupdates.add("artron_level INTEGER DEFAULT 0"); tardisupdates.add("beacon TEXT DEFAULT ''"); tardisupdates.add("chameleon_data INTEGER DEFAULT 11"); tardisupdates.add("chameleon_demat TEXT DEFAULT 'NEW'"); tardisupdates.add("chameleon_id INTEGER DEFAULT 35"); tardisupdates.add("chameleon_preset TEXT DEFAULT 'NEW'"); tardisupdates.add("condenser TEXT DEFAULT ''"); tardisupdates.add("creeper TEXT DEFAULT ''"); tardisupdates.add("eps TEXT DEFAULT ''"); tardisupdates.add("farm TEXT DEFAULT ''"); tardisupdates.add("handbrake_on INTEGER DEFAULT 1"); tardisupdates.add("hidden INTEGER DEFAULT 0"); tardisupdates.add("hutch TEXT DEFAULT ''"); tardisupdates.add("igloo TEXT DEFAULT ''"); tardisupdates.add("iso_on INTEGER DEFAULT 0"); tardisupdates.add("last_known_name TEXT COLLATE NOCASE DEFAULT ''"); tardisupdates.add("lastuse INTEGER DEFAULT " + now); tardisupdates.add("lights_on INTEGER DEFAULT 1"); tardisupdates.add("monsters INTEGER DEFAULT 0"); tardisupdates.add("powered_on INTEGER DEFAULT 0"); tardisupdates.add("rail TEXT DEFAULT ''"); tardisupdates.add("recharging INTEGER DEFAULT 0"); tardisupdates.add("renderer TEXT DEFAULT ''"); tardisupdates.add("scanner TEXT DEFAULT ''"); tardisupdates.add("siege_on INTEGER DEFAULT 0"); tardisupdates.add("stable TEXT DEFAULT ''"); tardisupdates.add("tardis_init INTEGER DEFAULT 0"); tardisupdates.add("tips INTEGER DEFAULT '-1'"); tardisupdates.add("village TEXT DEFAULT ''"); tardisupdates.add("zero TEXT DEFAULT ''"); inventoryupdates.add("attributes TEXT DEFAULT ''"); inventoryupdates.add("armour_attributes TEXT DEFAULT ''"); } /** * Adds new fields to tables in the database. */ public void updateTables() { int i = 0; try { for (String u : uuidUpdates) { String a_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + u + "' AND sql LIKE '%uuid%'"; ResultSet rsu = statement.executeQuery(a_query); if (!rsu.next()) { i++; String u_alter = "ALTER TABLE " + prefix + u + " ADD uuid TEXT DEFAULT ''"; statement.executeUpdate(u_alter); } } for (String a : areaupdates) { String[] asplit = a.split(" "); String acheck = asplit[0] + " " + asplit[1].substring(0, 3); String a_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "areas' AND sql LIKE '%" + acheck + "%'"; ResultSet rsa = statement.executeQuery(a_query); if (!rsa.next()) { i++; String a_alter = "ALTER TABLE " + prefix + "areas ADD " + a; statement.executeUpdate(a_alter); } } for (String b : blockupdates) { String[] bsplit = b.split(" "); String b_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "blocks' AND sql LIKE '%" + bsplit[0] + "%'"; ResultSet rsb = statement.executeQuery(b_query); if (!rsb.next()) { i++; String b_alter = "ALTER TABLE " + prefix + "blocks ADD " + b; statement.executeUpdate(b_alter); } } for (String c : countupdates) { String[] csplit = c.split(" "); String c_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "t_count' AND sql LIKE '%" + csplit[0] + "%'"; ResultSet rsc = statement.executeQuery(c_query); if (!rsc.next()) { i++; String c_alter = "ALTER TABLE " + prefix + "t_count ADD " + c; statement.executeUpdate(c_alter); } } for (String d : destupdates) { String[] dsplit = d.split(" "); String d_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "destinations' AND sql LIKE '%" + dsplit[0] + "%'"; ResultSet rsd = statement.executeQuery(d_query); if (!rsd.next()) { i++; String d_alter = "ALTER TABLE " + prefix + "destinations ADD " + d; statement.executeUpdate(d_alter); } } for (String o : doorupdates) { String[] osplit = o.split(" "); String o_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "doors' AND sql LIKE '%" + osplit[0] + "%'"; ResultSet rso = statement.executeQuery(o_query); if (!rso.next()) { i++; String o_alter = "ALTER TABLE " + prefix + "doors ADD " + o; statement.executeUpdate(o_alter); } } for (String g : gravityupdates) { String[] gsplit = g.split(" "); String g_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "gravity_well' AND sql LIKE '%" + gsplit[0] + "%'"; ResultSet rsg = statement.executeQuery(g_query); if (!rsg.next()) { i++; String g_alter = "ALTER TABLE " + prefix + "gravity_well ADD " + g; statement.executeUpdate(g_alter); } } for (String o : portalsupdates) { String[] osplit = o.split(" "); String ocheck = osplit[0] + " " + osplit[1].substring(0, 3); String o_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "portals' AND sql LIKE '%" + ocheck + "%'"; ResultSet rso = statement.executeQuery(o_query); if (!rso.next()) { i++; String o_alter = "ALTER TABLE " + prefix + "portals ADD " + o; statement.executeUpdate(o_alter); } } for (String p : prefsupdates) { String[] psplit = p.split(" "); String pcheck = psplit[0] + " " + psplit[1].substring(0, 3); String p_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "player_prefs' AND sql LIKE '%" + pcheck + "%'"; ResultSet rsp = statement.executeQuery(p_query); if (!rsp.next()) { i++; String p_alter = "ALTER TABLE " + prefix + "player_prefs ADD " + p; statement.executeUpdate(p_alter); } } String lamp_query1 = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "player_prefs' AND sql LIKE '%lamp TEXT%'"; boolean addlamp = false; ResultSet lamp1 = statement.executeQuery(lamp_query1); if (!lamp1.next()) { addlamp = true; // check again String lamp_query2 = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "player_prefs' AND sql LIKE '%lamp INTEGER%'"; ResultSet lamp2 = statement.executeQuery(lamp_query2); if (lamp2.next()) { addlamp = false; } } if (addlamp) { i++; String lamp_alter = "ALTER TABLE " + prefix + "player_prefs ADD lamp TEXT DEFAULT ''"; statement.executeUpdate(lamp_alter); } for (String t : tardisupdates) { String[] tsplit = t.split(" "); String t_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "tardis' AND sql LIKE '%" + tsplit[0] + "%'"; ResultSet rst = statement.executeQuery(t_query); if (!rst.next()) { i++; String t_alter = "ALTER TABLE " + prefix + "tardis ADD " + t; statement.executeUpdate(t_alter); } } for (String v : inventoryupdates) { String[] vsplit = v.split(" "); String v_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "inventories' AND sql LIKE '%" + vsplit[0] + "%'"; ResultSet rsv = statement.executeQuery(v_query); if (!rsv.next()) { i++; String v_alter = "ALTER TABLE " + prefix + "inventories ADD " + v; statement.executeUpdate(v_alter); } } // add biome to current location String bio_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "current' AND sql LIKE '%biome%'"; ResultSet rsbio = statement.executeQuery(bio_query); if (!rsbio.next()) { i++; String bio_alter = "ALTER TABLE " + prefix + "current ADD biome TEXT DEFAULT ''"; statement.executeUpdate(bio_alter); } // add tardis_id to dispersed String dispersed_query = "SELECT sql FROM sqlite_master WHERE tbl_name = '" + prefix + "dispersed' AND sql LIKE '%tardis_id%'"; ResultSet rsdispersed = statement.executeQuery(dispersed_query); if (!rsdispersed.next()) { i++; String dispersed_alter = "ALTER TABLE " + prefix + "dispersed ADD tardis_id INTEGER"; statement.executeUpdate(dispersed_alter); // update tardis_id column for existing records new TARDISDispersalUpdater(plugin).updateTardis_ids(); } // transfer `void` data to `thevoid`, then remove `void` table String voidQuery = "SELECT name FROM sqlite_master WHERE type='table' AND name='" + prefix + "void'"; ResultSet rsvoid = statement.executeQuery(voidQuery); if (rsvoid.next()) { String getVoid = "SELECT * FROM '" + prefix + "void'"; ResultSet rsv = statement.executeQuery(getVoid); while (rsv.next()) { String transfer = "INSERT OR IGNORE INTO " + prefix + "thevoid (tardis_id) VALUES (" + rsv.getInt("tardis_id") + ")"; statement.executeUpdate(transfer); } String delVoid = "DROP TABLE '" + prefix + "void'"; statement.executeUpdate(delVoid); } } catch (SQLException e) { plugin.debug("SQLite database add fields error: " + e.getMessage() + e.getErrorCode()); } if (i > 0) { plugin.getConsole().sendMessage(TARDIS.plugin.getPluginName() + "Added " + ChatColor.AQUA + i + ChatColor.RESET + " fields to the SQLite database!"); } } }