Skip to content

Commit

Permalink
inital commit
Browse files Browse the repository at this point in the history
  • Loading branch information
schmunk42 committed Sep 25, 2012
1 parent de3e664 commit fbfc980
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 0 deletions.
171 changes: 171 additions & 0 deletions P3DatabaseCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php
/**
* Class file.
*
* @author Tobias Munk <[email protected]>
* @link http://www.phundament.com/
* @copyright Copyright &copy; 2005-2011 diemeisterei GmbH
* @license http://www.phundament.com/license/
*/

/**
* Command to dump databases into PHP code for migration classes
*
* Creates a CDbMigration class in application.runtime
*
* Based upon http://www.yiiframework.com/doc/guide/1.1/en/database.migration#c2550 from Leric
*
* @author Tobias Munk <[email protected]>
* @package p3extensions.commands
* @since 3.0.1
*/

class P3DatabaseCommand extends CConsoleCommand {

/**
* @var string database connection component
*/
public $dbConnection = "db";
/**
* @var string wheter to dump a create table statement
*/
public $createSchema = true;
/**
* @var string wheter to dump a insert data statements
*/
public $insertData = true;
/**
* @var string dump only table with the given prefix
*/
public $prefix = "";

public function getHelp() {
echo <<<EOS
Usage: yiic {$this->name} <action>
Available actions: dump [--prefix=<table_prefix>] [--createSchema=<0|1>] [--insertData=<0|1>] [--dbConnection=<db>]
EOS;
}

public function actionDump($args) {

$schema = Yii::app()->{$this->dbConnection}->schema;
$tables = Yii::app()->{$this->dbConnection}->schema->tables;

$code = '';
$code .= $this->indent(2)."if (Yii::app()->db->schema instanceof CMysqlSchema)\n";
$code .= $this->indent(2)." \$options = 'ENGINE=InnoDB DEFAULT CHARSET=utf8';\n";
$code .= $this->indent(2)."else\n";
$code .= $this->indent(2)." \$options = '';\n";

foreach ($tables as $table) {
if (substr($table->name, 0, strlen($this->prefix)) != $this->prefix)
continue;

if ($this->createSchema == true) {
$code .= "\n\n\n".$this->indent(2)."// Schema for table '" . $table->name . "'\n\n";
$code .= $this->generateSchema($table, $schema);

$code .= "\n\n\n".$this->indent(2)."// Foreign Keys for table '" . $table->name . "'\n\n";
$code .= $this->indent(2)."if ((Yii::app()->db->schema instanceof CSqliteSchema) == false):\n";
$code .= $this->generateForeignKeys($table, $schema);
$code .= "\n".$this->indent(2)."endif;\n";
}

if ($this->insertData == true) {
$code .= "\n\n\n".$this->indent(2)."// Data for table '" . $table->name . "'\n\n";
$code .= $this->generateInserts($table, $schema);
}
}

$migrationClassName = 'm'.date('ymd_His')."_dump";
$filename = Yii::app()->basePath.DIRECTORY_SEPARATOR.'runtime'.DIRECTORY_SEPARATOR.$migrationClassName.".php";
$migrationClassCode = $this->renderFile(
dirname(__FILE__).'/views/migration.php',
array('migrationClassName' => $migrationClassName, 'functionUp'=>$code),
true);

file_put_contents($filename, $migrationClassCode);

echo "Your data has been dumped to '$filename'\n";
}

private function indent($level = 0) {
return str_repeat(" ", $level);
}


private function generateSchema($table, $schema) {
$options = "ENGINE=InnoDB DEFAULT CHARSET=utf8";
$code = '';
$code .= $this->indent(2).'$this->createTable("' . $table->name . '", ';
$code .= "\n";
$code .= $this->indent(3).'array(' . "\n";
foreach ($table->columns as $col) {
$code .= $this->indent(3). '"' . $col->name . '"=>"' . $this->resolveColumnType($col) . '",' . "\n";
}

// special case for non-auto-increment PKs
$code .= $this->generatePrimaryKeys($table->columns);
$code .= "\n";
$code .= $this->indent(3).'), ';
$code .= "\n";
$code .= $this->indent(2).'$options);';
return $code;
}


private function generatePrimaryKeys($columns) {
foreach ($columns as $col) {
if ($col->isPrimaryKey && !$col->autoIncrement) {
return $this->indent(3).'"PRIMARY KEY ('.$col->name.')"';
}
}
}

private function generateForeignKeys($table, $schema) {
$code = "";
foreach ($table->foreignKeys as $name => $foreignKey) {
#echo "FK" . $name . var_dump($foreignKey);
$code .= "\n".$this->indent(3)."\$this->addForeignKey('fk_{$foreignKey[0]}_{$name}', '{$table->name}', '{$name}', '{$foreignKey[0]}', '{$foreignKey[1]}', null, null); // update 'null' for ON DELTE and ON UPDATE\n";
}
return $code;
}

private function generateInserts($table, $schema) {
$code = '';
$data = Yii::app()->db->createCommand()
->from($table->name)
->query();

foreach ($data AS $row) {
$code .= $this->indent(2).'$this->insert("' . $table->name . '", array(' . "\n";
foreach ($row AS $column => $value) {
$code .= $this->indent(3).'"' . $column . '"=>' . (($value === null) ? 'null' : '"' . str_replace('"','\"',$value) . '"') . ',' . "\n";
}
$code .= $this->indent(2).') );' . "\n\n";
}
return $code;
}

private function resolveColumnType($col) {
if ($col->isPrimaryKey && $col->autoIncrement) {
return "pk";
}

$result = $col->dbType;

if (!$col->allowNull) {
$result .= ' NOT NULL';
}
if ($col->defaultValue != null) {
$result .= " DEFAULT '{$col->defaultValue}'";
}
return $result;
}

}

?>
15 changes: 15 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "schmunk42/database-command",
"description": "Yii command to create database migrations from existing schema",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Tobias Munk",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.3.2",
"yiisoft/yii": "1.1.*"
}
}
22 changes: 22 additions & 0 deletions views/migration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php echo "
/**
* Created with https://github.com/schmunk42/database-command
*/
<?php
class {$migrationClassName} extends CDbMigration {
public function safeUp() {
{$functionUp}
}
public function safeDown() {
echo 'Migration down not supported.';
}
}
?>
";
?>

0 comments on commit fbfc980

Please sign in to comment.