Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright 2010-2016 Boxfuse GmbH
*
* 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.resolver.sql;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.MigrationType;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.resolver.MigrationResolver;
import org.flywaydb.core.api.resolver.ResolvedMigration;
import org.flywaydb.core.internal.callback.SqlScriptFlywayCallback;
import org.flywaydb.core.internal.dbsupport.DbSupport;
import org.flywaydb.core.internal.resolver.MigrationInfoHelper;
import org.flywaydb.core.internal.resolver.ResolvedMigrationComparator;
import org.flywaydb.core.internal.resolver.ResolvedMigrationImpl;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.Pair;
import org.flywaydb.core.internal.util.PlaceholderReplacer;
import org.flywaydb.core.internal.util.scanner.Resource;
import org.flywaydb.core.internal.util.scanner.Scanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.zip.CRC32;
/**
* Migration resolver for sql files on the classpath. The sql files must have names like
* V1__Description.sql or V1_1__Description.sql.
*/
public class SqlMigrationResolver implements MigrationResolver {
/**
* Database-specific support.
*/
private final DbSupport dbSupport;
/**
* The scanner to use.
*/
private final Scanner scanner;
/**
* The base directory on the classpath where to migrations are located.
*/
private final Location location;
/**
* The placeholder replacer to apply to sql migration scripts.
*/
private final PlaceholderReplacer placeholderReplacer;
/**
* The encoding of Sql migrations.
*/
private final String encoding;
/**
* The prefix for sql migrations
*/
private final String sqlMigrationPrefix;
/**
* The prefix for repeatable sql migrations
*/
private final String repeatableSqlMigrationPrefix;
/**
* The separator for sql migrations
*/
private final String sqlMigrationSeparator;
/**
* The suffix for sql migrations
*/
private final String sqlMigrationSuffix;
/**
* Creates a new instance.
*
* @param dbSupport The database-specific support.
* @param scanner The Scanner for loading migrations on the classpath.
* @param location The location on the classpath where to migrations are located.
* @param placeholderReplacer The placeholder replacer to apply to sql migration scripts.
* @param encoding The encoding of Sql migrations.
* @param sqlMigrationPrefix The prefix for sql migrations
* @param repeatableSqlMigrationPrefix The prefix for repeatable sql migrations
* @param sqlMigrationSeparator The separator for sql migrations
* @param sqlMigrationSuffix The suffix for sql migrations
*/
public SqlMigrationResolver(DbSupport dbSupport, Scanner scanner, Location location,
PlaceholderReplacer placeholderReplacer, String encoding,
String sqlMigrationPrefix, String repeatableSqlMigrationPrefix,
String sqlMigrationSeparator, String sqlMigrationSuffix) {
this.dbSupport = dbSupport;
this.scanner = scanner;
this.location = location;
this.placeholderReplacer = placeholderReplacer;
this.encoding = encoding;
this.sqlMigrationPrefix = sqlMigrationPrefix;
this.repeatableSqlMigrationPrefix = repeatableSqlMigrationPrefix;
this.sqlMigrationSeparator = sqlMigrationSeparator;
this.sqlMigrationSuffix = sqlMigrationSuffix;
}
public List resolveMigrations() {
List migrations = new ArrayList();
scanForMigrations(migrations, sqlMigrationPrefix, sqlMigrationSeparator, sqlMigrationSuffix);
scanForMigrations(migrations, repeatableSqlMigrationPrefix, sqlMigrationSeparator, sqlMigrationSuffix);
Collections.sort(migrations, new ResolvedMigrationComparator());
return migrations;
}
public void scanForMigrations(List migrations, String prefix, String separator, String suffix) {
for (Resource resource : scanner.scanForResources(location, prefix, suffix)) {
String filename = resource.getFilename();
if (isSqlCallback(filename, suffix)) {
continue;
}
Pair info =
MigrationInfoHelper.extractVersionAndDescription(filename, prefix, separator, suffix);
ResolvedMigrationImpl migration = new ResolvedMigrationImpl();
migration.setVersion(info.getLeft());
migration.setDescription(info.getRight());
migration.setScript(extractScriptName(resource));
migration.setChecksum(calculateChecksum(resource, resource.loadAsString(encoding)));
migration.setType(MigrationType.SQL);
migration.setPhysicalLocation(resource.getLocationOnDisk());
migration.setExecutor(new SqlMigrationExecutor(dbSupport, resource, placeholderReplacer, encoding));
migrations.add(migration);
}
}
/**
* Checks whether this filename is actually a sql-based callback instead of a regular migration.
*
* @param filename The filename to check.
* @param suffix The sql migration suffix.
* @return {@code true} if it is, {@code false} if it isn't.
*/
/* private -> testing */
static boolean isSqlCallback(String filename, String suffix) {
String baseName = filename.substring(0, filename.length() - suffix.length());
return SqlScriptFlywayCallback.ALL_CALLBACKS.contains(baseName);
}
/**
* Extracts the script name from this resource.
*
* @param resource The resource to process.
* @return The script name.
*/
/* private -> for testing */ String extractScriptName(Resource resource) {
if (location.getPath().isEmpty()) {
return resource.getLocation();
}
return resource.getLocation().substring(location.getPath().length() + 1);
}
/**
* Calculates the checksum of this string.
*
* @param str The string to calculate the checksum for.
* @return The crc-32 checksum of the bytes.
*/
/* private -> for testing */
static int calculateChecksum(Resource resource, String str) {
final CRC32 crc32 = new CRC32();
BufferedReader bufferedReader = new BufferedReader(new StringReader(str));
try {
String line;
while ((line = bufferedReader.readLine()) != null) {
crc32.update(line.getBytes("UTF-8"));
}
} catch (IOException e) {
String message = "Unable to calculate checksum";
if (resource != null) {
message += " for " + resource.getLocation() + " (" + resource.getLocationOnDisk() + ")";
}
throw new FlywayException(message, e);
}
return (int) crc32.getValue();
}
}