All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javalite.db_migrator.MigrationResolver Maven / Gradle / Ivy

The newest version!
package org.javalite.db_migrator;

import io.github.classgraph.ClassGraph;
import io.github.classgraph.Resource;
import io.github.classgraph.ScanResult;
import org.javalite.common.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.javalite.db_migrator.MigrationManager.MIGRATION_LOGGER;

public class MigrationResolver {



    private File migrationsLocation; // directory on the file system where migrations reside
    private  String classpathMigrationsLocation; // location on classpath where migrations reside


    private List additionalClasspaths;

    private Properties mergeProperties;

    private static final Pattern MIGRATION_FILE_PATTERN = Pattern.compile("^(\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d)_.*\\.(sql|groovy)");

    /**
     * @param paths to be added to the classpath for search of project classes for the Groovy migrator.
     * @param migrationsLocation - directory on the file system where migrations reside
     */
    public MigrationResolver(List paths, File migrationsLocation) {
        this(paths, migrationsLocation, null);
    }

    /**
     * @param paths to be added to the classpath for search of project classes for the Groovy migrator.
     * @param migrationsLocation - directory where migrations reside
     */
    public MigrationResolver(List paths, File migrationsLocation, Properties mergeProperties) {
        this.additionalClasspaths = paths;
        this.migrationsLocation = migrationsLocation;
        this.mergeProperties = mergeProperties;
    }

    /**
     * @param additionalClasspaths to be added to the classpath for search of project classes for the Groovy migrator.
     * @param classpathMigrationsLocation - top directory of migrations if packaged on classpath
     */
    public MigrationResolver(List additionalClasspaths, String classpathMigrationsLocation, Properties mergeProperties) {
        this.additionalClasspaths = additionalClasspaths;
        this.classpathMigrationsLocation = classpathMigrationsLocation;
        this.mergeProperties = mergeProperties;
    }

    public List resolve() {

        List migrations = new ArrayList<>();

        if(this.classpathMigrationsLocation != null) { // assume loading from classpath
            migrations = loadMigrationsFromClassPath();
        }else {
            migrations = loadMigrationsFromFiles();
        }
        Collections.sort(migrations);
        return migrations;
    }

    private List loadMigrationsFromClassPath() {
        List migrations = loadMigrationsFromClassPath("sql");
        List groovyMigrations = loadMigrationsFromClassPath("groovy");
        migrations.addAll(groovyMigrations);
        return migrations;
    }

    private List loadMigrationsFromClassPath(String extension) {
        List migrations = new ArrayList<>();
        try (ScanResult scanResult = new ClassGraph().acceptPathsNonRecursive(classpathMigrationsLocation).scan()) {
            scanResult.getResourcesWithExtension(extension).forEachByteArrayThrowingIOException((Resource res, byte[] content) -> {
                String version = extractVersion(res.getPath().substring(res.getPath().lastIndexOf("/") + 1));
                migrations.add(new SQLMigration(version, res.getPath().toString(), new String(content), mergeProperties));
            });
        } catch (IOException e) {
            throw new MigrationException(e);
        }
        return migrations;
    }



    List loadMigrationsFromFiles(){
        List migrations = new ArrayList<>();
        MIGRATION_LOGGER.info("Trying migrations at: {} ", migrationsLocation.getAbsolutePath());
        //assume flat directory of migrations
        File[] files = migrationsLocation.listFiles();

        List migrationsFiles = new ArrayList<>();
        for (File file : files) {
            if (!file.isDirectory() && MIGRATION_FILE_PATTERN.matcher(file.getName()).matches()) {
                migrationsFiles.add(file);
            }
        }

        if(!migrationsLocation.isDirectory()){
            throw  new IllegalArgumentException(migrationsLocation + " is not a directory");
        }
        MIGRATION_LOGGER.info("Trying migrations at: {} ", migrationsLocation.getAbsolutePath());
        // Extract versions and create executable migrations for each resource.
        for (File migrationFile: migrationsFiles) {
            String version = extractVersion(migrationFile.getName());
            if(migrationFile.getName().endsWith("sql")){
                migrations.add(new SQLMigration(version, migrationFile.getName(), Util.readFile(migrationFile), mergeProperties));
            }else if(migrationFile.getName().endsWith("groovy")){
                migrations.add(new GroovyMigration(additionalClasspaths, version, migrationFile.getName(), Util.readFile(migrationFile), mergeProperties));
            }else {
                throw new RuntimeException("file type not supported");
            }
        }

        return migrations;
    }



    public String extractVersion(String name) {
        String errorMessage = "Error parsing migration version from " + name;
        try {
            Matcher matcher = MIGRATION_FILE_PATTERN.matcher(name);
            boolean found = matcher.find();
            if(!found) throw  new MigrationException(errorMessage);
            return matcher.group(1);
        }catch(MigrationException e){
            throw e;
        }
        catch (Exception e) {
            throw new MigrationException(errorMessage, e);
        }
    }



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy