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

ColumnSchema::size()   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 1
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 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