diff --git a/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AddSnapshotMojo.java b/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AddSnapshotMojo.java index a4ffea314d..d60514eb15 100644 --- a/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AddSnapshotMojo.java +++ b/jOOQ-migrations-maven/src/main/java/org/jooq/migrations/maven/AddSnapshotMojo.java @@ -80,31 +80,35 @@ public class AddSnapshotMojo extends AbstractMigrateMojo { @Override final void execute1(Migration migration) throws Exception { - History history = migration.dsl().migrations().history(); - Queries queries = migration.queries(); + migration.configuration().requireCommercial(() -> "Snapshots are a commercial only feature. Please upgrade to the jOOQ Professional Edition or jOOQ Enterprise Edition."); + + + + + + + + + + + + + + + + + + + + + + - if (queries.queries().length > 0) { - Queries queries2 = migration.queries(); - getLog().warn("There are pending changes that have not been migrated yet, which are not in the snapshot:\n" - + queries2); - } - HistoryVersion current = history.current(); - File file = new File(file(directory), current.version().id() + "/snapshots/" + fileName(current.version().id(), fileName, "snapshot")); - file.getParentFile().mkdirs(); - DDLExportConfiguration config = new DDLExportConfiguration(); - // Don't create schema in snapshots if it is managed by the migration. - if (TRUE.equals(migration.settings().isMigrationSchemataCreateSchemaIfNotExists())) - config = config.flags(EnumSet.complementOf(EnumSet.of(DDLFlag.SCHEMA))); - Meta meta = current.version().meta(); - String export = meta.ddl(config).toString(); - if (getLog().isInfoEnabled()) - getLog().info("Writing snapshot to: " + file + "\n" + export); - Files.write(file.toPath(), asList(export), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } } diff --git a/jOOQ-migrations/src/main/java/org/jooq/migrations/jgit/GitCommitProvider.java b/jOOQ-migrations/src/main/java/org/jooq/migrations/jgit/GitCommitProvider.java index 802279d77c..ab8c981384 100644 --- a/jOOQ-migrations/src/main/java/org/jooq/migrations/jgit/GitCommitProvider.java +++ b/jOOQ-migrations/src/main/java/org/jooq/migrations/jgit/GitCommitProvider.java @@ -82,7 +82,6 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.io.DisabledOutputStream; -import org.jetbrains.annotations.NotNull; /** * A {@link CommitProvider} that produces versions from a git repository. @@ -225,16 +224,18 @@ public final class GitCommitProvider implements CommitProvider { add(uncommitted, status.getChanged()); del(uncommitted, status.getRemoved()); + String message = null; + // [#9506] TODO: It should be possible to migrate to uncommitted changes in dev mode. if (!uncommitted.isEmpty()) - commit = commit.commit("uncommitted", "uncommitted", uncommitted).valid(false); + commit = commit.commit(message = "uncommitted", message, uncommitted).valid(false); add(untracked, status.getModified()); add(untracked, status.getUntracked()); del(untracked, status.getMissing()); if (!untracked.isEmpty()) - commit = commit.commit("untracked", "untracked", untracked).valid(false); + commit = commit.commit(message = message == null ? "untracked" : "uncommitted-and-untracked", message, untracked).valid(false); return commit; } diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index 78b3ef9439..565de0c46c 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -485,7 +485,9 @@ public class Settings @XmlSchemaType(name = "string") protected MigrationDefaultContentType migrationDefaultContentType = MigrationDefaultContentType.INCREMENT; @XmlElement(defaultValue = "false") - protected Boolean migrationAllowsUndo = false; + protected Boolean migrationAllowUndo = false; + @XmlElement(defaultValue = "false") + protected Boolean migrationAllowInvalidCommits = false; @XmlElement(defaultValue = "false") protected Boolean migrationRevertUntracked = false; @XmlElement(defaultValue = "false") @@ -6223,8 +6225,8 @@ public class Settings * {@link Boolean } * */ - public Boolean isMigrationAllowsUndo() { - return migrationAllowsUndo; + public Boolean isMigrationAllowUndo() { + return migrationAllowUndo; } /** @@ -6235,8 +6237,32 @@ public class Settings * {@link Boolean } * */ - public void setMigrationAllowsUndo(Boolean value) { - this.migrationAllowsUndo = value; + public void setMigrationAllowUndo(Boolean value) { + this.migrationAllowUndo = value; + } + + /** + * Whether migrations to invalid commits ({@link org.jooq.Commit#valid()}) are allowed.

This is a potentially destructive feature, which should not be turned on in production. It is useful mostly to quickly test uncommited or inconsistent changes in development. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public Boolean isMigrationAllowInvalidCommits() { + return migrationAllowInvalidCommits; + } + + /** + * Whether migrations to invalid commits ({@link org.jooq.Commit#valid()}) are allowed.

This is a potentially destructive feature, which should not be turned on in production. It is useful mostly to quickly test uncommited or inconsistent changes in development. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setMigrationAllowInvalidCommits(Boolean value) { + this.migrationAllowInvalidCommits = value; } /** @@ -9415,8 +9441,17 @@ public class Settings * 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. * */ - public Settings withMigrationAllowsUndo(Boolean value) { - setMigrationAllowsUndo(value); + public Settings withMigrationAllowUndo(Boolean value) { + setMigrationAllowUndo(value); + return this; + } + + /** + * Whether migrations to invalid commits ({@link org.jooq.Commit#valid()}) are allowed.

This is a potentially destructive feature, which should not be turned on in production. It is useful mostly to quickly test uncommited or inconsistent changes in development. + * + */ + public Settings withMigrationAllowInvalidCommits(Boolean value) { + setMigrationAllowInvalidCommits(value); return this; } @@ -9985,7 +10020,8 @@ public class Settings builder.append("migrationDefaultSchema", migrationDefaultSchema); builder.append("migrationSchemataCreateSchemaIfNotExists", migrationSchemataCreateSchemaIfNotExists); builder.append("migrationDefaultContentType", migrationDefaultContentType); - builder.append("migrationAllowsUndo", migrationAllowsUndo); + builder.append("migrationAllowUndo", migrationAllowUndo); + builder.append("migrationAllowInvalidCommits", migrationAllowInvalidCommits); builder.append("migrationRevertUntracked", migrationRevertUntracked); builder.append("migrationAutoBaseline", migrationAutoBaseline); builder.append("migrationAutoVerification", migrationAutoVerification); @@ -11841,12 +11877,21 @@ public class Settings return false; } } - if (migrationAllowsUndo == null) { - if (other.migrationAllowsUndo!= null) { + if (migrationAllowUndo == null) { + if (other.migrationAllowUndo!= null) { return false; } } else { - if (!migrationAllowsUndo.equals(other.migrationAllowsUndo)) { + if (!migrationAllowUndo.equals(other.migrationAllowUndo)) { + return false; + } + } + if (migrationAllowInvalidCommits == null) { + if (other.migrationAllowInvalidCommits!= null) { + return false; + } + } else { + if (!migrationAllowInvalidCommits.equals(other.migrationAllowInvalidCommits)) { return false; } } @@ -12363,7 +12408,8 @@ public class Settings 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)+((migrationAllowUndo == null)? 0 :migrationAllowUndo.hashCode())); + result = ((prime*result)+((migrationAllowInvalidCommits == null)? 0 :migrationAllowInvalidCommits.hashCode())); result = ((prime*result)+((migrationRevertUntracked == null)? 0 :migrationRevertUntracked.hashCode())); result = ((prime*result)+((migrationAutoBaseline == null)? 0 :migrationAutoBaseline.hashCode())); result = ((prime*result)+((migrationAutoVerification == null)? 0 :migrationAutoVerification.hashCode())); diff --git a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java index a00146039a..70a2e38bee 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java @@ -199,9 +199,15 @@ final class MigrationImpl extends AbstractScope implements Migration { validateCommitProvider(ctx, to()); revertUntracked(ctx, null, currentRecord); - // [#9506] TODO: Better error handling helping the understand see their mistake - if (!to().valid()) - throw new DataMigrationVerificationException("Commit is not a valid commit to migrate to: " + to()); + if (!to().valid() && !TRUE.equals(ctx.settings().isMigrationAllowInvalidCommits())) + throw new DataMigrationVerificationException( + """ + Commit is not a valid commit to migrate to: {commit} + Invalid commits include: + - Uncommitted or untracked changes in the GitCommitProvider + - Commits leading to inconsistent migration states due to editing of commit paths + """.replace("{commit}", to().id()) + ); } private final void validateCommitProvider(DefaultMigrationContext ctx, Commit commit) { @@ -216,9 +222,7 @@ final class MigrationImpl extends AbstractScope implements Migration { The commit referencing the schema: {commit}. All schemas that are referenced from commits in a migration must be configured for - inclusion in the migration - - TODO doclink + inclusion in the migration. """.replace("{schema}", schema.toString()) .replace("{commit}", commit.toString()) ); diff --git a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd index d7fbb6eb60..c4a11f65cd 100644 --- a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd +++ b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.20.0.xsd @@ -1548,10 +1548,14 @@ deployed on an RDBMS that does not.]]> - + 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.]]> + + This is a potentially destructive feature, which should not be turned on in production. It is useful mostly to quickly test uncommited or inconsistent changes in development.]]> + + This is a potentially destructive feature, which should not be turned on in production. It is useful mostly to quickly revert any elements created in a development environment. This feature is available only in commercial distributions.]]>