Parsers
This commit is contained in:
108
app/src/Parser/Column.php
Normal file
108
app/src/Parser/Column.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
44
app/src/Parser/Constraint.php
Normal file
44
app/src/Parser/Constraint.php
Normal 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) . ']';
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user