Files
Woles-Framework/app/Core/Database/Blueprint.php

415 lines
8.5 KiB
PHP
Raw Normal View History

<?php
namespace App\Core\Database;
/**
* NovaCore Database Blueprint
* Schema builder for migrations
*/
class Blueprint
{
private string $table;
private array $columns = [];
private array $indexes = [];
private string $primaryKey = 'id';
private array $timestamps = [];
public function __construct(string $table)
{
$this->table = $table;
}
/**
* Add primary key
*/
public function id(string $column = 'id'): Column
{
$this->primaryKey = $column;
$column = new Column('id', 'INT AUTO_INCREMENT PRIMARY KEY');
$this->columns[] = $column;
return $column;
}
/**
* Add string column
*/
public function string(string $name, int $length = 255): Column
{
$column = new Column($name, "VARCHAR({$length})");
$this->columns[] = $column;
return $column;
}
/**
* Add text column
*/
public function text(string $name): Column
{
$column = new Column($name, 'TEXT');
$this->columns[] = $column;
return $column;
}
/**
* Add long text column
*/
public function longText(string $name): Column
{
$column = new Column($name, 'LONGTEXT');
$this->columns[] = $column;
return $column;
}
/**
* Add integer column
*/
public function integer(string $name, int $length = null): Column
{
$type = $length ? "INT({$length})" : 'INT';
$column = new Column($name, $type);
$this->columns[] = $column;
return $column;
}
/**
* Add big integer column
*/
public function bigInteger(string $name): Column
{
$column = new Column($name, 'BIGINT');
$this->columns[] = $column;
return $column;
}
/**
* Add small integer column
*/
public function smallInteger(string $name): Column
{
$column = new Column($name, 'SMALLINT');
$this->columns[] = $column;
return $column;
}
/**
* Add tiny integer column
*/
public function tinyInteger(string $name): Column
{
$column = new Column($name, 'TINYINT');
$this->columns[] = $column;
return $column;
}
/**
* Add boolean column
*/
public function boolean(string $name): Column
{
$column = new Column($name, 'BOOLEAN');
$this->columns[] = $column;
return $column;
}
/**
* Add decimal column
*/
public function decimal(string $name, int $precision = 8, int $scale = 2): Column
{
$column = new Column($name, "DECIMAL({$precision}, {$scale})");
$this->columns[] = $column;
return $column;
}
/**
* Add float column
*/
public function float(string $name, int $precision = 8, int $scale = 2): Column
{
$column = new Column($name, "FLOAT({$precision}, {$scale})");
$this->columns[] = $column;
return $column;
}
/**
* Add double column
*/
public function double(string $name, int $precision = 8, int $scale = 2): Column
{
$column = new Column($name, "DOUBLE({$precision}, {$scale})");
$this->columns[] = $column;
return $column;
}
/**
* Add date column
*/
public function date(string $name): Column
{
$column = new Column($name, 'DATE');
$this->columns[] = $column;
return $column;
}
/**
* Add datetime column
*/
public function datetime(string $name): Column
{
$column = new Column($name, 'DATETIME');
$this->columns[] = $column;
return $column;
}
/**
* Add timestamp column
*/
public function timestamp(string $name): Column
{
$column = new Column($name, 'TIMESTAMP');
$this->columns[] = $column;
return $column;
}
/**
* Add timestamps
*/
public function timestamps(): void
{
$this->timestamp('created_at')->nullable();
$this->timestamp('updated_at')->nullable();
}
/**
* Add soft deletes
*/
public function softDeletes(): void
{
$this->timestamp('deleted_at')->nullable();
}
/**
* Add index
*/
public function index(array $columns, string $name = null): void
{
if (!$name) {
$name = $this->table . '_' . implode('_', $columns) . '_index';
}
$this->indexes[] = [
'name' => $name,
'columns' => $columns,
'type' => 'INDEX'
];
}
/**
* Add unique index
*/
public function unique(array $columns, string $name = null): void
{
if (!$name) {
$name = $this->table . '_' . implode('_', $columns) . '_unique';
}
$this->indexes[] = [
'name' => $name,
'columns' => $columns,
'type' => 'UNIQUE'
];
}
/**
* Add foreign key
*/
public function foreign(string $column): ForeignKey
{
$foreignKey = new ForeignKey($column);
$this->columns[] = $foreignKey;
return $foreignKey;
}
/**
* Generate SQL
*/
public function toSql(): string
{
$sql = "CREATE TABLE `{$this->table}` (";
$columnDefinitions = [];
foreach ($this->columns as $column) {
$columnDefinitions[] = $column->toSql();
}
$sql .= implode(', ', $columnDefinitions);
$sql .= ")";
return $sql;
}
}
/**
* Column definition
*/
class Column
{
private string $name;
private string $type;
private bool $nullable = false;
private $default = null;
private bool $autoIncrement = false;
private bool $primary = false;
private bool $unique = false;
public function __construct(string $name, string $type)
{
$this->name = $name;
$this->type = $type;
}
/**
* Set nullable
*/
public function nullable(): self
{
$this->nullable = true;
return $this;
}
/**
* Set default value
*/
public function default($value): self
{
$this->default = $value;
return $this;
}
/**
* Set auto increment
*/
public function autoIncrement(): self
{
$this->autoIncrement = true;
return $this;
}
/**
* Set primary key
*/
public function primary(): self
{
$this->primary = true;
return $this;
}
/**
* Set unique
*/
public function unique(): self
{
$this->unique = true;
return $this;
}
/**
* Generate SQL
*/
public function toSql(): string
{
$sql = "`{$this->name}` {$this->type}";
if ($this->autoIncrement) {
$sql .= " AUTO_INCREMENT";
}
if (!$this->nullable) {
$sql .= " NOT NULL";
}
if ($this->default !== null) {
$default = is_string($this->default) ? "'{$this->default}'" : $this->default;
$sql .= " DEFAULT {$default}";
}
if ($this->unique) {
$sql .= " UNIQUE";
}
if ($this->primary) {
$sql .= " PRIMARY KEY";
}
return $sql;
}
}
/**
* Foreign key definition
*/
class ForeignKey
{
private string $column;
private string $references;
private string $on;
private string $onDelete = 'RESTRICT';
private string $onUpdate = 'RESTRICT';
public function __construct(string $column)
{
$this->column = $column;
}
/**
* Set references
*/
public function references(string $column): self
{
$this->references = $column;
return $this;
}
/**
* Set on table
*/
public function on(string $table): self
{
$this->on = $table;
return $this;
}
/**
* Set on delete action
*/
public function onDelete(string $action): self
{
$this->onDelete = $action;
return $this;
}
/**
* Set on update action
*/
public function onUpdate(string $action): self
{
$this->onUpdate = $action;
return $this;
}
/**
* Generate SQL
*/
public function toSql(): string
{
$sql = "`{$this->column}` INT";
if ($this->references && $this->on) {
$sql .= ", FOREIGN KEY (`{$this->column}`) REFERENCES `{$this->on}` (`{$this->references}`)";
$sql .= " ON DELETE {$this->onDelete} ON UPDATE {$this->onUpdate}";
}
return $sql;
}
}