diff --git a/jOOQ/src/main/java/org/jooq/File.java b/jOOQ/src/main/java/org/jooq/File.java
index c90bba2cb3..a49fd7cc09 100644
--- a/jOOQ/src/main/java/org/jooq/File.java
+++ b/jOOQ/src/main/java/org/jooq/File.java
@@ -43,6 +43,9 @@ import org.jetbrains.annotations.ApiStatus.Experimental;
/**
* A source of migration content.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*
* @author Lukas Eder
*/
@@ -51,25 +54,41 @@ public interface File {
/**
* The path of the file within the repository.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*/
+ @Experimental
@NotNull
String path();
/**
* The name of the file.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*/
+ @Experimental
@NotNull
String name();
/**
* The file content.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*/
+ @Experimental
@Nullable
String content();
/**
* The file type.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*/
+ @Experimental
@NotNull
ContentType type();
}
diff --git a/jOOQ/src/main/java/org/jooq/Files.java b/jOOQ/src/main/java/org/jooq/Files.java
index 69d452993b..27c43ae00f 100644
--- a/jOOQ/src/main/java/org/jooq/Files.java
+++ b/jOOQ/src/main/java/org/jooq/Files.java
@@ -38,24 +38,37 @@
package org.jooq;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.ApiStatus.Experimental;
/**
* A set of files that are in a specific order.
*
* This type will help make sure that duplicate occurrences of the same file
* (e.g. edits) are streamlined.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*/
+@Experimental
public interface Files extends Iterable {
/**
* The from version from which this migration is done.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*/
@NotNull
+ @Experimental
Version from();
/**
* The to version to which this migration is done.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
*/
@NotNull
+ @Experimental
Version to();
}
diff --git a/jOOQ/src/main/java/org/jooq/History.java b/jOOQ/src/main/java/org/jooq/History.java
new file mode 100644
index 0000000000..ecd2c92981
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/History.java
@@ -0,0 +1,86 @@
+/*
+ * 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
+ * ASL 2.0 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 org.jooq.exception.DataMigrationVerificationException;
+
+import org.jetbrains.annotations.ApiStatus.Experimental;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * The History of {@link Version} elements as installed by previous
+ * {@link Migrations}.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
+ *
+ * @author Lukas Eder
+ */
+@Experimental
+public interface History extends Iterable {
+
+ /**
+ * The root {@link Version}.
+ *
+ * This corresponds to the {@link Configuration#commitProvider()}'s
+ * {@link Commits#root()} if migrations have been initialised on the
+ * configured database.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
+ *
+ * @throws DataMigrationVerificationException If no root version is
+ * available (e.g. because no migration has happened yet).
+ */
+ @NotNull
+ @Experimental
+ Version root() throws DataMigrationVerificationException;
+
+ /**
+ * The currently installed {@link Version}.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
+ *
+ * @throws DataMigrationVerificationException If no root version is
+ * available (e.g. because no migration has happened yet).
+ */
+ @NotNull
+ @Experimental
+ Version current();
+}
diff --git a/jOOQ/src/main/java/org/jooq/Migrations.java b/jOOQ/src/main/java/org/jooq/Migrations.java
index 7469343124..f0dced4167 100644
--- a/jOOQ/src/main/java/org/jooq/Migrations.java
+++ b/jOOQ/src/main/java/org/jooq/Migrations.java
@@ -80,6 +80,17 @@ public interface Migrations {
@NotNull
Commits commits();
+ /**
+ * Retrieve the {@link History} of previously installed {@link Version}
+ * objects from the database.
+ *
+ * This is EXPERIMENTAL functionality and subject to change in future jOOQ
+ * versions.
+ */
+ @Experimental
+ @NotNull
+ History history();
+
/**
* Create a migration from the currently installed version to a new version.
*
diff --git a/jOOQ/src/main/java/org/jooq/impl/CommitImpl.java b/jOOQ/src/main/java/org/jooq/impl/CommitImpl.java
index ef66141fa6..cac7c3a43f 100644
--- a/jOOQ/src/main/java/org/jooq/impl/CommitImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/CommitImpl.java
@@ -423,6 +423,10 @@ final class CommitImpl extends AbstractNode implements Commit {
files.clear();
}
+ // -------------------------------------------------------------------------
+ // The Object API
+ // -------------------------------------------------------------------------
+
@Override
public int hashCode() {
return id().hashCode();
diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java
index 0617665cdd..86a28b55e2 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java
@@ -175,6 +175,7 @@ import org.jooq.MergeKeyStep9;
import org.jooq.MergeKeyStepN;
import org.jooq.MergeUsingStep;
import org.jooq.Meta;
+import org.jooq.Migrations;
import org.jooq.Name;
import org.jooq.Param;
import org.jooq.Parser;
@@ -393,8 +394,8 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
}
@Override
- public org.jooq.Migrations migrations() {
- return new MigrationsImpl(this);
+ public Migrations migrations() {
+ return new MigrationsImpl(configuration());
}
@Override
diff --git a/jOOQ/src/main/java/org/jooq/impl/HistoryImpl.java b/jOOQ/src/main/java/org/jooq/impl/HistoryImpl.java
new file mode 100644
index 0000000000..4d93ab9a23
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/impl/HistoryImpl.java
@@ -0,0 +1,279 @@
+/*
+ * 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
+ * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
+ * database integrations.
+ *
+ * For more information, please visit: https://www.jooq.org/legal/licensing
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+package org.jooq.impl;
+
+import static java.lang.Boolean.TRUE;
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+import static org.jooq.impl.DSL.inline;
+import static org.jooq.impl.DSL.name;
+import static org.jooq.impl.DSL.schema;
+import static org.jooq.impl.History.HISTORY;
+import static org.jooq.impl.MigrationImpl.Status.SUCCESS;
+import static org.jooq.impl.Tools.isEmpty;
+import static org.jooq.tools.StringUtils.isBlank;
+
+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.Set;
+
+import org.jooq.Commit;
+import org.jooq.Commits;
+import org.jooq.Configuration;
+import org.jooq.DSLContext;
+import org.jooq.History;
+import org.jooq.Schema;
+import org.jooq.Version;
+import org.jooq.conf.InterpreterSearchSchema;
+import org.jooq.conf.MappedCatalog;
+import org.jooq.conf.MappedSchema;
+import org.jooq.conf.MigrationSchema;
+import org.jooq.conf.RenderMapping;
+import org.jooq.exception.DataAccessException;
+import org.jooq.exception.DataMigrationVerificationException;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Lukas Eder
+ */
+class HistoryImpl extends AbstractScope implements History {
+
+ final DSLContext ctx;
+ final DSLContext historyCtx;
+ final Commits commits;
+ final List versions;
+
+ HistoryImpl(Configuration configuration) {
+ super(configuration);
+
+ this.ctx = configuration.dsl();
+ this.historyCtx = initCtx(configuration, configuration.settings().getMigrationHistorySchema()).dsl();
+ this.commits = configuration.commitProvider().provide();
+ this.versions = initVersions();
+ }
+
+ @Override
+ public final Iterator iterator() {
+ return unmodifiableList(versions).iterator();
+ }
+
+ @Override
+ public final Version root() {
+ if (!isEmpty(versions))
+ return versions.get(0);
+ else
+ throw new DataMigrationVerificationException("No versions are available");
+ }
+
+ @Override
+ public final Version current() {
+ if (!isEmpty(versions))
+ return versions.get(versions.size() - 1);
+ else
+ throw new DataMigrationVerificationException("No versions are available");
+ }
+
+ final Set schemas() {
+ Set set = new LinkedHashSet<>();
+
+ for (MigrationSchema schema : configuration.settings().getMigrationSchemata())
+ addSchema(set, schema);
+
+ if (configuration.settings().getMigrationDefaultSchema() != null) {
+ addSchema(set, configuration.settings().getMigrationDefaultSchema());
+ set.add(DSL.schema(""));
+ }
+
+ return set;
+ }
+
+ private final void addSchema(Set set, MigrationSchema schema) {
+ if (schema != null)
+ set.addAll(lookup(asList(schema(name(schema.getCatalog(), schema.getSchema())))));
+ }
+
+ final Collection lookup(List schemas) {
+
+ // TODO: Refactor usages of getInterpreterSearchPath()
+ Collection result = schemas;
+ List searchPath = configuration().settings().getInterpreterSearchPath();
+
+ if (!searchPath.isEmpty()) {
+ result = new HashSet<>();
+ Schema defaultSchema = schema(name(searchPath.get(0).getCatalog(), searchPath.get(0).getSchema()));
+
+ for (Schema schema : schemas)
+ if (schema.getQualifiedName().empty())
+ result.add(defaultSchema);
+ else
+ result.add(schema);
+ }
+
+ return result;
+ }
+
+ static final Configuration initCtx(Configuration configuration, MigrationSchema defaultSchema) {
+ if (defaultSchema != null) {
+ Configuration result = configuration.derive();
+
+ if (!isBlank(defaultSchema.getCatalog())) {
+ result.settings().withRenderMapping(new RenderMapping()
+ .withCatalogs(new MappedCatalog()
+ .withInput("")
+ .withOutput(defaultSchema.getCatalog())
+ .withSchemata(new MappedSchema()
+ .withInput("")
+ .withOutput(defaultSchema.getSchema())
+ )
+ )
+ );
+ }
+ else if (!isBlank(defaultSchema.getSchema())) {
+ result.settings().withRenderMapping(new RenderMapping()
+ .withSchemata(new MappedSchema()
+ .withInput("")
+ .withOutput(defaultSchema.getSchema())
+ )
+ );
+ }
+
+ return result;
+ }
+ else
+ return configuration;
+ }
+
+ @Nullable
+ final HistoryRecord currentHistoryRecord() {
+ return existsHistory()
+ ? historyCtx.selectFrom(HISTORY)
+
+ // TODO: How to recover from failure?
+ .where(HISTORY.STATUS.eq(inline(SUCCESS)))
+ .orderBy(HISTORY.MIGRATED_AT.desc(), HISTORY.ID.desc())
+ .limit(1)
+ .fetchOne()
+ : null;
+ }
+
+ final boolean existsHistory() {
+
+ // [#8301] Find a better way to test if our table already exists
+ try {
+ Configuration c = historyCtx
+ .configuration()
+ .derive();
+ c.data("org.jooq.tools.LoggerListener.exception.mute", true);
+ c.dsl().fetchExists(HISTORY);
+ return true;
+ }
+ catch (DataAccessException ignore) {}
+
+ return false;
+ }
+
+ private final List initVersions() {
+ List result = new ArrayList<>();
+
+ if (existsHistory()) {
+ result.add(commits.root().version());
+
+ for (HistoryRecord r : historyCtx
+ .selectFrom(HISTORY)
+ .where(HISTORY.STATUS.eq(inline(SUCCESS)))
+ .orderBy(HISTORY.ID.asc())
+ ) {
+ Commit commit = commits.get(r.getMigratedTo());
+
+ if (commit != null)
+ result.add(commit.version());
+ else
+ throw new DataMigrationVerificationException("CommitProvider didn't provide version for ID: " + r.getMigratedTo());
+ }
+ }
+
+ return result;
+ }
+
+ final void init() {
+
+ // TODO: What to do when initialising jOOQ-migrations on an existing database?
+ // - Should there be init() commands that can be run explicitly by the user?
+ // - Will we reverse engineer the production Meta snapshot first?
+ if (!existsHistory()) {
+
+ // TODO: [#9506] Make this schema creation vendor agnostic
+ // TODO: [#15225] This CREATE SCHEMA statement should never be necessary.
+ if (TRUE.equals(historyCtx.settings().isMigrationHistorySchemaCreateSchemaIfNotExists())
+ && historyCtx.settings().getMigrationHistorySchema() != null
+ || TRUE.equals(historyCtx.settings().isMigrationSchemataCreateSchemaIfNotExists())
+ && historyCtx.settings().getMigrationDefaultSchema() != null)
+ historyCtx.createSchemaIfNotExists("").execute();
+
+ historyCtx.meta(HISTORY).ddl().executeBatch();
+ }
+ }
+
+ // -------------------------------------------------------------------------
+ // The Object API
+ // -------------------------------------------------------------------------
+
+ @Override
+ public int hashCode() {
+ return versions.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof HistoryImpl h) {
+ return versions.equals(h.versions);
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "History [" + current() + "]";
+ }
+}
diff --git a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java
index a2a330ac0b..4c55889dd2 100644
--- a/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/MigrationImpl.java
@@ -39,26 +39,19 @@ package org.jooq.impl;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
-import static java.util.Arrays.asList;
import static org.jooq.impl.DSL.createSchemaIfNotExists;
import static org.jooq.impl.DSL.dropSchemaIfExists;
import static org.jooq.impl.DSL.dropTableIfExists;
-import static org.jooq.impl.DSL.inline;
-import static org.jooq.impl.DSL.name;
-import static org.jooq.impl.DSL.schema;
import static org.jooq.impl.History.HISTORY;
+import static org.jooq.impl.HistoryImpl.initCtx;
import static org.jooq.impl.MigrationImpl.Status.FAILURE;
import static org.jooq.impl.MigrationImpl.Status.MIGRATING;
import static org.jooq.impl.MigrationImpl.Status.REVERTING;
import static org.jooq.impl.MigrationImpl.Status.STARTING;
import static org.jooq.impl.MigrationImpl.Status.SUCCESS;
-import static org.jooq.tools.StringUtils.isBlank;
import java.sql.Timestamp;
-import java.util.Collection;
import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Set;
import org.jooq.Commit;
@@ -66,7 +59,6 @@ import org.jooq.Commits;
import org.jooq.Configuration;
import org.jooq.Constants;
import org.jooq.ContextTransactionalRunnable;
-import org.jooq.DSLContext;
import org.jooq.Files;
import org.jooq.Meta;
import org.jooq.Migration;
@@ -75,11 +67,6 @@ import org.jooq.MigrationListener;
import org.jooq.Queries;
import org.jooq.Query;
import org.jooq.Schema;
-import org.jooq.conf.InterpreterSearchSchema;
-import org.jooq.conf.MappedCatalog;
-import org.jooq.conf.MappedSchema;
-import org.jooq.conf.MigrationSchema;
-import org.jooq.conf.RenderMapping;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.DataMigrationException;
import org.jooq.exception.DataMigrationVerificationException;
@@ -92,7 +79,7 @@ import org.jooq.tools.StopWatch;
final class MigrationImpl extends AbstractScope implements Migration {
static final JooqLogger log = JooqLogger.getLogger(Migration.class);
- final DSLContext historyCtx;
+ final HistoryImpl history;
final Commit to;
Commit from;
Queries queries;
@@ -105,38 +92,7 @@ final class MigrationImpl extends AbstractScope implements Migration {
));
this.to = to;
- this.historyCtx = initCtx(configuration(), configuration.settings().getMigrationHistorySchema()).dsl();
- }
-
- private static final Configuration initCtx(Configuration configuration, MigrationSchema defaultSchema) {
- if (defaultSchema != null) {
- Configuration result = configuration.derive();
-
- if (!isBlank(defaultSchema.getCatalog())) {
- result.settings().withRenderMapping(new RenderMapping()
- .withCatalogs(new MappedCatalog()
- .withInput("")
- .withOutput(defaultSchema.getCatalog())
- .withSchemata(new MappedSchema()
- .withInput("")
- .withOutput(defaultSchema.getSchema())
- )
- )
- );
- }
- else if (!isBlank(defaultSchema.getSchema())) {
- result.settings().withRenderMapping(new RenderMapping()
- .withSchemata(new MappedSchema()
- .withInput("")
- .withOutput(defaultSchema.getSchema())
- )
- );
- }
-
- return result;
- }
- else
- return configuration;
+ this.history = new HistoryImpl(configuration());
}
@Override
@@ -177,7 +133,7 @@ final class MigrationImpl extends AbstractScope implements Migration {
}
private final void verify0(DefaultMigrationContext ctx) {
- HistoryRecord currentRecord = currentHistoryRecord();
+ HistoryRecord currentRecord = history.currentHistoryRecord();
if (currentRecord != null) {
Commit currentCommit = commits().get(currentRecord.getMigratedTo());
@@ -195,39 +151,19 @@ final class MigrationImpl extends AbstractScope implements Migration {
if (commits().get(commit.id()) == null)
throw new DataMigrationVerificationException("Commit is not available from CommitProvider: " + commit.id());
- for (Schema schema : lookup(commit.meta().getSchemas()))
+ 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);
}
- private final Collection lookup(List schemas) {
-
- // TODO: Refactor usages of getInterpreterSearchPath()
- Collection result = schemas;
- List searchPath = dsl().settings().getInterpreterSearchPath();
-
- if (!searchPath.isEmpty()) {
- result = new HashSet<>();
- Schema defaultSchema = schema(name(searchPath.get(0).getCatalog(), searchPath.get(0).getSchema()));
-
- for (Schema schema : schemas)
- if (schema.getQualifiedName().empty())
- result.add(defaultSchema);
- else
- result.add(schema);
- }
-
- return result;
- }
-
private final Queries revertUntrackedQueries(Set includedSchemas) {
Commit currentCommit = currentCommit();
Meta currentMeta = currentCommit.meta();
Meta existingMeta = dsl().meta().filterSchemas(includedSchemas::contains);
Set expectedSchemas = new HashSet<>();
- expectedSchemas.addAll(lookup(from().meta().getSchemas()));
- expectedSchemas.addAll(lookup(to().meta().getSchemas()));
+ expectedSchemas.addAll(history.lookup(from().meta().getSchemas()));
+ expectedSchemas.addAll(history.lookup(to().meta().getSchemas()));
expectedSchemas.retainAll(includedSchemas);
schemaLoop:
@@ -258,8 +194,8 @@ final class MigrationImpl extends AbstractScope implements Migration {
execute(ctx, listener, ctx.revertUntrackedQueries);
}
- private final DefaultMigrationContext migrationContext() {
- Set schemas = schemas();
+ final DefaultMigrationContext migrationContext() {
+ Set schemas = history.schemas();
return new DefaultMigrationContext(
configuration(),
@@ -271,25 +207,6 @@ final class MigrationImpl extends AbstractScope implements Migration {
);
}
- private final Set schemas() {
- Set set = new LinkedHashSet<>();
-
- for (MigrationSchema schema : configuration.settings().getMigrationSchemata())
- addSchema(set, schema);
-
- if (configuration.settings().getMigrationDefaultSchema() != null) {
- addSchema(set, configuration.settings().getMigrationDefaultSchema());
- set.add(DSL.schema(""));
- }
-
- return set;
- }
-
- private final void addSchema(Set set, MigrationSchema schema) {
- if (schema != null)
- set.addAll(lookup(asList(schema(name(schema.getCatalog(), schema.getSchema())))));
- }
-
@Override
public final void execute() {
@@ -355,7 +272,7 @@ final class MigrationImpl extends AbstractScope implements Migration {
}
private final HistoryRecord createRecord(Status status) {
- HistoryRecord record = historyCtx.newRecord(HISTORY);
+ HistoryRecord record = history.historyCtx.newRecord(HISTORY);
record
.setJooqVersion(Constants.VERSION)
@@ -401,22 +318,7 @@ final class MigrationImpl extends AbstractScope implements Migration {
* History.
*/
final void init() {
-
- // TODO: What to do when initialising jOOQ-migrations on an existing database?
- // - Should there be init() commands that can be run explicitly by the user?
- // - Will we reverse engineer the production Meta snapshot first?
- if (!existsHistory()) {
-
- // TODO: [#9506] Make this schema creation vendor agnostic
- // TODO: [#15225] This CREATE SCHEMA statement should never be necessary.
- if (TRUE.equals(historyCtx.settings().isMigrationHistorySchemaCreateSchemaIfNotExists())
- && historyCtx.settings().getMigrationHistorySchema() != null
- || TRUE.equals(historyCtx.settings().isMigrationSchemataCreateSchemaIfNotExists())
- && historyCtx.settings().getMigrationDefaultSchema() != null)
- historyCtx.createSchemaIfNotExists("").execute();
-
- historyCtx.meta(HISTORY).ddl().executeBatch();
- }
+ history.init();
MigrationContext ctx = migrationContext();
if (TRUE.equals(ctx.settings().isMigrationSchemataCreateSchemaIfNotExists()))
@@ -424,36 +326,8 @@ final class MigrationImpl extends AbstractScope implements Migration {
dsl().createSchemaIfNotExists(schema).execute();
}
- private final boolean existsHistory() {
-
- // [#8301] Find a better way to test if our table already exists
- try {
- Configuration c = historyCtx
- .configuration()
- .derive();
- c.data("org.jooq.tools.LoggerListener.exception.mute", true);
- c.dsl().fetchExists(HISTORY);
- return true;
- }
- catch (DataAccessException ignore) {}
-
- return false;
- }
-
- private final HistoryRecord currentHistoryRecord() {
- return existsHistory()
- ? historyCtx.selectFrom(HISTORY)
-
- // TODO: How to recover from failure?
- .where(HISTORY.STATUS.eq(inline(SUCCESS)))
- .orderBy(HISTORY.MIGRATED_AT.desc(), HISTORY.ID.desc())
- .limit(1)
- .fetchOne()
- : null;
- }
-
final Commit currentCommit() {
- HistoryRecord currentRecord = currentHistoryRecord();
+ HistoryRecord currentRecord = history.currentHistoryRecord();
if (currentRecord == null) {
Commit result = TRUE.equals(settings().isMigrationAutoBaseline()) ? to() : to().root();
@@ -486,6 +360,18 @@ final class MigrationImpl extends AbstractScope implements Migration {
}
}
+ enum Status {
+ STARTING,
+ REVERTING,
+ MIGRATING,
+ SUCCESS,
+ FAILURE
+ }
+
+ // -------------------------------------------------------------------------
+ // The Object API
+ // -------------------------------------------------------------------------
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -496,12 +382,4 @@ final class MigrationImpl extends AbstractScope implements Migration {
return sb.toString();
}
-
- enum Status {
- STARTING,
- REVERTING,
- MIGRATING,
- SUCCESS,
- FAILURE
- }
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/MigrationsImpl.java b/jOOQ/src/main/java/org/jooq/impl/MigrationsImpl.java
index 386412a1ad..b22af2de7c 100644
--- a/jOOQ/src/main/java/org/jooq/impl/MigrationsImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/MigrationsImpl.java
@@ -41,9 +41,10 @@ import static java.util.Collections.emptyList;
import org.jooq.Commit;
import org.jooq.Commits;
+import org.jooq.Configuration;
import org.jooq.ContentType;
-import org.jooq.DSLContext;
import org.jooq.File;
+import org.jooq.History;
import org.jooq.Migration;
import org.jooq.Migrations;
import org.jooq.Version;
@@ -51,12 +52,10 @@ import org.jooq.Version;
/**
* @author Lukas Eder
*/
-final class MigrationsImpl implements Migrations {
+final class MigrationsImpl extends AbstractScope implements Migrations {
- final DSLContext ctx;
-
- MigrationsImpl(DSLContext ctx) {
- this.ctx = ctx;
+ MigrationsImpl(Configuration configuration) {
+ super(configuration);
}
@Override
@@ -64,18 +63,23 @@ final class MigrationsImpl implements Migrations {
return new FileImpl(path, content, type);
}
+ @Override
+ public final History history() {
+ return new HistoryImpl(configuration());
+ }
+
@Override
public final Version version(String id) {
- return new VersionImpl(ctx, id);
+ return new VersionImpl(configuration(), id);
}
@Override
public final Commits commits() {
- return new CommitsImpl(ctx.configuration(), new CommitImpl(ctx.configuration(), "init", "init", null, emptyList(), emptyList()));
+ return new CommitsImpl(configuration(), new CommitImpl(configuration(), "init", "init", null, emptyList(), emptyList()));
}
@Override
public final Migration migrateTo(Commit to) {
- return new MigrationImpl(ctx.configuration(), to);
+ return new MigrationImpl(configuration(), to);
}
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java b/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java
index bbcfdf3a83..1f28ab58a4 100644
--- a/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java
@@ -40,7 +40,6 @@ package org.jooq.impl;
import static java.lang.Boolean.TRUE;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
-import static java.util.Collections.unmodifiableList;
import static org.jooq.impl.DSL.createSchema;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.schema;
@@ -51,12 +50,9 @@ import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
+import org.jooq.Configuration;
import org.jooq.DSLContext;
import org.jooq.Meta;
import org.jooq.Queries;
@@ -75,10 +71,10 @@ final class VersionImpl extends AbstractNode implements Version {
final Meta meta;
final List parents;
- private VersionImpl(DSLContext ctx, String id, Meta meta, Version root, List parents) {
+ private VersionImpl(Configuration configuration, String id, Meta meta, Version root, List parents) {
super(id, null, root);
- this.ctx = ctx;
+ this.ctx = configuration.dsl();
this.meta = meta != null ? meta : init(ctx);
this.parents = parents;
}
@@ -96,19 +92,19 @@ final class VersionImpl extends AbstractNode implements Version {
return result;
}
- VersionImpl(DSLContext ctx, String id, Meta meta, Version root, Version parent, Queries queries) {
- this(ctx, id, meta, root, Arrays.asList(new Parent((VersionImpl) parent, queries)));
+ VersionImpl(Configuration configuration, String id, Meta meta, Version root, Version parent, Queries queries) {
+ this(configuration, id, meta, root, Arrays.asList(new Parent((VersionImpl) parent, queries)));
}
- VersionImpl(DSLContext ctx, String id, Meta meta, Version root, Version[] parents) {
- this(ctx, id, meta, root, wrap(parents));
+ VersionImpl(Configuration configuration, String id, Meta meta, Version root, Version[] parents) {
+ this(configuration, id, meta, root, wrap(parents));
}
/**
* Create the root {@link Version}.
*/
- VersionImpl(DSLContext ctx, String id) {
- this(ctx, id, null, null, asList());
+ VersionImpl(Configuration configuration, String id) {
+ this(configuration, id, null, null, asList());
}
private static List wrap(Version[] parents) {
@@ -152,7 +148,7 @@ final class VersionImpl extends AbstractNode implements Version {
@Override
public final Version apply(String newId, Queries migration) {
- return new VersionImpl(ctx, newId, meta().apply(migration), root, this, migration);
+ return new VersionImpl(ctx.configuration(), newId, meta().apply(migration), root, this, migration);
}
@Override
@@ -181,7 +177,7 @@ final class VersionImpl extends AbstractNode implements Version {
if (list == null)
list = new ArrayList<>();
- list.add(new Parent(new VersionImpl(ctx, parent.version.id(), parent.version.meta, root, emptyList()), parent.queries));
+ list.add(new Parent(new VersionImpl(ctx.configuration(), parent.version.id(), parent.version.meta, root, emptyList()), parent.queries));
}
else {
VersionImpl p = parent.version.subgraphTo(ancestor);
@@ -195,7 +191,7 @@ final class VersionImpl extends AbstractNode implements Version {
}
}
- return list == null ? null : new VersionImpl(ctx, id(), meta, root, list);
+ return list == null ? null : new VersionImpl(ctx.configuration(), id(), meta, root, list);
}
private final Queries migrateTo(VersionImpl target, Queries result) {
@@ -230,13 +226,13 @@ final class VersionImpl extends AbstractNode implements Version {
@Override
public final Version commit(String newId, Meta newMeta) {
- return new VersionImpl(ctx, newId, newMeta, root, new Version[] { this });
+ return new VersionImpl(ctx.configuration(), newId, newMeta, root, new Version[] { this });
}
@Override
public final Version merge(String newId, Version with) {
Meta m = commonAncestor(with).meta();
- return new VersionImpl(ctx, newId, m.apply(m.migrateTo(meta()).concat(m.migrateTo(with.meta()))), root, new Version[] { this, with });
+ return new VersionImpl(ctx.configuration(), newId, m.apply(m.migrateTo(meta()).concat(m.migrateTo(with.meta()))), root, new Version[] { this, with });
}
@Override