Changes for new migration code.
This commit is contained in:
parent
5d12093b8e
commit
10bdfcb17f
@ -465,6 +465,8 @@ final class Doctrine
|
||||
/**
|
||||
* getLoadedModels
|
||||
*
|
||||
* Get all the loaded models, you can provide an array of classes or it will use get_declared_classes()
|
||||
*
|
||||
* @package default
|
||||
* @author Jonathan H. Wage
|
||||
*/
|
||||
@ -507,12 +509,21 @@ final class Doctrine
|
||||
|
||||
return $loadedModels;
|
||||
}
|
||||
public function getConnectionByTableName($tableName)
|
||||
/**
|
||||
* getConnectionByTableName
|
||||
*
|
||||
* Get the connection object for a table by the actual table name
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return void
|
||||
* @author Jonathan H. Wage
|
||||
*/
|
||||
public static function getConnectionByTableName($tableName)
|
||||
{
|
||||
$loadedModels = Doctrine::getLoadedModels();
|
||||
$loadedModels = self::getLoadedModels();
|
||||
|
||||
foreach ($loadedModels AS $name) {
|
||||
$model = new $model();
|
||||
$model = new $name();
|
||||
$table = $model->getTable();
|
||||
|
||||
if ($table->getTableName() == $tableName) {
|
||||
|
@ -547,9 +547,13 @@ class Doctrine_Export extends Doctrine_Connection_Module
|
||||
* actually perform them otherwise.
|
||||
* @return void
|
||||
*/
|
||||
public function alterTable($name, array $changes, $check)
|
||||
public function alterTable($name, array $changes, $check = false)
|
||||
{
|
||||
$this->conn->execute($this->alterTableSql($name, $changes, $check));
|
||||
$sql = $this->alterTableSql($name, $changes, $check);
|
||||
|
||||
if (is_string($sql) && $sql) {
|
||||
$this->conn->execute($sql);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* generates the sql for altering an existing table
|
||||
@ -563,7 +567,7 @@ class Doctrine_Export extends Doctrine_Connection_Module
|
||||
* @see Doctrine_Export::alterTable()
|
||||
* @return string
|
||||
*/
|
||||
public function alterTableSql($name, array $changes, $check)
|
||||
public function alterTableSql($name, array $changes, $check = false)
|
||||
{
|
||||
throw new Doctrine_Export_Exception('Alter table not supported by this driver.');
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ class Doctrine_Export_Firebird extends Doctrine_Export
|
||||
* actually perform them otherwise.
|
||||
* @return void
|
||||
*/
|
||||
public function alterTable($name, array $changes, $check)
|
||||
public function alterTable($name, array $changes, $check = false)
|
||||
{
|
||||
foreach ($changes as $changeName => $change) {
|
||||
switch ($changeName) {
|
||||
|
@ -157,7 +157,7 @@ class Doctrine_Export_Frontbase extends Doctrine_Export
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function alterTable($name, array $changes, $check)
|
||||
public function alterTable($name, array $changes, $check = false)
|
||||
{
|
||||
foreach ($changes as $changeName => $change) {
|
||||
switch ($changeName) {
|
||||
|
@ -161,7 +161,7 @@ class Doctrine_Export_Mssql extends Doctrine_Export
|
||||
* actually perform them otherwise.
|
||||
* @return void
|
||||
*/
|
||||
public function alterTable($name, array $changes, $check)
|
||||
public function alterTable($name, array $changes, $check = false)
|
||||
{
|
||||
foreach ($changes as $changeName => $change) {
|
||||
switch ($changeName) {
|
||||
|
@ -267,7 +267,7 @@ class Doctrine_Export_Mysql extends Doctrine_Export
|
||||
* actually perform them otherwise.
|
||||
* @return boolean
|
||||
*/
|
||||
public function alterTableSql($name, array $changes, $check)
|
||||
public function alterTableSql($name, array $changes, $check = false)
|
||||
{
|
||||
if ( ! $name) {
|
||||
throw new Doctrine_Export_Exception('no valid table name specified');
|
||||
@ -355,7 +355,8 @@ class Doctrine_Export_Mysql extends Doctrine_Export
|
||||
}
|
||||
|
||||
$name = $this->conn->quoteIdentifier($name, true);
|
||||
return $this->conn->exec('ALTER TABLE ' . $name . ' ' . $query);
|
||||
|
||||
return 'ALTER TABLE ' . $name . ' ' . $query;
|
||||
}
|
||||
/**
|
||||
* create sequence
|
||||
|
@ -398,7 +398,7 @@ END;
|
||||
* actually perform them otherwise.
|
||||
* @return void
|
||||
*/
|
||||
public function alterTable($name, array $changes, $check)
|
||||
public function alterTable($name, array $changes, $check = false)
|
||||
{
|
||||
|
||||
foreach ($changes as $changeName => $change) {
|
||||
|
@ -182,7 +182,7 @@ class Doctrine_Export_Pgsql extends Doctrine_Export
|
||||
* @throws Doctrine_Connection_Exception
|
||||
* @return boolean
|
||||
*/
|
||||
public function alterTable($name, array $changes, $check)
|
||||
public function alterTable($name, array $changes, $check = false)
|
||||
{
|
||||
foreach ($changes as $changeName => $change) {
|
||||
switch ($changeName) {
|
||||
|
@ -325,4 +325,96 @@ class Doctrine_Export_Sqlite extends Doctrine_Export
|
||||
|
||||
return 'DROP TABLE ' . $sequenceName;
|
||||
}
|
||||
}
|
||||
|
||||
public function alterTableSql($name, array $changes, $check = false)
|
||||
{
|
||||
if ( ! $name) {
|
||||
throw new Doctrine_Export_Exception('no valid table name specified');
|
||||
}
|
||||
foreach ($changes as $changeName => $change) {
|
||||
switch ($changeName) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'rename':
|
||||
case 'name':
|
||||
break;
|
||||
default:
|
||||
throw new Doctrine_Export_Exception('change type "' . $changeName . '" not yet supported');
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$query = '';
|
||||
if ( ! empty($changes['name'])) {
|
||||
$change_name = $this->conn->quoteIdentifier($changes['name']);
|
||||
$query .= 'RENAME TO ' . $change_name;
|
||||
}
|
||||
|
||||
if ( ! empty($changes['add']) && is_array($changes['add'])) {
|
||||
foreach ($changes['add'] as $fieldName => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$query.= 'ADD ' . $this->getDeclaration($field['type'], $fieldName, $field);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($changes['remove']) && is_array($changes['remove'])) {
|
||||
foreach ($changes['remove'] as $fieldName => $field) {
|
||||
if ($query) {
|
||||
$query .= ', ';
|
||||
}
|
||||
$fieldName = $this->conn->quoteIdentifier($fieldName);
|
||||
$query .= 'DROP ' . $fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
$rename = array();
|
||||
if ( ! empty($changes['rename']) && is_array($changes['rename'])) {
|
||||
foreach ($changes['rename'] as $fieldName => $field) {
|
||||
$rename[$field['name']] = $fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($changes['change']) && is_array($changes['change'])) {
|
||||
foreach ($changes['change'] as $fieldName => $field) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
if (isset($rename[$fieldName])) {
|
||||
$oldFieldName = $rename[$fieldName];
|
||||
unset($rename[$fieldName]);
|
||||
} else {
|
||||
$oldFieldName = $fieldName;
|
||||
}
|
||||
$oldFieldName = $this->conn->quoteIdentifier($oldFieldName, true);
|
||||
$query .= 'CHANGE ' . $oldFieldName . ' '
|
||||
. $this->getDeclaration($field['definition']['type'], $fieldName, $field['definition']);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($rename) && is_array($rename)) {
|
||||
foreach ($rename as $renameName => $renamedField) {
|
||||
if ($query) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$field = $changes['rename'][$renamedField];
|
||||
$renamedField = $this->conn->quoteIdentifier($renamedField, true);
|
||||
$query .= 'CHANGE ' . $renamedField . ' '
|
||||
. $this->getDeclaration($field['definition']['type'], $field['name'], $field['definition']);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $query) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $this->conn->quoteIdentifier($name, true);
|
||||
|
||||
return 'ALTER TABLE ' . $name . ' ' . $query;
|
||||
}
|
||||
}
|
@ -43,7 +43,35 @@ class Doctrine_Migration
|
||||
'added_indexes' => array(),
|
||||
'removed_indexes' => array());
|
||||
|
||||
static public function migration($directory, $from, $to)
|
||||
static public function setCurrentVersion($number)
|
||||
{
|
||||
$conn = Doctrine_Manager::connection();
|
||||
|
||||
try {
|
||||
$conn->export->createTable('migration_version', array('version' => array('type' => 'integer', 'size' => 11)));
|
||||
} catch(Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
$current = self::getCurrentVersion();
|
||||
|
||||
if (!$current) {
|
||||
$conn->exec("INSERT INTO migration_version (version) VALUES ($number)");
|
||||
} else {
|
||||
$conn->exec("UPDATE migration_version SET version = $number");
|
||||
}
|
||||
}
|
||||
|
||||
static public function getCurrentVersion()
|
||||
{
|
||||
$conn = Doctrine_Manager::connection();
|
||||
|
||||
$result = $conn->fetchColumn("SELECT version FROM migration_version");
|
||||
|
||||
return isset($result[0]) ? $result[0]:false;
|
||||
}
|
||||
|
||||
static public function migration($from, $to)
|
||||
{
|
||||
if ($from === $to || $from === 0) {
|
||||
throw new Doctrine_Migration_Exception('You specified an invalid migration path. The from and to cannot be the same and from cannot be zero.');
|
||||
@ -53,29 +81,80 @@ class Doctrine_Migration
|
||||
|
||||
if ($direction === 'up') {
|
||||
for ($i = $from + 1; $i <= $to; $i++) {
|
||||
self::doDirectionStep($directory, $direction, $i);
|
||||
self::doDirectionStep($direction, $i);
|
||||
}
|
||||
} else {
|
||||
for ($i = $from; $i > $to; $i--) {
|
||||
self::doDirectionStep($directory, $direction, $i);
|
||||
self::doDirectionStep($direction, $i);
|
||||
}
|
||||
}
|
||||
|
||||
self::setCurrentVersion($to);
|
||||
}
|
||||
|
||||
public static function doDirectionStep($direction, $num)
|
||||
{
|
||||
$className = 'Migration' . $num;
|
||||
|
||||
if (class_exists($className)) {
|
||||
$migrate = new $className();
|
||||
$migrate->migrate($direction);
|
||||
} else {
|
||||
throw new Doctrine_Migration_Exception('Could not find migration class: ' . $className);
|
||||
}
|
||||
}
|
||||
|
||||
public static function doDirectionStep($directory, $direction, $num)
|
||||
public static function loadMigrationClasses($directory)
|
||||
{
|
||||
$className = 'Migration' . $num;
|
||||
$fileName = $className . '.class.php';
|
||||
$filePath = $directory . DIRECTORY_SEPARATOR . $fileName;
|
||||
|
||||
if (file_exists($filePath)) {
|
||||
require_once($filePath);
|
||||
|
||||
if (class_exists($className)) {
|
||||
$migrate = new $className();
|
||||
$migrate->migrate($direction);
|
||||
$classes = get_declared_classes();
|
||||
|
||||
if ($directory !== null) {
|
||||
foreach ((array) $directory as $dir) {
|
||||
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
|
||||
RecursiveIteratorIterator::LEAVES_ONLY);
|
||||
|
||||
foreach ($it as $file) {
|
||||
$e = explode('.', $file->getFileName());
|
||||
if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
|
||||
require_once $file->getPathName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$classes = array_diff(get_declared_classes(), $classes);
|
||||
}
|
||||
|
||||
return self::getLoadedMigrationClasses($classes);
|
||||
}
|
||||
|
||||
public static function getLoadedMigrationClasses($classes = null)
|
||||
{
|
||||
if ($classes === null) {
|
||||
$classes = get_declared_classes();
|
||||
}
|
||||
|
||||
$parent = new ReflectionClass('Doctrine_Migration');
|
||||
$loadedClasses = array();
|
||||
|
||||
foreach ($classes as $name) {
|
||||
$class = new ReflectionClass($name);
|
||||
|
||||
while ($class->isSubclassOf($parent)) {
|
||||
|
||||
$class = $class->getParentClass();
|
||||
if ($class === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($class === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$loadedClasses[] = $name;
|
||||
}
|
||||
|
||||
return $loadedClasses;
|
||||
}
|
||||
|
||||
public function migrate($direction)
|
||||
|
@ -37,7 +37,7 @@ class Doctrine_Migration_Process
|
||||
}
|
||||
|
||||
public function processCreatedTables($tables)
|
||||
{
|
||||
{
|
||||
foreach ($tables as $table) {
|
||||
$conn = $this->getConnection($table['tableName']);
|
||||
|
||||
@ -94,7 +94,7 @@ class Doctrine_Migration_Process
|
||||
$options = $column['options'];
|
||||
$options['type'] = $column['type'];
|
||||
|
||||
$conn->export->alterTable($column['tableName'], array('change' => array($column['oldColumnName'] => array('definition' => $options))), true);
|
||||
$conn->export->alterTable($column['tableName'], array('change' => array($column['columnName'] => array('definition' => $options))), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
<?php
|
||||
require_once('playground.php');
|
||||
require_once('connection.php');
|
||||
require_once('models.php');
|
||||
|
||||
Doctrine_Migration::migration('migration', 1, 3);
|
||||
Doctrine_Migration::migration('migration', 3, 1);
|
||||
require_once('models.php');
|
@ -32,4 +32,64 @@
|
||||
*/
|
||||
class Doctrine_Migration_TestCase extends Doctrine_UnitTestCase
|
||||
{
|
||||
public function testMigration()
|
||||
{
|
||||
// Upgrade one at a time
|
||||
Doctrine_Migration::migration(1, 2);
|
||||
Doctrine_Migration::migration(2, 3);
|
||||
Doctrine_Migration::migration(3, 4);
|
||||
|
||||
// Then revert back to version 1
|
||||
Doctrine_Migration::migration(4, 1);
|
||||
|
||||
// Check to make sure the current version is 1
|
||||
$this->assertEqual(Doctrine_Migration::getCurrentVersion(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
class MigrationTestTable extends Doctrine_Record
|
||||
{
|
||||
public function setTableDefinition()
|
||||
{
|
||||
$this->hasColumn('field1', 'string');
|
||||
}
|
||||
}
|
||||
|
||||
class Migration2 extends Doctrine_Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->createTable('migration_test_table', array('field1' => array('type' => 'string')));
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->dropTable('migration_test_table');
|
||||
}
|
||||
}
|
||||
|
||||
class Migration3 extends Doctrine_Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->addColumn('migration_test_table', 'field1', 'string');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->renameColumn('migration_test_table', 'field1', 'field2');
|
||||
}
|
||||
}
|
||||
|
||||
class Migration4 extends Doctrine_Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$this->changeColumn('migration_test_table', 'field1', 'integer');
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->changeColumn('migration_test_table', 'field1', 'string');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user