Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

before/after new hooks #109

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/main/java/org/apache/ibatis/migration/Change.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public Change(BigDecimal id, String appliedTimestamp, String description) {
this.description = description;
}

public Change(BigDecimal id, String appliedTimestamp, String description, String filename) {
this.id = id;
this.appliedTimestamp = appliedTimestamp;
this.description = description;
this.filename = filename;
}

public BigDecimal getId() {
return id;
}
Expand Down Expand Up @@ -71,7 +78,8 @@ public void setFilename(String filename) {

@Override
public String toString() {
return id + " " + (appliedTimestamp == null ? " ...pending... " : appliedTimestamp) + " " + description;
String ts = appliedTimestamp == null ? " ...pending... " : appliedTimestamp;
return String.format("%s %s %s %s", id, ts, description, filename);
}

@Override
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/org/apache/ibatis/migration/Environment.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ private enum SETTING_KEY {
hook_before_down,
hook_before_each_down,
hook_after_each_down,
hook_after_down
hook_after_down,
hook_before_new,
hook_after_new
}

private static final List<String> SETTING_KEYS;
Expand Down Expand Up @@ -88,6 +90,8 @@ private enum SETTING_KEY {
private final String hookBeforeEachDown;
private final String hookAfterEachDown;
private final String hookAfterDown;
private final String hookBeforeNew;
private final String hookAfterNew;

private final Properties variables = new Properties();

Expand All @@ -113,7 +117,9 @@ public Environment(File file) {
this.username = prop.getProperty(SETTING_KEY.username.name());
this.password = prop.getProperty(SETTING_KEY.password.name());

this.hookBeforeUp = prop.getProperty(SETTING_KEY.hook_before_up.name());
this.hookBeforeNew = prop.getProperty(SETTING_KEY.hook_before_new.name());
this.hookAfterNew = prop.getProperty(SETTING_KEY.hook_after_new.name());

this.hookBeforeEachUp = prop.getProperty(SETTING_KEY.hook_before_each_up.name());
this.hookAfterEachUp = prop.getProperty(SETTING_KEY.hook_after_each_up.name());
this.hookAfterUp = prop.getProperty(SETTING_KEY.hook_after_up.name());
Expand All @@ -122,6 +128,7 @@ public Environment(File file) {
this.hookAfterEachDown = prop.getProperty(SETTING_KEY.hook_after_each_down.name());
this.hookAfterDown = prop.getProperty(SETTING_KEY.hook_after_down.name());

this.hookBeforeUp = prop.getProperty(SETTING_KEY.hook_before_up.name());
// User defined variables.
Set<Entry<Object, Object>> entries = prop.entrySet();
for (Entry<Object, Object> entry : entries) {
Expand Down Expand Up @@ -197,6 +204,14 @@ public String getPassword() {
return password;
}

public String getBeforeNewHook() {
return hookBeforeNew;
}

public String getAfterNewHook() {
return hookAfterNew;
}

public String getHookBeforeUp() {
return hookBeforeUp;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.apache.ibatis.migration.utils.Util.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
Expand Down Expand Up @@ -49,10 +50,13 @@
import org.apache.ibatis.migration.FileMigrationLoaderFactory;
import org.apache.ibatis.migration.MigrationException;
import org.apache.ibatis.migration.MigrationLoader;
import org.apache.ibatis.migration.hook.FileHookScriptFactory;
import org.apache.ibatis.migration.hook.BasicHook;
import org.apache.ibatis.migration.hook.Hook;
import org.apache.ibatis.migration.hook.scripts.FileHookScriptFactory;
import org.apache.ibatis.migration.hook.FileMigrationHook;
import org.apache.ibatis.migration.hook.HookScriptFactory;
import org.apache.ibatis.migration.hook.scripts.HookScriptFactory;
import org.apache.ibatis.migration.hook.MigrationHook;
import org.apache.ibatis.migration.hook.NoOpHook;
import org.apache.ibatis.migration.io.ExternalResources;
import org.apache.ibatis.migration.options.DatabaseOperationOption;
import org.apache.ibatis.migration.options.Options;
Expand Down Expand Up @@ -152,7 +156,7 @@ private String generatePatternedId(String pattern) {
}
}

private String generateTimestampId() {
protected String generateTimestampId() {
final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
final Date now = new Date();
dateFormat.setTimeZone(TimeZone.getTimeZone(environment().getTimeZone()));
Expand Down Expand Up @@ -238,6 +242,17 @@ protected File existingEnvironmentFile() {
return envFile;
}

protected Properties environmentProperties() {
File envFile = existingEnvironmentFile();
Properties props = new Properties();
try {
props.load(new FileInputStream(envFile));
} catch (IOException e) {
throw new MigrationException("Failed to load environment file " + envFile.getAbsolutePath(), e);
}
return props;
}

protected Environment environment() {
if (environment != null) {
return environment;
Expand Down Expand Up @@ -315,6 +330,15 @@ protected MigrationLoader getMigrationLoader() {
: new FileMigrationLoader(paths.getScriptPath(), env.getScriptCharset(), env.getVariables());
}

protected Hook createNewMigrationHook() {
String before = environment().getBeforeNewHook();
String after = environment().getAfterNewHook();
if (before == null && after == null) {
return NoOpHook.getInstance();
}
return createBasicHook(before, after);
}

protected MigrationHook createUpHook() {
String before = environment().getHookBeforeUp();
String beforeEach = environment().getHookBeforeEachUp();
Expand Down Expand Up @@ -343,6 +367,11 @@ protected MigrationHook createFileMigrationHook(String before, String beforeEach
factory.create(after));
}

protected BasicHook createBasicHook(String before, String after) {
HookScriptFactory factory = new FileHookScriptFactory(options.getPaths(), environment(), printStream);
return new BasicHook(factory.create(before), factory.create(after));
}

protected DatabaseOperationOption getDatabaseOperationOption() {
DatabaseOperationOption option = new DatabaseOperationOption();
option.setChangelogTable(changelogTable());
Expand All @@ -356,4 +385,5 @@ protected DatabaseOperationOption getDatabaseOperationOption() {
option.setDelimiter(environment().getDelimiter());
return option;
}

}
111 changes: 88 additions & 23 deletions src/main/java/org/apache/ibatis/migration/commands/NewCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,23 @@
*/
package org.apache.ibatis.migration.commands;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.migration.Change;
import org.apache.ibatis.migration.MigrationException;
import org.apache.ibatis.migration.hook.Hook;
import org.apache.ibatis.migration.hook.MigrationHook;
import org.apache.ibatis.migration.options.SelectedOptions;
import org.apache.ibatis.migration.utils.Util;

public final class NewCommand extends BaseCommand {

Expand All @@ -36,34 +47,88 @@ public void execute(String... params) {
throw new MigrationException("No description specified for new migration.");
}
String description = params[0];
Properties variables = new Properties();
variables.setProperty("description", description);
existingEnvironmentFile();
String filename = getNextIDAsString() + "_" + description.replace(' ', '_') + ".sql";

if (options.getTemplate() != null) {
copyExternalResourceTo(options.getTemplate(), Util.file(paths.getScriptPath(), filename), variables);
} else {
Properties variables = getVariables(description);

Hook hook = createNewMigrationHook();

String nextId = getNextIDAsString();
String filename = nextId + "_" + description.replace(' ', '_') + ".sql";

Map<String, Object> hookBindings = createBinding(nextId, description, new File(filename));
{

Reader templateReader = getTemplateReader();
Change change = (Change) hookBindings.get("change");
hook.before(hookBindings);
File changeFile = new File(change.getFilename());
try {
String customConfiguredTemplate = getPropertyOption(CUSTOM_NEW_COMMAND_TEMPLATE_PROPERTY);
if (customConfiguredTemplate != null) {
copyExternalResourceTo(migrationsHome() + "/" + customConfiguredTemplate,
Util.file(paths.getScriptPath(), filename), variables);
} else {
copyDefaultTemplate(variables, filename);
}
} catch (FileNotFoundException e) {
printStream
.append("Your migrations configuration did not find your custom template. Using the default template.");
copyDefaultTemplate(variables, filename);
copyTemplate(templateReader, changeFile, variables);
} catch (IOException e) {
throw new MigrationException("Unable to create template file " + changeFile.getAbsolutePath());
}

hook.after(hookBindings);
}
printStream.println("Done!");
printStream.println();

}

private void copyDefaultTemplate(Properties variables, String filename) {
copyResourceTo("org/apache/ibatis/migration/template_migration.sql", Util.file(paths.getScriptPath(), filename),
variables);
private Properties getVariables(String description) {
Properties variables = environmentProperties();
variables.setProperty("description", description);
for (Entry<Object, Object> sys : System.getProperties().entrySet()) {
variables.put("sys." + sys.getKey(), "" + sys.getValue());
}
for (Entry<String, String> sys : System.getenv().entrySet()) {
variables.put("env." + sys.getKey(), sys.getValue());
}
return variables;
}

private Reader getTemplateReader() {
String def = "org/apache/ibatis/migration/template_migration.sql";
Reader templateReader = null;
try {
templateReader = Resources.getResourceAsReader(def);
} catch (IOException e) {
throw new MigrationException(String.format("Default template %s can't be found?! ", def), e);
}
try {
String template = getTemplateFile();
templateReader = new FileReader(template);
} catch (FileNotFoundException e) {
String msg = String.format(
"Your migrations configuration did not find your custom template: %s. " + "Using the default template.",
e.getMessage());
printStream.append(msg);
}
return templateReader;
}

private String getTemplateFile() throws FileNotFoundException {
String template = null;
if (options.getTemplate() != null) {
template = options.getTemplate();
} else {
String customConfiguredTemplate = getPropertyOption(CUSTOM_NEW_COMMAND_TEMPLATE_PROPERTY);
if (customConfiguredTemplate != null) {
template = migrationsHome() + "/" + customConfiguredTemplate;
}
}
return template;
}

private Map<String, Object> createBinding(String nextId, String description, File proposedFile) {
Map<String, Object> hookBindings = new HashMap<String, Object>();
BigDecimal id = new BigDecimal(nextId);
Change change = new Change(id, null, description, proposedFile.getAbsolutePath());
Properties props = environmentProperties();

hookBindings.put("change", change);
hookBindings.put("environment", props);
return hookBindings;
}

}
57 changes: 57 additions & 0 deletions src/main/java/org/apache/ibatis/migration/hook/BasicHook.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright 2010-2017 the original author or authors.
*
* 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 org.apache.ibatis.migration.hook;

import java.util.Map;
import org.apache.ibatis.migration.hook.scripts.HookScript;
import org.apache.ibatis.migration.hook.scripts.NoOpHookScript;

/**
* @author cbongiorno on 12/29/17.
*/
public class BasicHook implements Hook {
protected static final NoOpHookScript NO_OP = NoOpHookScript.getInstance();

private final HookScript beforeScript;
private final HookScript afterScript;

public BasicHook() {
this(NO_OP, NO_OP);
}

public BasicHook(HookScript beforeScript, HookScript afterScript) {
this.beforeScript = beforeScript == null ? NO_OP : beforeScript;
this.afterScript = afterScript == null ? NO_OP : beforeScript;
}

@Override
public void before(Map<String, Object> bindingMap) {
beforeScript.execute(bindingMap);
}

@Override
public void after(Map<String, Object> bindingMap) {
afterScript.execute(bindingMap);
}

public HookScript getBeforeScript() {
return beforeScript;
}

public HookScript getAfterScript() {
return afterScript;
}
}
Loading