Commit 81324ec8 authored by Jonathan.Wage's avatar Jonathan.Wage

Fleshing out functionality of CLI system and changed syntax of migration...

Fleshing out functionality of CLI system and changed syntax of migration classes to only required a to parameter since we already know where we are coming from.
parent 52551457
......@@ -516,6 +516,53 @@ final class Doctrine
{
return Doctrine_Manager::connection()->import->importSchema($directory, $databases);
}
/**
* generateModelsFromDb
*
* Generate your model definitions from an existing database
*
* @param string $directory
* @param string $array
* @return void
*/
public static function generateModelsFromDb($directory, array $databases = array())
{
return self::importSchema($directory, $databases);
}
/**
* generateYamlFromDb
*
* Generates models from database to temporary location then uses those models to generate a yaml schema file.
* This should probably be fixed. We should write something to generate a yaml schema file directly from the database.
*
* @param string $yamlPath
* @return void
*/
public static function generateYamlFromDb($yamlPath)
{
$directory = '/tmp/tmp_doctrine_models';
Doctrine::generateModelsFromDb($directory);
$export = new Doctrine_Export_Schema();
return $export->exportSchema($yamlPath, 'yml', $directory);
}
/**
* generateModelsFromYaml
*
* Generate a yaml schema file from an existing directory of models
*
* @param string $yamlPath
* @param string $directory
* @return void
*/
public static function generateModelsFromYaml($yamlPath, $directory)
{
$import = new Doctrine_Import_Schema();
return $import->importSchema($yamlPath, 'yml', $directory);
}
/**
* exportSchema
* method for exporting Doctrine_Record classes to a schema
......@@ -526,6 +573,182 @@ final class Doctrine
{
return Doctrine_Manager::connection()->export->exportSchema($directory);
}
/**
* createTablesFromModels
*
* Creates database tables for the models in the specified directory
*
* @param string $directory
* @return void
*/
public static function createTablesFromModels($directory = null)
{
return self::exportSchema($directory);
}
/**
* generateYamlFromModels
*
* Generate yaml schema file for the models in the specified directory
*
* @param string $yamlPath
* @param string $directory
* @return void
*/
public static function generateYamlFromModels($yamlPath, $directory)
{
$export = new Doctrine_Export_Schema();
return $export->exportSchema($yamlPath, 'yml', $directory);
}
/**
* createDatabases
*
* Creates databases for connections
*
* @param string $specifiedConnections
* @return void
*/
public static function createDatabases($specifiedConnections)
{
if (!is_array($specifiedConnections)) {
$specifiedConnections = (array) $specifiedConnections;
}
$connections = Doctrine_Manager::getInstance()->getConnections();
foreach ($connections as $name => $connection) {
if (!empty($specifiedConnections) && !in_array($name, $specifiedConnections)) {
continue;
}
$connection->export->createDatabase($name);
}
}
/**
* dropDatabases
*
* Drops databases for connections
*
* @param string $specifiedConnections
* @return void
*/
public static function dropDatabases($specifiedConnections = array())
{
if (!is_array($specifiedConnections)) {
$specifiedConnections = (array) $specifiedConnections;
}
$connections = Doctrine_Manager::getInstance()->getConnections();
foreach ($connections as $name => $connection) {
if (!empty($specifiedConnections) && !in_array($name, $specifiedConnections)) {
continue;
}
$connection->export->dropDatabase($name);
}
}
/**
* dumpData
*
* Dump data to a yaml fixtures file
*
* @param string $yamlPath
* @param string $individualFiles
* @return void
*/
public static function dumpData($yamlPath, $individualFiles = false)
{
$data = new Doctrine_Data();
return $data->exportData($yamlPath, 'yml', array(), $individualFiles);
}
/**
* loadData
*
* Load data from a yaml fixtures file.
* The output of dumpData can be fed to loadData
*
* @param string $yamlPath
* @param string $append
* @return void
*/
public static function loadData($yamlPath, $append = false)
{
$delete = isset($append) ? ($append ? false : true) : true;
if ($delete)
{
$models = Doctrine::getLoadedModels();
foreach ($models as $model)
{
$model = new $model();
$model->getTable()->createQuery()->delete($model)->execute();
}
}
$data = new Doctrine_Data();
return $data->importData($yamlPath, 'yml');
}
/**
* loadDummyData
*
* Populdate your models with dummy data
*
* @param string $append
* @param string $num
* @return void
*/
public static function loadDummyData($append, $num = 5)
{
$delete = isset($append) ? ($append ? false : true) : true;
if ($delete)
{
$models = Doctrine::getLoadedModels();
foreach ($models as $model)
{
$model = new $model();
$model->getTable()->createQuery()->delete($model)->execute();
}
}
$data = new Doctrine_Data();
return $data->importDummyData($num);
}
public static function migrate($directory, $to = null)
{
$migration = new Doctrine_Migration($directory);
return $migration->migrate($to);
}
public static function generateMigrationClass($className, $directory)
{
$migration = new Doctrine_Migration($directory);
$next = (string) $migration->getNextVersion();
$fileName = str_repeat('0', (3 - strlen($next))) . $next . '_' . Doctrine::tableize($className) . '.class.php';
$path = $directory . DIRECTORY_SEPARATOR . $fileName;
$code = '<?php' . PHP_EOL;
$code .= "// Automatically generated by Doctrine\n";
$code .= "class " . $className . " extends Doctrine_Migration\n";
$code .= "{\n";
$code .= "\tpublic function up()\n\t{ }\n\n";
$code .= "\tpublic function down()\n\t{ }\n";
$code .= "}";
file_put_contents($path, $code);
}
/**
* exportSql
* method for exporting Doctrine_Record classes to a schema
......@@ -536,6 +759,10 @@ final class Doctrine
{
return Doctrine_Manager::connection()->export->exportSql($directory);
}
public static function generateSqlFromModels($directory)
{
return self::exportSql($directory);
}
/**
* compile
* method for making a single file of most used doctrine runtime components
......
......@@ -34,6 +34,12 @@ class Doctrine_Cli
{
protected $tasks = array();
protected $scriptName = null;
protected $config = array();
public function __construct($config = array())
{
$this->config = $config;
}
public function run($args)
{
......@@ -55,14 +61,30 @@ class Doctrine_Cli
$taskInstance->taskName = str_replace('_', '-', Doctrine::tableize(str_replace('Doctrine_Cli_Task_', '', $taskName)));
$args = $taskInstance->prepareArgs($args);
$args = $this->prepareArgs($args);
$taskInstance->validate($args);
$taskInstance->execute($args);
$taskInstance->execute();
} else {
throw new Doctrine_Cli_Exception('Cli task could not be found: '.$taskClass);
}
}
protected function prepareArgs($args)
{
if (is_array($this->config) && !empty($this->config)) {
foreach ($this->config as $key => $value) {
if (array_key_exists($key, $args)) {
$args[$key] = $value;
}
}
}
return $args;
}
public function printTasks()
{
$tasks = $this->loadTasks();
......
......@@ -42,6 +42,8 @@ abstract class Doctrine_Cli_Task
public function validate($args)
{
$this->arguments = $args;
$requiredArguments = $this->getRequiredArguments();
foreach ($requiredArguments as $arg) {
......@@ -64,6 +66,8 @@ abstract class Doctrine_Cli_Task
foreach ($requiredArguments as $key => $arg) {
if (isset($args[$count])) {
$prepared[$arg] = $args[$count];
} else {
$prepared[$arg] = null;
}
$count++;
......
......@@ -36,5 +36,7 @@ class Doctrine_Cli_Task_CreateDb extends Doctrine_Cli_Task
$optionalArguments = array('connection' => 'Optionally specify a single connection to create the database for.');
public function execute()
{ }
{
Doctrine::createDatabases($this->getArgument('connection'));
}
}
\ No newline at end of file
......@@ -33,9 +33,11 @@
class Doctrine_Cli_Task_CreateTables extends Doctrine_Cli_Task
{
public $description = 'Create tables for all existing database connections',
$requiredArguments = array(),
$requiredArguments = array('models_path' => 'Specify path to your models directory.'),
$optionalArguments = array();
public function execute()
{ }
{
Doctrine::createTablesFromModels($this->getArgument('models_path'));
}
}
\ No newline at end of file
......@@ -37,5 +37,7 @@ class Doctrine_Cli_Task_DropDb extends Doctrine_Cli_Task
$optionalArguments = array('connection' => 'Optionally specify a single connection to drop the database for.');
public function execute()
{ }
{
Doctrine::dropDatabases($this->getArgument('connection'));
}
}
\ No newline at end of file
......@@ -33,9 +33,26 @@
class Doctrine_Cli_Task_DumpData extends Doctrine_Cli_Task
{
public $description = 'Dump data to a yaml data fixture file.',
$requiredArguments = array('path' => 'Specify the full path to write the yaml data fixtures file to.'),
$optionalArguments = array();
$requiredArguments = array('data_fixtures_path' => 'Specify path to write the yaml data fixtures file to.',
'models_path' => 'Specify path to your Doctrine_Record definitions.'),
$optionalArguments = array('individual_files' => 'Specify whether or not you want to dump to individual files. One file per model.');
public function execute()
{ }
{
Doctrine::loadModels($this->getArgument('models_path'));
$individualFiles = $this->getArgument('individual_files') ? true:false;
$path = $this->getArgument('data_fixtures_path');
if (!$individualFiles) {
$e = explode('.', $this->getArgument('data_fixtures_path'));
if (end($e) !== 'yml') {
$path = $this->getArgument('data_fixtures_path'). DIRECTORY_SEPARATOR . 'data.yml';
}
}
Doctrine::dumpData($path, $individualFiles);
}
}
\ No newline at end of file
......@@ -33,9 +33,12 @@
class Doctrine_Cli_Task_GenerateMigration extends Doctrine_Cli_Task
{
public $description = 'Generate new migration class definition',
$requiredArguments = array('path' => 'Specify the complete path to your migration classes folder.'),
$requiredArguments = array('class_name' => 'Name of the migration class to generate',
'migrations_path' => 'Specify the complete path to your migration classes folder.'),
$optionalArguments = array();
public function execute()
{ }
{
Doctrine::generateMigrationClass($this->getArgument('class_name'), $this->getArgument('migrations_path'));
}
}
\ No newline at end of file
......@@ -33,9 +33,11 @@
class Doctrine_Cli_Task_GenerateModelsFromDb extends Doctrine_Cli_Task
{
public $description = 'Generates your Doctrine_Record definitions from your existing database connections.',
$requiredArguments = array(),
$optionalArguments = array();
$requiredArguments = array('models_path' => 'Specify path to your Doctrine_Record definitions.'),
$optionalArguments = array('connection' => 'Optionally specify a single connection to generate the models for.');
public function execute()
{ }
{
Doctrine::generateModelsFromDb($this->getArgument('models_path'), (array) $this->getArgument('connection'));
}
}
\ No newline at end of file
......@@ -33,9 +33,12 @@
class Doctrine_Cli_Task_GenerateModelsFromYaml extends Doctrine_Cli_Task
{
public $description = 'Generates your Doctrine_Record definitions from a Yaml schema file',
$requiredArguments = array('path' => 'Specify the complete directory path to write the models to.'),
$requiredArguments = array('yaml_schema_path' => 'Specify the complete directory path to your yaml schema files.',
'models_path' => 'Specify complete path to your Doctrine_Record definitions.'),
$optionalArguments = array();
public function execute()
{ }
{
Doctrine::generateModelsFromYaml($this->getArgument('yaml_schema_path'), $this->getArgument('models_path'));
}
}
\ No newline at end of file
......@@ -33,9 +33,14 @@
class Doctrine_Cli_Task_GenerateSql extends Doctrine_Cli_Task
{
public $description = 'Generate sql for all existing database connections.',
$requiredArguments = array(),
$requiredArguments = array('models_path' => 'Specify complete path to your Doctrine_Record definitions.',
'sql_path' => 'Path to write the generated sql.'),
$optionalArguments = array();
public function execute()
{ }
{
$sql = Doctrine::generateSqlFromModels($this->getArgument('models_path'));
file_put_contents($this->getArgument('sql_path'), implode("\n", $sql));
}
}
\ No newline at end of file
<?php
/*
* $Id: GenerateYamlFromDb.php 2761 2007-10-07 23:42:29Z zYne $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
/**
* Doctrine_Cli_Task_GenerateYamlFromDb
*
* @package Doctrine
* @subpackage Cli
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision: 2761 $
* @author Jonathan H. Wage <jwage@mac.com>
*/
class Doctrine_Cli_Task_GenerateYamlFromDb extends Doctrine_Cli_Task
{
public $description = 'Generates a Yaml schema file from an existing database',
$requiredArguments = array('yaml_schema_path' => 'Specify the path to your yaml schema files.'),
$optionalArguments = array();
public function execute()
{
Doctrine::generateYamlFromDb($this->getArgument('yaml_schema_path'));
}
}
\ No newline at end of file
......@@ -33,9 +33,12 @@
class Doctrine_Cli_Task_GenerateYamlFromModels extends Doctrine_Cli_Task
{
public $description = 'Generates a Yaml schema file from existing Doctrine_Record definitions',
$requiredArguments = array('path' => 'Specify the complete path to write the yaml schema file to.'),
$requiredArguments = array('yaml_schema_path' => 'Specify the complete directory path to your yaml schema files.',
'models_path' => 'Specify complete path to your Doctrine_Record definitions.'),
$optionalArguments = array();
public function execute()
{ }
{
Doctrine::generateYamlFromModels($this->getArgument('yaml_schema_path'), $this->getArgument('models_path'));
}
}
\ No newline at end of file
<?php
/*
* $Id: GenerateSql.php 2761 2007-10-07 23:42:29Z zYne $
* $Id: LoadData.php 2761 2007-10-07 23:42:29Z zYne $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
......@@ -33,9 +33,13 @@
class Doctrine_Cli_Task_LoadData extends Doctrine_Cli_Task
{
public $description = 'Load data from a yaml data fixture file.',
$requiredArguments = array('path' => 'Specify the complete path to load the yaml data fixtures files from.'),
$requiredArguments = array('data_fixtures_path' => 'Specify the complete path to load the yaml data fixtures files from.',
'models_path' => 'Specify path to your Doctrine_Record definitions.'),
$optionalArguments = array();
public function execute()
{ }
{
Doctrine::loadModels($this->getArgument('models_path'));
Doctrine::loadData($this->getArgument('data_fixtures_path'));
}
}
\ No newline at end of file
<?php
/*
* $Id: LoadDummyData.php 2761 2007-10-07 23:42:29Z zYne $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
/**
* Doctrine_Cli_Task_LoadDummyData
*
* @package Doctrine
* @subpackage Cli
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision: 2761 $
* @author Jonathan H. Wage <jwage@mac.com>
*/
class Doctrine_Cli_Task_LoadDummyData extends Doctrine_Cli_Task
{
public $description = 'Load data from a yaml data fixture file.',
$requiredArguments = array('models_path' => 'Specify path to your Doctrine_Record definitions.'),
$optionalArguments = array('append' => 'Whether or not to append the data or to delete all data before loading.',
'num' => 'Number of records to populate for each model.');
public function execute()
{
Doctrine::loadModels($this->getArgument('models_path'));
Doctrine::loadDummyData($this->getArgument('append') ? true:false, $this->getArgument('num') ? $this->getArgument('num'):5);
}
}
\ No newline at end of file
......@@ -37,5 +37,7 @@ class Doctrine_Cli_Task_Migrate extends Doctrine_Cli_Task
$optionalArguments = array('version' => 'Version to migrate to. If you do not specify, the db will be migrated from the current version to the latest.');
public function execute()
{ }
{
Doctrine::migrate($this->getArgument('version'));
}
}
\ No newline at end of file
......@@ -104,7 +104,7 @@ class Doctrine_Data_Export extends Doctrine_Data
}
foreach ($data as $className => $classData) {
Doctrine_Parser::dump($classData->toArray(), $format, $directory.DIRECTORY_SEPARATOR.$className.'.'.$format);
Doctrine_Parser::dump(array($className => $classData), $format, $directory.DIRECTORY_SEPARATOR.$className.'.'.$format);
}
} else {
if (is_dir($directory)) {
......
......@@ -976,8 +976,12 @@ class Doctrine_Export extends Doctrine_Connection_Module
* @return void
*/
public function exportSchema($directory = null)
{
$models = Doctrine::loadModels($directory);
{
if ($directory !== null) {
$models = Doctrine::loadModels($directory);
} else {
$models = Doctrine::getLoadedModels();
}
$this->exportClasses($models);
}
......
......@@ -142,12 +142,27 @@ class Doctrine_Migration
continue;
}
$loadedClasses[$name] = $fileName;
$e = explode('_', $fileName);
$classMigrationNum = (int) $e[0];
$loadedClasses[$classMigrationNum] = $fileName;
}
$this->migrationClasses = $loadedClasses;
return $loadedClasses;
return $this->migrationClasses;
}
/**
* getMigrationClasses
*
* @return void
* @author Jonathan H. Wage
*/
public function getMigrationClasses()
{
return $this->migrationClasses;
}
/**
......@@ -213,15 +228,18 @@ class Doctrine_Migration
$this->loadMigrationClasses();
$versions = array();
foreach ($this->migrationClasses as $name => $fileName) {
$e = explode('_', $fileName);
$version = (int) $e[0];
$versions[$version] = $version;
foreach ($this->migrationClasses as $classMigrationNum => $fileName) {
$versions[$classMigrationNum] = $classMigrationNum;
}
rsort($versions);
return $versions[0];
return isset($versions[0]) ? $versions[0]:0;
}
public function getNextVersion()
{
return $this->getLatestVersion() + 1;
}
/**
......@@ -234,12 +252,7 @@ class Doctrine_Migration
*/
protected function getMigrationClass($num)
{
$classes = $this->migrationClasses;
foreach ($classes as $className => $fileName) {
$e = explode('_', $fileName);
$classMigrationNum = (int) $e[0];
foreach ($this->migrationClasses as $classMigrationNum => $fileName) {
if ($classMigrationNum === $num) {
return new $className();
}
......@@ -297,16 +310,17 @@ class Doctrine_Migration
* @param string $to
* @return void
*/
public function migrate($from = null, $to = null)
public function migrate($to = null)
{
$from = $this->getCurrentVersion();
// If nothing specified then lets assume we are migrating from the current version to the latest version
if ($from === null && $to === null) {
$from = $this->getCurrentVersion();
if ($to === null) {
$to = $this->getLatestVersion();
}
if ($from === $to) {
throw new Doctrine_Migration_Exception('You specified an invalid migration path. The from and to cannot be the same. You specified from: ' . $from . ' and to: ' . $to);
throw new Doctrine_Migration_Exception('Already up-to-date');
}
$direction = $from > $to ? 'down':'up';
......
......@@ -93,15 +93,11 @@ class AddUser extends Doctrine_Migration
++ Performing Migrations
<code type="php">
$migration = new Doctrine_Migration('migration_classes');
$migration->migrate(0, 1);
$migration->migrate(1, 2);
$migration->migrate(2, 3);
$migration = new Doctrine_Migration('/path/to/migration_classes');
// Then revert back to version 1
$migration->migrate(3, 2);
$migration->migrate(2, 1);
$migration->migrate(1, 0);
// Assume current version is 0
$migration->migrate(3); // takes you from 0 to 3
$migration->migrate(0); // takes you from 3 to 0
echo $migration->getCurrentVersion(); // should echo 0
echo $migration->getCurrentVersion(); // 0
</code>
\ 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