packages/ztd-query-postgres/fuzz/Input/SchemaRows.php

1<?php
2
3declare(strict_types=1);
4
5namespace Fuzz\Input;
6
7use ZtdQuery\Schema\TableDefinition;
8
9/**
10 * Creates reproducible PostgreSQL pipeline fixtures.
11 */
12final class SchemaRows
13{
14    /**
15     * Generate random fixture rows for a table definition.
16     *
17     * @return array<int, array<string, int|float|string|bool>>
18     */
19    public function generateFixtureRows(TableDefinition $definition, int $count): array
20    {
21        $rows = [];
22        for ($i = 0; $i < $count; $i++) {
23            $row = [];
24            foreach ($definition->columns as $col) {
25                $type = strtoupper($definition->columnTypes[$col] ?? 'TEXT');
26                $row[$col] = $this->generateValueForType($type, $i);
27            }
28            $rows[] = $row;
29        }
30        return $rows;
31    }
32
33    /**
34     * Generate a random value appropriate for the given SQL type.
35     */
36    public function generateValueForType(string $type, int $seed): int|float|string|bool
37    {
38        $baseType = preg_replace('/\(.*\)/', '', $type);
39        $baseType = trim($baseType ?? $type);
40        return match (true) {
41            in_array($baseType, ['INT', 'INT2', 'INT4', 'INT8', 'INTEGER', 'SMALLINT', 'BIGINT', 'SERIAL', 'SMALLSERIAL', 'BIGSERIAL'], true) => $seed + 1,
42            in_array($baseType, ['REAL', 'FLOAT4', 'DOUBLE PRECISION', 'FLOAT8', 'DECIMAL', 'NUMERIC'], true) => round($seed + 0.5, 2),
43            in_array($baseType, ['BOOLEAN', 'BOOL'], true) => $seed % 2 === 0,
44            default => 'val_' . $seed,
45        };
46    }
47
48    /**
49     * Extract table name from a CREATE TABLE statement.
50     */
51    public function extractTableName(string $createSql): ?string
52    {
53        if (preg_match('/CREATE\s+(?:TEMPORARY\s+|TEMP\s+|UNLOGGED\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:(?:"([^"]+)"|([a-zA-Z_]\w*))\.)?(?:"([^"]+)"|([a-zA-Z_]\w*))/i', $createSql, $m) !== 1) {
54            return null;
55        }
56        $quotedTable = $m[3] ?? '';
57        return $quotedTable !== '' ? $quotedTable : $m[4] ?? null;
58    }
59}
60