/** * OLAT - Online Learning and Training
* http://www.olat.org *

* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. *

* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),
* University of Zurich, Switzerland. *

*/ package org.olat.upgrade; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.sql.SQLException; import java.sql.Statement; import java.util.Iterator; import java.util.StringTokenizer; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.logging.StartupException; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; /** * *

* Initial Date: 15.08.2005
* @author gnaegi * @author guido */ public class UpgradeManagerImpl extends UpgradeManager { /** * used by spring */ private UpgradeManagerImpl() { // } /** * Execute the pre system init code of all upgrades in the order as they were configured * in the configuration file */ public void doPreSystemInitUpgrades() { Iterator iter = upgrades.iterator(); OLATUpgrade upgrade = null; try { while (iter.hasNext()) { upgrade = iter.next(); if (upgrade.doPreSystemInitUpgrade(this)) logAudit("Successfully installed PreSystemInitUpgrade::" + upgrade.getVersion()); //no DB Module is initialized in PreSystemInit State - no intermediate commit necessary. } } catch (Throwable e) { logWarn("Error upgrading PreSystemInitUpgrade::" + upgrade.getVersion(), e); abort(e); } } /** * Execute the post system init code of all upgrades in the order as they were configured * in the configuration file */ public void doPostSystemInitUpgrades() { Iterator iter = upgrades.iterator(); OLATUpgrade upgrade = null; try { while (iter.hasNext()) { upgrade = iter.next(); if (upgrade.doPostSystemInitUpgrade(this)) logAudit("Successfully installed PostSystemInitUpgrade::" + upgrade.getVersion()); //just in case a doPostSystemInitUpgrade did forget it. DBFactory.getInstance(false).commitAndCloseSession(); } } catch (Throwable e) { DBFactory.getInstance(false).rollbackAndCloseSession(); logWarn("Error upgrading PostSystemInitUpgrade::" + upgrade.getVersion(), e); abort(e); } } /** * @see org.olat.upgrade.UpgradeManager#runAlterDbStatements() */ @Override public void runAlterDbStatements() { String dialect = ""; //only run upgrades on mysql or postgresql if (dataSource.getUrl().contains("mysql")) dialect = "mysql"; else if (dataSource.getUrl().contains("postgresql")) dialect = "postgresql"; else if (dataSource.getUrl().contains("hsqldb")) return; else return; Statement statement = null; try { logAudit("+--------------------------------------------------------------+"); logAudit("+... DB upgrade: Starting alter DB statements ...+"); logAudit("+ If it fails, do it manually by applying the content of the alter_X_to_Y.sql files.+"); logAudit("+ For each file you upgraded to add an entry like this to the [pathToOlat]/olatdata/system/installed_upgrades.xml: +"); logAudit("+ Database updatetrue+"); logAudit("+--------------------------------------------------------------+"); statement = dataSource.getConnection().createStatement(); Iterator iter = upgrades.iterator(); OLATUpgrade upgrade = null; while (iter.hasNext()) { upgrade = iter.next(); String alterDbStatementsFilename = upgrade.getAlterDbStatements(); if (alterDbStatementsFilename != null) { UpgradeHistoryData uhd = getUpgradesHistory(upgrade.getVersion()); if (uhd == null) { // has never been called, initialize uhd = new UpgradeHistoryData(); } if (!uhd.getBooleanDataValue(upgrade.TASK_DP_UPGRADE)) { loadAndExecuteSqlStatements(statement, alterDbStatementsFilename, dialect); uhd.setBooleanDataValue(upgrade.TASK_DP_UPGRADE, true); setUpgradesHistory(uhd, upgrade.getVersion()); logAudit("Successfully executed alter DB statements for Version::" + upgrade.getVersion()); } } } } catch (SQLException e) { logError("Could not upgrade your database! Please do it manually and add ", e); throw new StartupException("Could not execute alter db statements. Please do it manually.", e); } catch (Throwable e) { logWarn("Error executing alter DB statements::", e); abort(e); } finally { try { if (statement != null) { statement.close(); } } catch (SQLException e2){ logWarn("Could not close sql statement", e2); throw new StartupException("Could not close sql statements.", e2); } } } /** * load file with alter statements and add to batch * @param statements * @param alterDbStatements */ private void loadAndExecuteSqlStatements(Statement statement, String alterDbStatements, String dialect) { try { Resource setupDatabaseFile = new ClassPathResource("/resources/database/"+dialect+"/"+alterDbStatements); if (!setupDatabaseFile.exists()) { throw new StartupException("The database upgrade file was not found on the classpath: "+"/database/"+dialect+"/"+alterDbStatements); } InputStream in = setupDatabaseFile.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String strLine; StringBuilder sb = new StringBuilder(); //Read File Line By Line while ((strLine = br.readLine()) != null) { if (strLine.length() > 1 && (!strLine.startsWith("--") && !strLine.startsWith("#"))) { sb.append(strLine.trim()); } } StringTokenizer tokenizer = new StringTokenizer(sb.toString(), ";"); String sql = null; while (tokenizer.hasMoreTokens()) { try { sql = tokenizer.nextToken()+";".toLowerCase(); if (sql.startsWith("update") || sql.startsWith("delete") || sql.startsWith("alter") || sql.startsWith("insert")) { statement.executeUpdate(sql); } else { statement.execute(sql); } logInfo("Successfully upgraded database with the following sql: "+sql); } catch (SQLException e) { String msg = e.getMessage(); //stop upgrading database if already done if (e.getMessage()!= null && (msg.contains("already exists") || msg.contains("Duplicate") || msg.contains("Can't create table") || msg.contains("column/key exists"))) { logError("Error while trying to upgrade the database with:("+sql+"). We will continue with upgrading but check the errors manually! Error says:", e); } } catch (Exception e) { //handle non sql errors logError("Could not upgrade your database!",e); throw new StartupException("Could not add alter db statements to batch.", e); } } in.close(); } catch (FileNotFoundException e1) { logError("could not find deleteDatabase.sql file!", e1); abort(e1); } catch (IOException e) { logError("could not read deleteDatabase.sql file!", e); abort(e); } } }