Passed
Push — master ( 9f7d35...3f1c7e )
by Wilmer
08:50 queued 06:32
created

ColumnSchema::getPhpType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
     */
42 234
    public function phpTypecast($value)
43
    {
44 234
        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
     */
57 80
    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
         */
63 80
        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
     */
75 294
    protected function typecast($value)
76
    {
77
        if (
78 294
            $value === ''
79 8
            && !in_array(
80 8
                $this->type,
81
                [
82 8
                    Schema::TYPE_TEXT,
83
                    Schema::TYPE_STRING,
84
                    Schema::TYPE_BINARY,
85
                    Schema::TYPE_CHAR,
86
                ],
87 294
                true
88
            )
89
        ) {
90 4
            return;
91
        }
92
93
        if (
94 294
            $value === null
95 294
            || gettype($value) === $this->phpType
96 294
            || $value instanceof ExpressionInterface
97 294
            || $value instanceof Query
98
        ) {
99 258
            return $value;
100
        }
101
102
        if (
103 223
            is_array($value)
104 223
            && count($value) === 2
105 223
            && isset($value[1])
106 223
            && in_array($value[1], $this->getPdoParamTypes(), true)
107
        ) {
108
            return new PdoValue($value[0], $value[1]);
109
        }
110
111 223
        switch ($this->phpType) {
112 223
            case 'resource':
113 223
            case 'string':
114 13
                if (is_resource($value)) {
115
                    return $value;
116
                }
117
118 13
                if (is_float($value)) {
119
                    /* ensure type cast always has . as decimal separator in all locales */
120 1
                    return NumericHelper::normalize($value);
121
                }
122
123 12
                if (is_bool($value)) {
124 4
                    return $value ? '1' : '0';
125
                }
126
127 8
                return (string) $value;
128 218
            case 'integer':
129 212
                return (int) $value;
130 101
            case 'boolean':
131
                /**
132
                 * treating a 0 bit value as false too
133
                 * https://github.com/yiisoft/yii2/issues/9006
134
                 */
135 43
                return (bool) $value && $value !== "\0";
136 99
            case 'double':
137 95
                return (float) $value;
138
        }
139
140 4
        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
            \PDO::PARAM_LOB,
153
            \PDO::PARAM_NULL,
154
            \PDO::PARAM_STMT
155
        ];
156
    }
157
158 4
    public function setType(string $value): void
159
    {
160 4
        $this->type = $value;
161 4
    }
162
163
    /**
164
     * @return string name of this column (without quotes).
165
     */
166 326
    public function getName(): string
167
    {
168 326
        return $this->name;
169
    }
170
171
    /**
172
     * @return bool whether this column can be null.
173
     */
174 28
    public function isAllowNull(): bool
175
    {
176 28
        return $this->allowNull;
177
    }
178
179
    /**
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 327
    public function getType(): string
184
    {
185 327
        return $this->type;
186
    }
187
188
    /**
189
     * @return string the PHP type of this column. Possible PHP types include: `string`, `boolean`, `integer`,
190
     * `double`, `array`.
191
     */
192 4
    public function getPhpType(): ?string
193
    {
194 4
        return $this->phpType;
195
    }
196
197
    /**
198
     * @return string the DB type of this column. Possible DB types vary according to the type of DBMS.
199
     */
200 327
    public function getDbType()
201
    {
202 327
        return $this->dbType;
203
    }
204
205
    /**
206
     * @return mixed default value of this column
207
     */
208 99
    public function getDefaultValue()
209
    {
210 99
        return $this->defaultValue;
211
    }
212
213
    /**
214
     * @return array enumerable values. This is set only if the column is declared to be an enumerable type.
215
     */
216 4
    public function getEnumValues(): ?array
217
    {
218 4
        return $this->enumValues;
219
    }
220
221
    /**
222
     * @return int display size of the column.
223
     */
224 223
    public function getSize(): ?int
225
    {
226 223
        return $this->size;
227
    }
228
229
    /**
230
     * @return int precision of the column data, if it is numeric.
231
     */
232 4
    public function getPrecision(): ?int
233
    {
234 4
        return $this->precision;
235
    }
236
237
    /**
238
     * @return int scale of the column data, if it is numeric.
239
     */
240 4
    public function getScale(): ?int
241
    {
242 4
        return $this->scale;
243
    }
244
245
    /**
246
     * @return bool whether this column is a primary key
247
     */
248 327
    public function isPrimaryKey(): bool
249
    {
250 327
        return $this->isPrimaryKey;
251
    }
252
253
    /**
254
     * @return bool whether this column is auto-incremental
255
     */
256 114
    public function isAutoIncrement(): bool
257
    {
258 114
        return $this->autoIncrement;
259
    }
260
261
    /**
262
     * @return bool whether this column is unsigned. This is only meaningful when {@see type} is `smallint`, `integer`
263
     * or `bigint`.
264
     */
265 40
    public function isUnsigned(): bool
266
    {
267 40
        return $this->unsigned;
268
    }
269
270
    /**
271
     * @return string comment of this column. Not all DBMS support this.
272
     */
273
    public function getComment(): ?string
274
    {
275
        return $this->comment;
276
    }
277
278 327
    public function name(string $value): void
279
    {
280 327
        $this->name = $value;
281 327
    }
282
283 327
    public function allowNull(bool $value): void
284
    {
285 327
        $this->allowNull =  $value;
286 327
    }
287
288 327
    public function type(string $value): void
289
    {
290 327
        $this->type = $value;
291 327
    }
292
293 327
    public function phpType(?string $value): void
294
    {
295 327
        $this->phpType = $value;
296 327
    }
297
298 327
    public function dbType(string $value): void
299
    {
300 327
        $this->dbType = $value;
301 327
    }
302
303 322
    public function defaultValue($value): void
304
    {
305 322
        $this->defaultValue = $value;
306 322
    }
307
308 195
    public function enumValues(?array $value): void
309
    {
310 195
        $this->enumValues = $value;
311 195
    }
312
313 312
    public function size(?int $value): void
314
    {
315 312
        $this->size = $value;
316 312
    }
317
318 312
    public function precision(?int $value): void
319
    {
320 312
        $this->precision = $value;
321 312
    }
322
323 139
    public function scale(?int $value): void
324
    {
325 139
        $this->scale = $value;
326 139
    }
327
328 327
    public function primaryKey(bool $value): void
329
    {
330 327
        $this->isPrimaryKey = $value;
331 327
    }
332
333 305
    public function autoIncrement(bool $value): void
334
    {
335 305
        $this->autoIncrement = $value;
336 305
    }
337
338 327
    public function unsigned(bool $value): void
339
    {
340 327
        $this->unsigned = $value;
341 327
    }
342
343 253
    public function comment(?string $value): void
344
    {
345 253
        $this->comment = $value;
346 253
    }
347
}
348