[jOOQ/jOOQ#9506] More work on Migrations API:
- Infer JDBC driver from JDBC URL if not given explicitly - Better FileData debugging info - Add HistoryVersion type to add a migratedAt() Instant to a Version - Add a CleanMojo - Improve mojo Javadocs - Rename init node to root - Make root a reserved ID
This commit is contained in:
parent
159b664e9a
commit
2343e3c53d
@ -79,11 +79,11 @@ public abstract class AbstractMigrateMojo extends AbstractMigrationsMojo {
|
||||
.migrations()
|
||||
.migrateTo(commits.latest());
|
||||
|
||||
if (getLog().isInfoEnabled()) {
|
||||
getLog().info("Migration from version: " + migration.from());
|
||||
getLog().info("Migration to version : " + migration.to());
|
||||
getLog().info("Migration queries : " + migration.queries().queries().length);
|
||||
}
|
||||
if (getLog().isInfoEnabled())
|
||||
getLog().info(
|
||||
"Migration loaded from version " + migration.from() + " to version " + migration.to()
|
||||
+ " (number of queries: " + migration.queries().queries().length + ")"
|
||||
);
|
||||
|
||||
execute1(migration);
|
||||
}
|
||||
|
||||
@ -49,7 +49,8 @@ import org.jooq.CloseableDSLContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.conf.MigrationSchema;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.tools.StringUtils;
|
||||
import org.jooq.tools.ClassUtils;
|
||||
import org.jooq.tools.jdbc.JDBCUtils;
|
||||
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
@ -160,11 +161,14 @@ abstract class AbstractMigrationsMojo extends AbstractMojo {
|
||||
// [#2886] Add the surrounding project's dependencies to the current classloader
|
||||
Thread.currentThread().setContextClassLoader(pluginClassLoader);
|
||||
|
||||
project.getRuntimeClasspathElements().forEach(System.out::println);
|
||||
|
||||
if (jdbc == null || jdbc.url == null)
|
||||
throw new MojoExecutionException("JDBC URL is required");
|
||||
|
||||
if (jdbc.driver != null)
|
||||
Class.forName(jdbc.driver);
|
||||
String driver = driverClass(jdbc);
|
||||
if (driver != null)
|
||||
ClassUtils.loadClass(driver).getConstructor().newInstance();
|
||||
|
||||
try (CloseableDSLContext ctx = DSL.using(jdbc.url, defaultIfNull(jdbc.user, jdbc.username), jdbc.password)) {
|
||||
|
||||
@ -227,6 +231,17 @@ abstract class AbstractMigrationsMojo extends AbstractMojo {
|
||||
}
|
||||
}
|
||||
|
||||
private String driverClass(Jdbc j) {
|
||||
String result = j.driver;
|
||||
|
||||
if (result == null) {
|
||||
result = JDBCUtils.driver(j.url);
|
||||
getLog().info("Inferring driver " + result + " from URL " + j.url);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
abstract void execute0(Configuration configuration) throws Exception;
|
||||
|
||||
private URLClassLoader getClassLoader() throws MojoExecutionException {
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* Apache-2.0 license and offer limited warranties, support, maintenance, and
|
||||
* commercial database integrations.
|
||||
*
|
||||
* For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.migrations.maven;
|
||||
|
||||
import static org.apache.maven.plugins.annotations.LifecyclePhase.GENERATE_SOURCES;
|
||||
import static org.apache.maven.plugins.annotations.ResolutionScope.TEST;
|
||||
|
||||
import org.jooq.Commit;
|
||||
import org.jooq.Files;
|
||||
import org.jooq.Migration;
|
||||
import org.jooq.Queries;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.Version;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
|
||||
/**
|
||||
* Clean the configured schemas, dropping all objects.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Mojo(
|
||||
name = "clean",
|
||||
defaultPhase = GENERATE_SOURCES,
|
||||
requiresDependencyResolution = TEST,
|
||||
threadSafe = true
|
||||
)
|
||||
public class CleanMojo extends AbstractMigrateMojo {
|
||||
|
||||
@Override
|
||||
final void execute1(Migration migration) throws Exception {
|
||||
Commit root = migration.to().root();
|
||||
root.settings().setMigrationAllowsUndo(true);
|
||||
migration.dsl().migrations().migrateTo(root).execute();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* Apache-2.0 license and offer limited warranties, support, maintenance, and
|
||||
* commercial database integrations.
|
||||
*
|
||||
* For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.migrations.maven;
|
||||
|
||||
import static org.apache.maven.plugins.annotations.LifecyclePhase.GENERATE_SOURCES;
|
||||
import static org.apache.maven.plugins.annotations.ResolutionScope.TEST;
|
||||
import static org.jooq.tools.StringUtils.isEmpty;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.jooq.HistoryVersion;
|
||||
import org.jooq.Migration;
|
||||
import org.jooq.Version;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
|
||||
/**
|
||||
* Show the history of currently installed versions on the connected database.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Mojo(
|
||||
name = "history",
|
||||
defaultPhase = GENERATE_SOURCES,
|
||||
requiresDependencyResolution = TEST,
|
||||
threadSafe = true
|
||||
)
|
||||
public class HistoryMojo extends AbstractMigrateMojo {
|
||||
|
||||
@Override
|
||||
final void execute1(Migration migration) throws Exception {
|
||||
if (getLog().isInfoEnabled()) {
|
||||
for (HistoryVersion version : migration.dsl().migrations().history()) {
|
||||
getLog().info(string(version.migratedAt()) + " - Version: " + string(version.version()));
|
||||
|
||||
if (version.version().parents().size() > 1) {
|
||||
getLog().info(" Merged parents: ");
|
||||
|
||||
for (Version p : version.version().parents())
|
||||
getLog().info(" - " + string(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final String string(Instant instant) {
|
||||
if (instant == null)
|
||||
return "0000-00-00T00:00:00.000Z";
|
||||
else
|
||||
return StringUtils.rightPad(instant.toString(), 24);
|
||||
}
|
||||
|
||||
private final String string(Version version) {
|
||||
return version.id() + (!isEmpty(version.message()) ? " (" + version.message() + ")" : "");
|
||||
}
|
||||
}
|
||||
@ -44,10 +44,11 @@ import org.jooq.Migration;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
|
||||
/**
|
||||
* The jOOQ Migrations migrate mojo
|
||||
* Log the queries of the outstanding migration.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@ -63,10 +64,14 @@ public class LogMojo extends AbstractMigrateMojo {
|
||||
final void execute1(Migration migration) throws Exception {
|
||||
if (getLog().isInfoEnabled()) {
|
||||
Query[] queries = migration.queries().queries();
|
||||
int pad = ("" + queries.length).length();
|
||||
|
||||
for (int i = 0; i < queries.length; i++)
|
||||
getLog().info(" Query " + StringUtils.leftPad("" + (i + 1), pad) + ": " + queries[i]);
|
||||
log(getLog(), queries);
|
||||
}
|
||||
}
|
||||
|
||||
static final void log(Log log, Query[] queries) {
|
||||
int pad = ("" + queries.length).length();
|
||||
|
||||
for (int i = 0; i < queries.length; i++)
|
||||
log.info(" Query " + StringUtils.leftPad("" + (i + 1), pad) + ": " + queries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ import org.jooq.Migration;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
|
||||
/**
|
||||
* The jOOQ Migrations migrate mojo
|
||||
* Run a migration.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
|
||||
@ -45,7 +45,7 @@ import org.jooq.Configuration;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
|
||||
/**
|
||||
* The jOOQ Migrations resolve mojo
|
||||
* Mark an outstanding migration as resolved.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
|
||||
@ -45,7 +45,7 @@ import org.jooq.Migration;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
|
||||
/**
|
||||
* The jOOQ Migrations verify mojo
|
||||
* Verify an outstanding migration.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
|
||||
@ -39,8 +39,8 @@ package org.jooq;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A change set describing the exact migration path between the
|
||||
|
||||
@ -52,7 +52,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Experimental
|
||||
public interface History extends Iterable<Version>, Scope {
|
||||
public interface History extends Iterable<HistoryVersion>, Scope {
|
||||
|
||||
/**
|
||||
* The root {@link Version}.
|
||||
@ -69,7 +69,7 @@ public interface History extends Iterable<Version>, Scope {
|
||||
*/
|
||||
@NotNull
|
||||
@Experimental
|
||||
Version root() throws DataMigrationVerificationException;
|
||||
HistoryVersion root() throws DataMigrationVerificationException;
|
||||
|
||||
/**
|
||||
* The currently installed {@link Version}.
|
||||
@ -82,7 +82,7 @@ public interface History extends Iterable<Version>, Scope {
|
||||
*/
|
||||
@NotNull
|
||||
@Experimental
|
||||
Version current();
|
||||
HistoryVersion current();
|
||||
|
||||
/**
|
||||
* Resolve any previous failures in the {@link History}.
|
||||
|
||||
70
jOOQ/src/main/java/org/jooq/HistoryVersion.java
Normal file
70
jOOQ/src/main/java/org/jooq/HistoryVersion.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* Apache-2.0 license and offer limited warranties, support, maintenance, and
|
||||
* commercial database integrations.
|
||||
*
|
||||
* For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A {@link Version} in the context of a {@link History}.
|
||||
*/
|
||||
public interface HistoryVersion {
|
||||
|
||||
/**
|
||||
* The version.
|
||||
*/
|
||||
@NotNull
|
||||
Version version();
|
||||
|
||||
/**
|
||||
* The history creating this {@link HistoryVersion}.
|
||||
*/
|
||||
@NotNull
|
||||
History history();
|
||||
|
||||
/**
|
||||
* The time when this {@link HistoryVersion} was migrated to in the context
|
||||
* of the {@link #history()}.
|
||||
* <p>
|
||||
* This is <code>null</code> for the {@link History#root()} version.
|
||||
*/
|
||||
@Nullable
|
||||
Instant migratedAt();
|
||||
}
|
||||
@ -39,21 +39,26 @@ package org.jooq;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental;
|
||||
|
||||
/**
|
||||
* An abstraction over directed, acyclic graph models.
|
||||
* <p>
|
||||
* Examples of such models are {@link Version} / {@link Versions} or
|
||||
* {@link Commit} / {@link Commits}.
|
||||
* Examples of such models are {@link Version} or {@link Commit} /
|
||||
* {@link Commits}.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Experimental
|
||||
public interface Node<N extends Node<N>> extends Scope {
|
||||
|
||||
/**
|
||||
* The name of the {@link #root()} node.
|
||||
*/
|
||||
String ROOT = "root";
|
||||
|
||||
/**
|
||||
* The ID of the node, unique within the graph.
|
||||
*/
|
||||
|
||||
@ -46,6 +46,7 @@ import java.util.Map.Entry;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Node;
|
||||
import org.jooq.exception.DataDefinitionException;
|
||||
import org.jooq.exception.DataMigrationVerificationException;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
@ -54,7 +55,7 @@ abstract class AbstractNode<N extends Node<N>> extends AbstractLazyScope impleme
|
||||
|
||||
final N root;
|
||||
final String id;
|
||||
final String message;
|
||||
String message;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
AbstractNode(Configuration configuration, String id, String message, N root) {
|
||||
|
||||
@ -64,10 +64,12 @@ import org.jooq.DSLContext;
|
||||
import org.jooq.File;
|
||||
import org.jooq.Files;
|
||||
import org.jooq.Meta;
|
||||
import org.jooq.Node;
|
||||
import org.jooq.Source;
|
||||
import org.jooq.Tag;
|
||||
import org.jooq.Version;
|
||||
import org.jooq.exception.DataMigrationException;
|
||||
import org.jooq.exception.DataMigrationVerificationException;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
/**
|
||||
@ -84,6 +86,9 @@ final class CommitImpl extends AbstractNode<Commit> implements Commit {
|
||||
CommitImpl(Configuration configuration, String id, String message, Commit root, List<Commit> parents, Collection<? extends File> delta) {
|
||||
super(configuration, id, message, root);
|
||||
|
||||
if (Node.ROOT.equals(id) && root != null)
|
||||
throw new DataMigrationVerificationException("Cannot use reserved ID \"root\"");
|
||||
|
||||
this.ctx = configuration.dsl();
|
||||
this.parents = parents;
|
||||
this.tags = new ArrayList<>();
|
||||
@ -363,7 +368,7 @@ final class CommitImpl extends AbstractNode<Commit> implements Commit {
|
||||
}
|
||||
|
||||
Map<String, File> versionFiles = new HashMap<>();
|
||||
Version from = version(ctx.migrations().version("init"), id(), versionFiles, history.values());
|
||||
Version from = version(ctx.migrations().version(ROOT), id(), versionFiles, history.values());
|
||||
Version to = version(from, resultCommit.id(), versionFiles, result.values());
|
||||
return new FilesImpl(from, to, result.values());
|
||||
}
|
||||
|
||||
@ -211,6 +211,24 @@ final class CommitsImpl implements Commits {
|
||||
this.tags.add(new TagType().withId(tagArray[0]).withMessage(tagArray.length > 1 ? tagArray[1] : null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
List<String> strings = new ArrayList<>();
|
||||
|
||||
if (id != null)
|
||||
strings.add("id: " + id);
|
||||
if (version != null)
|
||||
strings.add("version: " + version);
|
||||
if (message != null)
|
||||
strings.add("message: " + message);
|
||||
if (!tags.isEmpty())
|
||||
strings.add("tags: " + tags);
|
||||
if (!parentIds.isEmpty())
|
||||
strings.add("parents: " + parentIds);
|
||||
|
||||
return "File: " + file + " " + strings;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,7 +264,7 @@ final class CommitsImpl implements Commits {
|
||||
List<FileData> list = Stream.of(sql).map(FileData::new).collect(toList());
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
list.forEach(f -> log.debug("Reading file", f.basename));
|
||||
list.forEach(f -> log.debug("Reading file", f));
|
||||
|
||||
/*
|
||||
* An example:
|
||||
@ -320,6 +338,11 @@ final class CommitsImpl implements Commits {
|
||||
public final Commits load(MigrationsType migrations) {
|
||||
Map<String, CommitType> map = new HashMap<>();
|
||||
|
||||
for (CommitType commit : migrations.getCommits())
|
||||
if (Commit.ROOT.equals(commit.getId()))
|
||||
throw new DataMigrationVerificationException("Cannot define reserved commit name \"root\"");
|
||||
|
||||
map.put(Commit.ROOT, new CommitType().withId(root.id()).withMessage(root.message()));
|
||||
for (CommitType commit : migrations.getCommits())
|
||||
map.put(commit.getId(), commit);
|
||||
|
||||
|
||||
@ -50,12 +50,14 @@ import static org.jooq.impl.HistoryStatus.SUCCESS;
|
||||
import static org.jooq.impl.Tools.isEmpty;
|
||||
import static org.jooq.tools.StringUtils.isBlank;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jooq.Commit;
|
||||
@ -63,6 +65,7 @@ import org.jooq.Commits;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.History;
|
||||
import org.jooq.HistoryVersion;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Version;
|
||||
import org.jooq.conf.InterpreterSearchSchema;
|
||||
@ -72,6 +75,7 @@ import org.jooq.conf.MigrationSchema;
|
||||
import org.jooq.conf.RenderMapping;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.exception.DataMigrationVerificationException;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -80,10 +84,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
class HistoryImpl extends AbstractScope implements History {
|
||||
|
||||
final DSLContext ctx;
|
||||
final DSLContext historyCtx;
|
||||
final Commits commits;
|
||||
final List<Version> versions;
|
||||
private static final JooqLogger log = JooqLogger.getLogger(HistoryImpl.class);
|
||||
|
||||
final DSLContext ctx;
|
||||
final DSLContext historyCtx;
|
||||
final Commits commits;
|
||||
final List<HistoryVersion> versions;
|
||||
|
||||
HistoryImpl(Configuration configuration) {
|
||||
super(configuration);
|
||||
@ -97,12 +103,12 @@ class HistoryImpl extends AbstractScope implements History {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Iterator<Version> iterator() {
|
||||
public final Iterator<HistoryVersion> iterator() {
|
||||
return unmodifiableList(versions).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Version root() {
|
||||
public final HistoryVersion root() {
|
||||
if (!isEmpty(versions))
|
||||
return versions.get(0);
|
||||
else
|
||||
@ -110,7 +116,7 @@ class HistoryImpl extends AbstractScope implements History {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Version current() {
|
||||
public final HistoryVersion current() {
|
||||
if (!isEmpty(versions))
|
||||
return versions.get(versions.size() - 1);
|
||||
else
|
||||
@ -218,11 +224,15 @@ class HistoryImpl extends AbstractScope implements History {
|
||||
return false;
|
||||
}
|
||||
|
||||
private final List<Version> initVersions() {
|
||||
List<Version> result = new ArrayList<>();
|
||||
private final List<HistoryVersion> initVersions() {
|
||||
List<HistoryVersion> result = new ArrayList<>();
|
||||
|
||||
if (existsHistory()) {
|
||||
result.add(commits.root().version());
|
||||
result.add(new HistoryVersionImpl(
|
||||
this,
|
||||
commits.root().version(),
|
||||
null
|
||||
));
|
||||
|
||||
for (HistoryRecord r : historyCtx
|
||||
.selectFrom(HISTORY)
|
||||
@ -232,9 +242,20 @@ class HistoryImpl extends AbstractScope implements History {
|
||||
Commit commit = commits.get(r.getMigratedTo());
|
||||
|
||||
if (commit != null)
|
||||
result.add(commit.version());
|
||||
result.add(new HistoryVersionImpl(
|
||||
this,
|
||||
commit.version(),
|
||||
r.getMigratedAt().toInstant()
|
||||
));
|
||||
else
|
||||
throw new DataMigrationVerificationException("CommitProvider didn't provide version for ID: " + r.getMigratedTo());
|
||||
throw new DataMigrationVerificationException(
|
||||
"""
|
||||
CommitProvider didn't provide version for ID: {id}
|
||||
|
||||
This may happen if a successful migration has happened in a database, but the source
|
||||
for this migration is not available.
|
||||
""".replace("{id}", r.getMigratedTo())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,6 +277,7 @@ class HistoryImpl extends AbstractScope implements History {
|
||||
&& historyCtx.settings().getMigrationDefaultSchema() != null)
|
||||
historyCtx.createSchemaIfNotExists("").execute();
|
||||
|
||||
log.info("Initialising history table: " + historyCtx.map(HISTORY));
|
||||
historyCtx.meta(HISTORY).ddl().executeBatch();
|
||||
}
|
||||
}
|
||||
@ -272,6 +294,31 @@ class HistoryImpl extends AbstractScope implements History {
|
||||
throw new DataMigrationVerificationException("No current history record found to resolve");
|
||||
}
|
||||
|
||||
static final record HistoryVersionImpl(History history, Version version, Instant migratedAt) implements HistoryVersion {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
HistoryVersionImpl other = (HistoryVersionImpl) obj;
|
||||
return Objects.equals(version, other.version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HistoryVersion [version=" + version + ", migratedAt=" + migratedAt + "]";
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// The Object API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -169,7 +169,16 @@ final class MigrationImpl extends AbstractScope implements Migration {
|
||||
|
||||
for (Schema schema : history.lookup(commit.meta().getSchemas()))
|
||||
if (!ctx.migratedSchemas().contains(schema))
|
||||
throw new DataMigrationVerificationException("Schema is referenced from commit, but not configured for migration: " + schema);
|
||||
throw new DataMigrationVerificationException(
|
||||
"""
|
||||
Schema is referenced from commit, but not configured for migration: {schema}
|
||||
|
||||
All schemas that are referenced from commits in a migration must be configured for
|
||||
inclusion in the migration
|
||||
|
||||
TODO doclink
|
||||
""".replace("{schema}", schema.toString())
|
||||
);
|
||||
}
|
||||
|
||||
private final Queries revertUntrackedQueries(Set<Schema> includedSchemas) {
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.jooq.Commit.ROOT;
|
||||
|
||||
import org.jooq.Commit;
|
||||
import org.jooq.Commits;
|
||||
@ -75,7 +76,7 @@ final class MigrationsImpl extends AbstractScope implements Migrations {
|
||||
|
||||
@Override
|
||||
public final Commits commits() {
|
||||
return new CommitsImpl(configuration(), new CommitImpl(configuration(), "init", "init", null, emptyList(), emptyList()));
|
||||
return new CommitsImpl(configuration(), new CommitImpl(configuration(), ROOT, ROOT, null, emptyList(), emptyList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
Reference in New Issue
Block a user