Skip to content

Commit

Permalink
Allow to create a migration based on database
Browse files Browse the repository at this point in the history
  • Loading branch information
rougin committed Oct 19, 2024
1 parent beb4998 commit ddfff48
Show file tree
Hide file tree
Showing 8 changed files with 295 additions and 105 deletions.
16 changes: 15 additions & 1 deletion src/Commands/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,34 @@ public function run()
/** @var string */
$name = $this->getArgument('name');

/** @var boolean */
$useDb = $this->getOption('from-database');

$parser = new Parser($name);

$class = new Migration($name);

$class->setParser($parser);

if ($parser->isCreateTable() && $useDb && $this->driver)
{
$table = $parser->getTable();

$columns = $this->driver->columns($table);

$class->withColumns($columns);
}

if ($parser->isCreateColumn() || $parser->isDeleteColumn())
{
/** @var string */
$column = $parser->getColumn();

$column = $this->setColumn($column);

$class->withColumn($column);
$columns = array($column);

$class->withColumns($columns);
}

$maker = new Generator;
Expand Down
8 changes: 8 additions & 0 deletions src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ public function isCreateColumn()
return ($this->getType() === Migration::TYPE_ADD || $this->getType() === Migration::TYPE_CREATE) && $this->getColumn() !== null;
}

/**
* @return boolean
*/
public function isCreateTable()
{
return $this->getType() === Migration::TYPE_CREATE && $this->getColumn() === null;
}

/**
* @return boolean
*/
Expand Down
183 changes: 124 additions & 59 deletions src/Template/Migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ class Migration extends Classidy
const TYPE_UPDATE = 'update';

/**
* @var \Rougin\Describe\Column|null
* @var \Rougin\Describe\Column[]
*/
protected $column = null;
protected $columns = array();

/**
* @var \Rougin\Refinery\Parser
Expand Down Expand Up @@ -79,13 +79,13 @@ public function setParser($parser)
}

/**
* @param \Rougin\Describe\Column $column
* @param \Rougin\Describe\Column[] $columns
*
* @return self
*/
public function withColumn(Column $column)
public function withColumns($columns)
{
$this->column = $column;
$this->columns = $columns;

return $this;
}
Expand All @@ -103,17 +103,14 @@ protected function setDownMethod()

$fn = $this->getDeleteTable($table);

if ($this->column)
if ($this->parser->isCreateColumn())
{
if ($this->parser->isCreateColumn())
{
$fn = $this->getDeleteColumn($this->column, $table);
}
$fn = $this->getDeleteColumn($table);
}

if ($this->parser->isDeleteColumn())
{
$fn = $this->getCreateColumn($this->column, $table);
}
if ($this->parser->isDeleteColumn())
{
$fn = $this->getCreateColumn($table);
}

if ($this->parser->isDeleteTable())
Expand All @@ -139,17 +136,14 @@ protected function setUpMethod()

$fn = $this->getCreateTable($table);

if ($this->column)
if ($this->parser->isCreateColumn())
{
if ($this->parser->isCreateColumn())
{
$fn = $this->getCreateColumn($this->column, $table);
}
$fn = $this->getCreateColumn($table);
}

if ($this->parser->isDeleteColumn())
{
$fn = $this->getDeleteColumn($this->column, $table);
}
if ($this->parser->isDeleteColumn())
{
$fn = $this->getDeleteColumn($table);
}

if ($this->parser->isDeleteTable())
Expand All @@ -163,34 +157,25 @@ protected function setUpMethod()
}

/**
* @param \Rougin\Describe\Column $column
* @param string $table
* @param string $table
*
* @return callable
*/
protected function getCreateColumn(Column $column, $table)
protected function getCreateColumn($table)
{
return function ($lines) use ($column, $table)
$columns = $this->columns;

return function ($lines) use ($columns, $table)
{
$default = $column->getDefaultValue();
$default = $default ? '"' . $default . '"' : 'null';
$increment = $column->isAutoIncrement() ? 'true' : 'false';
$length = $column->getLength();
$name = $column->getField();
$null = $column->isNull() ? 'true' : 'false';
$type = $column->getDataType();
$unsigned = $column->isUnsigned() ? 'true' : 'false';

$lines[] = '$data = array(\'' . $name . '\' => array());';
$lines[] = '';
$lines[] = '$data[\'' . $name . '\'][\'type\'] = \'' . $type . '\';';
$lines[] = '$data[\'' . $name . '\'][\'constraint\'] = ' . $length . ';';
$lines[] = '$data[\'' . $name . '\'][\'auto_increment\'] = ' . $increment . ';';
$lines[] = '$data[\'' . $name . '\'][\'default\'] = ' . $default . ';';
$lines[] = '$data[\'' . $name . '\'][\'null\'] = ' . $null . ';';
$lines[] = '$data[\'' . $name . '\'][\'unsigned\'] = ' . $unsigned . ';';
$lines[] = '';
$lines[] = '$this->dbforge->add_column(\'' . $table . '\', $data);';
foreach ($columns as $index => $column)
{
if ($index !== 0)
{
$lines[] = '';
}

$lines = $this->parseColumn($lines, $table, $column);
}

return $lines;
};
Expand All @@ -203,14 +188,25 @@ protected function getCreateColumn(Column $column, $table)
*/
protected function getCreateTable($table)
{
return function ($lines) use ($table)
$columns = $this->columns;

if (count($columns) === 0)
{
$lines[] = '$data = array(\'id\' => array());';
$lines[] = '$data[\'id\'][\'type\'] = \'integer\';';
$lines[] = '$data[\'id\'][\'auto_increment\'] = true;';
$lines[] = '$data[\'id\'][\'constraint\'] = 10;';
$lines[] = '$this->dbforge->add_field($data);';
$lines[] = '$this->dbforge->add_key(\'id\', true);';
$columns[] = $this->newIdColumn();
}

return function ($lines) use ($columns, $table)
{
foreach ($columns as $index => $column)
{
if ($index !== 0)
{
$lines[] = '';
}

$lines = $this->parseColumn($lines, $table, $column);
}

$lines[] = '';
$lines[] = '$this->dbforge->create_table(\'' . $table . '\');';

Expand All @@ -234,20 +230,89 @@ protected function getDeleteTable($table)
}

/**
* @param \Rougin\Describe\Column $column
* @param string $table
* @param string $table
*
* @return callable
*/
protected function getDeleteColumn(Column $column, $table)
protected function getDeleteColumn($table)
{
return function ($lines) use ($column, $table)
$columns = $this->columns;

return function ($lines) use ($columns, $table)
{
$name = $column->getField();
foreach ($columns as $column)
{
$name = $column->getField();

$lines[] = '$this->dbforge->drop_column(\'' . $table . '\', \'' . $name . '\');';
$lines[] = '$this->dbforge->drop_column(\'' . $table . '\', \'' . $name . '\');';
}

return $lines;
};
}

/**
* @return \Rougin\Describe\Column
*/
protected function newIdColumn()
{
$column = new Column;

$column->setDataType('integer');
$column->setField('id');
$column->setAutoIncrement(true);
$column->setLength(10);
$column->setNull(false);
$column->setPrimary(true);

return $column;
}

/**
* @param string[] $lines
* @param string $table
* @param \Rougin\Describe\Column $column
*
* @return string[]
*/
protected function parseColumn($lines, $table, Column $column)
{
$default = $column->getDefaultValue();
$default = $default ? '"' . $default . '"' : 'null';
$increment = $column->isAutoIncrement() ? 'true' : 'false';
$length = $column->getLength();
$name = $column->getField();
$null = $column->isNull() ? 'true' : 'false';
$type = strtolower($column->getDataType());
$type = str_replace('string', 'varchar', $type);
$unsigned = $column->isUnsigned() ? 'true' : 'false';

$lines[] = '$data = array(\'' . $name . '\' => array());';
$lines[] = '$data[\'' . $name . '\'][\'type\'] = \'' . $type . '\';';
$lines[] = '$data[\'' . $name . '\'][\'auto_increment\'] = ' . $increment . ';';
$lines[] = '$data[\'' . $name . '\'][\'constraint\'] = ' . $length . ';';

if (! $column->isPrimaryKey())
{
$lines[] = '$data[\'' . $name . '\'][\'default\'] = ' . $default . ';';
$lines[] = '$data[\'' . $name . '\'][\'null\'] = ' . $null . ';';
$lines[] = '$data[\'' . $name . '\'][\'unsigned\'] = ' . $unsigned . ';';
}

if ($this->parser->isCreateTable() || $this->parser->isDeleteTable())
{
$lines[] = '$this->dbforge->add_field($data);';
}
else
{
$lines[] = '$this->dbforge->add_column(\'' . $table . '\', $data);';
}

if ($column->isPrimaryKey())
{
$lines[] = '$this->dbforge->add_key(\'' . $name . '\', true);';
}

return $lines;
}
}
6 changes: 2 additions & 4 deletions tests/Fixture/Plates/CreateColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ class Migration_add_name_in_users_table extends Migration
public function up()
{
$data = array('name' => array());

$data['name']['type'] = 'VARCHAR';
$data['name']['constraint'] = 100;
$data['name']['type'] = 'varchar';
$data['name']['auto_increment'] = false;
$data['name']['constraint'] = 100;
$data['name']['default'] = null;
$data['name']['null'] = true;
$data['name']['unsigned'] = false;

$this->dbforge->add_column('users', $data);
}

Expand Down
6 changes: 2 additions & 4 deletions tests/Fixture/Plates/DeleteColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ public function up()
public function down()
{
$data = array('name' => array());

$data['name']['type'] = 'VARCHAR';
$data['name']['constraint'] = 100;
$data['name']['type'] = 'varchar';
$data['name']['auto_increment'] = false;
$data['name']['constraint'] = 100;
$data['name']['default'] = null;
$data['name']['null'] = true;
$data['name']['unsigned'] = false;

$this->dbforge->add_column('users', $data);
}
}
38 changes: 38 additions & 0 deletions tests/Fixture/Plates/WithDatabase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

use Rougin\Refinery\Migration;

class Migration_create_users_table extends Migration
{
/**
* @return void
*/
public function up()
{
$data = array('id' => array());
$data['id']['type'] = 'integer';
$data['id']['auto_increment'] = true;
$data['id']['constraint'] = 10;
$this->dbforge->add_field($data);
$this->dbforge->add_key('id', true);

$data = array('name' => array());
$data['name']['type'] = 'varchar';
$data['name']['auto_increment'] = false;
$data['name']['constraint'] = 100;
$data['name']['default'] = null;
$data['name']['null'] = true;
$data['name']['unsigned'] = false;
$this->dbforge->add_field($data);

$this->dbforge->create_table('users');
}

/**
* @return void
*/
public function down()
{
$this->dbforge->drop_table('users');
}
}
Loading

0 comments on commit ddfff48

Please sign in to comment.