platform->getCreateTableSQL($tableName, $columns, $tableOptions); $this->connection->execute($sql); } public function dropTable(string $tableName, bool $ifExists = true): void { $sql = $this->platform->getDropTableSQL($tableName, $ifExists); $this->connection->execute($sql); } public function tableExists(string $tableName): bool { $sql = $this->platform->getTableExistsSQL($tableName); $result = $this->connection->queryColumn($sql, [$tableName]); return ! empty($result) && (int) $result[0] > 0; } public function createIndex(string $tableName, IndexDefinition $index): void { $sql = $this->platform->getCreateIndexSQL( $tableName, $index->name, $index->columns, ['type' => $index->type] ); $this->connection->execute($sql); } public function listTables(): array { $sql = $this->platform->getListTablesSQL(); return $this->connection->queryColumn($sql); } /** * Builder pattern for table creation */ public function table(string $tableName): TableBuilder { return new TableBuilder($this, $tableName); } } /** * Fluent table builder for easy table creation */ final class TableBuilder { private array $columns = []; private array $indexes = []; private ?TableOptions $options = null; public function __construct( private readonly SchemaBuilder $schemaBuilder, private readonly string $tableName ) { } public function id(string $name = 'id'): self { $this->columns[] = ColumnDefinition::id($name); return $this; } public function string(string $name, int $length = 255, bool $nullable = true): self { $this->columns[] = ColumnDefinition::string($name, $length, $nullable); return $this; } public function text(string $name, bool $nullable = true): self { $this->columns[] = ColumnDefinition::text($name, $nullable); return $this; } public function integer(string $name, bool $nullable = true, bool $unsigned = false): self { $this->columns[] = ColumnDefinition::integer($name, $nullable, $unsigned); return $this; } public function bigInteger(string $name, bool $nullable = true, bool $unsigned = false): self { $this->columns[] = ColumnDefinition::bigInteger($name, $nullable, $unsigned); return $this; } public function decimal(string $name, int $precision = 8, int $scale = 2, bool $nullable = true): self { $this->columns[] = ColumnDefinition::decimal($name, $precision, $scale, $nullable); return $this; } public function boolean(string $name, bool $nullable = true, ?bool $default = null): self { $this->columns[] = ColumnDefinition::boolean($name, $nullable, $default); return $this; } public function timestamp(string $name, bool $nullable = true): self { $this->columns[] = ColumnDefinition::timestamp($name, $nullable); return $this; } public function timestamps(): self { $timestamps = ColumnDefinition::timestamps(); foreach ($timestamps as $timestamp) { $this->columns[] = $timestamp; } return $this; } public function json(string $name, bool $nullable = true): self { $this->columns[] = ColumnDefinition::json($name, $nullable); return $this; } public function uuid(string $name, bool $nullable = true): self { $this->columns[] = ColumnDefinition::uuid($name, $nullable); return $this; } public function column(ColumnDefinition $column): self { $this->columns[] = $column; return $this; } public function index(IndexDefinition $index): self { $this->indexes[] = $index; return $this; } public function unique(string $name, array $columns): self { $this->indexes[] = IndexDefinition::unique($name, $columns); return $this; } public function foreignKey(string $column, string $referencedTable, string $referencedColumn = 'id'): self { // Foreign keys will be handled in a separate method/builder return $this; } public function engine(string $engine): self { $this->options = ($this->options ?? TableOptions::default())->withCustomOption('engine', $engine); return $this; } public function charset(string $charset, ?string $collation = null): self { $this->options = ($this->options ?? TableOptions::default())->withCharset($charset, $collation); return $this; } public function comment(string $comment): self { $this->options = ($this->options ?? TableOptions::default())->withComment($comment); return $this; } public function temporary(): self { $this->options = TableOptions::temporary(); return $this; } public function create(): void { if (empty($this->columns)) { throw new \RuntimeException("Cannot create table '{$this->tableName}' without columns"); } $this->schemaBuilder->createTable($this->tableName, $this->columns, $this->options); // Create additional indexes foreach ($this->indexes as $index) { $this->schemaBuilder->createIndex($this->tableName, $index); } } }