Issues (13)

src/Helpers/NumericColumnLimitHelper.php (1 issue)

Severity
1
<?php
2
namespace DBFaker\Helpers;
3
4
use DBFaker\Exceptions\UnsupportedDataTypeException;
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Types\Type;
7
8
/**
9
 * Class NumericColumnLimitHelper: gives the min and max numeric values for a column depending
10
 * on it's type and attributes (precision, scale, unsigned)
11
 *
12
 * @package DBFaker\Helpers
13
 */
14
class NumericColumnLimitHelper
15
{
16
17
    /**
18
     * @var Column
19
     */
20
    private $column;
21
22
    private static $handledNumberTypes = [
23
        Type::BIGINT,
24
        Type::DECIMAL,
25
        Type::INTEGER,
26
        Type::SMALLINT,
27
        Type::FLOAT
28
    ];
29
30
    /**
31
     * NumericColumnLimitHelper constructor
32
     * @param Column $column
33
     * @throws \DBFaker\Exceptions\UnsupportedDataTypeException
34
     */
35
    public function __construct(Column $column)
36
    {
37
        if (!\in_array($column->getType()->getName(), self::$handledNumberTypes, true)) {
38
            throw new UnsupportedDataTypeException('Unsupported column type : ' .
39
                $column->getType()->getName() . 'only ' .
40
                implode("', '", self::$handledNumberTypes) . ' types are supported.');
41
        }
42
        $this->column = $column;
43
    }
44
45
    /**
46
     * returns the min numeric value for the column
47
     * @return int|float|string
48
     */
49
    public function getMinNumericValue()
50
    {
51
        $precisionValue = $this->getAbsValueByLengthPrecision($this->column);
52
        switch ($this->column->getType()->getName()) {
53
            case Type::BIGINT:
54
                return $this->column->getUnsigned() ? 0 : bcmul('-1', bcpow('2', '63'));
55
                break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
56
            case Type::INTEGER:
57
                return $this->column->getUnsigned() ? 0 : max(-1 * $precisionValue, bcmul('-1', bcpow('2', '31')));
58
                break;
59
            case Type::SMALLINT:
60
                return $this->column->getUnsigned() ? 0 : bcmul('-1', bcpow('2', '15'));
61
                break;
62
            case Type::DECIMAL:
63
                return $this->column->getUnsigned() ? 0 : -1 * $precisionValue;
64
                break;
65
            case Type::FLOAT:
66
                return $this->column->getUnsigned() ? 0 : -8.95e307;
67
                break;
68
        }
69
    }
70
71
    /**
72
     * returns the max numeric value for the column
73
     * @return int|float|string
74
     */
75
    public function getMaxNumericValue()
76
    {
77
        $precisionValue = $this->getAbsValueByLengthPrecision($this->column);
78
        switch ($this->column->getType()->getName()) {
79
            case Type::BIGINT:
80
                return $this->column->getUnsigned() ? bcsub(bcpow('2', '64'), '1') : bcsub(bcpow('2', '63'), '1');
81
            case Type::INTEGER:
82
                return $this->column->getUnsigned() ? bcsub(bcpow('2', '32'), '1') : min($precisionValue, bcsub(bcpow('2', '31'), '1'));
83
            case Type::SMALLINT:
84
                return $this->column->getUnsigned() ? bcsub(bcpow('2', '16'), '1') : bcsub(bcpow('2', '15'), '1');
85
            case Type::DECIMAL:
86
                return $this->column->getUnsigned() ? 0 : $precisionValue;
87
            case Type::FLOAT:
88
                return 8.95e307;
89
        }
90
    }
91
92
    /**
93
     * @param Column $column
94
     * @return double|int
95
     */
96
    private function getAbsValueByLengthPrecision(Column $column)
97
    {
98
        switch ($column->getType()->getName()) {
99
            case Type::DECIMAL:
100
                $str = str_repeat('9', $column->getScale());
101
                return (double) substr_replace($str, '.', $column->getScale() - $column->getPrecision(), 0);
102
            case Type::INTEGER:
103
                $str = str_repeat('9', $column->getPrecision() - 1);
104
                return (int) $str;
105
        }
106
    }
107
}
108