Passed
Push — master ( 2a9aa3...e9c192 )
by Alexander
01:53
created

ColumnSchema   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Test Coverage

Coverage 53.06%

Importance

Changes 0
Metric Value
eloc 45
c 0
b 0
f 0
dl 0
loc 144
ccs 26
cts 49
cp 0.5306
rs 10
wmc 24

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getDimension() 0 3 1
A dimension() 0 3 1
A getSequenceName() 0 3 1
B phpTypecastValue() 0 25 9
A getArrayParser() 0 9 2
A phpTypecast() 0 18 4
A sequenceName() 0 3 1
A dbTypecast() 0 19 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql;
6
7
use JsonException;
8
use Yiisoft\Db\Expression\ArrayExpression;
9
use Yiisoft\Db\Expression\ExpressionInterface;
10
use Yiisoft\Db\Expression\JsonExpression;
11
use Yiisoft\Db\Schema\ColumnSchema as AbstractColumnSchema;
12
13
use function array_walk_recursive;
14
use function in_array;
15
use function is_array;
16
use function is_string;
17
use function json_decode;
18
use function strtolower;
19
20
final class ColumnSchema extends AbstractColumnSchema
21
{
22
    /**
23
     * @var int the dimension of array. Defaults to 0, means this column is not an array.
24
     */
25
    private int $dimension = 0;
26
27
    /**
28
     * @var string|null name of associated sequence if column is auto-incremental.
29
     */
30
    private ?string $sequenceName = null;
31
32
    /**
33
     * Converts the input value according to {@see type} and {@see dbType} for use in a db query.
34
     *
35
     * If the value is null or an {@see Expression}, it will not be converted.
36
     *
37
     * @param mixed $value input value
38
     *
39
     * @return mixed converted value. This may also be an array containing the value as the first element and the PDO
40
     * type as the second element.
41
     */
42 48
    public function dbTypecast($value)
43
    {
44 48
        if ($value === null) {
45 5
            return null;
46
        }
47
48 48
        if ($value instanceof ExpressionInterface) {
49 10
            return $value;
50
        }
51
52 43
        if ($this->dimension > 0) {
53
            return new ArrayExpression($value, $this->getDbType(), $this->dimension);
54
        }
55
56 43
        if (in_array($this->getDbType(), [Schema::TYPE_JSON, Schema::TYPE_JSONB], true)) {
57 1
            return new JsonExpression($value, $this->getDbType());
58
        }
59
60 42
        return $this->typecast($value);
61
    }
62
63
    /**
64
     * Converts the input value according to {@see phpType} after retrieval from the database.
65
     *
66
     * If the value is null or an {@see Expression}, it will not be converted.
67
     *
68
     * @param mixed $value input value
69
     *
70
     * @throws JsonException
71
     *
72
     * @return mixed converted value
73
     */
74 29
    public function phpTypecast($value)
75
    {
76 29
        if ($this->dimension > 0) {
77
            if (!is_array($value)) {
78
                $value = $this->getArrayParser()->parse($value);
79
            }
80
            if (is_array($value)) {
81
                array_walk_recursive($value, function (&$val) {
82
                    $val = $this->phpTypecastValue($val);
83
                });
84
            } else {
85
                return null;
86
            }
87
88
            return $value;
89
        }
90
91 29
        return $this->phpTypecastValue($value);
92
    }
93
94
    /**
95
     * Casts $value after retrieving from the DBMS to PHP representation.
96
     *
97
     * @param string|int|null $value
98
     *
99
     * @throws JsonException
100
     *
101
     * @return bool|mixed|null
102
     */
103 29
    protected function phpTypecastValue($value)
104
    {
105 29
        if ($value === null) {
106
            return null;
107
        }
108
109 29
        switch ($this->getType()) {
110
            case Schema::TYPE_BOOLEAN:
111
                $value = is_string($value) ? strtolower($value) : $value;
112
113
                switch ($value) {
114
                    case 't':
115
                    case 'true':
116
                        return true;
117
                    case 'f':
118
                    case 'false':
119
                        return false;
120
                }
121
122
                return (bool) $value;
123
            case Schema::TYPE_JSON:
124 27
                return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
125
        }
126
127 29
        return parent::phpTypecast($value);
128
    }
129
130
    /**
131
     * Creates instance of ArrayParser.
132
     *
133
     * @return ArrayParser
134
     */
135
    protected function getArrayParser(): ArrayParser
136
    {
137
        static $parser = null;
138
139
        if ($parser === null) {
140
            $parser = new ArrayParser();
141
        }
142
143
        return $parser;
144
    }
145
146 1
    public function getDimension(): int
147
    {
148 1
        return $this->dimension;
149
    }
150
151 64
    public function getSequenceName(): ?string
152
    {
153 64
        return $this->sequenceName;
154
    }
155
156 93
    public function dimension(int $dimension): void
157
    {
158 93
        $this->dimension = $dimension;
159 93
    }
160
161 61
    public function sequenceName(?string $sequenceName): void
162
    {
163 61
        $this->sequenceName = $sequenceName;
164 61
    }
165
}
166