WP-Query-Builder/Table.php

139 lines
4.5 KiB
PHP
Raw Normal View History

2025-01-28 16:53:37 +01:00
<?php
namespace DatabaseHelper;
use DatabaseHelper\enums\CascadeTypes;
use DatabaseHelper\enums\CharsetTypes;
use DatabaseHelper\enums\CollationTypes;
use DatabaseHelper\enums\ColumnTypes;
use DatabaseHelper\enums\EngineTypes;
use DatabaseHelper\interfaces\TableBlueprint;
use InvalidArgumentException;
class Table implements TableBlueprint
{
public string $tableName;
public array $columns = [];
public array $primaryKey;
public array $foreignKeys = [];
// Table settings
protected EngineTypes $engine = EngineTypes::INNODB;
protected CharsetTypes $charset = CharsetTypes::UTF8;
protected CollationTypes $collation = CollationTypes::UTF8_GENERAL_CI;
public function __construct(string $tableName) {
$this->tableName = $tableName;
}
public function column(string $name, ColumnTypes $type, mixed $default = null, bool $nullable = false, bool $unique = false): TableBlueprint {
if(isset($this->columns[$name]))
throw new InvalidArgumentException('Column name already exists.');
$this->columns[$name] = [
'colName' => $name,
'defaultVal' => $default,
'colType' => $type,
'nullable' => $nullable,
'unique' => $unique
];
return $this;
}
public function primaryColumn(string $name, ColumnTypes $type, bool $autoincrement = false): TableBlueprint {
if(isset($this->primaryKey))
throw new InvalidArgumentException('Primary column already exists.');
$this->primaryKey = [
'colName' => $name,
'colType' => $type,
'autoincrement' => $autoincrement
];
return $this->column($name, $type);
}
public function foreignColumn(TableBlueprint $foreignTable, CascadeTypes $onDelete, CascadeTypes $onUpdate): TableBlueprint {
$colName = $foreignTable->primaryKey['colName'];
if(isset($this->columns[$colName]))
throw new InvalidArgumentException('Column name already exists.');
$this->foreignKeys[] = [
'colName' => $colName,
'tableName' => $foreignTable->tableName,
'onDelete' => $onDelete,
'onUpdate' => $onUpdate
];
$this->columns[$colName] = $foreignTable->columns[$colName];
return $this;
}
public function engine(EngineTypes $engine): TableBlueprint {
$this->engine = $engine;
return $this;
}
public function charset(CharsetTypes $charset): TableBlueprint {
$this->charset = $charset;
return $this;
}
public function collation(CollationTypes $collation): TableBlueprint {
$this->collation = $collation;
return $this;
}
public function toSql(): string {
$sql = "CREATE TABLE `{$this->tableName}` (\n";
if (!empty($this->primaryKey)) {
$sql .= " `{$this->primaryKey['colName']}` {$this->primaryKey['colType']->value}";
if ($this->primaryKey['autoincrement'])
$sql .= " AUTO_INCREMENT";
$sql .= " NOT NULL,\n";
}
foreach ($this->columns as $column) {
if ($column['colName'] !== $this->primaryKey['colName']) {
$sql .= " `{$column['colName']}` {$column['colType']->value}";
if (!$column['nullable'])
$sql .= " NOT NULL";
if ($column['unique'])
$sql .= " UNIQUE";
if ($column['defaultVal'] !== null) {
$default = is_string($column['defaultVal']) ? "'{$column['defaultVal']}'" : $column['defaultVal'];
$sql .= " DEFAULT $default";
}
$sql .= ",\n";
}
}
if (!empty($this->primaryKey))
$sql .= " PRIMARY KEY (`{$this->primaryKey['colName']}`),\n";
foreach ($this->foreignKeys as $foreignKey) {
$sql .= " FOREIGN KEY (`{$foreignKey['colName']}`) REFERENCES `{$foreignKey['tableName']}` (`{$foreignKey['colName']}`)";
$sql .= " ON DELETE {$foreignKey['onDelete']->type()} ON UPDATE {$foreignKey['onUpdate']->type()},\n";
}
$sql = rtrim($sql, ",\n") . "\n";
$sql .= ") ENGINE={$this->engine->type()} CHARSET={$this->charset->type()} COLLATE={$this->collation->type()};";
return $sql;
}
public function create(): void {
$sql = $this->toSql();
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}