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