[jOOQ/jOOQ#8939] Support Flyway file ordering in DDLDatabase

This commit is contained in:
Mustafa Yücel 2019-07-23 01:34:25 +02:00
parent aaedefc9eb
commit 8767b8014d
10 changed files with 374 additions and 0 deletions

View File

@ -0,0 +1,2 @@
/target
/jooq-flyway-example.iml

View File

@ -0,0 +1,19 @@
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.
Other licenses:
-----------------------------------------------------------------------------
Commercial licenses for this work are available. These replace the above
ASL 2.0 and offer limited warranties, support, maintenance, and commercial
database integrations.
For more information, please visit: http://www.jooq.org/licenses

View File

@ -0,0 +1,12 @@
Thanks for downloading jOOQ.
Please visit http://www.jooq.org for more information.
To install and run this example, simply check it out and run the following Maven command
```
$ pwd
/path/to/checkout/dir
$ cd jOOQ-examples/jOOQ-flyway-ddl-example
...
$ mvn clean install
```

View File

@ -0,0 +1,111 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jooq</groupId>
<artifactId>jooq-flyway-ddl-example</artifactId>
<version>1.0</version>
<name>jOOQ Flyway/DDL Example</name>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.jooq.org/inc/LICENSE.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.springframework.version>3.2.6.RELEASE</org.springframework.version>
<org.jooq.version>3.12.0-SNAPSHOT</org.jooq.version>
</properties>
<dependencies>
<!-- Database access -->
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq</artifactId>
<version>${org.jooq.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>${org.jooq.version}</version>
<executions>
<execution>
<id>java-generator</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generator>
<database>
<name>org.jooq.meta.extensions.ddl.DDLDatabase</name>
<inputSchema>FLYWAY_TEST</inputSchema>
<properties>
<property>
<key>sort</key>
<value>flyway</value>
</property>
<property>
<key>scripts</key>
<value>src/main/resources/db/migration/*</value>
</property>
</properties>
</database>
<target>
<packageName>org.jooq.example.flyway.j.db.h2</packageName>
<directory>${project.build.directory}/generated-sources/jooq-h2-java</directory>
</target>
</generator>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq-meta-extensions</artifactId>
<version>${org.jooq.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<fork>true</fork>
<maxmem>1024m</maxmem>
<meminitial>256m</meminitial>
<encoding>UTF-8</encoding>
<release>11</release>
<!-- IntelliJ needs these https://youtrack.jetbrains.com/issue/IDEA-195472 -->
<source>11</source>
<target>11</target>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,12 @@
CREATE SEQUENCE flyway_test.s_author_id START WITH 1;
CREATE TABLE flyway_test.author (
id INT NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50) NOT NULL,
date_of_birth DATE,
year_of_birth INT,
address VARCHAR(50),
CONSTRAINT pk_t_author PRIMARY KEY (ID)
);

View File

@ -0,0 +1,17 @@
CREATE TABLE flyway_test.book (
id INT NOT NULL,
author_id INT NOT NULL,
title VARCHAR(400) NOT NULL,
CONSTRAINT pk_t_book PRIMARY KEY (id),
CONSTRAINT fk_t_book_author_id FOREIGN KEY (author_id) REFERENCES flyway_test.author(id)
);
INSERT INTO flyway_test.author VALUES (next value for flyway_test.s_author_id, 'George', 'Orwell', '1903-06-25', 1903, null);
INSERT INTO flyway_test.author VALUES (next value for flyway_test.s_author_id, 'Paulo', 'Coelho', '1947-08-24', 1947, null);
INSERT INTO flyway_test.book VALUES (1, 1, '1984');
INSERT INTO flyway_test.book VALUES (2, 1, 'Animal Farm');
INSERT INTO flyway_test.book VALUES (3, 2, 'O Alquimista');
INSERT INTO flyway_test.book VALUES (4, 2, 'Brida');

View File

@ -0,0 +1 @@
CREATE SCHEMA flyway_test;

View File

@ -69,6 +69,8 @@ public final class FilePattern {
};
else if ("none".equals(sort))
return null;
else if ("flyway".equals(sort))
return FlywayFileComparator.INSTANCE;
else
return FileComparator.INSTANCE;
}

View File

@ -0,0 +1,57 @@
/*
* 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.meta.tools;
import java.io.File;
import java.util.Comparator;
public final class FlywayFileComparator implements Comparator<File> {
public static final FlywayFileComparator INSTANCE = new FlywayFileComparator();
@Override
public final int compare(File o1, File o2) {
String s1 = o1 == null ? null : o1.getName();
String s2 = o2 == null ? null : o2.getName();
FlywayVersion v1 = FlywayVersion.fromVersion(s1 == null ? null : s1.substring(1, s1.indexOf("__")));
FlywayVersion v2 = FlywayVersion.fromVersion(s2 == null ? null : s2.substring(1, s2.indexOf("__")));
return v1.compareTo(v2);
}
}

View File

@ -0,0 +1,141 @@
/*
* Copyright 2010-2019 Boxfuse GmbH
*
* 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.jooq.meta.tools;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.jooq.tools.StringUtils;
/**
* A version of a migration.
*
* @author Axel Fontaine
*/
public final class FlywayVersion implements Comparable<FlywayVersion> {
/**
* Version for an empty schema.
*/
public static final FlywayVersion EMPTY = new FlywayVersion(null);
/**
* Regex for matching proper version format
*/
private static final Pattern SPLIT_REGEX = Pattern.compile("\\.(?=\\d)");
/**
* The individual parts this version string is composed of. Ex. 1.2.3.4.0 -> [1, 2, 3, 4, 0]
*/
private final List<BigInteger> versionParts;
/**
* Create a FlywayVersion from a version String.
*
* @param version The version String. The value {@code current} will be interpreted as FlywayVersion.CURRENT,
* a marker for the latest version that has been applied to the database.
* @return The FlywayVersion
*/
public static FlywayVersion fromVersion(String version) {
if (StringUtils.isEmpty(version)) return EMPTY;
return new FlywayVersion(version);
}
/**
* Creates a Version using this version string.
*
* @param version The version in one of the following formats: 6, 6.0, 005, 1.2.3.4, 201004200021. <br/>{@code null}
* means that this version refers to an empty schema.
*/
private FlywayVersion(String version) {
if (!StringUtils.isEmpty(version)) {
String normalizedVersion = version.replace('_', '.');
this.versionParts = tokenize(normalizedVersion);
}
else {
this.versionParts = new ArrayList<>();
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FlywayVersion version1 = (FlywayVersion) o;
return compareTo(version1) == 0;
}
@Override
public int hashCode() {
return versionParts == null ? 0 : versionParts.hashCode();
}
@Override
public int compareTo(FlywayVersion o) {
if (o == null) {
return 1;
}
if (this == EMPTY) {
if (o == EMPTY) return 0;
else return Integer.MIN_VALUE;
}
if (o == EMPTY) {
return Integer.MAX_VALUE;
}
final List<BigInteger> parts1 = versionParts;
final List<BigInteger> parts2 = o.versionParts;
int largestNumberOfParts = Math.max(parts1.size(), parts2.size());
for (int i = 0; i < largestNumberOfParts; i++) {
final int compared = getOrZero(parts1, i).compareTo(getOrZero(parts2, i));
if (compared != 0) {
return compared;
}
}
return 0;
}
private BigInteger getOrZero(List<BigInteger> elements, int i) {
return i < elements.size() ? elements.get(i) : BigInteger.ZERO;
}
/**
* Splits this string into list of Long
*
* @param versionStr The string to split.
* @return The resulting array.
*/
private List<BigInteger> tokenize(String versionStr) {
List<BigInteger> parts = new ArrayList<>();
for (String part : SPLIT_REGEX.split(versionStr)) {
parts.add(new BigInteger(part));
}
for (int i = parts.size() - 1; i > 0; i--) {
if (!parts.get(i).equals(BigInteger.ZERO)) {
break;
}
parts.remove(i);
}
return parts;
}
}