<commit_before><?php
/**
 * MigrateCommand class file.
 *
 * @author <NAME> <<EMAIL>>
 * @link http://www.yiiframework.com/
 * @copyright 2008-2013 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * MigrateCommand manages the database migrations.
 *
 * The implementation of this command and other supporting classes referenced
 * the yii-dbmigrations extension ((https://github.com/pieterclaerhout/yii-dbmigrations),
 * authored by <NAME>.
 *
 * Since version 1.1.11 this command will exit with the following exit codes:
 * <ul>
 * <li>0 on success</li>
 * <li>1 on general error</li>
 * <li>2 on failed migration.</li>
 * </ul>
 *
 * @author <NAME> <<EMAIL>>
 * @package system.cli.commands
 * @since 1.1.6
 */
class MigrateCommand extends CConsoleCommand
{
	const BASE_MIGRATION='m000000_000000_base';

	/**
	 * @var string the directory that stores the migrations. This must be specified
	 * in terms of a path alias, and the corresponding directory must exist.
	 * Defaults to 'application.migrations' (meaning 'protected/migrations').
	 */
	public $migrationPath='application.migrations';
	/**
	 * @var string the name of the table for keeping applied migration information.
	 * This table will be automatically created if not exists. Defaults to 'tbl_migration'.
	 * The table structure is: (version varchar(180) primary key, apply_time integer)
	 */
	public $migrationTable='tbl_migration';
	/**
	 * @var string the application component ID that specifies the database connection for
	 * storing migration information. Defaults to 'db'.
	 */
	public $connectionID='db';
	/**
	 * @var string the path of the template file for generating new migrations. This
	 * must be specified in terms of a path alias (e.g. application.migrations.template).
	 * If not set, an internal template will be used.
	 */
	public $templateFile;
	/**
	 * @var string the default command action. It defaults to 'up'.
	 */
	public $defaultAction='up';
	/**
	 * @var boolean whether to execute the migration in an interactive mode. Defaults to true.
	 * Set this to false when performing migration in a cron job or background process.
	 */
	public $interactive=true;

	public function beforeAction($action,$params)
	{
		$path=Yii::getPathOfAlias($this->migrationPath);
		if($path===false || !is_dir($path))
		{
			echo 'Error: The migration directory does not exist: '.$this->migrationPath."\n";
			exit(1);
		}
		$this->migrationPath=$path;

		$yiiVersion=Yii::getVersion();
		echo "\nYii Migration Tool v1.0 (based on Yii v{$yiiVersion})\n\n";

		return parent::beforeAction($action,$params);
	}

	public function actionUp($args)
	{
		if(($migrations=$this->getNewMigrations())===array())
		{
			echo "No new migration found. Your system is up-to-date.\n";
			return 0;
		}

		$total=count($migrations);
		$step=isset($args[0]) ? (int)$args[0] : 0;
		if($step>0)
			$migrations=array_slice($migrations,0,$step);

		$n=count($migrations);
		if($n===$total)
			echo "Total $n new ".($n===1 ? 'migration':'migrations')." to be applied:\n";
		else
			echo "Total $n out of $total new ".($total===1 ? 'migration':'migrations')." to be applied:\n";

		foreach($migrations as $migration)
			echo "    $migration\n";
		echo "\n";

		if($this->confirm('Apply the above '.($n===1 ? 'migration':'migrations')."?"))
		{
			foreach($migrations as $migration)
			{
				if($this->migrateUp($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			echo "\nMigrated up successfully.\n";
		}
	}

	public function actionDown($args)
	{
		$step=isset($args[0]) ? (int)$args[0] : 1;
		if($step<1)
		{
			echo "Error: The step parameter must be greater than 0.\n";
			return 1;
		}

		if(($migrations=$this->getMigrationHistory($step))===array())
		{
			echo "No migration has been done before.\n";
			return 0;
		}
		$migrations=array_keys($migrations);

		$n=count($migrations);
		echo "Total $n ".($n===1 ? 'migration':'migrations')." to be reverted:\n";
		foreach($migrations as $migration)
			echo "    $migration\n";
		echo "\n";

		if($this->confirm('Revert the above '.($n===1 ? 'migration':'migrations')."?"))
		{
			foreach($migrations as $migration)
			{
				if($this->migrateDown($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			echo "\nMigrated down successfully.\n";
		}
	}

	public function actionRedo($args)
	{
		$step=isset($args[0]) ? (int)$args[0] : 1;
		if($step<1)
		{
			echo "Error: The step parameter must be greater than 0.\n";
			return 1;
		}

		if(($migrations=$this->getMigrationHistory($step))===array())
		{
			echo "No migration has been done before.\n";
			return 0;
		}
		$migrations=array_keys($migrations);

		$n=count($migrations);
		echo "Total $n ".($n===1 ? 'migration':'migrations')." to be redone:\n";
		foreach($migrations as $migration)
			echo "    $migration\n";
		echo "\n";

		if($this->confirm('Redo the above '.($n===1 ? 'migration':'migrations')."?"))
		{
			foreach($migrations as $migration)
			{
				if($this->migrateDown($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			foreach(array_reverse($migrations) as $migration)
			{
				if($this->migrateUp($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			echo "\nMigration redone successfully.\n";
		}
	}

	public function actionTo($args)
	{
		if(!isset($args[0]))
			$this->usageError('Please specify which version, timestamp or datetime to migrate to.');

		if((string)(int)$args[0]===$args[0] && $args[0]>=~PHP_INT_MAX && $args[0]<=PHP_INT_MAX)
			return $this->migrateToTime($args[0]);
		elseif(($time=strtotime($args[0]))!==false)
			return $this->migrateToTime($time);
		else
			return $this->migrateToVersion($args[0]);
	}

	private function migrateToTime($time)
	{
		$data=$this->getDbConnection()->createCommand()
			->select('version,apply_time')
			->from($this->migrationTable)
			->where('apply_time<=:time',array(':time'=>$time))
			->order('apply_time DESC')
			->limit(1)
			->queryRow();

		if($data===false)
		{
			echo "Error: Unable to find a version before ".date('Y-m-d H:i:s',$time).".\n";
			return 1;
		}
		else
		{
			echo "Found version ".$data['version']." applied at ".date('Y-m-d H:i:s',$data['apply_time']).", it's before ".date('Y-m-d H:i:s',$time).".\n";
			return $this->migrateToVersion(substr($data['version'],1,13));
		}
	}

	private function migrateToVersion($version)
	{
		$originalVersion=$version;
		if(preg_match('/^m?(\d{6}_\d{6})(_.*?)?$/',$version,$matches))
			$version='m'.$matches[1];
		else
		{
			echo "Error: The version option must be either a timestamp (e.g. 101129_185401)\nor the full name of a migration (e.g. m101129_185401_create_user_table).\n";
			return 1;
		}<commit_msg>Minor fixes related to the feature of migrating to the certain date/time<commit_after><?php
/**
 * MigrateCommand class file.
 *
 * @author <NAME> <<EMAIL>>
 * @link http://www.yiiframework.com/
 * @copyright 2008-2013 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * MigrateCommand manages the database migrations.
 *
 * The implementation of this command and other supporting classes referenced
 * the yii-dbmigrations extension ((https://github.com/pieterclaerhout/yii-dbmigrations),
 * authored by <NAME>.
 *
 * Since version 1.1.11 this command will exit with the following exit codes:
 * <ul>
 * <li>0 on success</li>
 * <li>1 on general error</li>
 * <li>2 on failed migration.</li>
 * </ul>
 *
 * @author <NAME> <<EMAIL>>
 * @package system.cli.commands
 * @since 1.1.6
 */
class MigrateCommand extends CConsoleCommand
{
	const BASE_MIGRATION='m000000_000000_base';

	/**
	 * @var string the directory that stores the migrations. This must be specified
	 * in terms of a path alias, and the corresponding directory must exist.
	 * Defaults to 'application.migrations' (meaning 'protected/migrations').
	 */
	public $migrationPath='application.migrations';
	/**
	 * @var string the name of the table for keeping applied migration information.
	 * This table will be automatically created if not exists. Defaults to 'tbl_migration'.
	 * The table structure is: (version varchar(180) primary key, apply_time integer)
	 */
	public $migrationTable='tbl_migration';
	/**
	 * @var string the application component ID that specifies the database connection for
	 * storing migration information. Defaults to 'db'.
	 */
	public $connectionID='db';
	/**
	 * @var string the path of the template file for generating new migrations. This
	 * must be specified in terms of a path alias (e.g. application.migrations.template).
	 * If not set, an internal template will be used.
	 */
	public $templateFile;
	/**
	 * @var string the default command action. It defaults to 'up'.
	 */
	public $defaultAction='up';
	/**
	 * @var boolean whether to execute the migration in an interactive mode. Defaults to true.
	 * Set this to false when performing migration in a cron job or background process.
	 */
	public $interactive=true;

	public function beforeAction($action,$params)
	{
		$path=Yii::getPathOfAlias($this->migrationPath);
		if($path===false || !is_dir($path))
		{
			echo 'Error: The migration directory does not exist: '.$this->migrationPath."\n";
			exit(1);
		}
		$this->migrationPath=$path;

		$yiiVersion=Yii::getVersion();
		echo "\nYii Migration Tool v1.0 (based on Yii v{$yiiVersion})\n\n";

		return parent::beforeAction($action,$params);
	}

	public function actionUp($args)
	{
		if(($migrations=$this->getNewMigrations())===array())
		{
			echo "No new migration found. Your system is up-to-date.\n";
			return 0;
		}

		$total=count($migrations);
		$step=isset($args[0]) ? (int)$args[0] : 0;
		if($step>0)
			$migrations=array_slice($migrations,0,$step);

		$n=count($migrations);
		if($n===$total)
			echo "Total $n new ".($n===1 ? 'migration':'migrations')." to be applied:\n";
		else
			echo "Total $n out of $total new ".($total===1 ? 'migration':'migrations')." to be applied:\n";

		foreach($migrations as $migration)
			echo "    $migration\n";
		echo "\n";

		if($this->confirm('Apply the above '.($n===1 ? 'migration':'migrations')."?"))
		{
			foreach($migrations as $migration)
			{
				if($this->migrateUp($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			echo "\nMigrated up successfully.\n";
		}
	}

	public function actionDown($args)
	{
		$step=isset($args[0]) ? (int)$args[0] : 1;
		if($step<1)
		{
			echo "Error: The step parameter must be greater than 0.\n";
			return 1;
		}

		if(($migrations=$this->getMigrationHistory($step))===array())
		{
			echo "No migration has been done before.\n";
			return 0;
		}
		$migrations=array_keys($migrations);

		$n=count($migrations);
		echo "Total $n ".($n===1 ? 'migration':'migrations')." to be reverted:\n";
		foreach($migrations as $migration)
			echo "    $migration\n";
		echo "\n";

		if($this->confirm('Revert the above '.($n===1 ? 'migration':'migrations')."?"))
		{
			foreach($migrations as $migration)
			{
				if($this->migrateDown($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			echo "\nMigrated down successfully.\n";
		}
	}

	public function actionRedo($args)
	{
		$step=isset($args[0]) ? (int)$args[0] : 1;
		if($step<1)
		{
			echo "Error: The step parameter must be greater than 0.\n";
			return 1;
		}

		if(($migrations=$this->getMigrationHistory($step))===array())
		{
			echo "No migration has been done before.\n";
			return 0;
		}
		$migrations=array_keys($migrations);

		$n=count($migrations);
		echo "Total $n ".($n===1 ? 'migration':'migrations')." to be redone:\n";
		foreach($migrations as $migration)
			echo "    $migration\n";
		echo "\n";

		if($this->confirm('Redo the above '.($n===1 ? 'migration':'migrations')."?"))
		{
			foreach($migrations as $migration)
			{
				if($this->migrateDown($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			foreach(array_reverse($migrations) as $migration)
			{
				if($this->migrateUp($migration)===false)
				{
					echo "\nMigration failed. All later migrations are canceled.\n";
					return 2;
				}
			}
			echo "\nMigration redone successfully.\n";
		}
	}

	public function actionTo($args)
	{
		if(!isset($args[0]))
			$this->usageError('Please specify which version, timestamp or datetime to migrate to.');

		if((string)(int)$args[0]==$args[0])
			return $this->migrateToTime($args[0]);
		elseif(($time=strtotime($args[0]))!==false)
			return $this->migrateToTime($time);
		else
			return $this->migrateToVersion($args[0]);
	}

	private function migrateToTime($time)
	{
		$data=$this->getDbConnection()->createCommand()
			->select('version,apply_time')
			->from($this->migrationTable)
			->where('apply_time<=:time',array(':time'=>$time))
			->order('apply_time DESC')
			->limit(1)
			->queryRow();

		if($data===false)
		{
			echo "Error: Unable to find a version before ".date('Y-m-d H:i:s',$time).".\n";
			return 1;
		}
		else
		{
			echo "Found version ".$data['version']." applied at ".date('Y-m-d H:i:s',$data['apply_time']).", it is before ".date('Y-m-d H:i:s',$time).".\n";
			return $this->migrateToVersion(substr($data['version'],1,13));
		}
	}

	private function migrateToVersion($version)
	{
		$originalVersion=$version;
		if(preg_match('/^m?(\d{6}_\d{6})(_.*?)?$/',$version,$matches))
			$version='m'.$matches[1];
		else
		{
			echo "Error: The version option must be either a timestamp (e.g. 101129_185401)\nor the full name of a migration (e.g. m101129_185401_create_user_table).\n";
			return 1;
		}
{'fraction_non_alphanumeric': 0.1710241224902499, 'fraction_numerical': 0.015455727285858731, 'mean_word_length': 3.8722730471498945, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 92, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1874148', 'n_tokens_mistral': 5298, 'n_tokens_neox': 4657, 'n_words': 1188}