
org.nuiton.topia.service.migration.TopiaMigrationServiceExecutor Maven / Gradle / Ivy
Show all versions of topia-extension-migration Show documentation
package org.nuiton.topia.service.migration;
/*-
* #%L
* ObServe Toolkit :: ToPIA Migration service
* %%
* Copyright (C) 2017 - 2018 IRD, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* .
* #L%
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.persistence.TopiaException;
import org.nuiton.topia.persistence.internal.support.H2TopiaSqlDllSupportImpl;
import org.nuiton.topia.persistence.internal.support.PGTopiaSqlDllSupportImpl;
import org.nuiton.topia.persistence.support.TopiaSqlDllSupport;
import org.nuiton.topia.persistence.support.TopiaSqlDllSupportProvider;
import org.nuiton.topia.persistence.support.TopiaSqlQuery;
import org.nuiton.topia.persistence.support.TopiaSqlSupport;
import org.nuiton.topia.persistence.support.TopiaSqlWork;
import org.nuiton.topia.persistence.script.SqlScriptReader;
import org.nuiton.topia.persistence.script.SqlScriptWriter;
import org.nuiton.topia.service.migration.resources.MigrationVersionResourceExecutor;
import org.nuiton.version.Version;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
/**
* Default implementation of {@link MigrationVersionResourceExecutor} with extra methods used by {@link TopiaMigrationService#migrateVersion(TopiaMigrationServiceContext, Version)}.
*
* This executor is pass to each version to migrate.
*
* Created by tchemit on 06/05/2018.
*
* @author Tony Chemit - [email protected]
*/
@SuppressWarnings("WeakerAccess")
public class TopiaMigrationServiceExecutor implements MigrationVersionResourceExecutor {
private static final Log log = LogFactory.getLog(TopiaMigrationServiceExecutor.class);
protected final Version version;
protected final TopiaSqlSupport sqlSupport;
protected final TopiaSqlDllSupport sqlDllSupport;
protected final String classifier;
protected final Path scriptForVersion;
protected final SqlScriptWriter writer;
protected final String logPrefix;
protected TopiaMigrationServiceExecutor(Version version, TopiaSqlSupport sqlSupport, String classifier, Path scriptsPath) {
this.version = Objects.requireNonNull(version);
this.classifier = Objects.requireNonNull(classifier);
this.sqlSupport = Objects.requireNonNull(sqlSupport);
this.sqlDllSupport = TopiaSqlDllSupportProvider.get().get(classifier).orElseThrow(() -> new IllegalStateException("No TopiaSqlDllSupport for classifier: " + classifier));
this.scriptForVersion = Objects.requireNonNull(scriptsPath).resolve(String.format("migration-version-%s.sql", version));
this.writer = SqlScriptWriter.of(scriptForVersion);
this.logPrefix = String.format("[ Version %s ] ", version);
log.info(logPrefix + String.format("Will produce sql script at: %s", scriptForVersion));
}
public String getLogPrefix() {
return logPrefix;
}
public Path getScriptForVersion() {
return scriptForVersion;
}
@Override
public void writeSql(String sql) {
writer.writeSql(sql);
}
@Override
public void addScript(String rank, String prefix) {
loadScript(version, rank, prefix);
}
@Override
public O findSingleResult(TopiaSqlQuery query) {
return sqlSupport.findSingleResult(query);
}
@Override
public List findMultipleResult(TopiaSqlQuery query) {
return sqlSupport.findMultipleResult(query);
}
@Override
public Set findMultipleResultAstSet(TopiaSqlQuery query) {
return new LinkedHashSet<>(findMultipleResult(query));
}
@Override
public void doSqlWork(TopiaSqlWork sqlWork) {
sqlSupport.doSqlWork(sqlWork);
}
@Override
public Set getTopiaIds(final String tableName) {
return TopiaSqlDllSupport.selectAllAsSet(sqlSupport, String.format("SELECT topiaId FROM %s;", tableName));
}
@Override
public String getUniqueConstraintName(String tableName, String columnName) {
return sqlDllSupport.getUniqueConstraintName(sqlSupport, tableName, columnName);
}
@Override
public String getFirstTableUniqueConstraintName(String tableName) {
return sqlDllSupport.getFirstTableUniqueConstraintName(sqlSupport, tableName);
}
@Override
public Set getConstraintNames(String tableName) {
return sqlDllSupport.getConstraintNames(sqlSupport, tableName);
}
@Override
public Set getForeignKeyConstraintNames(String tableName) {
return sqlDllSupport.getForeignKeyConstraintNames(sqlSupport, tableName);
}
@Override
public String getForeignKeyConstraintName(String schemaName, String tableName, String columnName, boolean mustExists) {
return sqlDllSupport.getForeignKeyConstraintName(sqlSupport, schemaName, tableName, columnName, mustExists);
}
@Override
public Set getUniqueKeyConstraintNames(String tableName) {
return sqlDllSupport.getUniqueKeyConstraintNames(sqlSupport, tableName);
}
@Override
public void removeFK(String tableName) {
sqlDllSupport.removeFK(sqlSupport, tableName).forEach(this::writeSql);
}
@Override
public void removeFK(String schemaName, String tableName, String columnName) {
String sql = sqlDllSupport.removeFK(sqlSupport, schemaName, tableName, columnName);
writeSql(sql);
}
@Override
public void removeFKIfExists(String schemaName, String tableName, String columnName) {
sqlDllSupport.removeFKIfExists(sqlSupport, schemaName, tableName, columnName).ifPresent(this::writeSql);
}
@Override
public void removeUK(String tableName) {
sqlDllSupport.removeUK(sqlSupport, tableName).forEach(this::writeSql);
}
@Override
public void executeForPG(Consumer consumer) {
if (isPG()) {
consumer.accept(this);
}
}
@Override
public void executeForH2(Consumer consumer) {
if (isH2()) {
consumer.accept(this);
}
}
public long flush() throws IOException {
writer.flush();
return writer.getStatementCount();
}
@Override
public void close() throws IOException {
writer.close();
}
protected void loadScript(Version version, String rank, String prefix) {
URL scriptLocation = getScriptLocation(version, rank, prefix, classifier);
log.info(String.format("%sLoad migration script: %s", logPrefix, scriptLocation));
try (SqlScriptReader scriptReader = SqlScriptReader.of(scriptLocation)) {
for (String statement : scriptReader) {
writer.writeSql(statement);
}
} catch (IOException e) {
throw new TopiaException("Could not load migration script: " + scriptLocation, e);
}
}
protected URL getScriptLocation(Version version, String rank, String prefix, String classifier) {
String scriptPath = getScriptPath(version, rank, prefix, "common");
URL scriptLocation = getClass().getResource(scriptPath);
if (scriptLocation == null) {
scriptPath = getScriptPath(version, rank, prefix, classifier);
scriptLocation = getClass().getResource(scriptPath);
}
Objects.requireNonNull(scriptLocation, "Can't find script " + scriptPath + ", nor his common version.");
return scriptLocation;
}
protected String getScriptPath(Version version, String rank, String prefix, String scriptSuffix) {
String migrationScript = prefix + "-" + scriptSuffix + ".sql";
String scriptPath = "/db/migration/";
if (getClass().getName().contains(".old.")) {
scriptPath += "old/" + this.version + "/V" + version.getValidName() + "_" + rank + "_" + migrationScript;
} else {
scriptPath += this.version + "/" + rank + "_" + migrationScript;
}
return scriptPath;
}
protected boolean isH2() {
return H2TopiaSqlDllSupportImpl.CLASSIFIER.equals(classifier);
}
protected boolean isPG() {
return PGTopiaSqlDllSupportImpl.CLASSIFIER.equals(classifier);
}
}