Skip to content

Commit

Permalink
Merge pull request #10 from DasunNethsara-04/main
Browse files Browse the repository at this point in the history
Database Table Constraints implemented
  • Loading branch information
DasunNethsara-04 authored Oct 28, 2024
2 parents 41f3804 + 4edb188 commit b04d00b
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 11 deletions.
71 changes: 71 additions & 0 deletions Core/src/Database/Column.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace ZenithPHP\Core\Database;

class Column
{
protected string $name;
protected string $type;
protected array $modifiers = [];

public function __construct(string $name, string $type)
{
$this->name = $name;
$this->type = $type;
}

public function unique(): self
{
$this->modifiers[] = 'UNIQUE';
return $this;
}

public function default($value): self
{
$this->modifiers[] = "DEFAULT $value";
return $this;
}

public function nullable(): self
{
$this->modifiers[] = 'NULL';
return $this;
}

public function notNullable(): self
{
$this->modifiers[] = 'NOT NULL';
return $this;
}

public function constrained(string $table): self
{
$this->modifiers[] = "REFERENCES `$table` (`id`)";
return $this;
}

public function cascadeOnDelete(): self
{
$this->modifiers[] = 'ON DELETE CASCADE';
return $this;
}

public function cascadeOnUpdate(): self
{
$this->modifiers[] = 'ON UPDATE CASCADE';
return $this;
}

public function __toString(): string
{
$modifiers = $this->modifiers;

// Check if the column has a REFERENCES constraint before adding ON DELETE or ON UPDATE
if (!in_array('REFERENCES', array_map(fn($mod) => strtok($mod, ' '), $modifiers))) {
// Exclude cascade if it's not a foreign key constraint
$modifiers = array_filter($modifiers, fn($mod) => !str_contains($mod, 'ON DELETE') && !str_contains($mod, 'ON UPDATE'));
}
return "`{$this->name}` {$this->type} " . implode(' ', $modifiers);
}

}
82 changes: 71 additions & 11 deletions Core/src/Database/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,91 @@ public static function drop($tableName): void
Database::execute($sql);
}

public function id(): void
public function id(): Column
{
$this->columns[] = "`{$this->primaryKey}` INT AUTO_INCREMENT PRIMARY KEY";
$column = new Column($this->primaryKey, 'INT AUTO_INCREMENT PRIMARY KEY');
$this->columns[] = $column;
return $column;
}

public function string($name, $length = 255): void
public function string(string $name, int $length = 255): Column
{
$this->columns[] = "`$name` VARCHAR($length)";
$column = new Column($name, "VARCHAR($length)");
$this->columns[] = $column;
return $column;
}

public function integer($name): void
public function integer(string $name, int $length = 11): Column
{
$this->columns[] = "`$name` INT";
$column = new Column($name, "INT($length)");
$this->columns[] = $column;
return $column;
}

public function timestamps(): void
public function text(string $name): Column
{
$this->columns[] = "`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP";
$this->columns[] = "`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP";
$column = new Column($name, "TEXT");
$this->columns[] = $column;
return $column;
}

public function decimal(string $name, int $length = 10, int $decimals = 2): Column
{
$column = new Column($name, "DECIMAL($length, $decimals)");
$this->columns[] = $column;
return $column;
}

public function boolean(string $name): Column
{
$column = new Column($name, "TINYINT(1)");
$this->columns[] = $column;
return $column;
}

public function timestamp(string $name): Column
{
$column = new Column($name, "TIMESTAMP");
$this->columns[] = $column;
return $column;
}

public function date(string $name): Column
{
$column = new Column($name, "DATE");
$this->columns[] = $column;
return $column;
}

public function foreignId(string $name): Column
{
$column = new Column($name, "INT");
$this->columns[] = $column;
return $column;
}

protected function executeCreate(): void
{
$columnsSql = implode(", ", $this->columns);
$sql = "CREATE TABLE IF NOT EXISTS `{$this->tableName}` ({$columnsSql});";
$columnsSql = [];
$constraints = [];

foreach ($this->columns as $column) {
$columnDefinition = (string)$column;
// Move foreign key constraints to a separate array
if (str_contains($columnDefinition, 'REFERENCES')) {
$constraints[] = $columnDefinition;
} else {
$columnsSql[] = $columnDefinition;
}
}

$sql = "CREATE TABLE IF NOT EXISTS `{$this->tableName}` (" . implode(", ", $columnsSql);

if (!empty($constraints)) {
$sql .= ", " . implode(", ", $constraints);
}

$sql .= ");";
Database::execute($sql);
}
}
28 changes: 28 additions & 0 deletions Migrations/_2024_10_28_093729_user.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace ZenithPHP\Migrations;

use ZenithPHP\Core\Database\Migration;
use ZenithPHP\Core\Database\Schema;

class _2024_10_28_093729_user extends Migration
{
public function up()
{
Schema::create('user', function (Schema $table) {
$table->id();
$table->string('name', 50);
$table->string('email', 100)->unique();
$table->string('password');
$table->boolean('is_active')->default(1);
$table->text('bio')->nullable();
$table->timestamp('created_at')->default('CURRENT_TIMESTAMP');
$table->timestamp('updated_at')->default('CURRENT_TIMESTAMP')->cascadeOnUpdate();
});
}

public function down()
{
Schema::drop('user');
}
}

0 comments on commit b04d00b

Please sign in to comment.