Skip to content

Commit

Permalink
Merge pull request #250 from CakeDC/develop
Browse files Browse the repository at this point in the history
Update master with lastest changes
  • Loading branch information
steinkel committed Dec 18, 2015
2 parents 6832b54 + 166aeea commit 891f940
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 47 deletions.
146 changes: 124 additions & 22 deletions Console/Command/MigrationShell.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
App::uses('String', 'Utility');
App::uses('ClassRegistry', 'Utility');
App::uses('ConnectionManager', 'Model');
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');

/**
* Migration shell.
*
*/
class MigrationShell extends AppShell {

Expand Down Expand Up @@ -156,44 +157,48 @@ public function getOptionParser() {
'')
->addOption('plugin', array(
'short' => 'p',
'help' => __('Plugin name to be used')))
'help' => __d('migrations', 'Plugin name to be used')))
->addOption('precheck', array(
'short' => 'm',
'default' => 'Migrations.PrecheckException',
'help' => __('Precheck migrations')))
'help' => __d('migrations', 'Precheck migrations')))
->addOption('force', array(
'short' => 'f',
'boolean' => true,
'help' => __('Force \'generate\' to compare all tables.')))
'help' => __d('migrations', 'Force \'generate\' to compare all tables.')))
->addOption('overwrite', array(
'short' => 'o',
'boolean' => true,
'help' => __d('migrations', 'Overwrite the schema.php file after generated a migration.')))
->addOption('connection', array(
'short' => 'c',
'default' => null,
'help' => __('Overrides the \'default\' connection of the MigrationVersion')))
'help' => __d('migrations', 'Overrides the \'default\' connection of the MigrationVersion')))
->addOption('migrationConnection', array(
'short' => 'i',
'default' => null,
'help' => __('Overrides the \'default\' connection of the CakeMigrations that are applied')))
'help' => __d('migrations', 'Overrides the \'default\' connection of the CakeMigrations that are applied')))
->addOption('dry', array(
'short' => 'd',
'boolean' => true,
'default' => false,
'help' => __('Output the raw SQL queries rather than applying them to the database.')))
'help' => __d('migrations', 'Output the raw SQL queries rather than applying them to the database.')))
->addOption('no-auto-init', array(
'short' => 'n',
'boolean' => true,
'default' => false,
'help' => __('Disables automatic creation of migrations table and running any internal plugin migrations')))
'help' => __d('migrations', 'Disables automatic creation of migrations table and running any internal plugin migrations')))
->addOption('schema-class', array(
'short' => 's',
'boolean' => false,
'default' => false,
'help' => __('CamelCased Classname without the `Schema` suffix to use when reading or generating schema files. See `Console/cake schema generate --help`.')))
'help' => __d('migrations', 'CamelCased Classname without the `Schema` suffix to use when reading or generating schema files. See `Console/cake schema generate --help`.')))
->addSubcommand('status', array(
'help' => __('Displays a status of all plugin and app migrations.')))
'help' => __d('migrations', 'Displays a status of all plugin and app migrations.')))
->addSubcommand('run', array(
'help' => __('Run a migration to given direction or version.')))
'help' => __d('migrations', 'Run a migration to given direction or version.')))
->addSubcommand('generate', array(
'help' => __('Generates a migration file.')));
'help' => __d('migrations', 'Generates a migration file.')));
}

/**
Expand Down Expand Up @@ -267,7 +272,7 @@ public function run() {

$result = $this->_execute($options, $once);
if ($result !== true) {
$this->out(__d('migrations', $result));
$this->out($result);
}

$this->out(__d('migrations', 'All migrations have completed.'));
Expand Down Expand Up @@ -427,12 +432,15 @@ public function generate() {
$response = $this->in(__d('migrations', 'Do you want to compare the schema.php file to the database?'), array('y', 'n'), 'y');
if (strtolower($response) === 'y') {
$this->_generateFromComparison($migration, $oldSchema, $comparison);
if (empty($comparison)) {
$this->hr();
$this->out(__d('migrations', 'No database changes detected.'));
return $this->_stop();
}
$this->_migrationChanges($migration);
$fromSchema = true;
} else {
$response = $this->in(__d('migrations', 'Do you want to compare the database to the schema.php file?'), array('y', 'n'), 'y');
if(strtolower($response) === 'y') {
$this->_generateFromInverseComparison($migration, $oldSchema, $comparison);
$this->_migrationChanges($migration);
$fromSchema = false;
}
}
} else {
$response = $this->in(__d('migrations', 'Do you want to generate a dump from the current database?'), array('y', 'n'), 'y');
Expand All @@ -445,6 +453,10 @@ public function generate() {

$this->_finalizeGeneratedMigration($migration, $migrationName, $fromSchema);

if ($this->params['overwrite'] === true) {
$this->_overwriteSchema();
}

if ($fromSchema && isset($comparison)) {
$response = $this->in(__d('migrations', 'Do you want to update the schema.php file?'), array('y', 'n'), 'y');
if (strtolower($response) === 'y') {
Expand All @@ -453,6 +465,14 @@ public function generate() {
}
}

protected function _migrationChanges($migration) {
if (empty($migration)) {
$this->hr();
$this->out(__d('migrations', 'No database changes detected.'));
return $this->_stop();
}
}

/**
* Generate a migration by comparing schema.php with the database.
*
Expand All @@ -473,6 +493,26 @@ protected function _generateFromComparison(&$migration, &$oldSchema, &$compariso
$migration = $this->_fromComparison($migration, $comparison, $oldSchema->tables, $newSchema['tables']);
}

/**
* Generate a migration by comparing the database with schema.php.
*
* @param array &$migration Reference to variable of the same name in generate() method
* @param array &$oldSchema Reference to variable of the same name in generate() method
* @param array &$comparison Reference to variable of the same name in generate() method
* @return void (The variables passed by reference are changed; nothing is returned)
*/
protected function _generateFromInverseComparison(&$migration, &$oldSchema, &$comparison) {
$this->hr();
$this->out(__d('migrations', 'Comparing database to the schema.php...'));

if ($this->type !== 'migrations') {
unset($oldSchema->tables['schema_migrations']);
}
$database = $this->_readSchema();
$comparison = $this->Schema->compare($database, $oldSchema);
$migration = $this->_fromComparison($migration, $comparison, $oldSchema->tables, $database['tables']);
}

/**
* Generate a migration from arguments passed in at the command line
*
Expand Down Expand Up @@ -780,24 +820,49 @@ protected function _getSchema($type = null) {
$plugin = ($this->type === 'app') ? null : $this->type;
return new CakeSchema(array('connection' => $this->connection, 'plugin' => $plugin));
}
$file = $this->_getPath($type) . 'Config' . DS . 'Schema' . DS . 'schema.php';
if (!file_exists($file)) {

$folder = new Folder($this->_getPath($type) . 'Config' . DS . 'Schema');
$schema_files = $folder->find('.*schema.*.php');

if (count($schema_files) === 0) {
return false;
}
require_once $file;

$name = $this->_getSchemaClassName($type);
$file = $this->_findSchemaFile($folder, $schema_files, $name);

if ($type === 'app' && !class_exists($name)) {
if ($type === 'app' && empty($file)) {
$appDir = preg_replace('/[^a-zA-Z0-9]/', '', APP_DIR);
$name = Inflector::camelize($appDir) . 'Schema';
$file = $this->_getPath($type) . 'Config' . DS . 'Schema' . DS . 'schema.php';
}

require_once $file;

$plugin = ($type === 'app') ? null : $type;
$schema = new $name(array('connection' => $this->connection, 'plugin' => $plugin));
return $schema;
}

/**
* Finds schema file
*
* @param Folder $folder Folder object with schema folder path.
* @param string $schema_files Schema files inside schema folder.
* @param string $name Schema-class name.
* @return mixed null in case of no file found, schema file.
*/
protected function _findSchemaFile($folder, $schema_files, $name) {
foreach ($schema_files as $schema_file) {
$file = new File($folder->pwd() . DS . $schema_file);
$content = $file->read();
if (strpos($content, $name) !== false) {
return $file->path;
}
}
return null;
}

/**
* Reads the schema data
*
Expand Down Expand Up @@ -828,6 +893,43 @@ protected function _updateSchema() {
$this->dispatchShell($command);
}

/**
* Overwrite the schema.php file
*
* @return void
*/

protected function _overwriteSchema() {
$options = array();
if ($this->params['force']) {
$options['models'] = false;
} elseif (!empty($this->params['models'])) {
$options['models'] = String::tokenize($this->params['models']);
}

$cacheDisable = Configure::read('Cache.disable');
Configure::write('Cache.disable', true);

$content = $this->Schema->read($options);
$file = 'schema.php';

Configure::write('Cache.disable', $cacheDisable);

if (!empty($this->params['exclude']) && !empty($content)) {
$excluded = String::tokenize($this->params['exclude']);
foreach ($excluded as $table) {
unset($content['tables'][$table]);
}
}

if ($this->Schema->write($content)) {
$this->out(__d('cake_console', 'Schema file: %s generated', $file));
return $this->_stop();
}
$this->err(__d('cake_console', 'Schema file: %s generated'));
return $this->_stop();
}

/**
* Parse fields from the command line for use with generating new migration files
*
Expand Down
19 changes: 19 additions & 0 deletions Console/Command/MigrationsShell.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/**
* Copyright 2009 - 2014, Cake Development Corporation (http://cakedc.com)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2009 - 2014, Cake Development Corporation (http://cakedc.com)
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/

App::uses('MigrationShell', 'Migrations.Console/Command');

/**
* Migrations shell
*
* A proxy class to use the new CakePHP 2.7.x shell shortcut feature.
*/
class MigrationsShell extends MigrationShell {}
6 changes: 5 additions & 1 deletion Docs/Documentation/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ If any updates are added, go back to the base of your own repository, commit and
Composer
--------

The plugin also provides a "composer.json" file, to easily use the plugin through the Composer dependency manager.
To install the plugin with the [Composer dependency manager](https://getcomposer.org/), run the following from your CakePHP project's ROOT directory (where the ``composer.json`` file is located):

```
php composer.phar require cakedc/migrations "~2.4.0"
```
2 changes: 0 additions & 2 deletions Lib/CakeMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

/**
* Base Class for Migration management
*
*/
class CakeMigration extends Object {

Expand Down Expand Up @@ -637,7 +636,6 @@ public function generateModel($name, $table = null, $options = array()) {

/**
* Exception used when something goes wrong on migrations
*
*/
class MigrationException extends Exception {

Expand Down
4 changes: 1 addition & 3 deletions Lib/MigrationVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

/**
* Migration version management.
*
*/
class MigrationVersion {

Expand Down Expand Up @@ -349,7 +348,7 @@ public function run($options) {
} else {
$latestVersionName = null;
}
$errorMessage = __d('migrations', sprintf("There was an error during a migration. \n The error was: '%s' \n You must resolve the issue manually and try again.", $exception->getMessage(), $latestVersionName));
$errorMessage = __d('migrations', "There was an error during a migration. \n The error was: '%s' \n You must resolve the issue manually and try again.", $exception->getMessage(), $latestVersionName);
return $errorMessage;
}

Expand Down Expand Up @@ -492,7 +491,6 @@ protected function _enumerateOldMigrations($type) {

/**
* Usually used when migrations file/class or map files are not found
*
*/
class MigrationVersionException extends Exception {

Expand Down
1 change: 0 additions & 1 deletion Lib/Panel/MigrationsPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
* 'panels' => array('Migrations.migrations')
* ));
* @@@
*
*/
class MigrationsPanel extends DebugPanel {

Expand Down
Loading

0 comments on commit 891f940

Please sign in to comment.