/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* Copyright (c) 2013, MPL CodeInside http://codeinside.ru
*/
package ru.codeinside.gses.liquibase.impl;
import liquibase.exception.LiquibaseException;
import ru.codeinside.gses.liquibase.api.MigrationService;
import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.logging.Logger;
final public class MigrationServiceImpl implements MigrationService {
final Logger logger = Logger.getLogger(getClass().getName());
@Override
public void migrate(final String changeLog, final ClassLoader classLoader,
final String toVersion, final DataSource experimentalDs, final DataSource targetDs) {
final DbConfig experimentalConfig = new DbConfig(experimentalDs);
final DbConfig targetConfig = new DbConfig(targetDs);
try {
final Source source = Source.create(changeLog, classLoader);
Db.execute(experimentalConfig, new Query<Void>() {
public Void execute(final Db experimental) throws LiquibaseException {
Db.execute(targetConfig, new Query<Void>() {
public Void execute(Db targetDb) throws LiquibaseException {
targetDb.waitForLock();
try {
final String fromVersion = source.getVersion(targetDb, toVersion);
if (fromVersion != null) {
logger.fine("From version " + fromVersion);
experimental.createTo(source.getChanges(null, fromVersion));
} else {
experimental.dropAndLoad(null);
}
final File baseTmpDir = new File(System.getProperty("java.io.tmpdir"));
final File file = File.createTempFile("migration", ".diff", baseTmpDir);
final PrintStream printStream = new PrintStream(file, "UTF8");
try {
final String message = "Changes in changelog, that missed in version " + fromVersion;
if (!Assistance.isEquals(targetDb, experimental, message, printStream)) {
throw new IllegalStateException(
"Detected invalid version " + fromVersion +
" for " + changeLog +
", details in " + file);
}
} finally {
printStream.close();
}
file.delete();
logger.fine("To version " + toVersion);
targetDb.migrateTo(source.getChanges(fromVersion, toVersion));
return null;
} catch (IOException e) {
throw new LiquibaseException("io error", e);
} finally {
targetDb.releaseLock();
}
}
});
return null;
}
});
} catch (LiquibaseException e) {
throw new IllegalStateException(e);
}
}
}