[jOOQ/jOOQ#9506] More work on Migrations API:
- Add a Settings.migrationDefaultContentType configuration - Support special case of SCRIPT only migrations
This commit is contained in:
parent
073411a51d
commit
c19df5ff34
@ -0,0 +1,37 @@
|
||||
|
||||
package org.jooq.conf;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlEnum;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for MigrationDefaultContentType.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <pre>
|
||||
* <simpleType name="MigrationDefaultContentType">
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
|
||||
* <enumeration value="INCREMENT"/>
|
||||
* <enumeration value="SCRIPT"/>
|
||||
* </restriction>
|
||||
* </simpleType>
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@XmlType(name = "MigrationDefaultContentType")
|
||||
@XmlEnum
|
||||
public enum MigrationDefaultContentType {
|
||||
|
||||
INCREMENT,
|
||||
SCRIPT;
|
||||
|
||||
public String value() {
|
||||
return name();
|
||||
}
|
||||
|
||||
public static MigrationDefaultContentType fromValue(String v) {
|
||||
return valueOf(v);
|
||||
}
|
||||
|
||||
}
|
||||
@ -481,6 +481,9 @@ public class Settings
|
||||
protected MigrationSchema migrationDefaultSchema;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean migrationSchemataCreateSchemaIfNotExists = false;
|
||||
@XmlElement(defaultValue = "INCREMENT")
|
||||
@XmlSchemaType(name = "string")
|
||||
protected MigrationDefaultContentType migrationDefaultContentType = MigrationDefaultContentType.INCREMENT;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean migrationAllowsUndo = false;
|
||||
@XmlElement(defaultValue = "false")
|
||||
@ -6196,6 +6199,22 @@ public class Settings
|
||||
this.migrationSchemataCreateSchemaIfNotExists = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default {@link org.jooq.ContentType} that is used when loading migrations.
|
||||
*
|
||||
*/
|
||||
public MigrationDefaultContentType getMigrationDefaultContentType() {
|
||||
return migrationDefaultContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default {@link org.jooq.ContentType} that is used when loading migrations.
|
||||
*
|
||||
*/
|
||||
public void setMigrationDefaultContentType(MigrationDefaultContentType value) {
|
||||
this.migrationDefaultContentType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether migrations are allowed to be executed in inverse order.<p><strong>This is a potentially destructive feature, which should not be turned on in production</strong>. It is useful mostly to quickly switch between branches in a development environment. This feature is available only in commercial distributions.
|
||||
*
|
||||
@ -9383,6 +9402,15 @@ public class Settings
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default {@link org.jooq.ContentType} that is used when loading migrations.
|
||||
*
|
||||
*/
|
||||
public Settings withMigrationDefaultContentType(MigrationDefaultContentType value) {
|
||||
setMigrationDefaultContentType(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether migrations are allowed to be executed in inverse order.<p><strong>This is a potentially destructive feature, which should not be turned on in production</strong>. It is useful mostly to quickly switch between branches in a development environment. This feature is available only in commercial distributions.
|
||||
*
|
||||
@ -9956,6 +9984,7 @@ public class Settings
|
||||
builder.append("migrationHistorySchemaCreateSchemaIfNotExists", migrationHistorySchemaCreateSchemaIfNotExists);
|
||||
builder.append("migrationDefaultSchema", migrationDefaultSchema);
|
||||
builder.append("migrationSchemataCreateSchemaIfNotExists", migrationSchemataCreateSchemaIfNotExists);
|
||||
builder.append("migrationDefaultContentType", migrationDefaultContentType);
|
||||
builder.append("migrationAllowsUndo", migrationAllowsUndo);
|
||||
builder.append("migrationRevertUntracked", migrationRevertUntracked);
|
||||
builder.append("migrationAutoBaseline", migrationAutoBaseline);
|
||||
@ -11803,6 +11832,15 @@ public class Settings
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (migrationDefaultContentType == null) {
|
||||
if (other.migrationDefaultContentType!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!migrationDefaultContentType.equals(other.migrationDefaultContentType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (migrationAllowsUndo == null) {
|
||||
if (other.migrationAllowsUndo!= null) {
|
||||
return false;
|
||||
@ -12324,6 +12362,7 @@ public class Settings
|
||||
result = ((prime*result)+((migrationHistorySchemaCreateSchemaIfNotExists == null)? 0 :migrationHistorySchemaCreateSchemaIfNotExists.hashCode()));
|
||||
result = ((prime*result)+((migrationDefaultSchema == null)? 0 :migrationDefaultSchema.hashCode()));
|
||||
result = ((prime*result)+((migrationSchemataCreateSchemaIfNotExists == null)? 0 :migrationSchemataCreateSchemaIfNotExists.hashCode()));
|
||||
result = ((prime*result)+((migrationDefaultContentType == null)? 0 :migrationDefaultContentType.hashCode()));
|
||||
result = ((prime*result)+((migrationAllowsUndo == null)? 0 :migrationAllowsUndo.hashCode()));
|
||||
result = ((prime*result)+((migrationRevertUntracked == null)? 0 :migrationRevertUntracked.hashCode()));
|
||||
result = ((prime*result)+((migrationAutoBaseline == null)? 0 :migrationAutoBaseline.hashCode()));
|
||||
|
||||
@ -41,15 +41,17 @@ import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.unmodifiableCollection;
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.jooq.ContentType.INCREMENT;
|
||||
import static org.jooq.ContentType.SCRIPT;
|
||||
import static org.jooq.impl.Tools.filter;
|
||||
import static org.jooq.impl.Tools.isEmpty;
|
||||
import static org.jooq.impl.Tools.map;
|
||||
import static org.jooq.tools.StringUtils.defaultIfNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -67,6 +69,7 @@ import org.jooq.FilePattern;
|
||||
import org.jooq.Migrations;
|
||||
import org.jooq.Source;
|
||||
import org.jooq.Tag;
|
||||
import org.jooq.conf.MigrationDefaultContentType;
|
||||
import org.jooq.exception.DataMigrationVerificationException;
|
||||
import org.jooq.migrations.xml.jaxb.ChangeType;
|
||||
import org.jooq.migrations.xml.jaxb.CommitType;
|
||||
@ -173,7 +176,7 @@ final class CommitsImpl implements Commits {
|
||||
}
|
||||
|
||||
// [#9506] TODO: Formalise this decoding, and make it part of the public API
|
||||
static final class FileData {
|
||||
final class FileData {
|
||||
final FilePattern pattern;
|
||||
final Source source;
|
||||
final String path;
|
||||
@ -201,12 +204,11 @@ final class CommitsImpl implements Commits {
|
||||
// - id/increment/[path and message].sql
|
||||
// - id/[path and message].sql
|
||||
// - id.sql
|
||||
String path = pattern.path(source.file());
|
||||
java.io.File p1 = new java.io.File(path).getParentFile();
|
||||
java.io.File p1 = new java.io.File(pattern.path(source.file())).getParentFile();
|
||||
java.io.File p2 = p1 != null ? p1.getParentFile() : null;
|
||||
|
||||
this.contentType = p2 == null
|
||||
? ContentType.INCREMENT
|
||||
? defaultContentType()
|
||||
: contentType(p1.getName());
|
||||
this.path = name;
|
||||
|
||||
@ -243,6 +245,17 @@ final class CommitsImpl implements Commits {
|
||||
}
|
||||
}
|
||||
|
||||
private final ContentType defaultContentType() {
|
||||
switch (defaultIfNull(configuration.settings().getMigrationDefaultContentType(), MigrationDefaultContentType.INCREMENT)) {
|
||||
case INCREMENT:
|
||||
return INCREMENT;
|
||||
case SCRIPT:
|
||||
return SCRIPT;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unsupported ContentType: " + configuration.settings().getMigrationDefaultContentType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
List<String> strings = new ArrayList<>();
|
||||
|
||||
@ -39,6 +39,7 @@ package org.jooq.impl;
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static org.jooq.ContentType.SCRIPT;
|
||||
import static org.jooq.impl.DSL.createSchemaIfNotExists;
|
||||
import static org.jooq.impl.DSL.dropSchemaIfExists;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
@ -71,6 +72,7 @@ import org.jooq.Commits;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Constants;
|
||||
import org.jooq.ContextTransactionalRunnable;
|
||||
import org.jooq.File;
|
||||
import org.jooq.Files;
|
||||
import org.jooq.HistoryVersion;
|
||||
import org.jooq.Meta;
|
||||
@ -222,17 +224,26 @@ final class MigrationImpl extends AbstractScope implements Migration {
|
||||
);
|
||||
}
|
||||
|
||||
static final record Untracked(Meta current, Meta existing) {
|
||||
static final record Untracked(Configuration configuration, Meta current, Meta existing) {
|
||||
Queries revert() {
|
||||
return existing().migrateTo(current());
|
||||
if (existing() == null)
|
||||
return configuration().dsl().queries();
|
||||
else
|
||||
return existing().migrateTo(current());
|
||||
}
|
||||
|
||||
Queries apply() {
|
||||
return current().migrateTo(existing());
|
||||
if (current() == null)
|
||||
return configuration().dsl().queries();
|
||||
else
|
||||
return current().migrateTo(existing());
|
||||
}
|
||||
}
|
||||
|
||||
private final Untracked untracked(Set<Schema> includedSchemas) {
|
||||
if (scriptsOnly())
|
||||
return new Untracked(configuration(), null, null);
|
||||
|
||||
MigrationSchema hs = settings().getMigrationHistorySchema();
|
||||
MigrationSchema ds = settings().getMigrationDefaultSchema();
|
||||
|
||||
@ -272,7 +283,16 @@ final class MigrationImpl extends AbstractScope implements Migration {
|
||||
currentMeta = currentMeta.apply(createSchemaIfNotExists(schema));
|
||||
}
|
||||
|
||||
return new Untracked(currentMeta, existingMeta);
|
||||
return new Untracked(configuration(), currentMeta, existingMeta);
|
||||
}
|
||||
|
||||
private final boolean scriptsOnly() {
|
||||
for (Commit commit : commits())
|
||||
for (File file : commit.delta())
|
||||
if (file.type() != SCRIPT)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private final void revertUntracked(DefaultMigrationContext ctx, MigrationListener listener, HistoryRecord currentRecord) {
|
||||
|
||||
@ -1544,6 +1544,10 @@ deployed on an RDBMS that does not.]]></jxb:javadoc></jxb:property></appinfo></a
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether {@link #getMigrationSchemata()} should be created if they don't exist.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="migrationDefaultContentType" type="jooq-runtime:MigrationDefaultContentType" minOccurs="0" maxOccurs="1" default="INCREMENT">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The default {@link org.jooq.ContentType} that is used when loading migrations.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="migrationAllowsUndo" type="boolean" minOccurs="0" maxOccurs="1" default="false">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether migrations are allowed to be executed in inverse order.<p><strong>This is a potentially destructive feature, which should not be turned on in production</strong>. It is useful mostly to quickly switch between branches in a development environment. This feature is available only in commercial distributions.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
@ -1754,6 +1758,13 @@ inside of queries (including procedural statements) are still not supported.]]><
|
||||
</element>
|
||||
</all>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="MigrationDefaultContentType">
|
||||
<restriction base="string">
|
||||
<enumeration value="INCREMENT"/>
|
||||
<enumeration value="SCRIPT"/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="RenderTable">
|
||||
<restriction base="string">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user