Skip to content

Combined pull requests (status, BOM handling, sequential ordering, version conflict detection, etc) #28

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

Closed
wants to merge 75 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
5c4ebb8
releng: initial checkin of Travis CI descriptor
simotripo Feb 11, 2013
4b93397
releng: updated NOTICE content according to what discussed in the ML
simotripo Feb 11, 2013
4f010bc
releng: updated copyright year
simotripo Feb 11, 2013
f23ca80
releng: dropped SVN tags
simotripo Feb 11, 2013
71a0ed6
contributors email in canonical format
simotripo Feb 11, 2013
9c189c6
trivial: code format, no functional modifications
simotripo Feb 11, 2013
3e36dbb
releng: added missing project.url
simotripo Feb 11, 2013
271b2c8
releng: added missing
simotripo Feb 11, 2013
ead9eac
releng: added missing clirr property
simotripo Feb 11, 2013
a652927
Updated dependencies
emacarron Apr 6, 2013
171219a
Should be 3.1.1 as there is not any feature change to go to 3.2 yet
emacarron Apr 6, 2013
d4a803a
removed com.googlecode.maven-gcu-plugin
emacarron Apr 6, 2013
45ef07a
updated readme
emacarron Apr 25, 2013
a2d70bf
Configure travis to deploy snapshots after build.
harawata May 27, 2013
75741ba
Updated mybatis dependency to 3.2.3-SNAPSHOT (see #1).
harawata Jul 3, 2013
99eeef6
fixes #3 The lower version of the script command should be exclusive.
harawata Sep 27, 2013
fe23d06
[maven-release-plugin] prepare release mybatis-migrations-3.1.1
simotripo Sep 29, 2013
9deea00
[maven-release-plugin] prepare for next development iteration
simotripo Sep 29, 2013
f3e6f36
Allow the use of whitespace in the marker comments. This is now the …
Oct 4, 2013
2ea4b69
Updated parent version to 19-SNAPSHOT.
harawata Nov 22, 2013
cfa95d6
fixes #2 Implemented Runtime Schema Upgrade (a.k.a. in-app migration).
harawata Dec 26, 2013
5165ae8
Bumped to version 3.2.0.
harawata Dec 26, 2013
081bf3e
Down operation should stop when there is no changelog table.
harawata Dec 26, 2013
2f728d6
parent & mybatis core updated to latest released verisons
simotripo Jan 18, 2014
2a342d9
[maven-release-plugin] prepare release mybatis-migrations-3.2.0
simotripo Jan 18, 2014
a136dac
[maven-release-plugin] prepare for next development iteration
simotripo Jan 18, 2014
382a9b4
Upgraded parent and added "the video"
emacarron Jan 23, 2014
2f33432
Update README
cbegin Jan 28, 2014
029d579
Update git ignores
hazendaz Oct 28, 2014
e08d213
Change readme to markdown
hazendaz Oct 28, 2014
0bdd56d
Change assembly README file type.
hazendaz Oct 28, 2014
86398d9
Update pom
hazendaz Oct 28, 2014
db93729
Take mybatis off build status
hazendaz Oct 28, 2014
659b32f
Merge pull request #11 from hazendaz/master
emacarron Oct 28, 2014
e59614e
Updated site page xsd.
hazendaz Dec 25, 2014
74acd3f
fixes #13 Modified the FileMigrationLoader to use the last index of t…
Dec 30, 2014
b4ced4d
Update junit and appassembler
hazendaz Jan 18, 2015
9fcb305
add travis ci jdk8 build
hazendaz Jan 18, 2015
8fc748b
Merge pull request #15 from hazendaz/master
emacarron Jan 19, 2015
07506ca
Update README.md
WalterPhillips Mar 4, 2015
62648b8
Update README.md
WalterPhillips Mar 4, 2015
18cacb2
Merge pull request #1 from WalterPhillips/WalterPhillips-editing-mark…
WalterPhillips Mar 4, 2015
5e0ce2d
Merge pull request #1 from WalterPhillips/WalterPhillips-editing-mark…
WalterPhillips Mar 4, 2015
43e14fc
Update README.md
WalterPhillips Mar 4, 2015
0629822
Update README.md
WalterPhillips Mar 4, 2015
8956423
Initial partial commit
WalterPhillips Mar 5, 2015
b72d322
Initial partial commit
KimberlyAudlee Mar 5, 2015
0882700
Initial working version for using number sequence. Still need to get …
WalterPhillips Mar 6, 2015
1f23063
Initial working version for using number sequence. Still need to get …
WalterPhillips Mar 6, 2015
724d0c4
Merge remote-tracking branch 'origin/number-sequence-option' into num…
Mar 9, 2015
df00516
Fix bug sequence number initialization bug
Mar 9, 2015
73b1bf8
Allowing empty directory for test
WalterPhillips Mar 10, 2015
3a8318d
Adding additional test for special case file
WalterPhillips Mar 10, 2015
4e13dab
Adding the rest of the files which was left out
WalterPhillips Mar 10, 2015
7e4ad2e
Adding the missing empty directory to git
WalterPhillips Mar 10, 2015
dd4c08e
Fixing test to not delete ./.gitignore
WalterPhillips Mar 10, 2015
f145460
Status command indicates missing scripts.
Sep 3, 2015
7e373ca
Tighten up the code a bit.
Sep 3, 2015
c82e4dc
Add getter for missing script count.
Sep 3, 2015
6269ff3
Tests for missing scripts in status operation.
Sep 3, 2015
7a8eb03
BOM detection for UTF-8 and unicode unit test data addition
Sep 18, 2015
8146f9d
Merge branch 'number-sequence-option' into combined
Sep 18, 2015
f026002
replaced gitignore file with a more explicit placeholder file.
Sep 18, 2015
c1d5a02
Merge branch 'handle-utf-8-bom' into combined
Sep 18, 2015
6c7c2ce
Merge branch 'status-missing-scripts' into combined
Sep 18, 2015
7914b69
Fixed reset of derby test database state after test complete, so that…
Sep 24, 2015
830788f
added placeholder txt file to explicitly keep the scripts folder for …
Sep 24, 2015
6937b8e
Added internal caching of environment properties retrieved from the f…
Sep 24, 2015
c4ed2a8
Added extra catch to explictily handle cases where the file name star…
Sep 24, 2015
be34243
Corrected Version conflict detection and added a version override opt…
Sep 24, 2015
de09cd2
Added the configuration option to validate change filenames (such as …
Sep 24, 2015
3e20271
small help text fix (removed a ']' character)
Sep 24, 2015
068f144
Added placeholder file and change folder fetch method to fix Travis e…
Sep 24, 2015
333aa59
Fixed parsing of NewCommand version override value
Sep 25, 2015
9243772
Updated Number sequence configuration parameters to match the project…
Oct 2, 2015
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ ibderby
atlassian-ide-plugin.xml
.classpath
.project
.settings
.settings
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Install MyBatis Migrations ${project.version} (${implementation.build})

See the reference documentation here http://mybatis.github.io/migrations/

* Windows
### Windows

[1] Unzip the distribution archive, i.e. mybatis-${project.version}-migrations.zip to the directory you wish
to install MyBatis Migrations.
Expand All @@ -33,7 +33,7 @@ Install MyBatis Migrations ${project.version} (${implementation.build})
[4] In the same dialog, update/create the Path environment variable in the user variables and prepend the value
%MIGRATIONS% to add MyBatis Migrations available in the command line.

* Unix-based Operating Systems (Linux, Solaris and Mac OS X)
### Unix-based Operating Systems (Linux, Solaris and Mac OS X)

[1] Extract the distribution archive, i.e. mybatis-${project.version}-migrations.zip to the directory you wish to
install MyBatis Migrations. These instructions assume you chose
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/org/apache/ibatis/migration/Change.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public void setFilename(String filename) {
}

public String toString() {
return id + " " + (appliedTimestamp == null ? " ...pending... " : appliedTimestamp) + " " + description;
String status = appliedTimestamp == null ? " ...pending... " : appliedTimestamp;
String message = filename == null ? " ...missing script... " : " ";
return id + " " + status + message + description;
}

public boolean equals(Object o) {
Expand All @@ -83,14 +85,16 @@ public boolean equals(Object o) {

Change change = (Change) o;

return (id.equals(change.getId()));
return (id.equals(change.getId())) && (description == null ? change.getDescription() == null : description.equals(change.getDescription()));
}

public int hashCode() {
return id.hashCode();
return id.hashCode() ^ (description == null ? 0 : description.hashCode());
}

public int compareTo(Change change) {
return id.compareTo(change.getId());
return id.compareTo(change.getId()) != 0 ? id.compareTo(change.getId())
: (description == null ? (change.getDescription() == null ? 0 : 1)
: description.compareTo(change.getDescription()));
}
}
57 changes: 57 additions & 0 deletions src/main/java/org/apache/ibatis/migration/ChangeValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.apache.ibatis.migration;

import java.math.BigDecimal;
import java.util.Properties;
import java.util.regex.Pattern;

public class ChangeValidator {
private static final String CUSTOM_FILE_NAME_FILTER_PROPERTY = "filename_filter";

/**
* @param change to validate
* @param properties Environmental configuration
* @throws MigrationException
*/
public static void validateChangeForConfiguration(Change change, Properties properties)
throws MigrationException {
String filename = change.getFilename();
String filenameFilter = properties.getProperty(CUSTOM_FILE_NAME_FILTER_PROPERTY);
if (filenameFilter != null) {
Pattern p = null;
try {
p = Pattern.compile(filenameFilter, Pattern.CASE_INSENSITIVE);
} catch (Exception ex) {
throw new MigrationException("Exception parsing the value in your environmental configuration for the filename filter of " + filenameFilter, ex);
}
if (!p.matcher(filename).find()) {
throw new MigrationException("The change filename " + filename + " does not match the required filename filter of " + filenameFilter);
}
}
}

/**
* @param filename
* @param properties Environmental configuration
* @return Change
*/
public static Change parseChangeFromFilename(String filename, Properties properties) {
try {
Change change = new Change();
int lastIndexOfDot = filename.lastIndexOf(".");
String[] parts = filename.substring(0, lastIndexOfDot).split("_");
change.setId(new BigDecimal(parts[0]));
StringBuilder builder = new StringBuilder();
for (int i = 1; i < parts.length; i++) {
if (i > 1) {
builder.append(" ");
}
builder.append(parts[i]);
}
change.setDescription(builder.toString());
change.setFilename(filename);
return change;
} catch (Exception e) {
throw new MigrationException("Error parsing change from filename. Cause: " + e, e);
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/apache/ibatis/migration/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ private void printUsage() {
console.printf(" info Display build version informations.%n");
console.printf(" init Creates (if necessary) and initializes a migration path.%n");
console.printf(" bootstrap Runs the bootstrap SQL script (see scripts/bootstrap.sql for more).%n");
console.printf(" new <description> Creates a new migration with the provided description.%n");
console.printf(" new <desc> [n] Creates a new migration with the provided description and 'n' version.%n");
console.printf(" up [n] Run unapplied migrations, ALL by default, or 'n' specified.%n");
console.printf(
" down [n] Undoes migrations applied to the database. ONE by default or 'n' specified.%n");
Expand Down
27 changes: 4 additions & 23 deletions src/main/java/org/apache/ibatis/migration/FileMigrationLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand All @@ -27,6 +26,7 @@
import org.apache.ibatis.migration.utils.Util;

public class FileMigrationLoader implements MigrationLoader {

private final File scriptsDir;

private final String charset;
Expand All @@ -51,35 +51,15 @@ public List<Change> getMigrations() {
Arrays.sort(filenames);
for (String filename : filenames) {
if (filename.endsWith(".sql") && !"bootstrap.sql".equals(filename)) {
Change change = parseChangeFromFilename(filename);
Change change = ChangeValidator.parseChangeFromFilename(filename, properties);
ChangeValidator.validateChangeForConfiguration (change, properties);
migrations.add(change);
}
}
}
return migrations;
}

private Change parseChangeFromFilename(String filename) {
try {
Change change = new Change();
int lastIndexOfDot = filename.lastIndexOf(".");
String[] parts = filename.substring(0, lastIndexOfDot).split("_");
change.setId(new BigDecimal(parts[0]));
StringBuilder builder = new StringBuilder();
for (int i = 1; i < parts.length; i++) {
if (i > 1) {
builder.append(" ");
}
builder.append(parts[i]);
}
change.setDescription(builder.toString());
change.setFilename(filename);
return change;
} catch (Exception e) {
throw new MigrationException("Error parsing change from file. Cause: " + e, e);
}
}

@Override
public Reader getScriptReader(Change change, boolean undo) {
try {
Expand All @@ -101,4 +81,5 @@ public Reader getBootstrapReader() {
throw new MigrationException("Error reading bootstrap.sql", e);
}
}

}
10 changes: 10 additions & 0 deletions src/main/java/org/apache/ibatis/migration/MigrationReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.Set;

public class MigrationReader extends Reader {
// FEFF because this is the Unicode char represented by the UTF-8 byte order mark (EF BB BF).
public static final String UTF8_BOM = "\uFEFF";

private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");

Expand All @@ -51,7 +53,15 @@ public MigrationReader(InputStream inputStream, String charset, boolean undo, Pr
StringBuilder undoBuilder = new StringBuilder();
StringBuilder currentBuilder = doBuilder;
String line;
boolean firstLine = true;

while ((line = reader.readLine()) != null) {
if (firstLine) {
if ("UTF-8".equalsIgnoreCase(charset) && line.startsWith(UTF8_BOM)) {
line = line.substring(1);
}
firstLine = false;
}
if (line.trim().matches("^--\\s*//.*$")) {
if (line.contains("@UNDO")) {
currentBuilder = undoBuilder;
Expand Down
114 changes: 76 additions & 38 deletions src/main/java/org/apache/ibatis/migration/commands/BaseCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,28 @@
*/
package org.apache.ibatis.migration.commands;

import static org.apache.ibatis.migration.utils.Util.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;

import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
import org.apache.ibatis.io.ExternalResources;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.migration.ConnectionProvider;
import org.apache.ibatis.migration.DataSourceConnectionProvider;
import org.apache.ibatis.migration.FileMigrationLoader;
import org.apache.ibatis.migration.MigrationException;
import org.apache.ibatis.migration.MigrationLoader;
import org.apache.ibatis.migration.*;
import org.apache.ibatis.migration.options.DatabaseOperationOption;
import org.apache.ibatis.migration.options.SelectedOptions;
import org.apache.ibatis.migration.options.SelectedPaths;
import org.apache.ibatis.parsing.PropertyParser;

import java.io.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.SimpleDateFormat;
import java.util.*;

import static org.apache.ibatis.migration.utils.Util.file;

public abstract class BaseCommand implements Command {
private static final String DATE_FORMAT = "yyyyMMddHHmmss";
private static final String FILENAME_SEQUENCE_NUMBER_PADDING = "sequence_number_padding";

private Properties envProperties;

private ClassLoader driverClassLoader;

Expand Down Expand Up @@ -83,6 +72,48 @@ protected String changelogTable() {
}

protected String getNextIDAsString() {
if (getDatabaseOperationOption().useSequenceNumber()) {
return getNextSequenceNumberAsIdString();
}

return getNextTimestampIDAsString();
}

protected String getNextSequenceNumberAsIdString() {
// if script directory is empty, use the initial sequence
if (paths.getScriptPath().list().length==0) {
return getDatabaseOperationOption().getInitialSequence().toString();
}

// else, initialise with the largest seq number from scripts dir and increment by 1
File[] sqlFiles = paths.getScriptPath().listFiles();

Arrays.sort(
sqlFiles,
new Comparator<File>() {
public int compare(File a, File b) {
return sequenceNumberOfFile(a.getName()).compareTo(sequenceNumberOfFile(b.getName()));
}
});

File lastFile = sqlFiles[sqlFiles.length - 1];
Integer nextSeqNumber = sequenceNumberOfFile(lastFile.getName()) + 1;
Integer zerosToPadd = Integer.valueOf(environmentProperties().getProperty(FILENAME_SEQUENCE_NUMBER_PADDING, "1"));

return String.format("%0" + zerosToPadd + "d", nextSeqNumber);
}

private Integer sequenceNumberOfFile(String fileName) {
try {
return Integer.valueOf(fileName.substring(0, fileName.indexOf("_")));
} catch (StringIndexOutOfBoundsException e) {
} catch (NumberFormatException e) {}

// File does not have any numbers. Will ignore this and make this the same as the initial number
return getDatabaseOperationOption().getInitialSequence() - 1;
}

protected String getNextTimestampIDAsString() {
try {
// Ensure that two subsequent calls are less likely to return the same value.
Thread.sleep(1000);
Expand Down Expand Up @@ -149,24 +180,27 @@ protected File existingEnvironmentFile() {
}

protected Properties environmentProperties() {
FileInputStream fileInputStream = null;
try {
File file = existingEnvironmentFile();
Properties props = new Properties();
fileInputStream = new FileInputStream(file);
props.load(fileInputStream);
return props;
} catch (IOException e) {
throw new MigrationException("Error loading environment properties. Cause: " + e, e);
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
// Nothing to do here
if (envProperties == null) {
FileInputStream fileInputStream = null;
try {
File file = existingEnvironmentFile();
Properties props = new Properties();
fileInputStream = new FileInputStream(file);
props.load(fileInputStream);
envProperties = props;
} catch (IOException e) {
throw new MigrationException("Error loading environment properties. Cause: " + e, e);
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
// Nothing to do here
}
}
}
}
return envProperties;
}

protected int getStepCountParameter(int defaultSteps, String... params) {
Expand Down Expand Up @@ -246,6 +280,10 @@ protected DatabaseOperationOption getDatabaseOperationOption() {
option.setRemoveCRs(Boolean.valueOf(props.getProperty("remove_crs")));
String delimiterString = props.getProperty("delimiter");
option.setDelimiter(delimiterString == null ? ";" : delimiterString);
option.setUseSequenceNumber(Boolean.valueOf(props.getProperty("use_sequence_number")));
if (option.useSequenceNumber()) {
option.setInitialSequence(Integer.valueOf(props.getProperty("initial_sequence_number")));
}
return option;
}
}
Loading