Test Failed
Pull Request — master (#98)
by Wilmer
21:47 queued 09:55
created

ColumnSchema::phpTypecastValue()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

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