tableName = $tableName; } public function column(string $colName, ColumnTypes $colType, mixed $default = null, bool $nullable = false, bool $unique = false): Table { if(isset($this->columns[$colName])) throw new InvalidArgumentException('Column name already exists.'); $this->columns[$colName] = [ 'colName' => $colName, 'defaultVal' => $default, 'colType' => $colType, 'nullable' => $nullable, 'unique' => $unique ]; return $this; } public function primary(string $colName, ColumnTypes $colType, bool $autoInc = false): Table { if(isset($this->primaryKey)) throw new InvalidArgumentException('Primary column already exists.'); $this->primaryKey = [ 'colName' => $colName, 'colType' => $colType, 'autoincrement' => $autoInc ]; return $this->column($colName, $colType); } public function referenceColumn(Table $foreignTable, CascadeTypes $onDelete = CascadeTypes::CASCADE, CascadeTypes $onUpdate = CascadeTypes::CASCADE): Table { $colName = $foreignTable->primaryKey['colName']; if(isset($this->columns[$colName])) throw new InvalidArgumentException('Column name already exists.'); $this->foreignKeys[] = [ 'colName' => $colName, 'tableName' => $foreignTable->tableName, 'onDelete' => $onDelete, 'onUpdate' => $onUpdate ]; $this->columns[$colName] = $foreignTable->columns[$colName]; return $this; } public function engine(EngineTypes $engine): Table { $this->engine = $engine; return $this; } public function charset(CharsetTypes $charset): Table { $this->charset = $charset; return $this; } public function collation(CollationTypes $collation): Table { $this->collation = $collation; return $this; } public function toSql(): string { $sql = "CREATE TABLE `{$this->tableName}` (\n"; // Add primary key constraint if present if (!empty($this->primaryKey)) $sql .= " PRIMARY KEY (`{$this->primaryKey['colName']}`),\n"; foreach ($this->columns as $column) { if ($column['colName'] !== $this->primaryKey['colName']) { $sql .= " `{$column['colName']}` {$column['colType']->value}"; // Handle nulls, uniqueness, and defaults if (!$column['nullable']) $sql .= " NOT NULL"; if ($column['unique']) $sql .= " UNIQUE"; if ($column['defaultVal'] !== null) { $default = is_string($column['defaultVal']) ? "'{$column['defaultVal']}'" : $column['defaultVal']; $sql .= " DEFAULT $default"; } $sql .= ",\n"; } } // Add secondary constraints if present foreach ($this->foreignKeys as $foreignKey) { $sql .= " FOREIGN KEY (`{$foreignKey['colName']}`) REFERENCES `{$foreignKey['tableName']}` (`{$foreignKey['colName']}`)"; $sql .= " ON DELETE {$foreignKey['onDelete']->type()} ON UPDATE {$foreignKey['onUpdate']->type()},\n"; } // Close the SQL string and add constraints $sql = rtrim($sql, ",\n") . "\n"; $sql .= ") ENGINE={$this->engine->type()} CHARSET={$this->charset->type()} COLLATE={$this->collation->type()};"; return esc_sql($sql); } public function create(): Table { global $wpdb; if (empty($this->primaryKey)) throw new InvalidArgumentException('A primary key must be defined.'); $table_name = $wpdb->prefix . $this->tableName; if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") !== $table_name) { $sql = $this->toSql(); require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } return $this; } }