com.healthcit.cacure.utils.DBSchemaUpdater.java Source code

Java tutorial

Introduction

Here is the source code for com.healthcit.cacure.utils.DBSchemaUpdater.java

Source

/*L
 * Copyright HealthCare IT, Inc.
 *
 * Distributed under the OSI-approved BSD 3-Clause License.
 * See http://ncip.github.com/edct-formbuilder/LICENSE.txt for details.
 */

package com.healthcit.cacure.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.postgresql.util.PSQLException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.DataSourceUtils;

public class DBSchemaUpdater implements InitializingBean {

    private static Logger log = Logger.getLogger(DBSchemaUpdater.class);
    private static final String PATH_TO_UPPERS_FOLDER = "/db";
    private DataSource dataSource;

    @Override
    public void afterPropertiesSet() throws Exception {
        Connection connection = DataSourceUtils.getConnection(dataSource);
        connection.setAutoCommit(false);
        try {
            Statement statement = connection.createStatement();
            try {
                long version = 0;
                try {
                    ResultSet rs = statement.executeQuery("select schema_version from sys_variables limit 1;");
                    try {
                        if (!rs.next()) {
                            throw new RuntimeException("Seems there is no any row in sys_variables table.");
                        }
                        version = rs.getLong(1);
                    } finally {
                        rs.close();
                    }
                } catch (PSQLException e) {
                    //               it's needed for executing more scripts successfully
                    connection.rollback();
                    log.info("Can't find sys_variables tables. Appling initial script.");
                    String initialScriptStatements = getStatementsFor(0);
                    if (initialScriptStatements == null) {
                        throw new RuntimeException("Can't find initial script.");
                    }
                    statement.executeUpdate(initialScriptStatements);
                    //there is already schema_version at 0
                    connection.commit();
                    log.info("Initial script succesfully executed.");
                }
                for (long v = version + 1;; v++) {
                    String statements = getStatementsFor(v);
                    if (statements == null) {
                        break;
                    }
                    log.info("Updating schema to " + v + " version...");
                    statement.execute(statements);
                    statement.executeUpdate("update sys_variables set schema_version = " + v + ";");
                    connection.commit();
                    log.info("OK");
                }
            } catch (BatchUpdateException e) {
                if (e.getNextException() != null) {
                    e.getNextException().printStackTrace();
                }
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
                connection.rollback();
            } finally {
                statement.close();
            }
        } finally {
            DataSourceUtils.releaseConnection(connection, dataSource);
        }
    }

    /**
     * Returns sql statements from upper file for passed version.
     * If correspondent upper file is not found it returns null;
     * @param version
     * @return
     * @throws IOException
     */
    private String getStatementsFor(final long version) throws IOException {
        InputStream resourceAsStream = this.getClass()
                .getResourceAsStream(PATH_TO_UPPERS_FOLDER + "/" + version + ".up.sql");
        if (resourceAsStream == null) {
            return null;
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(resourceAsStream));
        StringBuffer sb = new StringBuffer();
        try {
            String line;
            while ((line = br.readLine()) != null) {
                if (StringUtils.isNotBlank(line) && !line.trim().startsWith("--")) {
                    sb.append(line);
                    sb.append("\n");
                }
            }
        } finally {
            br.close();
        }
        return sb.toString();
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

}