package mysqldbinit;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import util.ArgumentParametrParser;
/**
* Provide initialization aim project database. Create needed user and fill initial data.
*
* @author Artem Kozlov
*/
public class DataBaseInitializer {
public static final String[] ARGUMENT_KEYS = {"p", "prop", "dump", "?"};
private static final String CREATE_DB_QUERY = "CREATE DATABASE IF NOT EXISTS ";
private static final String CREATE_USER_QUERY_PART_1 = "GRANT ALL ON ";
private static final String CREATE_USER_QUERY_PART_2 = ".* TO ?@'localhost' IDENTIFIED BY ?";
private static final String DELETE_USER_QUERY = "DELETE FROM user WHERE user = ?";
private static final String FLUSH_PRIVILEGES = "FLUSH PRIVILEGES";
private String rootPassword;
private String dbHost;
private String dbPort;
private String dbName;
private String dbUsername;
private String dbUserPassword;
private Connection connection;
private Properties dbProperties = new Properties();
private String SQLDumpFilePath;
/**
*
* @param rootPassword root password for mysql database. This parametr is required.
* @param propertyFilePath path for custom property file. If null then default is used.
* @param sqlDumpFilePath path for custom sql database dump file. If null then default is used.
* @throws FileNotFoundException if some of passed file fas not found
* @throws SQLException somth wrong
* @throws IOException somth wrong
*/
public DataBaseInitializer( String rootPassword, String propertyFilePath, String sqlDumpFilePath ) throws FileNotFoundException, IOException, SQLException {
this.rootPassword = rootPassword;
if ( propertyFilePath == null ) {
loadDefaultResourceFiles();
} else {
loadCustomResources( propertyFilePath );
}
if ( sqlDumpFilePath != null ) {
SQLDumpFilePath = sqlDumpFilePath;
}
initializeProperties();
connection = DriverManager.getConnection( "jdbc:mysql://" + dbHost + ":" + dbPort + "/mysql", "root", rootPassword );
}
private void loadDefaultResourceFiles() throws IOException {
dbProperties.load( this.getClass().getResourceAsStream( "/resources/db-connection.properties" ) );
String filePathWithLeadDelimiter = this.getClass().getClassLoader().getResource( "resources/insurance_dump.sql" ).getPath();
SQLDumpFilePath = filePathWithLeadDelimiter.substring( 1 );
}
private void loadCustomResources( String propertyFilePath ) throws FileNotFoundException, IOException {
dbProperties.load( new FileReader( propertyFilePath ) );
}
private void initializeProperties() {
dbHost = dbProperties.getProperty( "db.host" );
dbPort = dbProperties.getProperty( "db.port" );
dbName = dbProperties.getProperty( "db.name" );
dbUsername = dbProperties.getProperty( "db.username" );
dbUserPassword = dbProperties.getProperty( "db.password" );
}
/**
* Create database, user. And fill database with initial data.
*
* @throws SQLException somth wrong
* @throws IOException somth wrong
* @throws InterruptedException somth wrong
*/
public void initializeDatabase() throws SQLException, IOException, InterruptedException {
createDB();
createUser();
restoreDbBackup();
}
/**
* Print program usage help to default output.
*/
public static void help() {
StringBuilder helpInformation = new StringBuilder();
helpInformation.append( "This program help to initialize database for aim project. \n\n" );
helpInformation.append( "mysql-db-init --" + ARGUMENT_KEYS[0] + "=<root password> [--" + ARGUMENT_KEYS[1] + "=<property file>] [--" + ARGUMENT_KEYS[1] + "=<dump file>]\n" );
helpInformation.append( ARGUMENT_KEYS[0] + " - is required.\n" );
System.out.print( helpInformation.toString() );
}
private void createDB() throws SQLException {
System.out.println( "Create database...\n" );
Statement createDbStatement = connection.createStatement();
createDbStatement.execute( CREATE_DB_QUERY + dbName );
}
private void createUser() throws SQLException {
System.out.println( "Create user...\n" );
PreparedStatement deleteUserStatement = connection.prepareStatement( DELETE_USER_QUERY );
deleteUserStatement.setString( 1, dbUsername );
deleteUserStatement.execute();
connection.createStatement().execute( FLUSH_PRIVILEGES );
PreparedStatement createUserStatement = connection.prepareStatement( CREATE_USER_QUERY_PART_1 +
dbName + CREATE_USER_QUERY_PART_2 );
createUserStatement.setString( 1, dbUsername );
createUserStatement.setString( 2, dbUserPassword );
createUserStatement.execute();
}
private void restoreDbBackup() throws IOException, SQLException, InterruptedException {
System.out.println( "Restor database backup...\n" );
String[] restoreCommand = new String[]{"mysql", "--user=root", "--password=" + rootPassword, dbName, "-e", "source " + SQLDumpFilePath};
Process restore = Runtime.getRuntime().exec( restoreCommand );
BufferedReader bufferedreader = new BufferedReader( new InputStreamReader( restore.getErrorStream() ) );
String line;
while ( ( line = bufferedreader.readLine() ) != null ) {
System.out.println( line );
}
}
public static void main( String[] args ) throws SQLException, FileNotFoundException, IOException, InterruptedException {
ArgumentParametrParser parser = new ArgumentParametrParser( args );
if ( args.length == 0 || parser.getValueByKey( ARGUMENT_KEYS[3] ) != null ) {
DataBaseInitializer.help();
return;
}
try {
DataBaseInitializer dbInit = new DataBaseInitializer( parser.getValueByKey( ARGUMENT_KEYS[0] ),
parser.getValueByKey( ARGUMENT_KEYS[1] ), parser.getValueByKey( ARGUMENT_KEYS[2] ) );
dbInit.initializeDatabase();
} catch ( FileNotFoundException ex ) {
System.out.println( "Selected file not found" + ex.getMessage() );
}
}
}