com.gs.obevo.db.apps.reveng.RevengWriter Maven / Gradle / Ivy
/**
* Copyright 2017 Goldman Sachs.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.gs.obevo.db.apps.reveng;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Locale;
import com.gs.obevo.api.appdata.ObjectTypeAndNamePredicateBuilder;
import com.gs.obevo.api.platform.ChangeAuditDao;
import com.gs.obevo.api.platform.ChangeType;
import com.gs.obevo.api.platform.DeployExecutionDao;
import com.gs.obevo.api.platform.Platform;
import com.gs.obevo.db.impl.core.checksum.DbChecksumDao;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.collections.api.block.function.Function;
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.block.predicate.Predicate2;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.api.multimap.set.MutableSetMultimap;
import org.eclipse.collections.api.set.MutableSet;
import org.eclipse.collections.api.tuple.Pair;
import org.eclipse.collections.impl.block.factory.Functions;
import org.eclipse.collections.impl.block.factory.HashingStrategies;
import org.eclipse.collections.impl.block.factory.Predicates;
import org.eclipse.collections.impl.block.factory.StringFunctions;
import org.eclipse.collections.impl.factory.HashingStrategyMaps;
import org.eclipse.collections.impl.factory.Lists;
import org.eclipse.collections.impl.factory.Maps;
import org.eclipse.collections.impl.factory.Multimaps;
import org.eclipse.collections.impl.factory.Sets;
public class RevengWriter {
private final Configuration templateConfig;
public static Predicate2 defaultShouldOverwritePredicate() {
return new Predicate2() {
@Override
public boolean accept(File mainFile, RevEngDestination dbFileRep) {
return !mainFile.exists();
}
};
}
public static Predicate2 overwriteAllPredicate() {
return new Predicate2() {
@Override
public boolean accept(File mainFile, RevEngDestination dbFileRep) {
return true;
}
};
}
public static Predicate2 overwriteForSpecificTablesPredicate(
final MutableSet tableNames) {
return new Predicate2() {
@Override
public boolean accept(File mainFile, RevEngDestination dbFileRep) {
return !mainFile.exists()
|| tableNames.collect(StringFunctions.toLowerCase()).contains(
dbFileRep.getObjectName().toLowerCase());
}
};
}
@SuppressWarnings("WeakerAccess")
public RevengWriter() {
this.templateConfig = new Configuration();
// Where load the templates from:
templateConfig.setClassForTemplateLoading(RevengWriter.class, "/");
// Some other recommended settings:
templateConfig.setDefaultEncoding("UTF-8");
templateConfig.setLocale(Locale.US);
templateConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
}
public void write(Platform platform, MutableList allRevEngDestinations, File outputDir, boolean generateBaseline, Predicate2 shouldOverwritePredicate, String jdbcUrl, String dbHost, Integer dbPort, String dbServer, String excludeObjects) {
outputDir.mkdirs();
if (shouldOverwritePredicate == null) {
shouldOverwritePredicate = defaultShouldOverwritePredicate();
}
MutableSetMultimap coreTablesToExclude = Multimaps.mutable.set.empty();
coreTablesToExclude.putAll(ChangeType.TABLE_STR, Sets.immutable.with(
ChangeAuditDao.CHANGE_AUDIT_TABLE_NAME,
DbChecksumDao.SCHEMA_CHECKSUM_TABLE_NAME,
DeployExecutionDao.DEPLOY_EXECUTION_TABLE_NAME,
DeployExecutionDao.DEPLOY_EXECUTION_ATTRIBUTE_TABLE_NAME
).collect(platform.convertDbObjectName()));
ObjectTypeAndNamePredicateBuilder objectExclusionPredicateBuilder = platform.getObjectExclusionPredicateBuilder()
.add(coreTablesToExclude.toImmutable());
if (excludeObjects != null) {
objectExclusionPredicateBuilder = objectExclusionPredicateBuilder.add(ObjectTypeAndNamePredicateBuilder.parse(excludeObjects, ObjectTypeAndNamePredicateBuilder.FilterType.EXCLUDE));
}
final Predicates super RevEngDestination> objectExclusionPredicate = objectExclusionPredicateBuilder.build(
new Function() {
@Override
public String valueOf(RevEngDestination dest) {
return dest.getDbObjectType().getName();
}
},
new Function() {
@Override
public String valueOf(RevEngDestination revEngDestination) {
return revEngDestination.getObjectName();
}
}
);
MutableMap> revEngDestinationMap = HashingStrategyMaps.mutable.of(HashingStrategies.fromFunction(new Function() {
@Override
public String valueOf(RevEngDestination revEngDestination) {
return revEngDestination.getIdentity();
}
}));
for (ChangeEntry allRevEngDestination : allRevEngDestinations.select(new Predicate() {
@Override
public boolean accept(ChangeEntry entry) {
return objectExclusionPredicate.accept(entry.getDestination());
}
})) {
MutableList changeEntries = revEngDestinationMap.get(allRevEngDestination.getDestination());
if (changeEntries == null) {
changeEntries = Lists.mutable.empty();
revEngDestinationMap.put(allRevEngDestination.getDestination(), changeEntries);
}
changeEntries.add(allRevEngDestination);
}
for (Pair> pair :
revEngDestinationMap.keyValuesView()) {
RevEngDestination dest = pair.getOne();
MutableList changes = pair.getTwo()
.toSortedListBy(Functions.firstNotNullValue(new Function() {
@Override
public String valueOf(ChangeEntry changeEntry1) {
return changeEntry1.getName();
}
}, Functions.getFixedValue("")))
.toSortedListBy(new Function() {
@Override
public Integer valueOf(ChangeEntry changeEntry1) {
return changeEntry1.getOrder();
}
});
MutableList metadataAnnotations = changes.flatCollect(new Function>() {
@Override
public Iterable valueOf(ChangeEntry changeEntry1) {
return changeEntry1.getMetadataAnnotations();
}
});
String metadataString;
if (metadataAnnotations.isEmpty()) {
metadataString = "";
} else {
metadataString = "//// METADATA " + metadataAnnotations.makeString(" ");
}
String mainSql = (metadataString.isEmpty() ? "" : metadataString + "\n")
+ changes.collect(new Function() {
@Override
public String valueOf(ChangeEntry changeEntry1) {
return changeEntry1.getSql();
}
}).collect(new Function() {
@Override
public String valueOf(String s) {
return s.trim();
}
}).makeString("\n");
try {
File mainDestinationFile = dest.getDestinationFile(outputDir, false);
if (dest.isBaselineEligible()) {
if (shouldOverwritePredicate.accept(mainDestinationFile, dest)) {
MutableList lines = Lists.mutable.empty();
String prevChange = null;
if (!metadataString.isEmpty()) {
lines.add(metadataString);
}
for (ChangeEntry changeEntry : changes) {
if (prevChange == null || !prevChange.equals(changeEntry.getName())) {
lines.add(String.format("//// CHANGE%1$s name=%2$s"
, StringUtils.isNotEmpty(changeEntry.getChangeAnnotation())
? " " + changeEntry.getChangeAnnotation() : ""
, changeEntry.getName()));
}
lines.add(changeEntry.getSql().trim());
lines.add("");
prevChange = changeEntry.getName();
}
FileUtils.writeStringToFile(mainDestinationFile, lines.makeString("\n"));
}
} else {
FileUtils.writeStringToFile(mainDestinationFile, mainSql);
}
if (generateBaseline && dest.isBaselineEligible()) {
FileUtils.writeStringToFile(dest.getDestinationFile(outputDir, true), mainSql);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
MutableSet schemas = allRevEngDestinations.collect(new Function() {
@Override
public String valueOf(ChangeEntry entry) {
return entry.getDestination().getSchema();
}
}, Sets.mutable.empty());
Writer fileWriter = null;
try {
Template template = templateConfig.getTemplate("deployer/reveng/system-config-template.xml.ftl");
fileWriter = new FileWriter(new File(outputDir, "system-config.xml"));
MutableMap params = Maps.mutable.empty();
params.put("platform", platform.getName());
params.put("schemas", schemas);
params.put("jdbcUrl", jdbcUrl);
params.put("dbHost", dbHost);
params.put("dbPort", dbPort != null ? String.valueOf(dbPort) : null);
params.put("dbServer", dbServer);
template.process(params, fileWriter);
} catch (TemplateException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(fileWriter);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy