From 5d0e9226ab0c61481f4f84a2c763abfa90129b0e Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Tue, 17 Dec 2019 13:12:08 +0100 Subject: [PATCH] [jOOQ/jOOQ#9506] Implement Settings.migrationAllowsUndo --- jOOQ/src/main/java/org/jooq/Version.java | 13 ++++++ .../src/main/java/org/jooq/conf/Settings.java | 42 +++++++++++++++++++ .../java/org/jooq/impl/MigrationImpl.java | 1 - .../main/java/org/jooq/impl/VersionImpl.java | 11 +++-- .../resources/xsd/jooq-runtime-3.13.0.xsd | 4 ++ 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/Version.java b/jOOQ/src/main/java/org/jooq/Version.java index f5117c2b4f..e2f48c6961 100644 --- a/jOOQ/src/main/java/org/jooq/Version.java +++ b/jOOQ/src/main/java/org/jooq/Version.java @@ -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. + *

+ * 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()}. + *

+ * In jOOQ's Open Source Edition, this method only allows for migrating + * "forward". */ Queries migrateTo(Version version); diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index 321082a8c4..6868345e2c 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -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.

This is a potentially destructive feature, which should not be turned on in production. 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())); diff --git a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java index 25a298b999..2655586c03 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java @@ -144,7 +144,6 @@ final class MigrationImpl extends AbstractScope implements Migration { validateVersionProvider(from()); validateVersionProvider(to()); - validateUnexpectedObjects(); } diff --git a/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java b/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java index dd9a463407..8d91764073 100644 --- a/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java @@ -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()); } diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd index 669916849f..997563b0aa 100644 --- a/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd +++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.13.0.xsd @@ -403,6 +403,10 @@ jOOQ queries, for which no specific fetchSize value was specified.]]> + + This is a potentially destructive feature, which should not be turned on in production. It is useful mostly to quickly switch between branches in a development environment. This feature is available only in commercial distributions.]]> + +