Search in sources :

Example 1 with DbInitializationException

use of com.haulmont.cuba.core.sys.DbInitializationException in project cuba by cuba-platform.

the class DbUpdaterUtil method execute.

@SuppressWarnings("AccessStaticViaInstance")
public void execute(String[] args) {
    Options cliOptions = new Options();
    Option dbConnectionOption = OptionBuilder.withArgName("connectionString").hasArgs().withDescription("JDBC Database URL").isRequired().create("dbUrl");
    Option dbUserOption = OptionBuilder.withArgName("userName").hasArgs().withDescription("Database user").isRequired().create("dbUser");
    Option dbPasswordOption = OptionBuilder.withArgName("password").hasArgs().withDescription("Database password").isRequired().create("dbPassword");
    Option dbDriverClassOption = OptionBuilder.withArgName("driverClassName").hasArgs().withDescription("JDBC driver class name").create("dbDriver");
    Option dbDirOption = OptionBuilder.withArgName("filePath").hasArgs().withDescription("Database scripts directory").isRequired().create("scriptsDir");
    Option dbTypeOption = OptionBuilder.withArgName("dbType").hasArgs().withDescription("DBMS type: postgres|mssql|oracle|etc").isRequired().create("dbType");
    Option dbVersionOption = OptionBuilder.withArgName("dbVersion").hasArgs().withDescription("DBMS version: 2012|etc").create("dbVersion");
    Option dbExecuteGroovyOption = OptionBuilder.withArgName("executeGroovy").hasArgs().withDescription("Ignoring Groovy scripts").create("executeGroovy");
    Option showUpdatesOption = OptionBuilder.withDescription("Print update scripts").create("check");
    Option applyUpdatesOption = OptionBuilder.withDescription("Update database").create("update");
    Option createDbOption = OptionBuilder.withDescription("Create database").create("create");
    cliOptions.addOption("help", false, "Print help");
    cliOptions.addOption(dbConnectionOption);
    cliOptions.addOption(dbUserOption);
    cliOptions.addOption(dbPasswordOption);
    cliOptions.addOption(dbDirOption);
    cliOptions.addOption(dbTypeOption);
    cliOptions.addOption(dbDriverClassOption);
    cliOptions.addOption(dbVersionOption);
    cliOptions.addOption(dbExecuteGroovyOption);
    cliOptions.addOption(showUpdatesOption);
    cliOptions.addOption(applyUpdatesOption);
    cliOptions.addOption(createDbOption);
    CommandLineParser parser = new PosixParser();
    HelpFormatter formatter = new HelpFormatter();
    CommandLine cmd;
    try {
        cmd = parser.parse(cliOptions, args);
    } catch (ParseException exp) {
        log.error("Incorrect arguments: " + exp.getMessage());
        formatter.printHelp("dbupdate", cliOptions);
        return;
    }
    if (cmd.hasOption("help") || (!cmd.hasOption(showUpdatesOption.getOpt())) && !cmd.hasOption(applyUpdatesOption.getOpt()) && !cmd.hasOption(createDbOption.getOpt()))
        formatter.printHelp("dbupdate", cliOptions);
    else {
        this.dbScriptsDirectory = cmd.getOptionValue(dbDirOption.getOpt());
        File directory = new File(dbScriptsDirectory);
        if (!directory.exists()) {
            log.error("Not found db update directory");
            return;
        }
        dbmsType = cmd.getOptionValue(dbTypeOption.getOpt());
        dbmsVersion = StringUtils.trimToEmpty(cmd.getOptionValue(dbVersionOption.getOpt()));
        AppContext.Internals.setAppComponents(new AppComponents("core"));
        AppContext.setProperty("cuba.dbmsType", dbmsType);
        AppContext.setProperty("cuba.dbmsVersion", dbmsVersion);
        String dbDriver;
        if (!cmd.hasOption(dbDriverClassOption.getOpt())) {
            switch(dbmsType) {
                case "postgres":
                    dbDriver = "org.postgresql.Driver";
                    break;
                case "mssql":
                    if (MS_SQL_2005.equals(dbmsVersion)) {
                        dbDriver = "net.sourceforge.jtds.jdbc.Driver";
                    } else {
                        dbDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
                    }
                    break;
                case "oracle":
                    dbDriver = "oracle.jdbc.OracleDriver";
                    break;
                case "mysql":
                    dbDriver = "com.mysql.jdbc.Driver";
                    break;
                default:
                    log.error("Unable to determine driver class name by DBMS type. Please provide driverClassName option");
                    return;
            }
        } else {
            dbDriver = cmd.getOptionValue(dbDriverClassOption.getOpt());
        }
        try {
            Class.forName(dbDriver);
        } catch (ClassNotFoundException e) {
            log.error("Unable to load driver class " + dbDriver);
            return;
        }
        String connectionStringParam = cmd.getOptionValue(dbConnectionOption.getOpt());
        try {
            this.dataSource = new SingleConnectionDataSource(connectionStringParam, cmd.getOptionValue(dbUserOption.getOpt()), cmd.getOptionValue(dbPasswordOption.getOpt()));
        } catch (SQLException e) {
            log.error("Unable to connect to db: " + connectionStringParam);
            return;
        }
        if (cmd.hasOption(createDbOption.getOpt())) {
            // create database from init scripts
            StringBuilder availableScripts = new StringBuilder();
            for (ScriptResource initScript : getInitScripts()) {
                availableScripts.append("\t").append(getScriptName(initScript)).append("\n");
            }
            log.info("Available create scripts: \n" + availableScripts);
            log.info(String.format("Do you want to create database %s ? [y/n]", connectionStringParam));
            Scanner scanner = new Scanner(new InputStreamReader(System.in, StandardCharsets.UTF_8));
            if ("y".equals(scanner.next())) {
                doInit();
            }
        } else {
            boolean updatesAvailable = false;
            try {
                List<String> scripts;
                executeGroovy = !(cmd.hasOption(dbExecuteGroovyOption.getOpt()) && cmd.getOptionValue(dbExecuteGroovyOption.getOpt()).equals("false"));
                scripts = findUpdateDatabaseScripts();
                if (!scripts.isEmpty()) {
                    StringBuilder availableScripts = new StringBuilder();
                    for (String script : scripts) {
                        availableScripts.append("\t").append(script).append("\n");
                    }
                    log.info("Available updates:\n" + availableScripts);
                    updatesAvailable = true;
                } else
                    log.info("No available updates found for database");
            } catch (DbInitializationException e) {
                log.warn("Database not initialized");
                return;
            }
            if (updatesAvailable && cmd.hasOption(applyUpdatesOption.getOpt())) {
                log.info(String.format("Do you want to apply updates to %s ? [y/n]", connectionStringParam));
                Scanner scanner = new Scanner(new InputStreamReader(System.in, StandardCharsets.UTF_8));
                if ("y".equals(scanner.next())) {
                    doUpdate();
                }
            }
        }
    }
}
Also used : Scanner(java.util.Scanner) DbInitializationException(com.haulmont.cuba.core.sys.DbInitializationException) InputStreamReader(java.io.InputStreamReader) SQLException(java.sql.SQLException) AppComponents(com.haulmont.cuba.core.sys.AppComponents) File(java.io.File) ScriptResource(com.haulmont.cuba.core.sys.dbupdate.ScriptResource)

Example 2 with DbInitializationException

use of com.haulmont.cuba.core.sys.DbInitializationException in project cuba by cuba-platform.

the class PersistenceManager method findUpdateDatabaseScripts.

@Override
public String findUpdateDatabaseScripts() {
    try {
        List<String> list = AppBeans.getPrototype(DbUpdater.class, Stores.MAIN).findUpdateDatabaseScripts();
        if (!list.isEmpty()) {
            File dbDir = new File(serverConfig.getDbDir());
            String indent = "\t";
            TextStringBuilder sb = new TextStringBuilder();
            sb.append(dbDir.getPath().replace('\\', '/')).append("/").append("\n");
            for (String path : list) {
                sb.append(indent).append(path).append("\n");
            }
            return sb.toString();
        } else
            return "No updates available";
    } catch (DbInitializationException e) {
        return e.getMessage();
    } catch (Throwable e) {
        return ExceptionUtils.getStackTrace(e);
    }
}
Also used : DbInitializationException(com.haulmont.cuba.core.sys.DbInitializationException) DbUpdater(com.haulmont.cuba.core.sys.DbUpdater) File(java.io.File) TextStringBuilder(org.apache.commons.text.TextStringBuilder)

Example 3 with DbInitializationException

use of com.haulmont.cuba.core.sys.DbInitializationException in project cuba by cuba-platform.

the class DbUpdaterEngine method findUpdateDatabaseScripts.

@Override
public List<String> findUpdateDatabaseScripts() throws DbInitializationException {
    if (dbInitialized()) {
        if (!scriptsExists) {
            return Collections.emptyList();
        }
        if (!changelogTableExists) {
            throw new DbInitializationException("Unable to determine required updates because SYS_DB_CHANGELOG table doesn't exist");
        } else {
            List<String> list = new ArrayList<>();
            List<ScriptResource> files = getUpdateScripts();
            Set<String> scripts = getExecutedScripts();
            for (ScriptResource file : files) {
                String name = getScriptName(file);
                if (!containsIgnoringPrefix(scripts, name)) {
                    list.add(name);
                }
            }
            return list;
        }
    } else {
        throw new DbInitializationException("Unable to determine required updates");
    }
}
Also used : DbInitializationException(com.haulmont.cuba.core.sys.DbInitializationException) Stores.storeNameToString(com.haulmont.cuba.core.global.Stores.storeNameToString)

Example 4 with DbInitializationException

use of com.haulmont.cuba.core.sys.DbInitializationException in project cuba by cuba-platform.

the class DbUpdaterEngine method dbInitialized.

public boolean dbInitialized() throws DbInitializationException {
    log.trace("Checking if the data store [{}] is initialized", storeNameToString(storeName));
    DataSource dataSource = getDataSource();
    if (dataSource == null) {
        log.trace("Database pool isn't initialized for data store [{}], so data store is initialized", storeNameToString(storeName));
        return true;
    }
    List<ScriptResource> initScripts = getInitScripts();
    List<ScriptResource> updateScripts = getUpdateScripts();
    if (initScripts.isEmpty() && updateScripts.isEmpty()) {
        log.trace("Init/Update scripts folder is empty for data store [{}], so data store is initialized", storeNameToString(storeName));
        return true;
    }
    scriptsExists = true;
    try (Connection connection = dataSource.getConnection()) {
        DatabaseMetaData dbMetaData = connection.getMetaData();
        DbProperties dbProperties = new DbProperties(getConnectionUrl(connection));
        boolean isSchemaByUser = DbmsSpecificFactory.getDbmsFeatures().isSchemaByUser();
        boolean isRequiresCatalog = DbmsSpecificFactory.getDbmsFeatures().isRequiresDbCatalogName();
        String schemaName = isSchemaByUser ? dbMetaData.getUserName() : dbProperties.getCurrentSchemaProperty();
        String catalogName = isRequiresCatalog ? connection.getCatalog() : null;
        ResultSet tables = dbMetaData.getTables(catalogName, schemaName, "%", null);
        while (tables.next()) {
            String tableName = tables.getString("TABLE_NAME");
            if ("SYS_DB_CHANGELOG".equalsIgnoreCase(tableName)) {
                log.trace("Found SYS_DB_CHANGELOG table");
                changelogTableExists = true;
            }
        }
        return changelogTableExists;
    } catch (SQLException e) {
        throw new DbInitializationException(true, String.format("Error connecting to data store [%s]: %s", storeNameToString(storeName), e.getMessage()), e);
    }
}
Also used : DbInitializationException(com.haulmont.cuba.core.sys.DbInitializationException) Stores.storeNameToString(com.haulmont.cuba.core.global.Stores.storeNameToString) DataSource(javax.sql.DataSource)

Example 5 with DbInitializationException

use of com.haulmont.cuba.core.sys.DbInitializationException in project cuba by cuba-platform.

the class DbUpdateManager method checkDatabase.

protected void checkDatabase(String storeName) {
    DbUpdater dbUpdater = AppBeans.getPrototype(DbUpdater.NAME, storeName);
    try {
        boolean initialized = false;
        try {
            initialized = dbUpdater.dbInitialized();
        } catch (DbInitializationException e) {
            if (!Stores.isMain(storeName)) {
                return;
            }
        }
        if (!initialized) {
            throw new IllegalStateException(StringHelper.wrapLogMessage("ERROR: Data store " + (Stores.isMain(storeName) ? "" : "[" + storeNameToString(storeName) + "]") + "is not initialized. " + getLogString(storeName)));
        }
        List<String> scripts = dbUpdater.findUpdateDatabaseScripts();
        if (!scripts.isEmpty()) {
            log.warn(StringHelper.wrapLogMessage("WARNING: The application contains unapplied update scripts for data store" + (Stores.isMain(storeName) ? "" : " [" + storeNameToString(storeName) + "]") + ":\n\n" + Joiner.on('\n').join(scripts) + "\n\n" + getLogString(storeName)));
        }
    } catch (DbInitializationException e) {
        throw new RuntimeException(StringHelper.wrapLogMessage("ERROR: Cannot check data store [" + storeNameToString(storeName) + "]. See the stacktrace below for details."), e);
    }
}
Also used : DbInitializationException(com.haulmont.cuba.core.sys.DbInitializationException) DbUpdater(com.haulmont.cuba.core.sys.DbUpdater) Stores.storeNameToString(com.haulmont.cuba.core.global.Stores.storeNameToString)

Aggregations

DbInitializationException (com.haulmont.cuba.core.sys.DbInitializationException)5 Stores.storeNameToString (com.haulmont.cuba.core.global.Stores.storeNameToString)3 DbUpdater (com.haulmont.cuba.core.sys.DbUpdater)2 File (java.io.File)2 AppComponents (com.haulmont.cuba.core.sys.AppComponents)1 ScriptResource (com.haulmont.cuba.core.sys.dbupdate.ScriptResource)1 InputStreamReader (java.io.InputStreamReader)1 SQLException (java.sql.SQLException)1 Scanner (java.util.Scanner)1 DataSource (javax.sql.DataSource)1 TextStringBuilder (org.apache.commons.text.TextStringBuilder)1