Skip to content

Commit

Permalink
Merge pull request #321 from QoboLtd/update-to-latest-phinx
Browse files Browse the repository at this point in the history
Upgrade robmorgan/phinx to v0.8.1
  • Loading branch information
lorenzo authored Aug 1, 2017
2 parents 62cc863 + 12fc74e commit 419e044
Show file tree
Hide file tree
Showing 15 changed files with 287 additions and 56 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"require": {
"php": ">=5.5.9",
"robmorgan/phinx": "0.6.6",
"robmorgan/phinx": "0.8.1",
"cakephp/orm": "~3.2",
"cakephp/cache": "~3.2"
},
Expand Down
3 changes: 2 additions & 1 deletion src/AbstractSeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ protected function runCall($seeder)
$seedCommand->setInput($input);
$config = $seedCommand->getConfig();

require_once($config->getSeedPath() . DS . $seeder . '.php');
$seedPaths = $config->getSeedPaths();
require_once(array_pop($seedPaths) . DS . $seeder . '.php');
$seeder = new $seeder();
$seeder->setOutput($this->getOutput());
$seeder->setAdapter($this->getAdapter());
Expand Down
34 changes: 34 additions & 0 deletions src/CakeAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ public function getConnection()
return $this->adapter->getConnection();
}

/**
* Gets the database PDO connection object.
*
* @param \PDO $connection Connection
* @return AdapterInterface
*/
public function setConnection($connection)
{
return $this->adapter->setConnection($connection);
}

/**
* Gets the CakePHP Connection object.
*
Expand Down Expand Up @@ -456,6 +467,17 @@ public function dropTable($tableName)
$this->adapter->dropTable($tableName);
}

/**
* Truncates the specified table
*
* @param string $tableName
* @return void
*/
public function truncateTable($tableName)
{
$this->adapter->truncateTable($tableName);
}

/**
* Returns table columns
*
Expand Down Expand Up @@ -697,6 +719,18 @@ public function dropDatabase($name)
$this->adapter->dropDatabase($name);
}

/**
* Cast a value to a boolean appropriate for the adapter.
*
* @param mixed $value The value to be cast
*
* @return mixed
*/
public function castToBool($value)
{
return $this->adapter->castToBool($value);
}

/**
* Sets the console input.
*
Expand Down
9 changes: 8 additions & 1 deletion src/Command/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ protected function configure()
'l',
InputOption::VALUE_REQUIRED,
'Use a class implementing "' . parent::CREATION_INTERFACE . '" to generate the template'
)
->addOption(
'path',
null,
InputOption::VALUE_REQUIRED,
'Specify the path in which to create this migration'
);
}

Expand All @@ -67,7 +73,8 @@ protected function execute(InputInterface $input, OutputInterface $output)

$output->writeln('<info>renaming file in CamelCase to follow CakePHP convention...</info>');

$migrationPath = $this->getConfig()->getMigrationPath() . DS;
$migrationPaths = $this->getConfig()->getMigrationPaths();
$migrationPath = array_pop($migrationPaths) . DS;
$name = $input->getArgument('name');
list($phinxTimestamp, $phinxName) = explode('_', Util::mapClassNameToFileName($name), 2);
$migrationFilename = glob($migrationPath . '*' . $phinxName);
Expand Down
3 changes: 2 additions & 1 deletion src/Command/MarkMigrated.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->bootstrap($input, $output);
$this->output($output);

$path = $this->getConfig()->getMigrationPath();
$migrationPaths = $this->getConfig()->getMigrationPaths();
$path = array_pop($migrationPaths);

if ($this->invalidOnlyOrExclude()) {
$output->writeln(
Expand Down
4 changes: 2 additions & 2 deletions src/Command/Seed.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
class Seed extends SeedRun
{

use CommandTrait;
use ConfigurationTrait {
use CommandTrait {
execute as parentExecute;
}
use ConfigurationTrait;
use EventDispatcherTrait;

/**
Expand Down
29 changes: 24 additions & 5 deletions src/Migrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Cake\Datasource\ConnectionManager;
use Phinx\Config\Config;
use Phinx\Config\ConfigInterface;
use Phinx\Migration\Manager;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\NullOutput;
Expand Down Expand Up @@ -230,8 +231,9 @@ public function markMigrated($version = null, $options = [])
$input = $this->getInput('MarkMigrated', ['version' => $version], $options);
$this->setInput($input);

$migrationPaths = $this->getConfig()->getMigrationPaths();
$params = [
$this->getConfig()->getMigrationPath(),
array_pop($migrationPaths),
$this->getManager()->getVersionsToMark($input),
$this->output
];
Expand Down Expand Up @@ -281,19 +283,36 @@ public function seed($options = [])
protected function run($method, $params, $input)
{
if ($this->configuration instanceof Config) {
$migrationPath = $this->getConfig()->getMigrationPath();
$seedPath = $this->getConfig()->getSeedPath();
$migrationPaths = $this->getConfig()->getMigrationPaths();
$migrationPath = array_pop($migrationPaths);
$seedPaths = $this->getConfig()->getSeedPaths();
$seedPath = array_pop($seedPaths);
}

if ($this->manager instanceof Manager) {
$pdo = $this->manager->getEnvironment('default')
->getAdapter()
->getConnection();
}

$this->setInput($input);
$newConfig = $this->getConfig(true);
$manager = $this->getManager($newConfig);
$manager->setInput($input);

if (isset($migrationPath) && $newConfig->getMigrationPath() !== $migrationPath) {

if (isset($pdo)) {
$this->manager->getEnvironment('default')
->getAdapter()
->setConnection($pdo);
}

$newMigrationPaths = $newConfig->getMigrationPaths();
if (isset($migrationPath) && array_pop($newMigrationPaths) !== $migrationPath) {
$manager->resetMigrations();
}
if (isset($seedPath) && $newConfig->getSeedPath() !== $seedPath) {
$newSeedPaths = $newConfig->getSeedPaths();
if (isset($seedPath) && array_pop($newSeedPaths) !== $seedPath) {
$manager->resetSeeds();
}

Expand Down
20 changes: 20 additions & 0 deletions src/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,30 @@ public function create()
*/
public function update()
{
if ($this->getAdapter()->getAdapterType() == 'sqlite') {
$this->foreignKeys = [];
}

parent::update();
TableRegistry::clear();
}

/**
* {@inheritDoc}
*
* We disable foreign key deletion for the SQLite adapter as SQLite does not support the feature natively and the
* process implemented by Phinx has serious side-effects (for instance it rename FK references in existing tables
* which breaks the database schema cohesion).
*/
public function dropForeignKey($columns, $constraint = null)
{
if ($this->getAdapter()->getAdapterType() == 'sqlite') {
return $this;
}

return parent::dropForeignKey($columns, $constraint);
}

/**
* This method is called in case a primary key was defined using the addPrimaryKey() method.
* It currently does something only if using SQLite.
Expand Down
160 changes: 160 additions & 0 deletions tests/CommandTester.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php
/**
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/

namespace Migrations\Test;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Complete override of the Symfony class needed to have a charged instance of the output object used in the tests.
* The output object used should be the one of the command.
*/
class CommandTester
{
private $command;
private $input;
private $output;
private $inputs = array();
private $statusCode;

/**
* Constructor.
*
* @param Command $command A Command instance to test
*/
public function __construct(Command $command)
{
$this->command = $command;
}

/**
* Executes the command.
*
* Available execution options:
*
* * interactive: Sets the input interactive flag
* * decorated: Sets the output decorated flag
* * verbosity: Sets the output verbosity flag
*
* @param array $input An array of command arguments and options
* @param array $options An array of execution options
*
* @return int The command exit code
*/
public function execute(array $input, array $options = array())
{
// set the command name automatically if the application requires
// this argument and no command name was passed
if (!isset($input['command'])
&& (null !== $application = $this->command->getApplication())
&& $application->getDefinition()->hasArgument('command')
) {
$input = array_merge(array('command' => $this->command->getName()), $input);
}

$this->input = new ArrayInput($input);
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
}

if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}

// This is where the magic does its magic : we use the output object of the command.
$this->output = $this->command->getManager()->getOutput();
$this->output->setDecorated(isset($options['decorated']) ? $options['decorated'] : false);
if (isset($options['verbosity'])) {
$this->output->setVerbosity($options['verbosity']);
}

return $this->statusCode = $this->command->run($this->input, $this->output);
}

/**
* Gets the display returned by the last execution of the command.
*
* @param bool $normalize Whether to normalize end of lines to \n or not
*
* @return string The display
*/
public function getDisplay($normalize = false)
{
rewind($this->output->getStream());

$display = stream_get_contents($this->output->getStream());

if ($normalize) {
$display = str_replace(PHP_EOL, "\n", $display);
}

return $display;
}

/**
* Gets the input instance used by the last execution of the command.
*
* @return InputInterface The current input instance
*/
public function getInput()
{
return $this->input;
}

/**
* Gets the output instance used by the last execution of the command.
*
* @return OutputInterface The current output instance
*/
public function getOutput()
{
return $this->output;
}

/**
* Gets the status code returned by the last execution of the application.
*
* @return int The status code
*/
public function getStatusCode()
{
return $this->statusCode;
}

/**
* Sets the user inputs.
*
* @param array An array of strings representing each input
* passed to the command input stream.
*
* @return CommandTester
*/
public function setInputs(array $inputs)
{
$this->inputs = $inputs;

return $this;
}

private static function createStream(array $inputs)
{
$stream = fopen('php://memory', 'r+', false);

fwrite($stream, implode(PHP_EOL, $inputs));
rewind($stream);

return $stream;
}
}
2 changes: 1 addition & 1 deletion tests/TestCase/Command/CreateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ protected function getCommandTester($params)
$manager = new CakeManager($this->command->getConfig(), $input, $this->streamOutput);
$manager->getEnvironment('default')->getAdapter()->setConnection($this->Connection->driver()->connection());
$this->command->setManager($manager);
$commandTester = new CommandTester($this->command);
$commandTester = new \Migrations\Test\CommandTester($this->command);

return $commandTester;
}
Expand Down
Loading

0 comments on commit 419e044

Please sign in to comment.