/*
* Copyright (c) 2016 OBiBa. All rights reserved.
*
* This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.obiba.runtime.upgrade.support;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.obiba.runtime.Version;
import org.obiba.runtime.upgrade.AbstractUpgradeStep;
import liquibase.change.AddNotNullConstraintChange;
import liquibase.change.Change;
import liquibase.change.DropColumnChange;
import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.database.sql.visitor.SqlVisitor;
import liquibase.database.structure.Column;
import liquibase.database.structure.DatabaseSnapshot;
import liquibase.exception.JDBCException;
public abstract class LiquiBaseUpgradeStep extends AbstractUpgradeStep {
//
// Instance Variables
//
private DataSource dataSource;
//
// AbstractUpgradeStep Methods
//
@Override
public void execute(Version currentVersion) {
applyChanges();
}
//
// Methods
//
/**
* Applies the schema changes specified by <code>getChanges()</code>.
*/
public void applyChanges() {
Database database = getDatabase();
try {
List<SqlVisitor> visitors = new ArrayList<SqlVisitor>();
for(Change change : getChanges()) {
change.executeStatements(database, visitors);
}
} catch(Exception ex) {
throw new RuntimeException("Could not apply change to the database", ex);
}
}
/**
* Creates a "change" consisting of the adding of not-null constraints for the specified table column.
*
* @param databaseSnapshot database snapshot
* @param table table
* @param column column
* @return not-null constraint change
*/
public AddNotNullConstraintChange createAddNotNullConstraintChange(DatabaseSnapshot databaseSnapshot, String table,
String column) {
AddNotNullConstraintChange change = new AddNotNullConstraintChange();
change.setTableName(table);
change.setColumnName(column);
// Set the column data type (required for MySQL and MSSQL).
Column columnMetadata = databaseSnapshot.getColumn(table, column);
String dataType = columnMetadata.getDataTypeString(databaseSnapshot.getDatabase());
change.setColumnDataType(dataType);
return change;
}
/**
* Creates a "change" consisting of dropping the specified table column.
*
* @param databaseSnapshot database snapshot
* @param table table
* @param column column
* @return drop column change
*/
public DropColumnChange createDropColumnChange(DatabaseSnapshot databaseSnapshot, String table, String column) {
DropColumnChange change = new DropColumnChange();
change.setTableName(table);
change.setColumnName(column);
return change;
}
public Database getDatabase() {
// Get a connection to the dataSource.
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch(SQLException ex) {
throw new RuntimeException("Could not acquire a connection to the datasource", ex);
}
// Find an appropriate database instance for the connection.
Database database = null;
try {
DatabaseFactory databaseFactory = DatabaseFactory.getInstance();
database = databaseFactory.findCorrectDatabaseImplementation(connection);
} catch(JDBCException ex) {
throw new RuntimeException("Could not find database implemention", ex);
}
return database;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Returns the list of schema changes to be applied.
*
* @return schema changes to be applied
*/
protected abstract List<Change> getChanges();
}