From 83a475ad6b1f0499aeb2171ef2f1fd8add5b22d5 Mon Sep 17 00:00:00 2001 From: mark_story Date: Wed, 16 Oct 2013 21:11:50 -0400 Subject: [PATCH] Remove schema shell from 3.0 Remove the schema shell. I don't think we are going to have time to build a proper replacement for 3.0.0. I also think that migrations are something that would be better handled in a plugin where ideas can be iterated more quickly and compatibility constraints are less strict. --- Cake/Console/Command/SchemaShell.php | 589 --------------- .../Console/Command/CommandListShellTest.php | 2 +- .../Console/Command/CompletionShellTest.php | 2 +- .../Console/Command/SchemaShellTest.php | 697 ------------------ 4 files changed, 2 insertions(+), 1288 deletions(-) delete mode 100644 Cake/Console/Command/SchemaShell.php delete mode 100644 Cake/Test/TestCase/Console/Command/SchemaShellTest.php diff --git a/Cake/Console/Command/SchemaShell.php b/Cake/Console/Command/SchemaShell.php deleted file mode 100644 index e822d7e92c8..00000000000 --- a/Cake/Console/Command/SchemaShell.php +++ /dev/null @@ -1,589 +0,0 @@ -_welcome(); - $this->out('Cake Schema Shell'); - $this->hr(); - - Cache::disable(); - - $name = $path = $connection = $plugin = null; - if (!empty($this->params['name'])) { - $name = $this->params['name']; - } elseif (!empty($this->args[0]) && $this->args[0] !== 'snapshot') { - $name = $this->params['name'] = $this->args[0]; - } - - if (strpos($name, '.')) { - list($this->params['plugin'], $splitName) = pluginSplit($name); - $name = $this->params['name'] = $splitName; - } - - if ($name && empty($this->params['file'])) { - $this->params['file'] = Inflector::underscore($name); - } - - if (empty($this->params['file'])) { - $this->params['file'] = 'schema.php'; - } - if (strpos($this->params['file'], '.php') === false) { - $this->params['file'] .= '.php'; - } - $file = $this->params['file']; - - if (!empty($this->params['path'])) { - $path = $this->params['path']; - } - - if (!empty($this->params['connection'])) { - $connection = $this->params['connection']; - } - if (!empty($this->params['plugin'])) { - $plugin = $this->params['plugin']; - if (empty($name)) { - $name = $plugin; - } - } - $name = Inflector::classify($name); - $this->Schema = new Schema(compact('name', 'path', 'file', 'connection', 'plugin')); - } - -/** - * Read and output contents of schema object - * path to read as second arg - * - * @return void - */ - public function view() { - $File = new File($this->Schema->path . DS . $this->params['file']); - if ($File->exists()) { - $this->out($File->read()); - return $this->_stop(); - } - $file = $this->Schema->path . DS . $this->params['file']; - $this->err(__d('cake_console', 'Schema file (%s) could not be found.', $file)); - return $this->_stop(); - } - -/** - * Read database and Write schema object - * accepts a connection as first arg or path to save as second arg - * - * @return void - */ - public function generate() { - $this->out(__d('cake_console', 'Generating Schema...')); - $options = array(); - if ($this->params['force']) { - $options['models'] = false; - } elseif (!empty($this->params['models'])) { - $options['models'] = String::tokenize($this->params['models']); - } - - $snapshot = false; - if (isset($this->args[0]) && $this->args[0] === 'snapshot') { - $snapshot = true; - } - - if (!$snapshot && file_exists($this->Schema->path . DS . $this->params['file'])) { - $snapshot = true; - $prompt = __d('cake_console', "Schema file exists.\n [O]verwrite\n [S]napshot\n [Q]uit\nWould you like to do?"); - $result = strtolower($this->in($prompt, array('o', 's', 'q'), 's')); - if ($result === 'q') { - return $this->_stop(); - } - if ($result === 'o') { - $snapshot = false; - } - } - - Cache::enable(); - - $content = $this->Schema->read($options); - $content['file'] = $this->params['file']; - - Cache::disable(); - - if (!empty($this->params['exclude']) && !empty($content)) { - $excluded = String::tokenize($this->params['exclude']); - foreach ($excluded as $table) { - unset($content['tables'][$table]); - } - } - - if ($snapshot === true) { - $fileName = rtrim($this->params['file'], '.php'); - $Folder = new Folder($this->Schema->path); - $result = $Folder->read(); - - $numToUse = false; - if (isset($this->params['snapshot'])) { - $numToUse = $this->params['snapshot']; - } - - $count = 0; - if (!empty($result[1])) { - foreach ($result[1] as $file) { - if (preg_match('/' . preg_quote($fileName) . '(?:[_\d]*)?\.php$/', $file)) { - $count++; - } - } - } - - if ($numToUse !== false) { - if ($numToUse > $count) { - $count = $numToUse; - } - } - - $content['file'] = $fileName . '_' . $count . '.php'; - } - - if ($this->Schema->write($content)) { - $this->out(__d('cake_console', 'Schema file: %s generated', $content['file'])); - return $this->_stop(); - } - $this->err(__d('cake_console', 'Schema file: %s generated')); - return $this->_stop(); - } - -/** - * Dump Schema object to sql file - * Use the `write` param to enable and control SQL file output location. - * Simply using -write will write the sql file to the same dir as the schema file. - * If -write contains a full path name the file will be saved there. If -write only - * contains no DS, that will be used as the file name, in the same dir as the schema file. - * - * @return string - */ - public function dump() { - $write = false; - $Schema = $this->Schema->load(); - if (!$Schema) { - $this->err(__d('cake_console', 'Schema could not be loaded')); - return $this->_stop(); - } - if (!empty($this->params['write'])) { - if ($this->params['write'] == 1) { - $write = Inflector::underscore($this->Schema->name); - } else { - $write = $this->params['write']; - } - } - $db = ConnectionManager::getDataSource($this->Schema->connection); - $contents = "\n\n" . $db->dropSchema($Schema) . "\n\n" . $db->createSchema($Schema); - - if ($write) { - if (strpos($write, '.sql') === false) { - $write .= '.sql'; - } - if (strpos($write, DS) !== false) { - $File = new File($write, true); - } else { - $File = new File($this->Schema->path . DS . $write, true); - } - - if ($File->write($contents)) { - $this->out(__d('cake_console', 'SQL dump file created in %s', $File->pwd())); - return $this->_stop(); - } - $this->err(__d('cake_console', 'SQL dump could not be created')); - return $this->_stop(); - } - $this->out($contents); - return $contents; - } - -/** - * Run database create commands. Alias for run create. - * - * @return void - */ - public function create() { - list($Schema, $table) = $this->_loadSchema(); - $this->_create($Schema, $table); - } - -/** - * Run database create commands. Alias for run create. - * - * @return void - */ - public function update() { - list($Schema, $table) = $this->_loadSchema(); - $this->_update($Schema, $table); - } - -/** - * Prepares the Schema objects for database operations. - * - * @return void - */ - protected function _loadSchema() { - $name = $plugin = null; - if (!empty($this->params['name'])) { - $name = $this->params['name']; - } - if (!empty($this->params['plugin'])) { - $plugin = $this->params['plugin']; - } - - if (!empty($this->params['dry'])) { - $this->_dry = true; - $this->out(__d('cake_console', 'Performing a dry run.')); - } - - $options = array('name' => $name, 'plugin' => $plugin); - if (!empty($this->params['snapshot'])) { - $fileName = rtrim($this->Schema->file, '.php'); - $options['file'] = $fileName . '_' . $this->params['snapshot'] . '.php'; - } - - $Schema = $this->Schema->load($options); - - if (!$Schema) { - $this->err(__d('cake_console', 'The chosen schema could not be loaded. Attempted to load:')); - $this->err(__d('cake_console', 'File: %s', $this->Schema->path . DS . $this->Schema->file)); - $this->err(__d('cake_console', 'Name: %s', $this->Schema->name)); - return $this->_stop(); - } - $table = null; - if (isset($this->args[1])) { - $table = $this->args[1]; - } - return array(&$Schema, $table); - } - -/** - * Create database from Schema object - * Should be called via the run method - * - * @param Cake\Model\Schema $Schema - * @param string $table - * @return void - */ - protected function _create(CakeSchema $Schema, $table = null) { - $db = ConnectionManager::getDataSource($this->Schema->connection); - - $drop = $create = array(); - - if (!$table) { - foreach ($Schema->tables as $table => $fields) { - $drop[$table] = $db->dropSchema($Schema, $table); - $create[$table] = $db->createSchema($Schema, $table); - } - } elseif (isset($Schema->tables[$table])) { - $drop[$table] = $db->dropSchema($Schema, $table); - $create[$table] = $db->createSchema($Schema, $table); - } - if (empty($drop) || empty($create)) { - $this->out(__d('cake_console', 'Schema is up to date.')); - return $this->_stop(); - } - - $this->out("\n" . __d('cake_console', 'The following table(s) will be dropped.')); - $this->out(array_keys($drop)); - - if ( - !empty($this->params['yes']) || - $this->in(__d('cake_console', 'Are you sure you want to drop the table(s)?'), array('y', 'n'), 'n') === 'y' - ) { - $this->out(__d('cake_console', 'Dropping table(s).')); - $this->_run($drop, 'drop', $Schema); - } - - $this->out("\n" . __d('cake_console', 'The following table(s) will be created.')); - $this->out(array_keys($create)); - - if ( - !empty($this->params['yes']) || - $this->in(__d('cake_console', 'Are you sure you want to create the table(s)?'), array('y', 'n'), 'y') === 'y' - ) { - $this->out(__d('cake_console', 'Creating table(s).')); - $this->_run($create, 'create', $Schema); - } - $this->out(__d('cake_console', 'End create.')); - } - -/** - * Update database with Schema object - * Should be called via the run method - * - * @param Cake\Model\Schema $Schema - * @param string $table - * @return void - */ - protected function _update(&$Schema, $table = null) { - $db = ConnectionManager::getDataSource($this->Schema->connection); - - $this->out(__d('cake_console', 'Comparing Database to Schema...')); - $options = array(); - if (isset($this->params['force'])) { - $options['models'] = false; - } - $Old = $this->Schema->read($options); - $compare = $this->Schema->compare($Old, $Schema); - - $contents = array(); - - if (empty($table)) { - foreach ($compare as $table => $changes) { - if (isset($compare[$table]['create'])) { - $contents[$table] = $db->createSchema($Schema, $table); - } else { - $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table); - } - } - } elseif (isset($compare[$table])) { - if (isset($compare[$table]['create'])) { - $contents[$table] = $db->createSchema($Schema, $table); - } else { - $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table); - } - } - - if (empty($contents)) { - $this->out(__d('cake_console', 'Schema is up to date.')); - return $this->_stop(); - } - - $this->out("\n" . __d('cake_console', 'The following statements will run.')); - $this->out(array_map('trim', $contents)); - if ( - !empty($this->params['yes']) || - $this->in(__d('cake_console', 'Are you sure you want to alter the tables?'), array('y', 'n'), 'n') === 'y' - ) { - $this->out(); - $this->out(__d('cake_console', 'Updating Database...')); - $this->_run($contents, 'update', $Schema); - } - - $this->out(__d('cake_console', 'End update.')); - } - -/** - * Runs sql from _create() or _update() - * - * @param array $contents - * @param string $event - * @param Cake\Model\Schema $Schema - * @return void - */ - protected function _run($contents, $event, CakeSchema $Schema) { - if (empty($contents)) { - $this->err(__d('cake_console', 'Sql could not be run')); - return; - } - Configure::write('debug', 2); - $db = ConnectionManager::getDataSource($this->Schema->connection); - - foreach ($contents as $table => $sql) { - if (empty($sql)) { - $this->out(__d('cake_console', '%s is up to date.', $table)); - } else { - if ($this->_dry === true) { - $this->out(__d('cake_console', 'Dry run for %s :', $table)); - $this->out($sql); - } else { - if (!$Schema->before(array($event => $table))) { - return false; - } - $error = null; - try { - $db->execute($sql); - } catch (PDOException $e) { - $error = $table . ': ' . $e->getMessage(); - } - - $Schema->after(array($event => $table, 'errors' => $error)); - - if (!empty($error)) { - $this->err($error); - } else { - $this->out(__d('cake_console', '%s updated.', $table)); - } - } - } - } - } - -/** - * get the option parser - * - * @return void - */ - public function getOptionParser() { - $plugin = array( - 'short' => 'p', - 'help' => __d('cake_console', 'The plugin to use.'), - ); - $connection = array( - 'short' => 'c', - 'help' => __d('cake_console', 'Set the db config to use.'), - 'default' => 'default' - ); - $path = array( - 'help' => __d('cake_console', 'Path to read and write schema.php'), - 'default' => APP . 'Config/Schema' - ); - $file = array( - 'help' => __d('cake_console', 'File name to read and write.'), - 'default' => 'schema.php' - ); - $name = array( - 'help' => __d('cake_console', - 'Classname to use. If its Plugin.class, both name and plugin options will be set.' - ) - ); - $snapshot = array( - 'short' => 's', - 'help' => __d('cake_console', 'Snapshot number to use/make.') - ); - $models = array( - 'short' => 'm', - 'help' => __d('cake_console', 'Specify models as comma separated list.'), - ); - $dry = array( - 'help' => __d('cake_console', - 'Perform a dry run on create and update commands. Queries will be output instead of run.' - ), - 'boolean' => true - ); - $force = array( - 'short' => 'f', - 'help' => __d('cake_console', 'Force "generate" to create a new schema'), - 'boolean' => true - ); - $write = array( - 'help' => __d('cake_console', 'Write the dumped SQL to a file.') - ); - $exclude = array( - 'help' => __d('cake_console', 'Tables to exclude as comma separated list.') - ); - $yes = array( - 'short' => 'y', - 'help' => __d('cake_console', 'Do not prompt for confirmation. Be careful!'), - 'boolean' => true - ); - - $parser = parent::getOptionParser(); - $parser->description( - __d('cake_console', - 'The Schema Shell generates a schema object from the database and updates the database from the schema.' - ) - )->addSubcommand('view', array( - 'help' => __d('cake_console', 'Read and output the contents of a schema file'), - 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection'), - 'arguments' => compact('name') - ) - ))->addSubcommand('generate', array( - 'help' => __d('cake_console', 'Reads from --connection and writes to --path. Generate snapshots with -s'), - 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force', 'models', 'exclude'), - 'arguments' => array( - 'snapshot' => array('help' => __d('cake_console', 'Generate a snapshot.')) - ) - ) - ))->addSubcommand('dump', array( - 'help' => __d('cake_console', 'Dump database SQL based on a schema file to stdout.'), - 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'write'), - 'arguments' => compact('name') - ) - ))->addSubcommand('create', array( - 'help' => __d('cake_console', 'Drop and create tables based on the schema file.'), - 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot', 'yes'), - 'args' => array( - 'name' => array( - 'help' => __d('cake_console', 'Name of schema to use.') - ), - 'table' => array( - 'help' => __d('cake_console', 'Only create the specified table.') - ) - ) - ) - ))->addSubcommand('update', array( - 'help' => __d('cake_console', 'Alter the tables based on the schema file.'), - 'parser' => array( - 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot', 'force', 'yes'), - 'args' => array( - 'name' => array( - 'help' => __d('cake_console', 'Name of schema to use.') - ), - 'table' => array( - 'help' => __d('cake_console', 'Only create the specified table.') - ) - ) - ) - )); - return $parser; - } - -} diff --git a/Cake/Test/TestCase/Console/Command/CommandListShellTest.php b/Cake/Test/TestCase/Console/Command/CommandListShellTest.php index 965f0548cc9..1352f159adc 100644 --- a/Cake/Test/TestCase/Console/Command/CommandListShellTest.php +++ b/Cake/Test/TestCase/Console/Command/CommandListShellTest.php @@ -92,7 +92,7 @@ public function testMain() { $expected = "/\[.*TestPluginTwo.*\] example, welcome/"; $this->assertRegExp($expected, $output); - $expected = "/\[.*CORE.*\] acl, api, bake, command_list, completion, i18n, schema, server, test, upgrade/"; + $expected = "/\[.*CORE.*\] acl, api, bake, command_list, completion, i18n, server, test, upgrade/"; $this->assertRegExp($expected, $output); $expected = "/\[.*app.*\] sample/"; diff --git a/Cake/Test/TestCase/Console/Command/CompletionShellTest.php b/Cake/Test/TestCase/Console/Command/CompletionShellTest.php index 97515645b56..0195e5553f0 100644 --- a/Cake/Test/TestCase/Console/Command/CompletionShellTest.php +++ b/Cake/Test/TestCase/Console/Command/CompletionShellTest.php @@ -112,7 +112,7 @@ public function testCommands() { $this->Shell->runCommand('commands', array()); $output = $this->Shell->stdout->output; - $expected = "TestPlugin.example TestPluginTwo.example TestPluginTwo.welcome acl api bake command_list completion i18n schema server test upgrade sample\n"; + $expected = "TestPlugin.example TestPluginTwo.example TestPluginTwo.welcome acl api bake command_list completion i18n server test upgrade sample\n"; $this->assertEquals($expected, $output); } diff --git a/Cake/Test/TestCase/Console/Command/SchemaShellTest.php b/Cake/Test/TestCase/Console/Command/SchemaShellTest.php deleted file mode 100644 index 506a190e2b9..00000000000 --- a/Cake/Test/TestCase/Console/Command/SchemaShellTest.php +++ /dev/null @@ -1,697 +0,0 @@ - array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'), - 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0), - 'user_id' => array('type' => 'integer', 'null' => false), - 'title' => array('type' => 'string', 'null' => false, 'length' => 100), - 'comment' => array('type' => 'text', 'null' => false, 'default' => null), - 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)), - ); - -/** - * posts property - * - * @var array - */ - public $articles = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'), - 'user_id' => array('type' => 'integer', 'null' => true, 'default' => ''), - 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'), - 'body' => array('type' => 'text', 'null' => true, 'default' => null), - 'summary' => array('type' => 'text', 'null' => true), - 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)), - ); - - public $newone = array( - 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'), - 'testit' => array('type' => 'string', 'null' => false, 'default' => 'Title'), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)), - ); -} - -/** - * SchemaShellTest class - * - */ -class SchemaShellTest extends TestCase { - -/** - * Fixtures - * - * @var array - */ - public $fixtures = array( - 'core.article', 'core.user', 'core.post', 'core.auth_user', 'core.author', - 'core.comment', 'core.test_plugin_comment', 'core.aco', 'core.aro', 'core.aros_aco', - ); - -/** - * setUp method - * - * @return void - */ - public function setUp() { - parent::setUp(); - $this->markTestIncomplete('SchemaShell is not working as models are not working.'); - - $out = $this->getMock('Cake\Console\ConsoleOutput', array(), array(), '', false); - $in = $this->getMock('Cake\Console\ConsoleInput', array(), array(), '', false); - $this->Shell = $this->getMock( - 'Cake\Console\Command\SchemaShell', - array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop'), - array($out, $out, $in) - ); - } - -/** - * tearDown method - * - * @return void - */ - public function tearDown() { - parent::tearDown(); - if (!empty($this->file) && $this->file instanceof File) { - $this->file->delete(); - unset($this->file); - } - } - -/** - * test startup method - * - * @return void - */ - public function testStartup() { - $this->Shell->startup(); - $this->assertTrue(isset($this->Shell->Schema)); - $this->assertInstanceOf('Cake\Model\Schema', $this->Shell->Schema); - $this->assertEquals(Inflector::camelize(Inflector::slug(APP_DIR)), $this->Shell->Schema->name); - $this->assertEquals('schema.php', $this->Shell->Schema->file); - - $this->Shell->Schema = null; - $this->Shell->params = array( - 'name' => 'TestSchema' - ); - $this->Shell->startup(); - $this->assertEquals('TestSchema', $this->Shell->Schema->name); - $this->assertEquals('test_schema.php', $this->Shell->Schema->file); - $this->assertEquals('default', $this->Shell->Schema->connection); - $this->assertEquals(APP . 'Config/Schema', $this->Shell->Schema->path); - - $this->Shell->Schema = null; - $this->Shell->params = array( - 'file' => 'other_file.php', - 'connection' => 'test', - 'path' => '/test/path' - ); - $this->Shell->startup(); - $this->assertEquals(Inflector::camelize(Inflector::slug(APP_DIR)), $this->Shell->Schema->name); - $this->assertEquals('other_file.php', $this->Shell->Schema->file); - $this->assertEquals('test', $this->Shell->Schema->connection); - $this->assertEquals('/test/path', $this->Shell->Schema->path); - } - -/** - * Test View - and that it dumps the schema file to stdout - * - * @return void - */ - public function testView() { - $this->Shell->startup(); - $this->Shell->Schema->path = APP . 'Config/Schema'; - $this->Shell->params['file'] = 'i18n.php'; - $this->Shell->expects($this->once())->method('_stop'); - $this->Shell->expects($this->once())->method('out'); - $this->Shell->view(); - } - -/** - * test that view() can find plugin schema files. - * - * @return void - */ - public function testViewWithPlugins() { - App::build(array( - 'Plugin' => array(CAKE . 'Test/TestApp/Plugin/') - )); - Plugin::load('TestPlugin'); - $this->Shell->args = array('TestPlugin.schema'); - $this->Shell->startup(); - $this->Shell->expects($this->exactly(2))->method('_stop'); - $this->Shell->expects($this->atLeastOnce())->method('out'); - $this->Shell->view(); - - $this->Shell->args = array(); - $this->Shell->params = array('plugin' => 'TestPlugin'); - $this->Shell->startup(); - $this->Shell->view(); - - App::build(); - Plugin::unload(); - } - -/** - * test dump() with sql file generation - * - * @return void - */ - public function testDumpWithFileWriting() { - $this->Shell->params = array( - 'name' => 'i18n', - 'connection' => 'test', - 'write' => TMP . 'tests/i18n.sql' - ); - $this->Shell->expects($this->once())->method('_stop'); - $this->Shell->startup(); - $this->Shell->dump(); - - $this->file = new File(TMP . 'tests/i18n.sql'); - $contents = $this->file->read(); - $this->assertRegExp('/DROP TABLE/', $contents); - $this->assertRegExp('/CREATE TABLE.*?i18n/', $contents); - $this->assertRegExp('/id/', $contents); - $this->assertRegExp('/model/', $contents); - $this->assertRegExp('/field/', $contents); - $this->assertRegExp('/locale/', $contents); - $this->assertRegExp('/foreign_key/', $contents); - $this->assertRegExp('/content/', $contents); - } - -/** - * test that dump() can find and work with plugin schema files. - * - * @return void - */ - public function testDumpFileWritingWithPlugins() { - App::build(array( - 'Plugin' => array(CAKE . 'Test/TestApp/Plugin/') - )); - Plugin::load('TestPlugin'); - $this->Shell->args = array('TestPlugin.TestPluginApp'); - $this->Shell->params = array( - 'connection' => 'test', - 'write' => TMP . 'tests/dump_test.sql' - ); - $this->Shell->startup(); - $this->Shell->expects($this->once())->method('_stop'); - $this->Shell->dump(); - - $this->file = new File(TMP . 'tests/dump_test.sql'); - $contents = $this->file->read(); - - $this->assertRegExp('/CREATE TABLE.*?test_plugin_acos/', $contents); - $this->assertRegExp('/id/', $contents); - $this->assertRegExp('/model/', $contents); - - $this->file->delete(); - App::build(); - Plugin::unload(); - } - -/** - * test generate with snapshot generation - * - * @return void - */ - public function testGenerateSnapshot() { - $this->Shell->path = TMP; - $this->Shell->params['file'] = 'schema.php'; - $this->Shell->params['force'] = false; - $this->Shell->args = array('snapshot'); - $this->Shell->Schema = $this->getMock('Cake\Model\Schema'); - $this->Shell->Schema->expects($this->at(0))->method('read')->will($this->returnValue(array('schema data'))); - $this->Shell->Schema->expects($this->at(0))->method('write')->will($this->returnValue(true)); - - $this->Shell->Schema->expects($this->at(1))->method('read'); - $this->Shell->Schema->expects($this->at(1))->method('write')->with(array('schema data', 'file' => 'schema_0.php')); - - $this->Shell->generate(); - } - -/** - * test generate without a snapshot. - * - * @return void - */ - public function testGenerateNoOverwrite() { - touch(TMP . 'schema.php'); - $this->Shell->params['file'] = 'schema.php'; - $this->Shell->params['force'] = false; - $this->Shell->args = array(); - - $this->Shell->expects($this->once())->method('in')->will($this->returnValue('q')); - $this->Shell->Schema = $this->getMock('Cake\Model\Schema'); - $this->Shell->Schema->path = TMP; - $this->Shell->Schema->expects($this->never())->method('read'); - - $this->Shell->generate(); - unlink(TMP . 'schema.php'); - } - -/** - * test generate with overwriting of the schema files. - * - * @return void - */ - public function testGenerateOverwrite() { - touch(TMP . 'schema.php'); - $this->Shell->params['file'] = 'schema.php'; - $this->Shell->params['force'] = false; - $this->Shell->args = array(); - - $this->Shell->expects($this->once())->method('in')->will($this->returnValue('o')); - - $this->Shell->expects($this->at(2))->method('out') - ->with(new \PHPUnit_Framework_Constraint_PCREMatch('/Schema file:\s[a-z\.]+\sgenerated/')); - - $this->Shell->Schema = $this->getMock('Cake\Model\Schema'); - $this->Shell->Schema->path = TMP; - $this->Shell->Schema->expects($this->once())->method('read')->will($this->returnValue(array('schema data'))); - $this->Shell->Schema->expects($this->once())->method('write')->will($this->returnValue(true)); - - $this->Shell->Schema->expects($this->once())->method('read'); - $this->Shell->Schema->expects($this->once())->method('write') - ->with(array('schema data', 'file' => 'schema.php')); - - $this->Shell->generate(); - unlink(TMP . 'schema.php'); - } - -/** - * test that generate() can read plugin dirs and generate schema files for the models - * in a plugin. - * - * @return void - */ - public function testGenerateWithPlugins() { - App::build(array( - 'Plugin' => array(CAKE . 'Test/TestApp/Plugin/') - ), App::RESET); - Plugin::load('TestPlugin'); - - $this->db->cacheSources = false; - $this->Shell->params = array( - 'plugin' => 'TestPlugin', - 'connection' => 'test', - 'force' => false - ); - $this->Shell->startup(); - $this->Shell->Schema->path = TMP . 'tests/'; - - $this->Shell->generate(); - $this->file = new File(TMP . 'tests/schema.php'); - $contents = $this->file->read(); - - $this->assertRegExp('/class TestPluginSchema/', $contents); - $this->assertRegExp('/public \$posts/', $contents); - $this->assertRegExp('/public \$auth_users/', $contents); - $this->assertRegExp('/public \$authors/', $contents); - $this->assertRegExp('/public \$test_plugin_comments/', $contents); - $this->assertNotRegExp('/public \$users/', $contents); - $this->assertNotRegExp('/public \$articles/', $contents); - Plugin::unload(); - } - -/** - * test generate with specific models - * - * @return void - */ - public function testGenerateModels() { - App::build(array( - 'Plugin' => array(CAKE . 'Test/TestApp/Plugin/') - ), App::RESET); - Plugin::load('TestPlugin'); - - $this->db->cacheSources = false; - $this->Shell->params = array( - 'plugin' => 'TestPlugin', - 'connection' => 'test', - 'models' => 'TestPluginComment', - 'force' => false, - 'overwrite' => true - ); - $this->Shell->startup(); - $this->Shell->Schema->path = TMP . 'tests/'; - - $this->Shell->generate(); - $this->file = new File(TMP . 'tests/schema.php'); - $contents = $this->file->read(); - - $this->assertRegExp('/class TestPluginSchema/', $contents); - $this->assertRegExp('/public \$test_plugin_comments/', $contents); - $this->assertNotRegExp('/public \$authors/', $contents); - $this->assertNotRegExp('/public \$auth_users/', $contents); - $this->assertNotRegExp('/public \$posts/', $contents); - Plugin::unload(); - } - -/** - * test generate with excluded tables - * - * @return void - */ - public function testGenerateExclude() { - Configure::write('Acl.database', 'test'); - $this->db->cacheSources = false; - $this->Shell->params = array( - 'connection' => 'test', - 'force' => false, - 'models' => 'Aro, Aco, Permission', - 'overwrite' => true, - 'exclude' => 'acos, aros', - ); - $this->Shell->startup(); - $this->Shell->Schema->path = TMP . 'tests' . DS; - - $this->Shell->generate(); - $this->file = new File(TMP . 'tests' . DS . 'schema.php'); - $contents = $this->file->read(); - - $this->assertNotContains('public $acos = array(', $contents); - $this->assertNotContains('public $aros = array(', $contents); - $this->assertContains('public $aros_acos = array(', $contents); - } - -/** - * Test schema run create with --yes option - * - * @return void - */ - public function testCreateOptionYes() { - $this->Shell = $this->getMock( - 'SchemaShell', - array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop', '_run'), - array(&$this->Dispatcher) - ); - - $this->Shell->params = array( - 'connection' => 'test', - 'yes' => true, - ); - $this->Shell->args = array('i18n'); - $this->Shell->expects($this->never())->method('in'); - $this->Shell->expects($this->exactly(2))->method('_run'); - $this->Shell->startup(); - $this->Shell->create(); - } - -/** - * Test schema run create with no table args. - * - * @return void - */ - public function testCreateNoArgs() { - $this->Shell->params = array( - 'connection' => 'test' - ); - $this->Shell->args = array('i18n'); - $this->Shell->startup(); - $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y')); - $this->Shell->create(); - - $db = ConnectionManager::getDataSource('test'); - - $db->cacheSources = false; - $sources = $db->listSources(); - $this->assertTrue(in_array($db->config['prefix'] . 'i18n', $sources)); - - $schema = new i18nSchema(); - $db->execute($db->dropSchema($schema)); - } - -/** - * Test schema run create with no table args. - * - * @return void - */ - public function testCreateWithTableArgs() { - $db = ConnectionManager::getDataSource('test'); - $sources = $db->listSources(); - if (in_array('i18n', $sources)) { - $this->markTestSkipped('i18n table already exists, cannot try to create it again.'); - } - $this->Shell->params = array( - 'connection' => 'test', - 'name' => 'I18n', - 'path' => APP . 'Config' . DS . 'Schema' - ); - $this->Shell->args = array('I18n', 'i18n'); - $this->Shell->startup(); - $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y')); - $this->Shell->create(); - - $db = ConnectionManager::getDataSource('test'); - $db->cacheSources = false; - $sources = $db->listSources(); - $this->assertTrue(in_array($db->config['prefix'] . 'i18n', $sources), 'i18n should be present.'); - - $schema = new I18nSchema(); - $db->execute($db->dropSchema($schema, 'i18n')); - } - -/** - * test run update with a table arg. - * - * @return void - */ - public function testUpdateWithTable() { - $this->Shell = $this->getMock( - 'SchemaShell', - array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop', '_run'), - array(&$this->Dispatcher) - ); - - $this->Shell->params = array( - 'connection' => 'test', - 'force' => true - ); - $this->Shell->args = array('SchemaShellTest', 'articles'); - $this->Shell->startup(); - $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y')); - $this->Shell->expects($this->once())->method('_run') - ->with($this->arrayHasKey('articles'), 'update', $this->isInstanceOf('Cake\Model\Schema')); - - $this->Shell->update(); - } - -/** - * test run update with a table arg. and checks that a CREATE statement is issued - * table creation - * @return void - */ - public function testUpdateWithTableCreate() { - $this->Shell = $this->getMock( - 'SchemaShell', - array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop', '_run'), - array(&$this->Dispatcher) - ); - - $this->Shell->params = array( - 'connection' => 'test', - 'force' => true - ); - $this->Shell->args = array('SchemaShellTest', 'newone'); - $this->Shell->startup(); - $this->Shell->expects($this->any()) - ->method('in') - ->will($this->returnValue('y')); - $r = $this->Shell->expects($this->once()) - ->method('_run') - ->with($this->arrayHasKey('newone'), 'update', $this->isInstanceOf('Cake\Model\Schema')); - - $this->Shell->update(); - } - -/** - * test run update with --yes option - * - * @return void - */ - public function testUpdateWithOptionYes() { - $this->Shell = $this->getMock( - 'SchemaShell', - array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop', '_run'), - array(&$this->Dispatcher) - ); - - $this->Shell->params = array( - 'connection' => 'test', - 'force' => true, - 'yes' => true, - ); - $this->Shell->args = array('SchemaShellTest', 'articles'); - $this->Shell->startup(); - $this->Shell->expects($this->never())->method('in'); - $this->Shell->expects($this->once()) - ->method('_run') - ->with($this->arrayHasKey('articles'), 'update', $this->isInstanceOf('CakeSchema')); - - $this->Shell->update(); - } - -/** - * test that the plugin param creates the correct path in the schema object. - * - * @return void - */ - public function testPluginParam() { - App::build(array( - 'Plugin' => array(CAKE . 'Test/TestApp/Plugin/') - )); - Plugin::load('TestPlugin'); - $this->Shell->params = array( - 'plugin' => 'TestPlugin', - 'connection' => 'test' - ); - $this->Shell->startup(); - $expected = CAKE . 'Test/TestApp/Plugin/TestPlugin/Config/Schema'; - $this->assertEquals($expected, $this->Shell->Schema->path); - Plugin::unload(); - } - -/** - * test that underscored names also result in CamelCased class names - * - * @return void - */ - public function testName() { - App::build(array( - 'Plugin' => array(CAKE . 'Test/TestApp/Plugin/') - )); - Plugin::load('TestPlugin'); - $this->Shell->params = array( - 'plugin' => 'TestPlugin', - 'connection' => 'test', - 'name' => 'custom_name', - 'force' => false, - 'overwrite' => true, - ); - $this->Shell->startup(); - if (file_exists($this->Shell->Schema->path . DS . 'custom_name.php')) { - unlink($this->Shell->Schema->path . DS . 'custom_name.php'); - } - $this->Shell->generate(); - - $contents = file_get_contents($this->Shell->Schema->path . DS . 'custom_name.php'); - $this->assertRegExp('/class CustomNameSchema/', $contents); - unlink($this->Shell->Schema->path . DS . 'custom_name.php'); - Plugin::unload(); - } - -/** - * test that passing name and file creates the passed filename with the - * passed classname - * - * @return void - */ - public function testNameAndFile() { - App::build(array( - 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS) - )); - CakePlugin::load('TestPlugin'); - $this->Shell->params = array( - 'plugin' => 'TestPlugin', - 'connection' => 'test', - 'name' => 'custom_name', - 'file' => 'other_name', - 'force' => false, - 'overwrite' => true, - ); - $this->Shell->startup(); - $file = $this->Shell->Schema->path . DS . 'other_name.php'; - if (file_exists($file)) { - unlink($file); - } - $this->Shell->generate(); - - $this->assertFileExists($file); - $contents = file_get_contents($file); - $this->assertRegExp('/class CustomNameSchema/', $contents); - - if (file_exists($file)) { - unlink($file); - } - CakePlugin::unload(); - } - -/** - * test that using Plugin.name with write. - * - * @return void - */ - public function testPluginDotSyntaxWithCreate() { - App::build(array( - 'Plugin' => array(CAKE . 'Test/TestApp/Plugin/') - )); - Plugin::load('TestPlugin'); - $this->Shell->params = array( - 'connection' => 'test' - ); - $this->Shell->args = array('TestPlugin.TestPluginApp'); - $this->Shell->startup(); - $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y')); - $this->Shell->create(); - - $db = ConnectionManager::getDataSource('test'); - $sources = $db->listSources(); - $this->assertTrue(in_array($db->config['prefix'] . 'test_plugin_acos', $sources)); - - $schema = new TestPluginAppSchema(); - $db->execute($db->dropSchema($schema, 'test_plugin_acos')); - Plugin::unload(); - } -}