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