Flyway 不提供任何内置功能来执行相同的操作。
但是我已经为我的项目做了这个,我认为到目前为止这是我们能做的最好的。
- 将 Flyway 版本设置为实际时间戳,因此无论您创建哪个 git 分支,它始终是唯一且有序的。
- 编写程序生成此版本并询问所有开发人员
使用此文件以获得下一个版本
需要使用。
以下是我目前使用的示例
package com.demo;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class GenerateFileVersion {
public static void main (String... args){
GenerateFileVersion f=new GenerateFileVersion();
f.fileVersion();
}
private String trimOrPad(String str, int length, char padChar) {
String result;
if (str == null) {
result = "";
} else {
result = str;
}
if (result.length() > length) {
return result.substring(0, length);
} else {
while (result.length() < length) {
result = padChar+result;
}
return result;
}
}
private String fileVersion(){
Date date = new Date();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CST6CDT"));
calendar.setTime(date);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
StringBuffer sb=new StringBuffer();
sb.append(calendar.get(Calendar.YEAR)%100);
sb.append(".");
sb.append(this.trimOrPad(String.valueOf(calendar.get(Calendar.MONTH)+1),2,'0'));
sb.append(".");
sb.append(this.trimOrPad(String.valueOf(calendar.get(Calendar.DATE)),2,'0'));
sb.append(".");
sb.append(this.trimOrPad(String.valueOf(calendar.get(Calendar.HOUR_OF_DAY)),2,'0'));
sb.append(this.trimOrPad(String.valueOf(calendar.get(Calendar.MINUTE)),2,'0'));
sb.append(this.trimOrPad(String.valueOf(calendar.get(Calendar.SECOND)),2,'0'));
System.out.println("Choose Your Next File Name From below list...");
int i=0;
for(ENVIRONMENT env: ENVIRONMENT.values()){
System.out.println("Next File Name for Making DDL Change : "+"V"+sb.toString()+this.trimOrPad(String.valueOf(i++),2,'0')+"__"+env.toString()+"_DDL.sql");
System.out.println("Next File Name for Making DML Change : "+"V"+sb.toString()+this.trimOrPad(String.valueOf(i++),2,'0')+"__"+env.toString()+"_DML.sql");
}
return sb.toString();
}
private enum ENVIRONMENT{COMMON(1),LOCAL(9),STAGE(4),MTF(5),PERF(7),PROD(2);
private int value;
private ENVIRONMENT(int value) { this.value = value; }
}
}
您还可以为您的项目添加更多功能,以确保所有开发人员不会犯任何错误,您可以将以下程序添加为 junit 测试用例,以便在任何文件不遵循 flyway 版本控制标准时构建失败。
示例如下
package com.demo;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootRestApplicationTests {
@Test
public void checkDuplicateVersion() {
System.out.println("Starting checkDuplicateVersion");
List<ClassLoader> classLoadersList = new LinkedList<>();
classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new ResourcesScanner())
.setUrls(ClasspathHelper.forManifest(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("local"))));
Reflections reflections1 = new Reflections(new ConfigurationBuilder()
.setScanners(new ResourcesScanner())
.setUrls(ClasspathHelper.forManifest(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("common"))));
Stream<String> stream1= reflections.getStore().get("ResourcesScanner").keys().stream();
Stream<String> stream2= reflections1.getStore().get("ResourcesScanner").keys().stream();
Stream<String> resultingStream=Stream.of(stream1,stream2).flatMap(i -> i);
//resultingStream.forEach(System.out::println);
List<String> existingFileVersions=
resultingStream
.filter(f -> f.startsWith("V"))
.filter(f -> f.endsWith(".sql"))
//.forEach(System.out::println);
.map(n -> n.split("__")[0].substring(1))
//.forEach(System.out::println);
.collect(Collectors.toList());
Set<String> duplicateVersion=existingFileVersions.stream().filter(i -> Collections.frequency(existingFileVersions, i) >1)
.collect(Collectors.toSet());
duplicateVersion.forEach( i -> System.out.println("Duplicate Version found "+i));
Assert.assertEquals(0,duplicateVersion.size());
}
@Test
public void checkFlywayFileNamingStandard(){
System.out.println("Starting checkFlywayFileNamingStandard");
List<ClassLoader> classLoadersList = new LinkedList<>();
classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new ResourcesScanner())
.setUrls(ClasspathHelper.forManifest(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("local"))));
Reflections reflections1 = new Reflections(new ConfigurationBuilder()
.setScanners(new ResourcesScanner())
.setUrls(ClasspathHelper.forManifest(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("common"))));
Stream<String> stream1= reflections.getStore().get("ResourcesScanner").keys().stream();
Stream<String> stream2= reflections1.getStore().get("ResourcesScanner").keys().stream();
Stream<String> resultingStream=Stream.of(stream1,stream2).flatMap(i -> i);
//resultingStream.forEach(System.out::println);
resultingStream
.filter(f -> f.endsWith(".sql"))
.forEach(n -> {
if(!n.split("__")[0].toUpperCase().startsWith("V")){
System.out.println("File starts with " + n + " Does not start with Letter V or v. Please fix it.");
Assert.fail();
}
for(String s : n.split("__")[0].substring(1).split("\\.")){
try {
//System.out.println(n);
Integer.valueOf(s);
}catch(Exception e){
//e.printStackTrace();
System.out.println("File starting with "+ n + " does not match flyway standard");
System.out.println("Flyway standard is V{version}__{description}.sql");
Assert.fail();
}
}
});
}
}
更多详情可以看我的项目here