schema with beans instead of arrays

This commit is contained in:
Jan-Niclas Loosen
2025-02-21 19:06:16 +01:00
parent 13fa680b87
commit 024e6e73cb
13 changed files with 123 additions and 140 deletions

View File

@@ -1,6 +1,10 @@
<?php
namespace DatabaseHelper;
use DatabaseHelper\beans\Column;
use DatabaseHelper\beans\Primary;
use DatabaseHelper\beans\Reference;
use DatabaseHelper\beans\Schema;
use DatabaseHelper\enums\Propagation;
use DatabaseHelper\enums\Charset;
use DatabaseHelper\enums\Collation;
@@ -18,42 +22,34 @@ class Table
}
public function column(string $name, Type $type, mixed $default = null, bool $isNullable = false, bool $isUnique = false): Table {
$this->table->columns[$name] = [
'name' => $name,
'default' => $default,
'type' => $type,
'isNullable' => $isNullable,
'isUnique' => $isUnique
];
$col = new Column;
$col->name = $name;
$col->default = $default;
$col->type = $type;
$col->isUnique = $isUnique;
$col->isNullable = $isNullable;
$this->table->columns[$name] = $col;
return $this;
}
public function primary(string $name, Type $type, bool $autoInc = false): Table {
if(isset($this->primaryKey))
throw new InvalidArgumentException('Primary column already exists.');
$this->table->primaryKey = [
'name' => $name,
'autoInc' => $autoInc
];
return $this->column($name, $type);
protected function id(): Table {
$id = new Primary;
$id->name = $this->table->name . '_id';
$this->table->primary = $id;
return $this;
}
public function reference(Schema $foreignTable, Propagation $onDelete = Propagation::CASCADE, Propagation $onUpdate = Propagation::CASCADE): Table {
$name = $foreignTable->primaryKey();
if(isset($this->columns[$name]))
throw new InvalidArgumentException('Column name already exists.');
$name = $foreignTable->primary->name;
$this->table->foreignKeys[$name] = [
'name' => $name,
'table' => $foreignTable->name,
'onDelete' => $onDelete,
'onUpdate' => $onUpdate
];
$ref = new Reference;
$ref->name = $name;
$ref->otherTable = $foreignTable;
$ref->onDelete = $onDelete;
$ref->onUpdate = $onUpdate;
$this->table->columns[$name] = $foreignTable->columns[$name];
$this->table->references[$name] = $ref;
return $this;
}
@@ -72,26 +68,19 @@ class Table
return $this;
}
/**
* Generates the SQL statement.
* @return string SQL query.
* @throws InvalidArgumentException
*/
public function toSql(): string {
$primaryKey = $this->table->primaryKey();
$primaryKey = $this->table->primary->name;
$clause = "CREATE TABLE `{$this->table->name}` (\n";
$clause .= " PRIMARY KEY (`$primaryKey`),\n";
foreach ($this->table->columns as $col) {
if ($col['name'] !== $primaryKey) {
$clause .= " `{$col['name']}` {$col['type']->toString()}";
if ($col->name !== $primaryKey) {
$clause .= " `$col->name` {$col->type->toString()}";
$clause .= !$col->isNullable ? ' NOT NULL' : '';
$clause .= $col->isUnique ? ' UNIQUE' : '';
$clause .= !$col['isNullable'] ? ' NOT NULL' : '';
$clause .= $col['isUnique'] ? ' UNIQUE' : '';
if (!is_null($col['default'])) {
$default = is_string($col['default']) ? "'{$col['default']}'" : $col['default'];
if (!is_null($col->default)) {
$default = is_string($col->default) ? "'{$col->default}'" : $col->default;
$clause .= " DEFAULT $default";
}
@@ -100,33 +89,34 @@ class Table
}
// Add foreign keys
foreach ($this->table->foreignKeys as $key) {
$clause .= " FOREIGN KEY (`{$key['name']}`)";
$clause .= " REFERENCES `{$key['table']}` (`{$key['name']}`)";
$clause .= " ON DELETE {$key['onDelete']->toString()}";
$clause .= " ON UPDATE {$key['onUpdate']->toString()},\n";
foreach ($this->table->references as $ref) {
$clause .= " FOREIGN KEY (`{$ref->name}`)";
$clause .= " REFERENCES `{$ref->otherTable->name}` (`{$ref->name}`)";
$clause .= " ON DELETE {$ref->onDelete->toString()}";
$clause .= " ON UPDATE {$ref->onUpdate->toString()},\n";
}
// Close the SQL string and add constraints
$clause = rtrim($clause, ",\n") . "\n) ";
$clause .= "ENGINE={$this->table->engine->toString()} ";
$clause .= "CHARSET={$this->table->charset->toString()} ";
$clause -= "COLLATE={$this->table->collation->toString()};";
$clause .= "COLLATE={$this->table->collation->toString()};";
return $clause;
}
public function create(): Schema {
global $wpdb;
$this->id();
if (empty($this->primaryKey))
throw new InvalidArgumentException('A primary key must be defined.');
$table_name = $wpdb->prefix . $this->table->name;
Database::standardizeTableNames($this->table->name);
$tableName = $this->table->name;
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") !== $table_name) {
$foundTables = $wpdb->get_var("SHOW TABLES LIKE '$tableName'");
if (is_null($foundTables)) {
$sql = $this->toSql();
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
return $this->table;
}
}
}