StatusOperation.java

  1. /*
  2.  *    Copyright 2010-2023 the original author or authors.
  3.  *
  4.  *    Licensed under the Apache License, Version 2.0 (the "License");
  5.  *    you may not use this file except in compliance with the License.
  6.  *    You may obtain a copy of the License at
  7.  *
  8.  *       https://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  *    Unless required by applicable law or agreed to in writing, software
  11.  *    distributed under the License is distributed on an "AS IS" BASIS,
  12.  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  *    See the License for the specific language governing permissions and
  14.  *    limitations under the License.
  15.  */
  16. package org.apache.ibatis.migration.operations;

  17. import java.io.PrintStream;
  18. import java.sql.Connection;
  19. import java.sql.SQLException;
  20. import java.util.ArrayList;
  21. import java.util.Collections;
  22. import java.util.HashSet;
  23. import java.util.List;
  24. import java.util.Set;

  25. import org.apache.ibatis.migration.Change;
  26. import org.apache.ibatis.migration.ConnectionProvider;
  27. import org.apache.ibatis.migration.MigrationException;
  28. import org.apache.ibatis.migration.MigrationLoader;
  29. import org.apache.ibatis.migration.options.DatabaseOperationOption;
  30. import org.apache.ibatis.migration.utils.Util;

  31. public final class StatusOperation extends DatabaseOperation {

  32.   private int applied;
  33.   private int pending;
  34.   private int missing;

  35.   private List<Change> changes;

  36.   public StatusOperation operate(ConnectionProvider connectionProvider, MigrationLoader migrationsLoader,
  37.       DatabaseOperationOption option, PrintStream printStream) {
  38.     if (option == null) {
  39.       option = new DatabaseOperationOption();
  40.     }
  41.     println(printStream, "ID             Applied At          Description");
  42.     println(printStream, Util.horizontalLine("", 80));
  43.     changes = new ArrayList<>();
  44.     List<Change> migrations = migrationsLoader.getMigrations();
  45.     String skippedOrMissing = null;
  46.     try (Connection con = connectionProvider.getConnection()) {
  47.       if (changelogExists(con, option)) {
  48.         List<Change> changelog = getChangelog(con, option);
  49.         skippedOrMissing = checkSkippedOrMissing(changelog, migrations);

  50.         Set<Change> changelogAndMigrations = new HashSet<>(changelog);
  51.         changelogAndMigrations.addAll(migrations);

  52.         for (Change change : changelogAndMigrations) {
  53.           if (!migrations.contains(change)) {
  54.             change = new MissingScript(change);
  55.             missing++;
  56.           } else if (change.getAppliedTimestamp() != null) {
  57.             applied++;
  58.           } else {
  59.             pending++;
  60.           }
  61.           changes.add(change);
  62.         }
  63.       } else {
  64.         changes.addAll(migrations);
  65.         pending = migrations.size();
  66.       }
  67.     } catch (SQLException e) {
  68.       throw new MigrationException("Error getting connection. Cause: " + e, e);
  69.     }

  70.     Collections.sort(changes);
  71.     for (Change change : changes) {
  72.       println(printStream, change.toString());
  73.     }
  74.     println(printStream);

  75.     if (skippedOrMissing != null && !skippedOrMissing.isEmpty()) {
  76.       println(printStream, skippedOrMissing);
  77.     }

  78.     return this;
  79.   }

  80.   public int getAppliedCount() {
  81.     return applied;
  82.   }

  83.   public int getPendingCount() {
  84.     return pending;
  85.   }

  86.   public int getMissingCount() {
  87.     return missing;
  88.   }

  89.   public List<Change> getCurrentStatus() {
  90.     return changes;
  91.   }

  92.   class MissingScript extends Change {
  93.     public MissingScript(Change change) {
  94.       super(change);
  95.     }

  96.     @Override
  97.     public String toString() {
  98.       return super.toString() + " <=== MISSING!";
  99.     }
  100.   }
  101. }