001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.dataAccess.db;
019
020import io.stallion.boot.AppContextLoader;
021import io.stallion.boot.StallionRunAction;
022import io.stallion.boot.SqlMigrateCommandOptions;
023import io.stallion.services.Log;
024
025import javax.script.ScriptEngine;
026import java.util.List;
027
028import static io.stallion.utils.Literals.*;
029
030/**
031 * A command-line action that checks to see if a database migration needs to be run, that is
032 * if there is a SQL migration file in the sql folder that has not yet been marked as run in
033 * the database.
034 * This is used by the publish/deployment action, if a migration has not been run, deployment
035 * should be aborted.
036 */
037public class SqlCheckNeedsMigrationAction implements StallionRunAction<SqlMigrateCommandOptions> {
038    private ScriptEngine scriptEngine;
039
040    @Override
041    public String getActionName() {
042        return "sql-check-migrations";
043    }
044
045    @Override
046    public String getHelp() {
047        return "Checks to see if a SQL migration needs to be run.";
048    }
049
050
051    @Override
052    public SqlMigrateCommandOptions newCommandOptions() {
053        return new SqlMigrateCommandOptions();
054    }
055
056    @Override
057    public void loadApp(SqlMigrateCommandOptions options) {
058        AppContextLoader.loadWithSettingsOnly(options);
059        DB.load();
060    }
061
062    @Override
063    public void execute(SqlMigrateCommandOptions options) throws Exception {
064        if (!DB.available()) {
065            // No db available, no migrations to run
066            Log.info("No DB available, no migrations to run.");
067            System.out.println("result:success");
068            return;
069        }
070        SqlMigrationAction migrationAction = new SqlMigrationAction();
071        migrationAction.createMigrationTrackingTableIfNotExists();
072        // Get a ticket to make sure the tickets table is operational
073        List<SqlMigration> migrations = migrationAction.getDefaultMigrations();
074        migrations.addAll(migrationAction.getUserMigrations());
075        DB db = DB.instance();
076        List<SqlMigration> unrunMigrations = list();
077        for (SqlMigration migration: migrations) {
078            Long currentVersion = or(db.queryScalar("SELECT MAX(versionNumber) FROM stallion_sql_migrations WHERE appName=?", migration.getAppName()), 0L);
079            if (currentVersion >= migration.getVersionNumber()) {
080                Log.finer("File {0} is below current version of {1} for app {2}", migration.getFilename(), currentVersion, migration.getAppName());
081                continue;
082            }
083            Log.warn("Un-executed migration found: {0}", migration.getFilename());
084            unrunMigrations.add(migration);
085        }
086        if (unrunMigrations.size() > 0) {
087
088            Log.warn("Un-executed migrations found. Exiting with error code.");
089            System.out.println("result:failure");
090            System.exit(1);
091        } else {
092            Log.info("No un-executed migrations found.");
093            System.out.println("result:success");
094        }
095
096
097    }
098
099}