This commit is contained in:
Juan Pablo Vial
2024-12-21 18:59:55 -03:00
parent ea205df76d
commit eb26f31ed6
2 changed files with 152 additions and 0 deletions

108
app/src/Parser/Column.php Normal file
View File

@ -0,0 +1,108 @@
<?php
namespace ProVM\Parser;
use ProVM\Concept;
class Column implements Concept\Parser
{
public function __construct(protected string $line) {}
public function parse(): string
{
return "->addColumn('{$this->getName()}', '{$this->getType()}'{$this->getOptions()})";
}
protected int $ini;
protected int $end;
protected array $parts;
protected array $options;
protected function getName(): string
{
$ini = $this->getIni();
$end = $this->getEnd();
return substr($this->line, $ini, $end - $ini);
}
protected function getType(): string
{
$parts = $this->getParts();
$type = array_shift($parts);
if (str_contains($type, '(')) {
list($type, $length) = explode('(', $type);
$this->options []= "'length' => " . rtrim($length, ')');
}
return match($type) {
'int' => 'integer',
'tinyint' => 'boolean',
'varchar' => 'string',
default => $type
};
}
protected function getOptions(): string
{
$parts = $this->getParts();
array_shift($parts);
$validOptions = [
'default' => function($parts) {
$i = array_search('default', array_map(function($part) {return strtolower($part);}, $parts));
return ['default', $parts[$i + 1]];
},
'null' => function($parts) {
$value = true;
$i = array_search('null', array_map(function($part) {return strtolower($part);}, $parts));
if (key_exists($i - 1, $parts) and strtolower($parts[$i - 1]) === 'not') {
$value = false;
}
return ['null', $value];
},
'unsigned' => function($parts) {
return ['signed', false];
},
'auto_increment' => function($parts) {
return ['auto_increment', true];
}
];
foreach ($validOptions as $validOption => $callable) {
if (str_contains(strtolower($this->line), $validOption)) {
list($option, $value) = $callable($parts);
if (strtolower($value) === 'null') {
$value = 'null';
}
if ($value !== 'null' and !is_bool($value) and !ctype_digit($value)) {
$value = trim($value, "'");
$value = "'{$value}'";
}
if (is_bool($value)) {
$value = $value ? 'true' : 'false';
}
$this->options []= "'{$option}' => {$value}";
}
}
if (count($this->options) === 0) {
return '';
}
return ', [' . implode(', ', $this->options) . ']';
}
protected function getIni(): int
{
if (!isset($this->ini)) {
$this->ini = strpos($this->line, '`') + 1;
}
return $this->ini;
}
protected function getEnd(): int
{
if (!isset($this->end)) {
$this->end = strpos($this->line, '`', $this->getIni());
}
return $this->end;
}
protected function getParts(): array
{
if (!isset($this->parts)) {
$this->parts = explode(' ', trim(substr($this->line, $this->getEnd() + 1), ' ,'));
}
return $this->parts;
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace ProVM\Parser;
use ProVM\Concept;
class Constraint implements Concept\Parser
{
public function __construct(protected string $line) {}
public function parse(): string
{
return "->addForeignKey({$this->getColumns()}, '{$this->getTable()}', {$this->getReferences()}, ['delete' => 'cascade', 'update' => 'cascade'])";
}
protected function getColumns(): string
{
$ini = strpos(strtolower($this->line), 'foreign key') + strlen('FOREIGN KEY ');
$ini = strpos($this->line, '(', $ini) + 1;
$end = strpos(strtolower($this->line), ' references', $ini + 1) - strlen(')');
return $this->getNames($ini, $end);
}
protected function getTable(): string
{
$ini = strpos(strtolower($this->line), 'references') + strlen('REFERENCES ') + 1;
$end = strpos($this->line, '`', $ini + 1);
return substr($this->line, $ini, $end - $ini);
}
protected function getReferences(): string
{
$ini = strpos($this->line, '(', strpos(strtolower($this->line), 'references')) + 1;
$end = strpos($this->line, ')', $ini);
return $this->getNames($ini, $end);
}
protected function getNames($ini, $end): string
{
$names = substr($this->line, $ini, $end - $ini);
if (!str_contains($names, ',')) {
return str_replace('`', "'", $names);
}
$names = explode(', ', $names);
$columns = array_map(function($name) {return str_replace('`', "'", $name);}, $names);
return '[' . implode(', ', $columns) . ']';
}
}