CI_Migration::version PHP Method

version() public method

Calls each migration step required to get to the schema version of choice
public version ( string $target_version ) : mixed
$target_version string Target schema version
return mixed TRUE if no migrations are found, current version string on success, FALSE on failure
    public function version($target_version)
    {
        // Note: We use strings, so that timestamp versions work on 32-bit systems
        $current_version = $this->_get_version();
        if ($this->_migration_type === 'sequential') {
            $target_version = sprintf('%03d', $target_version);
        } else {
            $target_version = (string) $target_version;
        }
        $migrations = $this->find_migrations();
        if ($target_version > 0 && !isset($migrations[$target_version])) {
            $this->_error_string = sprintf($this->lang->line('migration_not_found'), $target_version);
            return FALSE;
        }
        if ($target_version > $current_version) {
            $method = 'up';
        } elseif ($target_version < $current_version) {
            $method = 'down';
            // We need this so that migrations are applied in reverse order
            krsort($migrations);
        } else {
            // Well, there's nothing to migrate then ...
            return TRUE;
        }
        // Validate all available migrations within our target range.
        //
        // Unfortunately, we'll have to use another loop to run them
        // in order to avoid leaving the procedure in a broken state.
        //
        // See https://github.com/bcit-ci/CodeIgniter/issues/4539
        $pending = array();
        foreach ($migrations as $number => $file) {
            // Ignore versions out of our range.
            //
            // Because we've previously sorted the $migrations array depending on the direction,
            // we can safely break the loop once we reach $target_version ...
            if ($method === 'up') {
                if ($number <= $current_version) {
                    continue;
                } elseif ($number > $target_version) {
                    break;
                }
            } else {
                if ($number > $current_version) {
                    continue;
                } elseif ($number <= $target_version) {
                    break;
                }
            }
            // Check for sequence gaps
            if ($this->_migration_type === 'sequential') {
                if (isset($previous) && abs($number - $previous) > 1) {
                    $this->_error_string = sprintf($this->lang->line('migration_sequence_gap'), $number);
                    return FALSE;
                }
                $previous = $number;
            }
            include_once $file;
            $class = 'Migration_' . ucfirst(strtolower($this->_get_migration_name(basename($file, '.php'))));
            // Validate the migration file structure
            if (!class_exists($class, FALSE)) {
                $this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class);
                return FALSE;
            } elseif (!in_array($method, array_map('strtolower', get_class_methods($class)))) {
                $this->_error_string = sprintf($this->lang->line('migration_missing_' . $method . '_method'), $class);
                return FALSE;
            }
            $pending[$number] = array($class, $method);
        }
        // Now just run the necessary migrations
        foreach ($pending as $number => $migration) {
            log_message('debug', 'Migrating ' . $method . ' from version ' . $current_version . ' to version ' . $number);
            $migration[0] = new $migration[0]();
            call_user_func($migration);
            $current_version = $number;
            $this->_update_version($current_version);
        }
        // This is necessary when moving down, since the the last migration applied
        // will be the down() method for the next migration up from the target
        if ($current_version != $target_version) {
            $current_version = $target_version;
            $this->_update_version($current_version);
        }
        log_message('debug', 'Finished migrating to ' . $current_version);
        return $current_version;
    }

Usage Example

Ejemplo n.º 1
0
 /**
  * Extends migration mechanism to create backup before running migrations and remove it on success, but keep on failure
  * (non-PHPdoc)
  * @see CI_Migration::version()
  */
 public function version($target_version)
 {
     // Make DB backup
     $backupFile = $this->_make_backup();
     if ($backupFile === FALSE) {
         log_message('DEBUG', 'Making backup before migrating failed.');
     }
     // Run migrationgs
     $migrationsResult = parent::version($target_version);
     // If everything went well - remove backup
     if ($migrationsResult !== FALSE && $migrationsResult == $target_version) {
         if ($backupFile !== FALSE && !$this->_delete_backup($backupFile)) {
             log_message('debug', 'There was an error when removing backup file.');
         }
     } else {
         if ($backupFile !== FALSE) {
             log_message('error', 'Migrating to version ' . $target_version . ' failed. Backup from before migration stored in ' . $backupFile);
         } else {
             log_message('error', 'Migrating to version ' . $target_version . ' failed, but no valid backup saved.');
         }
     }
     return $migrationsResult;
 }