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; } }