151 lines
5.6 KiB
PHP
151 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace Lean\Console\Form\Storage;
|
|
|
|
use Picea\Ui\Method\{ FormInterface, FormContext, FormContextInterface };
|
|
|
|
use \Lean\Console\Lib;
|
|
|
|
use Picea\Compiler\Context;
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
use Ulmus\Common\EntityResolver;
|
|
use \Ulmus\Entity\InformationSchema\Table;
|
|
|
|
class DatabaseMigration implements FormInterface
|
|
{
|
|
public function __construct(
|
|
protected ? Lib\DatabaseMigrations $migration,
|
|
protected null|Lib\Database\DefinitionCollection $definition = null,
|
|
)
|
|
{
|
|
$this->definition ??= new Lib\Database\DefinitionCollection();
|
|
}
|
|
|
|
public function initialize(FormContextInterface $context) : void
|
|
{
|
|
foreach($this->migration->entities as $entity => $table) {
|
|
$previous = null;
|
|
|
|
$connection = $entity::resolveEntity()->sqlAdapter();
|
|
$adapter = $connection->adapter();
|
|
$tableName = $table->tableName();
|
|
$databaseName = $table->databaseName();
|
|
|
|
if ( ! $tableName || ! $databaseName ) {
|
|
continue;
|
|
}
|
|
|
|
# Query current table's columns
|
|
$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 ) {
|
|
$this->definition[$entity]['columns'] = new Lib\Database\DefinitionCollection();
|
|
|
|
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) => strtolower($e->name) === $field)->count() === 0 ) {
|
|
$def->action = "add";
|
|
|
|
$def->modifier = new Lib\Database\Modifier(
|
|
type: Lib\Database\ModifierTypeEnum::Alter,
|
|
query: $entity::repository()
|
|
->alterSqlQuery([ $def->toArray() ])
|
|
->getSqlQuery(true)
|
|
);
|
|
}
|
|
}
|
|
|
|
$alter = $this->definition[$entity]['columns']->filterAlter();
|
|
|
|
if ( $alter->count() ) {
|
|
if ( $adapter->splitAlterQuery() ) {
|
|
$query = $alter->map(fn(Lib\Database\Definition $map) => $entity::repository()
|
|
->alterSqlQuery([$map->toArray()])
|
|
->getSqlQuery(true));
|
|
}
|
|
else {
|
|
$query = $entity::repository()
|
|
->alterSqlQuery($alter->map(fn(Lib\Database\Definition $map) => $map->toArray()))
|
|
->getSqlQuery(true);
|
|
}
|
|
|
|
$tableDefinition->modifier = new Lib\Database\Modifier(
|
|
type: Lib\Database\ModifierTypeEnum::Alter,
|
|
query: $query,
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
$tableDefinition->modifier = new Lib\Database\Modifier(
|
|
type: Lib\Database\ModifierTypeEnum::Create,
|
|
query: $entity::repository()
|
|
->createSqlQuery()
|
|
->getSqlQuery(true)
|
|
);
|
|
}
|
|
}
|
|
|
|
$context->definition = $this->definition;
|
|
}
|
|
|
|
public function validate(FormContextInterface $context) : bool
|
|
{
|
|
return $context->valid();
|
|
}
|
|
|
|
public function execute(FormContextInterface $context) : void
|
|
{
|
|
$create = $context->createAll ? explode(',', $context->createAll) : [ $context->create ];
|
|
|
|
foreach(array_filter($create) as $entity) {
|
|
if ($this->definition[$entity]['table']->modifier->type === Lib\Database\ModifierTypeEnum::Create) {
|
|
$entity::repository()->createTable();
|
|
}
|
|
}
|
|
|
|
$alter = $context->alterAll ? explode(',', $context->alterAll) : [ $context->alter ];
|
|
|
|
foreach(array_filter($alter) as $entity) {
|
|
if ($this->definition[$entity]['table']->modifier->type === Lib\Database\ModifierTypeEnum::Alter) {
|
|
$adapter = $entity::resolveEntity()->sqlAdapter()->adapter();
|
|
|
|
$def = $this->definition[$entity]['columns']->filterAlter();
|
|
|
|
if ( $adapter->splitAlterQuery() ) {
|
|
$def->walk(fn(Lib\Database\Definition $definition) =>
|
|
$entity::repository()->alterTable([ $definition->toArray() ])
|
|
);
|
|
}
|
|
else {
|
|
$entity::repository()->alterTable($def->map( fn(Lib\Database\Definition $e) => $e->toArray() ));
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->initialize($context);
|
|
}
|
|
|
|
public static function getContext(ServerRequestInterface $request, ? string $formName = null) : FormContextInterface
|
|
{
|
|
return new class($request, $formName) extends FormContext {
|
|
|
|
public array $status = [];
|
|
|
|
public array $actions = [];
|
|
};
|
|
}
|
|
}
|