Viewing file: Migration.php (7.81 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * CodeIgniter * * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author EllisLab Dev Team * @copyright Copyright (c) 2006 - 2014, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 * @filesource */
// ------------------------------------------------------------------------
/** * Migration Class * * All migrations should implement this, forces up() and down() and gives * access to the CI super-global. * * @package CodeIgniter * @subpackage Libraries * @category Libraries * @author Reactor Engineers * @link */ class CI_Migration {
protected $_migration_enabled = FALSE; protected $_migration_path = NULL; protected $_migration_version = 0;
protected $_error_string = '';
public function __construct($config = array()) { # Only run this constructor on main library load if (get_parent_class($this) !== FALSE) { return; }
foreach ($config as $key => $val) { $this->{'_' . $key} = $val; }
log_message('debug', 'Migrations class initialized');
// Are they trying to use migrations while it is disabled? if ($this->_migration_enabled !== TRUE) { show_error('Migrations has been loaded but is disabled or set up incorrectly.'); }
// If not set, set it $this->_migration_path == '' AND $this->_migration_path = APPPATH . 'migrations/';
// Add trailing slash if not set $this->_migration_path = rtrim($this->_migration_path, '/').'/';
// Load migration language $this->lang->load('migration');
// They'll probably be using dbforge $this->load->dbforge();
// If the migrations table is missing, make it if ( ! $this->db->table_exists('migrations')) { $this->dbforge->add_field(array( 'version' => array('type' => 'INT', 'constraint' => 3), ));
$this->dbforge->create_table('migrations', TRUE);
$this->db->insert('migrations', array('version' => 0)); } }
// --------------------------------------------------------------------
/** * Migrate to a schema version * * Calls each migration step required to get to the schema version of * choice * * @param int Target schema version * @return mixed TRUE if already latest, FALSE if failed, int if upgraded */ public function version($target_version) { $start = $current_version = $this->_get_version(); $stop = $target_version;
if ($target_version > $current_version) { // Moving Up ++$start; ++$stop; $step = 1; } else { // Moving Down $step = -1; }
$method = ($step === 1) ? 'up' : 'down'; $migrations = array();
// We now prepare to actually DO the migrations // But first let's make sure that everything is the way it should be for ($i = $start; $i != $stop; $i += $step) { $f = glob(sprintf($this->_migration_path . '%03d_*.php', $i));
// Only one migration per step is permitted if (count($f) > 1) { $this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $i); return FALSE; }
// Migration step not found if (count($f) == 0) { // If trying to migrate up to a version greater than the last // existing one, migrate to the last one. if ($step == 1) { break; }
// If trying to migrate down but we're missing a step, // something must definitely be wrong. $this->_error_string = sprintf($this->lang->line('migration_not_found'), $i); return FALSE; }
$file = basename($f[0]); $name = basename($f[0], '.php');
// Filename validations if (preg_match('/^\d{3}_(\w+)$/', $name, $match)) { $match[1] = strtolower($match[1]);
// Cannot repeat a migration at different steps if (in_array($match[1], $migrations)) { $this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $match[1]); return FALSE; }
include $f[0]; $class = 'Migration_' . ucfirst($match[1]);
if ( ! class_exists($class)) { $this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class); return FALSE; }
if ( ! is_callable(array($class, $method))) { $this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class); return FALSE; }
$migrations[] = $match[1]; } else { $this->_error_string = sprintf($this->lang->line('migration_invalid_filename'), $file); return FALSE; } }
log_message('debug', 'Current migration: ' . $current_version);
$version = $i + ($step == 1 ? -1 : 0);
// If there is nothing to do so quit if ($migrations === array()) { return TRUE; }
log_message('debug', 'Migrating from ' . $method . ' to version ' . $version);
// Loop through the migrations foreach ($migrations AS $migration) { // Run the migration class $class = 'Migration_' . ucfirst(strtolower($migration)); call_user_func(array(new $class, $method));
$current_version += $step; $this->_update_version($current_version); }
log_message('debug', 'Finished migrating to '.$current_version);
return $current_version; }
// --------------------------------------------------------------------
/** * Set's the schema to the latest migration * * @return mixed true if already latest, false if failed, int if upgraded */ public function latest() { if ( ! $migrations = $this->find_migrations()) { $this->_error_string = $this->lang->line('migration_none_found'); return false; }
$last_migration = basename(end($migrations));
// Calculate the last migration step from existing migration // filenames and procceed to the standard version migration return $this->version((int) substr($last_migration, 0, 3)); }
// --------------------------------------------------------------------
/** * Set's the schema to the migration version set in config * * @return mixed true if already current, false if failed, int if upgraded */ public function current() { return $this->version($this->_migration_version); }
// --------------------------------------------------------------------
/** * Error string * * @return string Error message returned as a string */ public function error_string() { return $this->_error_string; }
// --------------------------------------------------------------------
/** * Set's the schema to the latest migration * * @return mixed true if already latest, false if failed, int if upgraded */ protected function find_migrations() { // Load all *_*.php files in the migrations path $files = glob($this->_migration_path . '*_*.php'); $file_count = count($files);
for ($i = 0; $i < $file_count; $i++) { // Mark wrongly formatted files as false for later filtering $name = basename($files[$i], '.php'); if ( ! preg_match('/^\d{3}_(\w+)$/', $name)) { $files[$i] = FALSE; } }
sort($files); return $files; }
// --------------------------------------------------------------------
/** * Retrieves current schema version * * @return int Current Migration */ protected function _get_version() { $row = $this->db->get('migrations')->row(); return $row ? $row->version : 0; }
// --------------------------------------------------------------------
/** * Stores the current schema version * * @param int Migration reached * @return bool */ protected function _update_version($migrations) { return $this->db->update('migrations', array( 'version' => $migrations )); }
// --------------------------------------------------------------------
/** * Enable the use of CI super-global * * @param mixed $var * @return mixed */ public function __get($var) { return get_instance()->$var; }
}
/* End of file Migration.php */ /* Location: ./system/libraries/Migration.php */
|