/* * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute * Copyright [2016-2017] EMBL-European Bioinformatics Institute * * 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. */ package org.ensembl.healthcheck.util; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; import java.io.*; import org.ensembl.healthcheck.ConfigurableTestRunner; import org.ensembl.healthcheck.Debug; import org.ensembl.healthcheck.configuration.ConfigureHealthcheckDatabase; /** * Class used to create an empty database with the healthcheck schema. * Location and name of the database to be created is passed as a * configuration object to the constructor. * */ public class CreateHealthCheckDB { static final Logger log = Logger.getLogger(CreateHealthCheckDB.class.getCanonicalName()); private final ConfigureHealthcheckDatabase conf; public CreateHealthCheckDB(ConfigureHealthcheckDatabase conf) { this.conf = conf; try { Class.forName(conf.getOutputDriver()); } catch (ClassNotFoundException e) { throw new RuntimeException("Could not load database driver: " + conf.getOutputDriver(), e); } } public String getDbUrl() { String dbUrl = "jdbc:mysql://" + conf.getOutputHost() + ":" + conf.getOutputPort() + "/"; return dbUrl; } public Set<String> getDatabasesOnServer() { Connection con = connectToDb(getDbUrl()); Set databasesOnServer = new HashSet<String>(); try { DatabaseMetaData metadata = con.getMetaData(); ResultSet catalogs = metadata.getCatalogs(); ResultSetMetaData rsmd = catalogs.getMetaData(); int cols = rsmd.getColumnCount(); while(catalogs.next()) { for (int i = 1; i <= cols; i++) { //System.out.println(catalogs.getString(i)); databasesOnServer.add(catalogs.getString(i)); } } } catch(SQLException e) { throw new RuntimeException("Could not get databases on Server! " + conf, e); } return databasesOnServer; } public Connection connectToDb(String dbUrl) { Connection con; try { con = DriverManager.getConnection( dbUrl, conf.getOutputUser(), conf.getOutputPassword() ); } catch (SQLException e) { throw new RuntimeException("Could not connect to database! " + conf.toString(), e); } return con; } /** * Checks, if a database exists with the name passed as an argument. * * @param nameOfDatabase * @return true if exists * */ public boolean databaseExists(String nameOfDatabase) { Set<String> databasesOnServer = getDatabasesOnServer(); return databasesOnServer.contains(nameOfDatabase); } public void dropDatabase(Connection con, String dbName) { try { Statement stmt = con.createStatement(); log.info("Dropping database " + dbName); stmt.execute("drop database if exists " + dbName + ";"); } catch (SQLException e) { throw new RuntimeException("Error dropping database " + dbName, e); } } public void run() { try { String dbUrl = getDbUrl(); log.info("Connecting to " + dbUrl + " as " + conf.getOutputUser()); Connection con = connectToDb(dbUrl); Statement stmt = con.createStatement(); dropDatabase(con, conf.getOutputDatabase()); //log.info("Dropping database " + conf.getOutputDatabase()); //stmt.execute("drop database if exists " + conf.getOutputDatabase() + ";"); log.info("Creating database " + conf.getOutputDatabase()); stmt.execute("create database " + conf.getOutputDatabase() + ";"); stmt.execute("use " + conf.getOutputDatabase() + ";"); log.info("Running " + conf.getOutputSchemafile() + " to create schema."); ScriptRunner s = new ScriptRunner(con, true, true); Reader r; try { // Try to find the file on the filesystem r = new FileReader(conf.getOutputSchemafile()); } catch (FileNotFoundException e) { try { // if that does not work, try to find the file on the classpath. r = new BufferedReader( new InputStreamReader( getClass().getClassLoader().getResourceAsStream( conf.getOutputSchemafile() ) ) ); } // If the file can't be found, the previous statement will throw // a NullPointerException. This is because getResourceAsStream // will return null and the InputStreamReader will then throw // the exception. // catch (NullPointerException n) { throw new FileNotFoundException("Couldn't find " + conf.getOutputSchemafile() + " from the current location and in the classpath which is:\n\n" + Debug.classpathToString() ); } } s.runScript(r); } catch (SQLException e) { throw new RuntimeException(e); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } }