Passed
Push — master ( 03d3d0...cea9c0 )
by Alexander
07:36 queued 05:58
created

ColumnSchema   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 42
c 0
b 0
f 0
dl 0
loc 151
ccs 46
cts 46
cp 1
rs 10
wmc 23

8 Methods

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