2021-04-03 16:23:30 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Driver\SQL\Query;
|
|
|
|
|
|
|
|
use Driver\SQL\Column\Column;
|
2021-12-08 16:53:43 +01:00
|
|
|
use Driver\SQL\Column\EnumColumn;
|
2021-04-03 16:23:30 +02:00
|
|
|
use Driver\SQL\Constraint\Constraint;
|
2021-04-08 18:29:47 +02:00
|
|
|
use Driver\SQL\Constraint\ForeignKey;
|
|
|
|
use Driver\SQL\Constraint\PrimaryKey;
|
2021-12-08 16:53:43 +01:00
|
|
|
use Driver\SQL\MySQL;
|
|
|
|
use Driver\SQL\PostgreSQL;
|
2021-04-03 16:23:30 +02:00
|
|
|
use Driver\SQL\SQL;
|
|
|
|
|
|
|
|
class AlterTable extends Query {
|
|
|
|
|
|
|
|
private string $table;
|
|
|
|
private string $action;
|
2021-12-08 16:53:43 +01:00
|
|
|
private $data;
|
2021-04-03 16:23:30 +02:00
|
|
|
|
|
|
|
private ?Column $column;
|
|
|
|
private ?Constraint $constraint;
|
|
|
|
|
|
|
|
public function __construct(SQL $sql, string $table) {
|
|
|
|
parent::__construct($sql);
|
|
|
|
$this->table = $table;
|
2021-04-03 16:25:40 +02:00
|
|
|
$this->column = null;
|
|
|
|
$this->constraint = null;
|
2021-04-03 16:23:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function add($what): AlterTable {
|
|
|
|
if ($what instanceof Column) {
|
|
|
|
$this->column = $what;
|
|
|
|
} else if ($what instanceof Constraint) {
|
|
|
|
$this->constraint = $what;
|
|
|
|
} else {
|
|
|
|
$this->column = new Column($what);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->action = "ADD";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function modify(Column $column): AlterTable {
|
|
|
|
$this->column = $column;
|
|
|
|
$this->action = "MODIFY";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function drop($what): AlterTable {
|
|
|
|
if ($what instanceof Column) {
|
|
|
|
$this->column = $what;
|
|
|
|
} else if ($what instanceof Constraint) {
|
|
|
|
$this->constraint = $what;
|
|
|
|
} else {
|
|
|
|
$this->column = new Column($what);
|
|
|
|
}
|
|
|
|
$this->action = "DROP";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2021-11-11 14:25:26 +01:00
|
|
|
public function resetAutoIncrement(): AlterTable {
|
|
|
|
$this->action = "RESET_AUTO_INCREMENT";
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2021-12-08 16:53:43 +01:00
|
|
|
public function addToEnum(EnumColumn $column, string $newValue): AlterTable {
|
|
|
|
$this->action = "MODIFY";
|
|
|
|
$this->column = $column;
|
|
|
|
$this->data = $newValue;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2021-04-03 16:23:30 +02:00
|
|
|
public function getAction(): string { return $this->action; }
|
|
|
|
public function getColumn(): ?Column { return $this->column; }
|
|
|
|
public function getConstraint(): ?Constraint { return $this->constraint; }
|
|
|
|
public function getTable(): string { return $this->table; }
|
2021-04-08 18:29:47 +02:00
|
|
|
|
2021-04-09 16:05:36 +02:00
|
|
|
public function build(array &$params): ?string {
|
2021-04-08 18:29:47 +02:00
|
|
|
$tableName = $this->sql->tableName($this->getTable());
|
|
|
|
$action = $this->getAction();
|
|
|
|
$column = $this->getColumn();
|
|
|
|
$constraint = $this->getConstraint();
|
|
|
|
|
2021-11-11 14:25:26 +01:00
|
|
|
if ($action === "RESET_AUTO_INCREMENT") {
|
|
|
|
return "ALTER TABLE $tableName AUTO_INCREMENT=1";
|
|
|
|
}
|
|
|
|
|
2021-04-08 18:29:47 +02:00
|
|
|
$query = "ALTER TABLE $tableName $action ";
|
|
|
|
|
|
|
|
if ($column) {
|
|
|
|
$query .= "COLUMN ";
|
|
|
|
if ($action === "DROP") {
|
|
|
|
$query .= $this->sql->columnName($column->getName());
|
|
|
|
} else {
|
|
|
|
// ADD or modify
|
2021-12-08 16:53:43 +01:00
|
|
|
if ($column instanceof EnumColumn) {
|
|
|
|
if ($this->sql instanceof PostgreSQL) {
|
|
|
|
$typeName = $this->sql->getColumnType($column);
|
|
|
|
$value = $this->sql->addValue($this->data, $params);
|
|
|
|
return "ALTER TYPE $typeName ADD VALUE $value";
|
|
|
|
}
|
|
|
|
$column->addValue($this->data);
|
|
|
|
}
|
|
|
|
|
2021-04-08 18:29:47 +02:00
|
|
|
$query .= $this->sql->getColumnDefinition($column);
|
|
|
|
}
|
|
|
|
} else if ($constraint) {
|
|
|
|
if ($action === "DROP") {
|
|
|
|
if ($constraint instanceof PrimaryKey) {
|
|
|
|
$query .= "PRIMARY KEY";
|
|
|
|
} else if ($constraint instanceof ForeignKey) {
|
|
|
|
// TODO: how can we pass the constraint name here?
|
|
|
|
$this->sql->setLastError("DROP CONSTRAINT foreign key is not supported yet.");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else if ($action === "ADD") {
|
|
|
|
$query .= "CONSTRAINT ";
|
|
|
|
$query .= $this->sql->getConstraintDefinition($constraint);
|
|
|
|
} else if ($action === "MODIFY") {
|
|
|
|
$this->sql->setLastError("MODIFY CONSTRAINT foreign key is not supported.");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->sql->setLastError("ALTER TABLE requires at least a column or a constraint.");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $query;
|
|
|
|
}
|
2021-04-03 16:23:30 +02:00
|
|
|
}
|