From 323aa54079308f471ea72b5b7feb587bafb053ec Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Wed, 9 Dec 2015 15:27:52 +0100 Subject: [PATCH] Added forced upgrade --- Zutil.jar | Bin 1182524 -> 1183630 bytes src/zutil/db/DBUpgradeHandler.java | 120 ++++++++++++++++++----------- 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/Zutil.jar b/Zutil.jar index cc99db7f6ed49129d904271f2c2e22e9b3bd26db..7457c19d13d59b9712d6fa246505a7f185c9c878 100755 GIT binary patch delta 25640 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

Qx4KBbGKUd8G0NHlqMonqlaQDZDb%RuZnva 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 tableRenameMap; @@ -57,7 +58,7 @@ public class DBUpgradeHandler { * @param enable */ public void forceDBUpgrade(boolean enable){ - this.forceUpgrade = enable; + this.forceUpgradeEnabled = enable; } public void upgrade() throws SQLException { @@ -84,29 +85,28 @@ public class DBUpgradeHandler { private void upgradeRenameTables() throws SQLException { if(tableRenameMap.size() > 0) { - List targetTables = target.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); + List targetTables = getTableList(target); for (String oldTableName : tableRenameMap.keySet()) { if (targetTables.contains(oldTableName)) { String newTableName = tableRenameMap.get(oldTableName); logger.fine("Renaming table from: " + oldTableName + ", to: " + newTableName); - target.exec("ALTER TABLE "+oldTableName+" RENAME TO "+newTableName); + target.exec(String.format( + "ALTER TABLE %s RENAME TO %s", oldTableName, newTableName)); } } } } private void upgradeCreateTables() throws SQLException { - List refTables = reference.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); - List targetTables = target.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); + List refTables = getTableList(reference); + List targetTables = getTableList(target); for(String table : refTables){ if(!targetTables.contains(table)){ logger.fine("Creating new table: "+ table); // Get reference create sql - PreparedStatement stmt = reference.getPreparedStatement("SELECT sql FROM sqlite_master WHERE name == ?"); - stmt.setString(1, table); - String sql = DBConnection.exec(stmt, new SimpleSQLResult()); + String sql = getTableSql(reference, table); // Execute sql on target target.exec(sql); } @@ -114,8 +114,8 @@ public class DBUpgradeHandler { } private void upgradeDropTables() throws SQLException { - List refTables = reference.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); - List targetTables = target.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); + List refTables = getTableList(reference); + List targetTables = getTableList(target); for(String table : targetTables){ if(!refTables.contains(table)){ @@ -126,55 +126,87 @@ public class DBUpgradeHandler { } private void upgradeAlterTables() throws SQLException { - List refTables = reference.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); - List targetTables = target.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); + List refTables = getTableList(reference); + List targetTables = getTableList(target); for(String table : targetTables){ if(refTables.contains(table)){ // Get reference structure - List refStruct = reference.exec("PRAGMA table_info("+table+")", - new TableStructureResultHandler()); + List refStruct = getColumnList(reference, table); // Get target structure - List targetStruct = target.exec("PRAGMA table_info("+table+")", - new TableStructureResultHandler()); + List targetStruct = getColumnList(target, table); - // Check existing columns - for(DBColumn column : refStruct) { - if(!targetStruct.contains(column)) { - logger.fine("Adding column '" + column.name + "' to table: " + table); - target.exec("ALTER TABLE "+table+" ADD COLUMN" - + " " + column.name // Column name - + " " + column.type // Column type - + (column.defaultValue != null ? " DEFAULT '"+column.defaultValue+"'" : "") - + (column.notNull ? " NOT NULL" : "") - + (column.publicKey ? " PRIMARY KEY" : "")); - } - } // Check unnecessary columns + boolean forcedUpgrade = false; for(DBColumn column : targetStruct) { if(!refStruct.contains(column)) { - if(forceUpgrade){ - /* - - put in a list the existing columns List columns = DBUtils.GetColumns(db, TableName); - - backup table (ALTER table " + TableName + " RENAME TO 'temp_" + TableName) - - create new table (the newest table creation schema) - - get the intersection with the new columns, this time columns taken from the upgraded table (columns.retainAll(DBUtils.GetColumns(db, TableName));) - - restore data (String cols = StringUtils.join(columns, ","); - db.execSQL(String.format( - "INSERT INTO %s (%s) SELECT %s from temp_%s", - TableName, cols, cols, TableName)); - ) - - remove backup table (DROP table 'temp_" + TableName) - */ - } + if(forceUpgradeEnabled) + forcedUpgrade = true; else - logger.warning("Unable to drop column: '" + column.name + "' from table: "+ table +" (SQLite does not support dropping columns)"); + logger.warning("Unable to drop column: '" + column.name + "' from table: "+ table + +" (SQLite does not support dropping columns)"); + } + } + + // Do a forced upgrade where we create a new table and migrate the old data + if(forcedUpgrade){ + // Backup table + String backupTable = table+"_temp"; + logger.fine("Forced Upgrade: Backing up table: "+table+", to: "+backupTable); + target.exec(String.format("ALTER TABLE %s RENAME TO %s", table, backupTable)); + + // Creating new table + logger.fine("Forced Upgrade: Creating new table: "+table); + String sql = getTableSql(reference, table); + target.exec(sql); + + // Restoring data + logger.fine("Forced Upgrade: Restoring data for table: "+table); + String cols = StringUtils.join(refStruct, ","); + target.exec(String.format( + "INSERT INTO %s (%s) SELECT %s FROM %s", + table, cols, cols, backupTable)); + + // Remove backup table + logger.fine("Forced Upgrade: Removing backup table: "+backupTable); + target.exec("DROP TABLE " + backupTable); + } + // Do a + else{ + // Add new columns + for(DBColumn column : refStruct) { + if(!targetStruct.contains(column)) { + logger.fine("Adding column '" + column.name + "' to table: " + table); + target.exec( + String.format("ALTER TABLE %s ADD COLUMN %s %s %s%s%s", + table, + column.name, + column.type, + (column.defaultValue != null ? " DEFAULT '"+column.defaultValue+"'" : ""), + (column.notNull ? " NOT NULL" : ""), + (column.publicKey ? " PRIMARY KEY" : ""))); + } } } } } } + + private static List getTableList(DBConnection db) throws SQLException { + return db.exec("SELECT name FROM sqlite_master WHERE type='table';", new ListSQLResult()); + } + private static String getTableSql(DBConnection db, String table) throws SQLException { + PreparedStatement stmt = db.getPreparedStatement("SELECT sql FROM sqlite_master WHERE name == ?"); + stmt.setString(1, table); + return DBConnection.exec(stmt, new SimpleSQLResult()); + } + private static List getColumnList(DBConnection db, String table) throws SQLException { + return db.exec( + String.format("PRAGMA table_info(%s)", table), + new TableStructureResultHandler()); + } + private static class DBColumn{ String name; String type;