/*
 * Copyright 2010-2020 Redgate Software Ltd
 *
 * 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
 *
 *         http://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.
 */
package org.flywaydb.core.internal.schemahistory;

import org.flywaydb.core.api.MigrationType;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.resolver.ResolvedMigration;
import org.flywaydb.core.internal.database.base.Schema;
import org.flywaydb.core.internal.database.base.Table;
import org.flywaydb.core.internal.util.AbbreviationUtils;
import org.flywaydb.core.internal.util.StringUtils;

import java.util.List;
import java.util.concurrent.Callable;

The schema history used to track all applied migrations.
/** * The schema history used to track all applied migrations. */
public abstract class SchemaHistory { public static final String NO_DESCRIPTION_MARKER = "<< no description >>";
The schema history table used by Flyway. Non-final due to the table name fallback mechanism. Will be made final in Flyway 6.0.
/** * The schema history table used by Flyway. * Non-final due to the table name fallback mechanism. Will be made final in Flyway 6.0. */
protected Table table;
Acquires an exclusive read-write lock on the schema history table. This lock will be released automatically upon completion.
Returns:The result of the action.
/** * Acquires an exclusive read-write lock on the schema history table. This lock will be released automatically upon completion. * * @return The result of the action. */
public abstract <T> T lock(Callable<T> callable);
Returns:Whether the schema history table exists.
/** * @return Whether the schema history table exists. */
public abstract boolean exists();
Creates the schema history. Do nothing if it already exists.
Params:
  • baseline – Whether to include the creation of a baseline marker.
/** * Creates the schema history. Do nothing if it already exists. * * @param baseline Whether to include the creation of a baseline marker. */
public abstract void create(boolean baseline);
Checks whether the schema history table contains at least one non-synthetic applied migration.
Returns:true if it does, false if it doesn't.
/** * Checks whether the schema history table contains at least one non-synthetic applied migration. * * @return {@code true} if it does, {@code false} if it doesn't. */
public final boolean hasNonSyntheticAppliedMigrations() { for (AppliedMigration appliedMigration : allAppliedMigrations()) { if (!appliedMigration.getType().isSynthetic() ) { return true; } } return false; }
Returns:The list of all migrations applied on the schema in the order they were applied (oldest first). An empty list if no migration has been applied so far.
/** * @return The list of all migrations applied on the schema in the order they were applied (oldest first). * An empty list if no migration has been applied so far. */
public abstract List<AppliedMigration> allAppliedMigrations();
Retrieves the baseline marker from the schema history table.
Returns:The baseline marker or null if none could be found.
/** * Retrieves the baseline marker from the schema history table. * * @return The baseline marker or {@code null} if none could be found. */
public final AppliedMigration getBaselineMarker() { List<AppliedMigration> appliedMigrations = allAppliedMigrations(); // BASELINE can only be the first or second (in case there is a SCHEMA one) migration. for (int i = 0; i < Math.min(appliedMigrations.size(), 2); i++) { AppliedMigration appliedMigration = appliedMigrations.get(i); if (appliedMigration.getType() == MigrationType.BASELINE) { return appliedMigration; } } return null; }

Repairs the schema history table after a failed migration. This is only necessary for databases without DDL-transaction support.

On databases with DDL transaction support, a migration failure automatically triggers a rollback of all changes, including the ones in the schema history table.

/** * <p> * Repairs the schema history table after a failed migration. * This is only necessary for databases without DDL-transaction support. * </p> * <p> * On databases with DDL transaction support, a migration failure automatically triggers a rollback of all changes, * including the ones in the schema history table. * </p> */
public abstract void removeFailedMigrations();
Indicates in the schema history table that Flyway created these schemas.
Params:
  • schemas – The schemas that were created by Flyway.
/** * Indicates in the schema history table that Flyway created these schemas. * * @param schemas The schemas that were created by Flyway. */
public final void addSchemasMarker(Schema[] schemas) { addAppliedMigration(null, "<< Flyway Schema Creation >>", MigrationType.SCHEMA, StringUtils.arrayToCommaDelimitedString(schemas), null, 0, true); }
Checks whether the schema history table contains a marker row for schema creation.
Returns:true if it does, false if it doesn't.
/** * Checks whether the schema history table contains a marker row for schema creation. * * @return {@code true} if it does, {@code false} if it doesn't. */
public final boolean hasSchemasMarker() { List<AppliedMigration> appliedMigrations = allAppliedMigrations(); return !appliedMigrations.isEmpty() && appliedMigrations.get(0).getType() == MigrationType.SCHEMA; }
Updates this applied migration to match this resolved migration.
Params:
  • appliedMigration – The applied migration to update.
  • resolvedMigration – The resolved migration to source the new values from.
/** * Updates this applied migration to match this resolved migration. * * @param appliedMigration The applied migration to update. * @param resolvedMigration The resolved migration to source the new values from. */
public abstract void update(AppliedMigration appliedMigration, ResolvedMigration resolvedMigration);
Clears the applied migration cache.
/** * Clears the applied migration cache. */
public void clearCache() { // Do nothing by default. }
Records a new applied migration.
Params:
  • version – The target version of this migration.
  • description – The description of the migration.
  • type – The type of migration (BASELINE, SQL, ...)
  • script – The name of the script to execute for this migration, relative to its classpath location.
  • checksum – The checksum of the migration. (Optional)
  • executionTime – The execution time (in millis) of this migration.
  • success – Flag indicating whether the migration was successful or not.
/** * Records a new applied migration. * * @param version The target version of this migration. * @param description The description of the migration. * @param type The type of migration (BASELINE, SQL, ...) * @param script The name of the script to execute for this migration, relative to its classpath location. * @param checksum The checksum of the migration. (Optional) * @param executionTime The execution time (in millis) of this migration. * @param success Flag indicating whether the migration was successful or not. */
public final void addAppliedMigration(MigrationVersion version, String description, MigrationType type, String script, Integer checksum, int executionTime, boolean success) { int installedRank = type == MigrationType.SCHEMA ? 0 : calculateInstalledRank(); doAddAppliedMigration( installedRank, version, AbbreviationUtils.abbreviateDescription(description), type, AbbreviationUtils.abbreviateScript(script), checksum, executionTime, success); }
Calculates the installed rank for the new migration to be inserted.
Returns:The installed rank.
/** * Calculates the installed rank for the new migration to be inserted. * * @return The installed rank. */
private int calculateInstalledRank() { List<AppliedMigration> appliedMigrations = allAppliedMigrations(); if (appliedMigrations.isEmpty()) { return 1; } return appliedMigrations.get(appliedMigrations.size() - 1).getInstalledRank() + 1; } protected abstract void doAddAppliedMigration(int installedRank, MigrationVersion version, String description, MigrationType type, String script, Integer checksum, int executionTime, boolean success); @Override public String toString() { return table.toString(); } }