From dc5e8a0460c809b7a523b07c34ac04540d05e59f Mon Sep 17 00:00:00 2001 From: Dasun Date: Mon, 28 Oct 2024 14:22:58 +0530 Subject: [PATCH] new class Column added --- Core/src/Database/Column.php | 71 ++++++++++++++++++++++ Core/src/Database/Schema.php | 82 ++++++++++++++++++++++---- Migrations/_2024_10_28_093729_user.php | 28 +++++++++ 3 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 Core/src/Database/Column.php create mode 100644 Migrations/_2024_10_28_093729_user.php diff --git a/Core/src/Database/Column.php b/Core/src/Database/Column.php new file mode 100644 index 0000000..529501a --- /dev/null +++ b/Core/src/Database/Column.php @@ -0,0 +1,71 @@ +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); + } + +} diff --git a/Core/src/Database/Schema.php b/Core/src/Database/Schema.php index de260ab..11defe1 100644 --- a/Core/src/Database/Schema.php +++ b/Core/src/Database/Schema.php @@ -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); } } diff --git a/Migrations/_2024_10_28_093729_user.php b/Migrations/_2024_10_28_093729_user.php new file mode 100644 index 0000000..77b5e9c --- /dev/null +++ b/Migrations/_2024_10_28_093729_user.php @@ -0,0 +1,28 @@ +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'); + } +}