Commit 10bdfcb1 authored by Jonathan.Wage's avatar Jonathan.Wage

Changes for new migration code.

parent 5d12093b
......@@ -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;
}
}
\ No newline at end of file
......@@ -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($directory, $direction, $num)
public static function doDirectionStep($direction, $num)
{
$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);
} else {
throw new Doctrine_Migration_Exception('Could not find migration class: ' . $className);
}
}
public static function loadMigrationClasses($directory)
{
$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)
......
......@@ -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);
}
}
......
......@@ -2,6 +2,3 @@
require_once('playground.php');
require_once('connection.php');
require_once('models.php');
\ No newline at end of file
Doctrine_Migration::migration('migration', 1, 3);
Doctrine_Migration::migration('migration', 3, 1);
......@@ -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');
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment