public static synchronized boolean applyScript( boolean runScript, String moduleKey, VirtualFile evolutionsDirectory) { try { Connection connection = EvolutionQuery.getNewConnection(Evolutions.autoCommit()); int applying = -1; try { for (Evolution evolution : getEvolutionScript(moduleKey, evolutionsDirectory)) { applying = evolution.revision; EvolutionQuery.apply(connection, runScript, evolution, moduleKey); } return true; } catch (Exception e) { String message = e.getMessage(); if (e instanceof SQLException) { SQLException ex = (SQLException) e; message += " [ERROR:" + ex.getErrorCode() + ", SQLSTATE:" + ex.getSQLState() + "]"; } EvolutionQuery.setProblem(connection, applying, moduleKey, message); EvolutionQuery.closeConnection(connection); Logger.error(e, "Can't apply evolution"); return false; } } catch (Exception e) { throw new UnexpectedException(e); } }
public static synchronized Stack<Evolution> listDatabaseEvolutions(String moduleKey) { Stack<Evolution> evolutions = new Stack<Evolution>(); evolutions.add(new Evolution("", 0, "", "", false)); Connection connection = null; try { connection = EvolutionQuery.getNewConnection(); String tableName = "play_evolutions"; boolean tableExists = true; ResultSet rs = connection.getMetaData().getTables(null, null, tableName, null); if (!rs.next()) { // Table in lowercase does not exist // oracle gives table names in upper case tableName = tableName.toUpperCase(); Logger.trace("Checking " + tableName); rs.close(); rs = connection.getMetaData().getTables(null, null, tableName, null); // Does it exist? if (!rs.next()) { // did not find it in uppercase either tableExists = false; } } // Do we have a if (tableExists) { checkAndUpdateEvolutionsForMultiModuleSupport(connection); ResultSet databaseEvolutions = EvolutionQuery.getEvolutions(connection, moduleKey); while (databaseEvolutions.next()) { Evolution evolution = new Evolution( moduleKey, databaseEvolutions.getInt(1), databaseEvolutions.getString(3), databaseEvolutions.getString(4), false); evolutions.add(evolution); } } else { EvolutionQuery.createTable(); } } catch (SQLException e) { Logger.error(e, "SQL error while checking play evolutions"); } finally { EvolutionQuery.closeConnection(connection); } Collections.sort(evolutions); return evolutions; }
public static synchronized void resolve(String moduleKey, int revision) { try { EvolutionQuery.resolve(revision, moduleKey); } catch (Exception e) { throw new UnexpectedException(e); } }
public static synchronized void resolve(int revision) { try { EvolutionQuery.resolve(revision, Play.configuration.getProperty("application.name")); } catch (Exception e) { throw new UnexpectedException(e); } }
public static synchronized void checkEvolutionsState() { for (Entry<String, VirtualFile> moduleRoot : modulesWithEvolutions.entrySet()) { if (EvolutionQuery.getDatasource() != null) { List<Evolution> evolutionScript = getEvolutionScript(moduleRoot.getKey(), moduleRoot.getValue()); Connection connection = null; try { connection = EvolutionQuery.getNewConnection(); ResultSet rs = EvolutionQuery.getEvolutionsToApply(connection, moduleRoot.getKey()); if (rs.next()) { int revision = rs.getInt("id"); String state = rs.getString("state"); String hash = rs.getString("hash").substring(0, 7); String script = ""; if (state.equals("applying_up")) { script = rs.getString("apply_script"); } else { script = rs.getString("revert_script"); } script = "# --- Rev:" + revision + "," + (state.equals("applying_up") ? "Ups" : "Downs") + " - " + hash + "\n\n" + script; String error = rs.getString("last_problem"); throw new InconsistentDatabase(script, error, revision, moduleRoot.getKey()); } } catch (SQLException e) { throw new UnexpectedException(e); } finally { EvolutionQuery.closeConnection(connection); } if (!evolutionScript.isEmpty()) { throw new InvalidDatabaseRevision(toHumanReadableScript(evolutionScript)); } } } }
private static void checkAndUpdateEvolutionsForMultiModuleSupport(Connection connection) throws SQLException { ResultSet rs = connection.getMetaData().getColumns(null, null, "play_evolutions", "module_key"); if (!rs.next()) { System.out.println( "!!! - Updating the play_evolutions table to cope with multiple modules - !!!"); EvolutionQuery.alterForModuleSupport(connection); } }
public static void main(String[] args) throws SQLException { /** Start the DB plugin * */ Play.id = System.getProperty("play.id"); Play.applicationPath = new File(System.getProperty("application.path")); Play.guessFrameworkPath(); Play.readConfiguration(); Play.javaPath = new ArrayList<VirtualFile>(); Play.classes = new ApplicationClasses(); Play.classloader = new ApplicationClassloader(); Play.templatesPath = new ArrayList<VirtualFile>(); Play.modulesRoutes = new HashMap<String, VirtualFile>(); Play.loadModules(); if (System.getProperty("modules") != null) { populateModulesWithSpecificModules(); } else { populateModulesWithEvolutions(); } if (modulesWithEvolutions.isEmpty()) { System.out.println("~ Nothing has evolutions, go away and think again."); return; } Logger.init(); Logger.setUp("ERROR"); new DBPlugin().onApplicationStart(); /** Connected * */ System.out.println( "~ Connected to " + EvolutionQuery.getDatasource().getConnection().getMetaData().getURL()); for (Entry<String, VirtualFile> moduleRoot : modulesWithEvolutions.entrySet()) { /** Sumary * */ Evolution database = listDatabaseEvolutions(moduleRoot.getKey()).peek(); Evolution application = listApplicationEvolutions(moduleRoot.getKey(), moduleRoot.getValue()).peek(); if ("resolve".equals(System.getProperty("mode"))) { try { checkEvolutionsState(); System.out.println("~"); System.out.println("~ Nothing to resolve for " + moduleRoot.getKey() + "..."); System.out.println("~"); return; } catch (InconsistentDatabase e) { resolve(moduleRoot.getKey(), e.getRevision()); System.out.println("~"); System.out.println( "~ Revision " + e.getRevision() + " for " + moduleRoot.getKey() + " has been resolved;"); System.out.println("~"); } catch (InvalidDatabaseRevision e) { // see later } } /** Check inconsistency * */ try { checkEvolutionsState(); } catch (InconsistentDatabase e) { System.out.println("~"); System.out.println("~ Your database is in an inconsistent state!"); System.out.println("~"); System.out.println("~ While applying this script part:"); System.out.println(""); System.out.println(e.getEvolutionScript()); System.out.println(""); System.out.println("~ The following error occured:"); System.out.println(""); System.out.println(e.getError()); System.out.println(""); System.out.println( "~ Please correct it manually, and mark it resolved by running `play evolutions:resolve`"); System.out.println("~"); return; } catch (InvalidDatabaseRevision e) { // see later } System.out.print( "~ '" + moduleRoot.getKey() + "' Application revision is " + application.revision + " [" + application.hash.substring(0, 7) + "]"); System.out.println( " and '" + moduleRoot.getKey() + "' Database revision is " + database.revision + " [" + database.hash.substring(0, 7) + "]"); System.out.println("~"); /** Evolution script * */ List<Evolution> evolutions = getEvolutionScript(moduleRoot.getKey(), moduleRoot.getValue()); if (evolutions.isEmpty()) { System.out.println("~ Your database is up to date for " + moduleRoot.getKey()); System.out.println("~"); } else { if ("apply".equals(System.getProperty("mode"))) { System.out.println("~ Applying evolutions for " + moduleRoot.getKey() + ":"); System.out.println(""); System.out.println( "# ------------------------------------------------------------------------------"); System.out.println(""); System.out.println(toHumanReadableScript(evolutions)); System.out.println(""); System.out.println( "# ------------------------------------------------------------------------------"); System.out.println(""); if (applyScript(true, moduleRoot.getKey(), moduleRoot.getValue())) { System.out.println("~"); System.out.println( "~ Evolutions script successfully applied for " + moduleRoot.getKey() + "!"); System.out.println("~"); } else { System.out.println("~"); System.out.println("~ Can't apply evolutions for " + moduleRoot.getKey() + "..."); System.out.println("~"); } } else if ("markApplied".equals(System.getProperty("mode"))) { if (applyScript(false, moduleRoot.getKey(), moduleRoot.getValue())) { System.out.println( "~ Evolutions script marked as applied for " + moduleRoot.getKey() + "!"); System.out.println("~"); } else { System.out.println("~ Can't apply evolutions for " + moduleRoot.getKey() + "..."); System.out.println("~"); } } else { System.out.println("~ Your database needs evolutions for " + moduleRoot.getKey() + "!"); System.out.println(""); System.out.println( "# ------------------------------------------------------------------------------"); System.out.println(""); System.out.println(toHumanReadableScript(evolutions)); System.out.println(""); System.out.println( "# ------------------------------------------------------------------------------"); System.out.println(""); System.out.println( "~ Run `play evolutions:apply` to automatically apply this script to the database"); System.out.println( "~ or apply it yourself and mark it done using `play evolutions:markApplied`"); System.out.println("~"); System.exit(-1); } } } }