ulmus/src/Migration/FieldDefinition.php

156 lines
4.0 KiB
PHP

<?php
namespace Ulmus\Migration;
use Ulmus\Annotation\Property\Field;
use Ulmus\Entity;
class FieldDefinition {
public bool $nullable;
public bool $builtIn;
public string $name;
public string $type;
public array $tags;
public /* ? string */ $default;
public ? int $precision;
public ? int $length;
public ? string $update;
public function __construct(array $data)
{
$this->name = $data['name'];
$this->builtIn = $data['builtin'];
$this->tags = $data['tags'];
$field = $this->getFieldTag();
$this->type = $field->type ?? $data['type'];
$this->length = $field->length ?? null;
$this->precision = $field->precision ?? null;
$this->nullable = isset($field->nullable) ? $field->nullable : $data['nullable'];
$this->update = $field->attributes['update'] ?? null;
}
public function getSqlName() : string
{
return $this->getColumnName();
}
public function getSqlType(bool $typeOnly = false) : string
{
$type = $this->type;
$length = $this->length;
if ( is_a($type, Entity\Field\Date::class, true) ) {
$type = "DATE";
}
elseif ( is_a($type, Entity\Field\Time::class, true) ) {
$type = "TIME";
}
elseif ( is_a($type, \DateTime::class, true) ) {
$type = "DATETIME";
}
switch($type) {
case "bool":
$type = "TINYINT";
$length = 1;
break;
case "array":
case "string":
if ($length && $length <= 255) {
$type = "VARCHAR";
break;
}
elseif (! $length || ( $length <= 65535 ) ) {
$type = "TEXT";
}
elseif ( $length <= 16777215 ) {
$type = "MEDIUMTEXT";
}
elseif ($length <= 4294967295) {
$type = "LONGTEXT";
}
else {
throw new \Exception("A column with size bigger than 4GB cannot be created.");
}
# Length is unnecessary on TEXT fields
unset($length);
break;
case "float":
$type = "DOUBLE";
break;
default:
$type = strtoupper($type);
break;
}
return $typeOnly ? $type : $type . ( $length ? "($length" . ( $precision ? ",$precision" : "" ) . ")" : "" );
}
public function getSqlParams() : string
{
$default = $this->getDefault();
return implode(' ', array_filter([
$this->isUnsigned() ? "UNSIGNED" : null,
$this->nullable ? "NULL" : "NOT NULL",
$this->update ? "ON UPDATE {$this->update}" : null,
$default ? "DEFAULT $default" : null,
$this->isAutoIncrement() ? "AUTO_INCREMENT" : null,
$this->isPrimaryKey() ? "PRIMARY KEY" : null,
]));
}
protected function getFieldTag() : ? Field
{
$field = array_filter($this->tags, fn($item) => $item['object'] instanceof Field);
return array_pop($field)['object'];
}
protected function getColumnName() : ? string
{
return $this->getFieldTag()->name ?? $this->name;
}
protected function getDefault() : ? string
{
return $this->getFieldTag()->attributes['default'] ?? ( $this->nullable ? "NULL" : null ) ;
}
protected function isPrimaryKey() : bool
{
return $this->getFieldTag()->attributes['primary_key'] ?? false;
}
protected function isAutoIncrement() : bool
{
return $this->getFieldTag()->attributes['auto_increment'] ?? false;
}
protected function isUnique() : bool
{
return $this->getFieldTag()->attributes['unique'] ?? false;
}
protected function isUnsigned() : bool
{
return $this->getFieldTag()->attributes['unsigned'] ?? false;
}
}