[jOOQ/jOOQ#9506] Implement Settings.migrationAllowsUndo

This commit is contained in:
Lukas Eder 2019-12-17 13:12:08 +01:00
parent f6870fe15c
commit 5d0e9226ab
5 changed files with 66 additions and 5 deletions

View File

@ -39,6 +39,8 @@ package org.jooq;
import java.util.Collection;
import org.jooq.conf.Settings;
/**
* A version ID attached to a {@link Meta} description of a database.
*
@ -58,6 +60,17 @@ public interface Version {
/**
* Produce a migration to a new version.
* <p>
* In jOOQ's commercial distributions, this method allows for migrating
* between versions in any direction, regardless of which version was
* "first" in a version graph, or if the two versions are on different
* branches. The resulting queries are potentially destructive in such a
* case. Such destructive queries ("UNDO" migrations) are prevented by
* default, and can be turned on using
* {@link Settings#isMigrationAllowsUndo()}.
* <p>
* In jOOQ's Open Source Edition, this method only allows for migrating
* "forward".
*/
Queries migrateTo(Version version);

View File

@ -196,6 +196,8 @@ public class Settings
@XmlElement(type = String.class)
@XmlJavaTypeAdapter(LocaleAdapter.class)
protected Locale interpreterLocale;
@XmlElement(defaultValue = "false")
protected Boolean migrationAllowsUndo = false;
@XmlElement(defaultValue = "true")
protected Boolean migrationAutoValidation = true;
@XmlElement(type = String.class)
@ -1659,6 +1661,30 @@ public class Settings
this.interpreterLocale = 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.
*
* @return
* possible object is
* {@link Boolean }
*
*/
public Boolean isMigrationAllowsUndo() {
return migrationAllowsUndo;
}
/**
* Sets the value of the migrationAllowsUndo property.
*
* @param value
* allowed object is
* {@link Boolean }
*
*/
public void setMigrationAllowsUndo(Boolean value) {
this.migrationAllowsUndo = value;
}
/**
* Whether a migration automatically runs a validation first.
*
@ -2407,6 +2433,11 @@ public class Settings
return this;
}
public Settings withMigrationAllowsUndo(Boolean value) {
setMigrationAllowsUndo(value);
return this;
}
public Settings withMigrationAutoValidation(Boolean value) {
setMigrationAutoValidation(value);
return this;
@ -2608,6 +2639,7 @@ public class Settings
builder.append("interpreterDialect", interpreterDialect);
builder.append("interpreterNameLookupCaseSensitivity", interpreterNameLookupCaseSensitivity);
builder.append("interpreterLocale", interpreterLocale);
builder.append("migrationAllowsUndo", migrationAllowsUndo);
builder.append("migrationAutoValidation", migrationAutoValidation);
builder.append("locale", locale);
builder.append("parseDialect", parseDialect);
@ -3236,6 +3268,15 @@ public class Settings
return false;
}
}
if (migrationAllowsUndo == null) {
if (other.migrationAllowsUndo!= null) {
return false;
}
} else {
if (!migrationAllowsUndo.equals(other.migrationAllowsUndo)) {
return false;
}
}
if (migrationAutoValidation == null) {
if (other.migrationAutoValidation!= null) {
return false;
@ -3426,6 +3467,7 @@ public class Settings
result = ((prime*result)+((interpreterDialect == null)? 0 :interpreterDialect.hashCode()));
result = ((prime*result)+((interpreterNameLookupCaseSensitivity == null)? 0 :interpreterNameLookupCaseSensitivity.hashCode()));
result = ((prime*result)+((interpreterLocale == null)? 0 :interpreterLocale.hashCode()));
result = ((prime*result)+((migrationAllowsUndo == null)? 0 :migrationAllowsUndo.hashCode()));
result = ((prime*result)+((migrationAutoValidation == null)? 0 :migrationAutoValidation.hashCode()));
result = ((prime*result)+((locale == null)? 0 :locale.hashCode()));
result = ((prime*result)+((parseDialect == null)? 0 :parseDialect.hashCode()));

View File

@ -144,7 +144,6 @@ final class MigrationImpl extends AbstractScope implements Migration {
validateVersionProvider(from());
validateVersionProvider(to());
validateUnexpectedObjects();
}

View File

@ -37,6 +37,7 @@
*/
package org.jooq.impl;
import static java.lang.Boolean.TRUE;
import static org.jooq.impl.DSL.createSchema;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.schema;
@ -154,11 +155,13 @@ final class VersionImpl implements Version {
VersionImpl subgraph = ((VersionImpl) version).subgraphTo(this);
// TODO: When there's no common ancestor, we're switching branches.
// We should make this configurable, and turn it off by default.
// This is hardly what we want in production.
if (subgraph == null)
return meta().migrateTo(version.meta());
throw new DataDefinitionException("No forward path available between versions " + id() + " and " + version.id() + ". Use Settings.migrationAllowsUndo to enable this feature.");
return migrateTo(subgraph, ctx.queries());
}

View File

@ -403,6 +403,10 @@ jOOQ queries, for which no specific fetchSize value was specified.]]></jxb:javad
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#9677] The search path to be used for unqualified table lookups by the interpreter.]]></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>
<element name="migrationAutoValidation" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether a migration automatically runs a validation first.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>