Passed
Pull Request — master (#163)
by Wilmer
12:20
created

ColumnSchema::typecast()   D

Complexity

Conditions 21
Paths 18

Size

Total Lines 66
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 21.8613

Importance

Changes 0
Metric Value
cc 21
eloc 39
c 0
b 0
f 0
nc 18
nop 1
dl 0
loc 66
ccs 28
cts 32
cp 0.875
crap 21.8613
rs 4.1666

How to fix   Long Method    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
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Schema;
6
7
use Yiisoft\Db\Expression\ExpressionInterface;
8
use Yiisoft\Db\Pdo\PdoValue;
9
use Yiisoft\Db\Query\Query;
10
use Yiisoft\Strings\NumericHelper;
11
use Yiisoft\Strings\StringHelper;
12
13
/**
14
 * ColumnSchema class describes the metadata of a column in a database table.
15
 */
16
class ColumnSchema
17
{
18
    private string $name;
19
    private bool $allowNull;
20
    private string $type;
21
    private ?string $phpType = null;
22
    private string $dbType;
23
    private $defaultValue;
24
    private ?array $enumValues = null;
25
    private ?int $size = null;
26
    private ?int $precision = null;
27
    private ?int $scale = null;
28
    private bool $isPrimaryKey = false;
29
    private bool $autoIncrement = false;
30
    private bool $unsigned = false;
31
    private ?string $comment = null;
32
33
    /**
34
     * Converts the input value according to {@see phpType} after retrieval from the database.
35
     *
36
     * If the value is null or an {@see Expression}, it will not be converted.
37
     *
38
     * @param mixed $value input value
39
     *
40
     * @return mixed converted value
41 150
     */
42
    public function phpTypecast($value)
43 150
    {
44
        return $this->typecast($value);
45
    }
46
47
    /**
48
     * Converts the input value according to {@see type} and {@see dbType} for use in a db query.
49
     *
50
     * If the value is null or an {@see Expression}, it will not be converted.
51
     *
52
     * @param mixed $value input value
53
     *
54
     * @return mixed converted value. This may also be an array containing the value as the first element
55
     * and the PDO type as the second element.
56 40
     */
57
    public function dbTypecast($value)
58
    {
59
        /**
60
         * the default implementation does the same as casting for PHP, but it should be possible to override this with
61
         * annotation of explicit PDO type.
62 40
         */
63
        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
     * @return mixed converted value
74 211
     */
75
    protected function typecast($value)
76
    {
77 211
        if (
78 6
            $value === ''
79 6
            && !in_array(
80
                $this->type,
81 6
                [
82
                    Schema::TYPE_TEXT,
83
                    Schema::TYPE_STRING,
84
                    Schema::TYPE_BINARY,
85
                    Schema::TYPE_CHAR,
86 211
                ],
87
                true
88
            )
89 3
        ) {
90
            return;
91
        }
92
93 211
        if (
94 211
            $value === null
95 211
            || gettype($value) === $this->phpType
96 211
            || $value instanceof ExpressionInterface
97
            || $value instanceof Query
98 177
        ) {
99
            return $value;
100
        }
101
102 159
        if (
103 159
            is_array($value)
104 159
            && count($value) === 2
105 159
            && isset($value[1])
106
            && in_array($value[1], $this->getPdoParamTypes(), true)
107
        ) {
108
            return new PdoValue($value[0], $value[1]);
109
        }
110 159
111 159
        switch ($this->phpType) {
112 159
            case 'resource':
113 9
            case 'string':
114
                if (is_resource($value)) {
115
                    return $value;
116 9
                }
117
118
                if (is_float($value)) {
119
                    /* ensure type cast always has . as decimal separator in all locales */
120
                    return NumericHelper::normalize($value);
121 9
                }
122 152
123 148
                if (is_bool($value)) {
124 77
                    return $value ? '1' : '0';
125
                }
126
127
                return (string) $value;
128
            case 'integer':
129 44
                return (int) $value;
130 76
            case 'boolean':
131 73
                /**
132
                 * treating a 0 bit value as false too
133
                 * https://github.com/yiisoft/yii2/issues/9006
134 3
                 */
135
                return (bool) $value && $value !== "\0";
136
            case 'double':
137
                return (float) $value;
138
        }
139
140
        return $value;
141
    }
142
143
    /**
144
     * @return int[] array of numbers that represent possible PDO parameter types
145
     */
146
    private function getPdoParamTypes(): array
147
    {
148
        return [
149
            \PDO::PARAM_BOOL,
150
            \PDO::PARAM_INT,
151
            \PDO::PARAM_STR,
152 3
            \PDO::PARAM_LOB,
153
            \PDO::PARAM_NULL,
154 3
            \PDO::PARAM_STMT
155 3
        ];
156
    }
157
158
    public function setType(string $value): void
159
    {
160 245
        $this->type = $value;
161
    }
162 245
163
    /**
164
     * @return string name of this column (without quotes).
165
     */
166
    public function getName(): string
167
    {
168 4
        return $this->name;
169
    }
170 4
171
    /**
172
     * @return bool whether this column can be null.
173
     */
174
    public function isAllowNull(): bool
175
    {
176
        return $this->allowNull;
177 246
    }
178
179 246
    /**
180
     * @return string abstract type of this column. Possible abstract types include: char, string, text, boolean,
181
     * smallint, integer, bigint, float, decimal, datetime, timestamp, time, date, binary, and money.
182
     */
183
    public function getType(): string
184
    {
185
        return $this->type;
186 3
    }
187
188 3
    /**
189
     * @return string the PHP type of this column. Possible PHP types include: `string`, `boolean`, `integer`,
190
     * `double`, `array`.
191
     */
192
    public function getPhpType(): ?string
193
    {
194 246
        return $this->phpType;
195
    }
196 246
197
    /**
198
     * @return string the DB type of this column. Possible DB types vary according to the type of DBMS.
199
     */
200
    public function getDbType()
201
    {
202 98
        return $this->dbType;
203
    }
204 98
205
    /**
206
     * @return mixed default value of this column
207
     */
208
    public function getDefaultValue()
209
    {
210 3
        return $this->defaultValue;
211
    }
212 3
213
    /**
214
     * @return array enumerable values. This is set only if the column is declared to be an enumerable type.
215
     */
216
    public function getEnumValues(): ?array
217
    {
218 152
        return $this->enumValues;
219
    }
220 152
221
    /**
222
     * @return int display size of the column.
223
     */
224
    public function getSize(): ?int
225
    {
226 3
        return $this->size;
227
    }
228 3
229
    /**
230
     * @return int precision of the column data, if it is numeric.
231
     */
232
    public function getPrecision(): ?int
233
    {
234 3
        return $this->precision;
235
    }
236 3
237
    /**
238
     * @return int scale of the column data, if it is numeric.
239
     */
240
    public function getScale(): ?int
241
    {
242 246
        return $this->scale;
243
    }
244 246
245
    /**
246
     * @return bool whether this column is a primary key
247
     */
248
    public function isPrimaryKey(): bool
249
    {
250 58
        return $this->isPrimaryKey;
251
    }
252 58
253
    /**
254
     * @return bool whether this column is auto-incremental
255
     */
256
    public function isAutoIncrement(): bool
257
    {
258
        return $this->autoIncrement;
259 36
    }
260
261 36
    /**
262
     * @return bool whether this column is unsigned. This is only meaningful when {@see type} is `smallint`, `integer`
263
     * or `bigint`.
264
     */
265
    public function isUnsigned(): bool
266
    {
267 2
        return $this->unsigned;
268
    }
269 2
270
    /**
271
     * @return string comment of this column. Not all DBMS support this.
272 246
     */
273
    public function getComment(): ?string
274 246
    {
275 246
        return $this->comment;
276
    }
277 246
278
    public function name(string $value): void
279 246
    {
280 246
        $this->name = $value;
281
    }
282 246
283
    public function allowNull(bool $value): void
284 246
    {
285 246
        $this->allowNull =  $value;
286
    }
287 246
288
    public function type(string $value): void
289 246
    {
290 246
        $this->type = $value;
291
    }
292 246
293
    public function phpType(?string $value): void
294 246
    {
295 246
        $this->phpType = $value;
296
    }
297 244
298
    public function dbType(string $value): void
299 244
    {
300 244
        $this->dbType = $value;
301
    }
302 113
303
    public function defaultValue($value): void
304 113
    {
305 113
        $this->defaultValue = $value;
306
    }
307 242
308
    public function enumValues(?array $value): void
309 242
    {
310 242
        $this->enumValues = $value;
311
    }
312 242
313
    public function size(?int $value): void
314 242
    {
315 242
        $this->size = $value;
316
    }
317 141
318
    public function precision(?int $value): void
319 141
    {
320 141
        $this->precision = $value;
321
    }
322 246
323
    public function scale(?int $value): void
324 246
    {
325 246
        $this->scale = $value;
326
    }
327 223
328
    public function primaryKey(bool $value): void
329 223
    {
330 223
        $this->isPrimaryKey = $value;
331
    }
332 246
333
    public function autoIncrement(bool $value): void
334 246
    {
335 246
        $this->autoIncrement = $value;
336
    }
337 171
338
    public function unsigned(bool $value): void
339 171
    {
340 171
        $this->unsigned = $value;
341
    }
342
343
    public function comment(?string $value): void
344
    {
345
        $this->comment = $value;
346
    }
347
}
348