/**
  * Runs all the migrations in the configuration which version key is not already present in the
  * database. The migration will get run in the same order they are in the list.
  *
  * @param configuration Configuration with the database and all the migrations.
  */
 public static void migrate(Configuration configuration) {
   Migrate4Droid.configuration = configuration;
   ensureMigrationDao();
   List<Migration> migrations = configuration.getMigrations();
   List<String> actual = migrationDao.getAllMigrations();
   for (Migration m : migrations) if (!actual.contains(m.getMigration())) runMigration(m);
 }
 /**
  * Register in the database all of the migrations in the <code>config</code> parameter as run.
  *
  * @param config Configuration with the migrations that need to be marked as run.
  */
 public static void markAsMigrated(Configuration config) {
   configuration = config;
   ensureMigrationDao();
   List<String> actual = migrationDao.getAllMigrations();
   for (Migration m : config.getMigrations())
     if (!actual.contains(m.getMigration())) markAsMigrated(m);
 }
 /**
  * Moves the database to the <code>migration</code> specified, using the migrations in the <code>
  * configuration</code>, iterating them and checking:
  *
  * <ul>
  *   <li>If the migration's key is smaller than or equal to the desired <code>migration</code>'s
  *       key parameterized and it's not present in the database, the migration will get upgraded.
  *       That is, its method {@link Migration#up()} will be called. The order will be the same as
  *       the migrations are in the <code>configuration</code>.
  *   <li>If the migration's key is greater than the desired <code>migration</code>'s key
  *       parameterized and it IS present in the database, the migration will get downgraded. That
  *       is, its method {@link Migration#down()} will be called. The order will be the opposite
  *       the migrations are in the <code>configuration</code>.
  * </ul>
  *
  * @param configuration Configuration with the database and all the migrations that have to be
  *     considered during the migration.
  * @param migration String key of the migration the database is desired to be.
  */
 public static void migrate(Configuration configuration, String migration) {
   Migrate4Droid.configuration = configuration;
   ensureMigrationDao();
   List<Migration> migrations = configuration.getMigrations();
   List<Migration> downs = new ArrayList<Migration>();
   List<String> actual = migrationDao.getAllMigrations();
   for (Migration m : migrations) {
     String mig = m.getMigration();
     if (mig.compareTo(migration) <= 0 && !actual.contains(mig)) runMigration(m);
     else if (mig.compareTo(migration) > 0 && actual.contains(mig)) downs.add(0, m);
   }
   for (Migration m : downs) runMigration(m, false);
 }
 /**
  * Executes the migration in the database. If <code>up</code> is set to <code>true</code>, then
  * the method {@link Migration#up()} will be called. Otherwise, the method {@link
  * Migration#down()} will get called.
  *
  * @param m The migration to run.
  * @param up If <code>true</code>, it will upgrade. Otherwise, it will downgrade.
  */
 private static void runMigration(Migration m, boolean up) {
   SQLiteDatabase db = configuration.getDatabase();
   db.beginTransaction();
   try {
     if (up) {
       m.up();
       markAsMigrated(m);
     } else {
       m.down();
       migrationDao.delete(m.getMigration());
     }
     db.setTransactionSuccessful();
   } catch (Exception e) {
     Logger.e("Exception when migrating " + m.getClass().getName(), e);
   } finally {
     db.endTransaction();
   }
 }
 /**
  * If {@link Migrate4Droid#migrationDao} is <code>null</code>, instantiates it. Otherwise, just
  * updates the database in the Dao using the actual in the {@link Migrate4Droid#configuration}
  * object.
  */
 private static void ensureMigrationDao() {
   if (migrationDao == null) migrationDao = new DbMigrationDao(configuration.getDatabase());
   else migrationDao.setDatabase(configuration.getDatabase());
 }
 protected static void markAsMigrated(Migration m) {
   DbMigration mig = new DbMigration();
   mig.setMigration(m.getMigration());
   migrationDao.save(mig);
 }