Completed
Push — master ( adc131...6e9eb4 )
by Kevin
03:32
created

NumericColumnLimitHelper::getMinNumericValue()   B

Complexity

Conditions 11
Paths 11

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 7.3166
c 0
b 0
f 0
cc 11
nc 11
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
        }
43
        $this->column = $column;
44
    }
45
46
    /**
47
     * returns the min numeric value for the column
48
     * @return int|float|string
49
     */
50
    public function getMinNumericValue()
51
    {
52
        $precisionValue = $this->getAbsValueByLengthPrecision($this->column);
53
        switch ($this->column->getType()->getName()){
54
            case Type::BIGINT:
55
                return $this->column->getUnsigned() ? 0 : bcpow('2', '63');
56
                break;
0 ignored issues
show
Unused Code introduced by
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...
57
            case Type::INTEGER:
58
                return $this->column->getUnsigned() ? 0 : max(-1 * $precisionValue, bcmul('-1' , bcpow('2', '31')));
59
                break;
60
            case Type::SMALLINT:
61
                return $this->column->getUnsigned() ? 0 : bcmul('-1' , bcpow('2', '15'));
62
                break;
63
            case Type::DECIMAL:
64
                return $this->column->getUnsigned() ? 0 : -1 * $precisionValue;
65
                break;
66
            case Type::FLOAT:
67
                return $this->column->getUnsigned() ? 0 : -1.79 * bcpow('10', '308');
68
                break;
69
        }
70
    }
71
72
    /**
73
     * returns the max numeric value for the column
74
     * @return int|float|string
75
     */
76
    public function getMaxNumericValue()
77
    {
78
        $precisionValue = $this->getAbsValueByLengthPrecision($this->column);
79
        switch ($this->column->getType()->getName()){
80
            case Type::BIGINT:
81
                return $this->column->getUnsigned() ? bcpow('2', '64') : bcsub(bcpow('2', '63') , '1');
82
            case Type::INTEGER:
83
                return $this->column->getUnsigned() ? bcpow('2', '32') : min($precisionValue, bcsub( bcpow('2', '31') , '1'));
84
            case Type::SMALLINT:
85
                return $this->column->getUnsigned() ? bcpow('2', '16') : bcsub( bcpow('2', '15') , '1');
86
            case Type::DECIMAL:
87
                return $this->column->getUnsigned() ? 0 : $precisionValue;
88
            case Type::FLOAT:
89
                return 1.79 * bcpow('10', '308');
90
        }
91
    }
92
93
    /**
94
     * @param Column $column
95
     * @return double|int
96
     */
97
    private function getAbsValueByLengthPrecision(Column $column)
98
    {
99
        switch ($column->getType()->getName()){
100
            case Type::DECIMAL:
101
                $str = str_repeat('9', $column->getScale());
102
                return (double) substr_replace($str, '.', $column->getScale() - $column->getPrecision(), 0);
103
            case Type::INTEGER:
104
                $str = str_repeat('9', $column->getPrecision() - 1);
105
                return (int) $str;
106
        }
107
    }
108
109
}