- WIP on database migration
This commit is contained in:
parent
f66ac02bcd
commit
5035a65672
|
@ -13,25 +13,21 @@ use \Ulmus\Entity\InformationSchema\Table;
|
||||||
|
|
||||||
class DatabaseMigration implements FormInterface
|
class DatabaseMigration implements FormInterface
|
||||||
{
|
{
|
||||||
protected ? Lib\DatabaseMigrations $migration;
|
public function __construct(
|
||||||
|
protected ? Lib\DatabaseMigrations $migration,
|
||||||
protected array $alter = [];
|
protected null|Lib\Database\DefinitionCollection $definition = null,
|
||||||
|
)
|
||||||
public function __construct(Lib\DatabaseMigrations $migration)
|
|
||||||
{
|
{
|
||||||
$this->migration = $migration;
|
$this->definition ??= new Lib\Database\DefinitionCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initialize(FormContextInterface $context) : void
|
public function initialize(FormContextInterface $context) : void
|
||||||
{
|
{
|
||||||
$context->tableExist = [];
|
|
||||||
|
|
||||||
foreach($this->migration->entities as $entity => $table) {
|
foreach($this->migration->entities as $entity => $table) {
|
||||||
$previous = null;
|
$previous = null;
|
||||||
$this->alter[$entity] = [];
|
|
||||||
$connection = $entity::resolveEntity()->sqlAdapter();
|
$connection = $entity::resolveEntity()->sqlAdapter();
|
||||||
$adapter = $connection->adapter();
|
$adapter = $connection->adapter();
|
||||||
|
|
||||||
$tableName = $table->tableName();
|
$tableName = $table->tableName();
|
||||||
$databaseName = $table->databaseName();
|
$databaseName = $table->databaseName();
|
||||||
|
|
||||||
|
@ -42,51 +38,58 @@ class DatabaseMigration implements FormInterface
|
||||||
# Query current table's columns
|
# Query current table's columns
|
||||||
$tableEntity = $adapter->schemaTable($connection, $databaseName, $tableName);
|
$tableEntity = $adapter->schemaTable($connection, $databaseName, $tableName);
|
||||||
|
|
||||||
|
$this->definition[$entity]['table'] = $tableDefinition = new Lib\Database\Definition(
|
||||||
|
entity: $entity,
|
||||||
|
modifier: new Lib\Database\Modifier( type: Lib\Database\ModifierTypeEnum::None, ),
|
||||||
|
);
|
||||||
|
|
||||||
if ( $tableEntity ) {
|
if ( $tableEntity ) {
|
||||||
|
$this->definition[$entity]['columns'] = new Lib\Database\DefinitionCollection();
|
||||||
|
|
||||||
foreach($table->fieldList(EntityResolver::KEY_COLUMN_NAME, true) as $field => $definition) {
|
foreach($table->fieldList(EntityResolver::KEY_COLUMN_NAME, true) as $field => $definition) {
|
||||||
|
$this->definition[$entity]['columns'][$field] = $def = new Lib\Database\Definition(
|
||||||
|
entity: $entity,
|
||||||
|
field: $field,
|
||||||
|
definition: $definition,
|
||||||
|
modifier: new Lib\Database\Modifier( type: Lib\Database\ModifierTypeEnum::None, ),
|
||||||
|
previous: $def ?? null,
|
||||||
|
);
|
||||||
|
|
||||||
|
# Column do not exists
|
||||||
if ( $tableEntity->columns->filtersCollection(fn($e) => $e->name === $field)->count() === 0 ) {
|
if ( $tableEntity->columns->filtersCollection(fn($e) => $e->name === $field)->count() === 0 ) {
|
||||||
$this->alter[$entity][$field] = [
|
$def->action = "add";
|
||||||
'previous' => $previous,
|
|
||||||
'action' => 'add',
|
$def->modifier = new Lib\Database\Modifier(
|
||||||
'definition' => $definition,
|
type: Lib\Database\ModifierTypeEnum::Alter,
|
||||||
];
|
query: $entity::repository()
|
||||||
|
->alterSqlQuery([ $def->toArray() ])
|
||||||
|
->getSqlQuery(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$previous = [
|
$alter = $this->definition[$entity]['columns']->filterAlter();
|
||||||
'field' => $field,
|
|
||||||
'definition' => $definition
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $this->alter[$entity] ) {
|
if ( $alter->count() ) {
|
||||||
$context->status[$entity] = [
|
$tableDefinition->modifier = new Lib\Database\Modifier(
|
||||||
'msg' => "altering",
|
type: Lib\Database\ModifierTypeEnum::Alter,
|
||||||
"query" => $entity::repository()
|
query: $entity::repository()
|
||||||
->alterSqlQuery($this->alter[$entity])
|
->alterSqlQuery($alter->map(fn(Lib\Database\Definition $e) => $e->toArray()))
|
||||||
->getSqlQuery(true),
|
->getSqlQuery(true),
|
||||||
];
|
);
|
||||||
}
|
|
||||||
else {
|
|
||||||
# if columns are different
|
|
||||||
$context->status[$entity] = [
|
|
||||||
'msg' => "up-to-date",
|
|
||||||
'query' => "",
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$context->status[$entity] = [
|
$tableDefinition->modifier = new Lib\Database\Modifier(
|
||||||
'msg' => "unexisting",
|
type: Lib\Database\ModifierTypeEnum::Create,
|
||||||
'query' => $entity::repository()
|
query: $entity::repository()
|
||||||
->createSqlQuery()
|
->createSqlQuery()
|
||||||
->getSqlQuery(true),
|
->getSqlQuery(true)
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $context->formSent() ) {
|
$context->definition = $this->definition;
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate(FormContextInterface $context) : bool
|
public function validate(FormContextInterface $context) : bool
|
||||||
|
@ -99,13 +102,19 @@ class DatabaseMigration implements FormInterface
|
||||||
$create = $context->createAll ? explode(',', $context->createAll) : [ $context->create ];
|
$create = $context->createAll ? explode(',', $context->createAll) : [ $context->create ];
|
||||||
|
|
||||||
foreach(array_filter($create) as $entity) {
|
foreach(array_filter($create) as $entity) {
|
||||||
|
if ($this->definition[$entity]['table']->modifier->type === Lib\Database\ModifierTypeEnum::Create) {
|
||||||
$entity::repository()->createTable();
|
$entity::repository()->createTable();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$alter = $context->alterAll ? explode(',', $context->alterAll) : [ $context->alter ];
|
$alter = $context->alterAll ? explode(',', $context->alterAll) : [ $context->alter ];
|
||||||
|
|
||||||
foreach(array_filter($alter) as $entity) {
|
foreach(array_filter($alter) as $entity) {
|
||||||
$entity::repository()->alterTable($this->alter[$entity]);
|
|
||||||
|
|
||||||
|
if ($this->definition[$entity]['table']->modifier->type === Lib\Database\ModifierTypeEnum::Alter) {
|
||||||
|
$entity::repository()->alterTable($this->definition[$entity]['columns']->filterAlter ()->map( fn($e) => $e->toArray() ));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->initialize($context);
|
$this->initialize($context);
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lean\Console\Lib\Database;
|
||||||
|
|
||||||
|
class Definition
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $entity,
|
||||||
|
public string|null $field = null,
|
||||||
|
public array|null $definition = null,
|
||||||
|
public null|Modifier $modifier = null,
|
||||||
|
public null|Definition $previous = null,
|
||||||
|
public null|string $action = null,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function toArray() : array
|
||||||
|
{
|
||||||
|
return array_filter(get_object_vars($this));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lean\Console\Lib\Database;
|
||||||
|
|
||||||
|
class DefinitionCollection extends \Ulmus\EntityCollection
|
||||||
|
{
|
||||||
|
public function filterType(ModifierTypeEnum $type) : self
|
||||||
|
{
|
||||||
|
return $this->filtersCollection(fn(Definition $e) => $e->modifier->type === $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterCreate() : self
|
||||||
|
{
|
||||||
|
return $this->filterType(ModifierTypeEnum::Create);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterAlter() : self
|
||||||
|
{
|
||||||
|
return $this->filterType(ModifierTypeEnum::Alter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterDelete() : self
|
||||||
|
{
|
||||||
|
return $this->filterType(ModifierTypeEnum::Delete);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lean\Console\Lib\Database;
|
||||||
|
|
||||||
|
class Modifier
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public ModifierTypeEnum $type,
|
||||||
|
public null|array|string $query = null,
|
||||||
|
) {}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lean\Console\Lib\Database;
|
||||||
|
|
||||||
|
enum ModifierTypeEnum: string
|
||||||
|
{
|
||||||
|
case Alter = 'alter';
|
||||||
|
case Create = 'create';
|
||||||
|
case Delete = 'delete';
|
||||||
|
case None = 'none';
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
{% use Lean\Console\Lib\Database\ModifierTypeEnum %}
|
||||||
|
|
||||||
{% extends "lean-console/base/layout" %}
|
{% extends "lean-console/base/layout" %}
|
||||||
|
|
||||||
{% language.set "lean.storage" %}
|
{% language.set "lean.storage" %}
|
||||||
|
@ -44,16 +46,16 @@
|
||||||
<div class="col"><span>📄</span> <span>{{ $item->tableName() }}</span></div>
|
<div class="col"><span>📄</span> <span>{{ $item->tableName() }}</span></div>
|
||||||
<div class="col">{% _ "database.table.fields", [ 'count' => count( $item->fieldList() ) ] %}</div>
|
<div class="col">{% _ "database.table.fields", [ 'count' => count( $item->fieldList() ) ] %}</div>
|
||||||
<div class="col col-grow-2">
|
<div class="col col-grow-2">
|
||||||
{% if $context->status[$entity]['query'] %}
|
{% if $context->definition[$entity]['table']->modifier->query %}
|
||||||
<code>{{ $context->status[$entity]['query'] }}</code>
|
<code>{{ $context->definition[$entity]['table']->modifier->query }}</code>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div>🗸 This table is up-to-date</div>
|
<div>🗸 This table is up-to-date</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{% switch $context->status[$entity]['msg'] %}
|
{% switch $context->definition[$entity]['table']->modifier->type %}
|
||||||
{% case 'unexisting' %}
|
{% case ModifierTypeEnum::Create %}
|
||||||
{% php $createAll[] = $entity %}
|
{% php $createAll[] = $entity %}
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
|
@ -61,8 +63,8 @@
|
||||||
</div>
|
</div>
|
||||||
{% break %}
|
{% break %}
|
||||||
|
|
||||||
{% case 'altering' %}
|
{% case ModifierTypeEnum::Alter %}
|
||||||
{% php $alter[] = $entity %}
|
{% php $alterAll[] = $entity %}
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<button name="alter" value="{{$entity}}" class="btn-blue">🗸 {% _ 'database.table.alter' %}</button>
|
<button name="alter" value="{{$entity}}" class="btn-blue">🗸 {% _ 'database.table.alter' %}</button>
|
||||||
|
@ -81,7 +83,7 @@
|
||||||
|
|
||||||
{% if ($alterAll ?? 0) > 1 %}
|
{% if ($alterAll ?? 0) > 1 %}
|
||||||
<div class="text-right" style="padding:0.5rem 0">
|
<div class="text-right" style="padding:0.5rem 0">
|
||||||
<button name="createAll" value="{{ implode(',', $alterAll) }}" class="btn-red">🗸 {% _ 'database.table.alterAll' %}</button>
|
<button name="alterAll" value="{{ implode(',', $alterAll) }}" class="btn-red">🗸 {% _ 'database.table.alterAll' %}</button>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% ui.endform %}
|
{% ui.endform %}
|
||||||
|
|
Loading…
Reference in New Issue