packages/sql-fixture/src/Platform/PostgreSql/Value/NumericGenerator.php

1<?php
2
3declare(strict_types=1);
4
5namespace SqlFixture\Platform\PostgreSql\Value;
6
7use Faker\Generator;
8use LogicException;
9use SqlFixture\Schema\ColumnDefinition;
10use SqlFixture\TypeMapper\IntegerRange;
11use SqlFixture\TypeMapper\IntegerWidth;
12
13/**
14 * Generates numeric values for the dialect's declared column type.
15 *
16 * @visibility root
17 */
18final class NumericGenerator
19{
20    /**
21     * Generates a value for a supported member of this type family.
22     * @throws LogicException
23     */
24    public function generate(Generator $faker, ColumnDefinition $column): int|float
25    {
26        $type = strtoupper($column->type);
27        $width = match ($type) {
28            'SMALLINT', 'INT2' => IntegerWidth::Bits16,
29            'INTEGER', 'INT', 'INT4' => IntegerWidth::Bits32,
30            'BIGINT', 'INT8' => IntegerWidth::Bits64,
31            default => null,
32        };
33        if ($width !== null) {
34            $range = new IntegerRange($width);
35            return $faker->numberBetween($range->minimum, $range->maximum);
36        }
37        return match ($type) {
38            'REAL', 'FLOAT4' => $faker->randomFloat(2, -1000.0, 1000.0),
39            'DOUBLE PRECISION', 'FLOAT8' => $faker->randomFloat(4, -1000000.0, 1000000.0),
40            'DECIMAL', 'NUMERIC', 'DEC' => (new DecimalGenerator())->generateDecimal($faker, $column),
41            'MONEY' => $faker->randomFloat(2, 0.0, 99999.99),
42            default => throw new LogicException('Unsupported numeric type: ' . $column->type),
43        };
44    }
45}
46