1
0
mirror of synced 2025-02-20 22:23:14 +03:00

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.

This commit is contained in:
Jonathan.Wage 2007-10-11 03:23:33 +00:00
parent 5255145701
commit 81324ec826
20 changed files with 452 additions and 52 deletions

View File

@ -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

View File

@ -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();

View File

@ -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++;

View File

@ -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'));
}
}

View 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'));
}
}

View 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'));
}
}

View 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);
}
}

View 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'));
}
}

View 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'));
}
}

View 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'));
}
}

View 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));
}
}

View File

@ -0,0 +1,43 @@
<?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'));
}
}

View 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'));
}
}

View File

@ -1,6 +1,6 @@
<?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'));
}
}

View File

@ -0,0 +1,45 @@
<?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);
}
}

View 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'));
}
}

View 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)) {

View File

@ -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);
}

View File

@ -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';

View File

@ -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>