Package org.olat.upgrade

Source Code of org.olat.upgrade.UpgradeManagerImpl

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/

package org.olat.upgrade;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.helpers.Settings;
import org.olat.core.logging.StartupException;

/**
*
* <P>
* Initial Date:  15.08.2005 <br>
* @author gnaegi
* @author guido
*/
public class UpgradeManagerImpl extends UpgradeManager {
 
  private String alterDbFilesDir;
  private Map<String, String> dbProperties;
 
 
  /**
   * used by spring
   */
  public UpgradeManagerImpl(String alterDbFilesDir, Map<String, String> dbProperties) {
    this.alterDbFilesDir = alterDbFilesDir;
    this.dbProperties = dbProperties;
  }
 
  /**
   * Execute the pre system init code of all upgrades in the order as they were configured
   * in the configuration file
   */
  public void doPreSystemInitUpgrades() {
    if (Settings.isJUnitTest()) return;
   
    Iterator<OLATUpgrade> iter = upgrades.iterator();
    OLATUpgrade upgrade = null;
    try {
      while (iter.hasNext()) {
        upgrade = iter.next();
        if (upgrade.doPreSystemInitUpgrade(this))
          log.audit("Successfully installed PreSystemInitUpgrade::" + upgrade.getVersion());
        //no DB Module is initialized in PreSystemInit State - no intermediate commit necessary.
      }
    } catch (Throwable e) {
      log.warn("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() {
    if (Settings.isJUnitTest()) return;
   
    Iterator<OLATUpgrade> iter = upgrades.iterator();
    OLATUpgrade upgrade = null;
    try {
      while (iter.hasNext()) {
        upgrade = iter.next();
        if (upgrade.doPostSystemInitUpgrade(this))
          log.audit("Successfully installed PostSystemInitUpgrade::" + upgrade.getVersion());
        //just in case a doPostSystemInitUpgrade did forget it.
        DBFactory.getInstance(false).commitAndCloseSession();
      }
    } catch (Throwable e) {
      DBFactory.getInstance(false).rollbackAndCloseSession();
      log.warn("Error upgrading PostSystemInitUpgrade::" + upgrade.getVersion(), e);
      abort(e);
    }
  }

  @Override
  public void runAlterDbStatements() {
   
    if (Settings.isJUnitTest()) return;
   
    String dialect = null;
    if (dbProperties.get("db.dbms").indexOf("mysql") != -1) dialect = "mysql";
    if (dbProperties.get("db.dbms").indexOf("postgresql") != -1) dialect = "postgresql";
   
    Connection con = null;
    Statement statement = null;
   
   
    try {
     
      log.audit("+--------------------------------------------------------------+");
      log.audit("+... DB upgrade: Starting alter DB statements ...+");
      log.audit("+--------------------------------------------------------------+");
     
     
      Class.forName(dbProperties.get("db.jdbc.driver"));
     
      String dbUrl = dbProperties.get("db.jdbc.url");
      String username = dbProperties.get("db.user");
      String password = dbProperties.get("db.pass");
     
      con = DriverManager.getConnection(dbUrl, username, password);
      if (con == null) {
        throw new StartupException("Could not connect to database. Make sure you have the right driver and your database is running. Try 'ant checkdb'", null);
      }
      //TODO:gs  check if I can alter a db statement and report an exception if not (not all users are allowed to do this)
      statement = con.createStatement();
      Iterator<OLATUpgrade> 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());
            log.audit("Successfully executed alter DB statements for Version::" + upgrade.getVersion());
          }
         
        }
      }
     
    } catch (ClassNotFoundException e) {
      log.warn("Could not load jdbc driver for database configured in olat_config.xml. Driver: "+ dbProperties.get("db.jdbc.driver"), e);
      throw new StartupException("Could not load jdbc driver for database configured in olat_config.xml. Driver: "+ dbProperties.get("db.jdbc.driver"), e);
     
    catch (SQLException e) {
      log.error("Could not upgrade your database!");
      throw new StartupException("Could not execute alter db statements.", e);
     
    } catch (Throwable e) {
      log.warn("Error executing alter DB statements::", e);
      abort(e);
     
    } finally {
      try {
        if (statement != null) {
          statement.close();
        }
      } catch (SQLException e2){
        log.warn("Could not close sql statement", e2);
        throw new StartupException("Could not close sql statements.", e2);
      } finally {
        try {
          if (con != null) {
            con.close();
          }
        } catch (SQLException e3){
          log.warn("Could not close db connection.", e3);
          throw new StartupException("Could not close db connection.", e3);
        }
      }
    }
   
  }

  /**
   * load file with alter statements and add to batch
   * @param statements
   * @param alterDbStatements
   */
  private void loadAndExecuteSqlStatements(Statement statement, String alterDbStatements, String dialect) {
    try {
      FileInputStream file = new FileInputStream(alterDbFilesDir+"/database/"+dialect+"/"+alterDbStatements);
      DataInputStream in = new DataInputStream(file);
      // this might be a good way to take care of the above
      //DataInputStream in =  new DataInputStream(this.getClass().getClassLoader().getResourceAsStream("database/"+dialect+"/"+alterDbStatements));
      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);
            }
            log.info("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"))) {
              log.error("Error while trying to upgrade the database with:("+sql+"). We will continue with upgrading but check the errors manually! Error says:", e);
            } else {
              log.error("Could not upgrade you database!");
              throw new StartupException("Could not add alter db statements to batch.", e);
            }
          }
        }
       
      in.close();
    } catch (FileNotFoundException e1) {
      log.error("could not find deleteDatabase.sql file!", e1);
      abort(e1);
    } catch (IOException e) {
      log.error("could not read deleteDatabase.sql file!", e);
      abort(e);
    }
  }

}
TOP

Related Classes of org.olat.upgrade.UpgradeManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.