[jOOQ/jOOQ#9506] Added a History API draft

This commit is contained in:
Lukas Eder 2023-06-15 16:13:41 +02:00
parent 61fd552bb8
commit 80ac10e1c8
10 changed files with 466 additions and 175 deletions

View File

@ -43,6 +43,9 @@ import org.jetbrains.annotations.ApiStatus.Experimental;
/**
* A source of migration content.
* <p>
* 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.
* <p>
* This is EXPERIMENTAL functionality and subject to change in future jOOQ
* versions.
*/
@Experimental
@NotNull
String path();
/**
* The name of the file.
* <p>
* This is EXPERIMENTAL functionality and subject to change in future jOOQ
* versions.
*/
@Experimental
@NotNull
String name();
/**
* The file content.
* <p>
* This is EXPERIMENTAL functionality and subject to change in future jOOQ
* versions.
*/
@Experimental
@Nullable
String content();
/**
* The file type.
* <p>
* This is EXPERIMENTAL functionality and subject to change in future jOOQ
* versions.
*/
@Experimental
@NotNull
ContentType type();
}

View File

@ -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.
* <p>
* This type will help make sure that duplicate occurrences of the same file
* (e.g. edits) are streamlined.
* <p>
* This is EXPERIMENTAL functionality and subject to change in future jOOQ
* versions.
*/
@Experimental
public interface Files extends Iterable<File> {
/**
* The from version from which this migration is done.
* <p>
* 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.
* <p>
* This is EXPERIMENTAL functionality and subject to change in future jOOQ
* versions.
*/
@NotNull
@Experimental
Version to();
}

View File

@ -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}.
* <p>
* This is EXPERIMENTAL functionality and subject to change in future jOOQ
* versions.
*
* @author Lukas Eder
*/
@Experimental
public interface History extends Iterable<Version> {
/**
* The root {@link Version}.
* <p>
* This corresponds to the {@link Configuration#commitProvider()}'s
* {@link Commits#root()} if migrations have been initialised on the
* configured database.
* <p>
* 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}.
* <p>
* 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();
}

View File

@ -80,6 +80,17 @@ public interface Migrations {
@NotNull
Commits commits();
/**
* Retrieve the {@link History} of previously installed {@link Version}
* objects from the database.
* <p>
* 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.
* <p>

View File

@ -423,6 +423,10 @@ final class CommitImpl extends AbstractNode<Commit> implements Commit {
files.clear();
}
// -------------------------------------------------------------------------
// The Object API
// -------------------------------------------------------------------------
@Override
public int hashCode() {
return id().hashCode();

View File

@ -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

View File

@ -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<Version> 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<Version> 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<Schema> schemas() {
Set<Schema> 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<Schema> set, MigrationSchema schema) {
if (schema != null)
set.addAll(lookup(asList(schema(name(schema.getCatalog(), schema.getSchema())))));
}
final Collection<Schema> lookup(List<Schema> schemas) {
// TODO: Refactor usages of getInterpreterSearchPath()
Collection<Schema> result = schemas;
List<InterpreterSearchSchema> 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<Version> initVersions() {
List<Version> 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() + "]";
}
}

View File

@ -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<Schema> lookup(List<Schema> schemas) {
// TODO: Refactor usages of getInterpreterSearchPath()
Collection<Schema> result = schemas;
List<InterpreterSearchSchema> 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<Schema> includedSchemas) {
Commit currentCommit = currentCommit();
Meta currentMeta = currentCommit.meta();
Meta existingMeta = dsl().meta().filterSchemas(includedSchemas::contains);
Set<Schema> 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<Schema> schemas = schemas();
final DefaultMigrationContext migrationContext() {
Set<Schema> schemas = history.schemas();
return new DefaultMigrationContext(
configuration(),
@ -271,25 +207,6 @@ final class MigrationImpl extends AbstractScope implements Migration {
);
}
private final Set<Schema> schemas() {
Set<Schema> 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<Schema> 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
}
}

View File

@ -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);
}
}

View File

@ -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<Version> implements Version {
final Meta meta;
final List<Parent> parents;
private VersionImpl(DSLContext ctx, String id, Meta meta, Version root, List<Parent> parents) {
private VersionImpl(Configuration configuration, String id, Meta meta, Version root, List<Parent> 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<Version> 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<Parent> wrap(Version[] parents) {
@ -152,7 +148,7 @@ final class VersionImpl extends AbstractNode<Version> 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<Version> 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<Version> 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<Version> 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