packages/sql-fixture/src/Platform/PostgreSql/Schema/CatalogDdl.php

1<?php
2
3declare(strict_types=1);
4
5namespace SqlFixture\Platform\PostgreSql\Schema;
6
7use PDO;
8
9/**
10 * Reconstructs CREATE TABLE SQL from PostgreSQL catalog columns.
11 *
12 * @visibility root
13 */
14final class CatalogDdl
15{
16    /**
17     * Reconstructs create table.
18     */
19    public function reconstructCreateTable(PDO $pdo, string $tableName): ?string
20    {
21        $schema = 'public';
22        $table = $tableName;
23        if (str_contains($tableName, '.')) {
24            $parts = explode('.', $tableName, 2);
25            $schema = $parts[0];
26            $table = $parts[1];
27        }
28
29        $columns = (new CatalogQuery())->columns($pdo, $schema, $table);
30
31        if ($columns === []) {
32            return null;
33        }
34
35        $primaryKeys = (new CatalogQuery())->primaryKeys($pdo, $schema, $table);
36
37        $columnDefs = [];
38        foreach ($columns as $col) {
39            $def = '"' . $col['column_name'] . '" ' . (new CatalogColumn())->mapDataType($col);
40            if ($col['is_nullable'] === 'NO') {
41                $def .= ' NOT NULL';
42            }
43            if ($col['column_default'] !== null) {
44                $def .= ' DEFAULT ' . $col['column_default'];
45            }
46            $columnDefs[] = $def;
47        }
48
49        if ($primaryKeys !== []) {
50            $columnDefs[] = 'PRIMARY KEY (' . implode(', ', array_map(static fn (string $pk): string => '"' . $pk . '"', $primaryKeys)) . ')';
51        }
52
53        return "CREATE TABLE \"{$table}\" (" . implode(', ', $columnDefs) . ')';
54    }
55}
56