Passed
Pull Request — master (#722)
by Wilmer
02:29
created

AbstractColumnSchema   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 259
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 50
eloc 82
dl 0
loc 259
rs 8.4
c 0
b 0
f 0

35 Methods

Rating   Name   Duplication   Size   Complexity  
A type() 0 3 1
A size() 0 3 1
A primaryKey() 0 3 1
A phpType() 0 3 1
A scale() 0 3 1
A phpTypecast() 0 3 1
A unsigned() 0 3 1
A precision() 0 3 1
A getScale() 0 3 1
A isAllowNull() 0 3 1
A enumValues() 0 3 1
A computed() 0 3 1
C typecast() 0 57 16
A getType() 0 3 1
A getPhpType() 0 3 1
A isAutoIncrement() 0 3 1
A dbTypecast() 0 7 1
A dbType() 0 3 1
A getComment() 0 3 1
A isUnsigned() 0 3 1
A getDefaultValue() 0 3 1
A getDbType() 0 3 1
A defaultValue() 0 3 1
A getEnumValues() 0 3 1
A __construct() 0 3 1
A extra() 0 3 1
A getExtra() 0 3 1
A isComputed() 0 3 1
A getPrecision() 0 3 1
A autoIncrement() 0 3 1
A getName() 0 3 1
A comment() 0 3 1
A getSize() 0 3 1
A allowNull() 0 3 1
A isPrimaryKey() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like AbstractColumnSchema often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AbstractColumnSchema, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Schema;
6
7
use Yiisoft\Db\Command\DataType;
8
use Yiisoft\Db\Expression\ExpressionInterface;
9
use Yiisoft\Db\Helper\DbStringHelper;
10
11
use function gettype;
12
use function in_array;
13
use function is_bool;
14
use function is_float;
15
use function is_resource;
16
17
/**
18
 * Represents the metadata of a column in a database table.
19
 *
20
 * It provides information about the column's name, type, size, precision, and other details.
21
 *
22
 * The `ColumnSchema` class is used to store and retrieve metadata about a column in a database table.
23
 *
24
 * It's typically used in conjunction with the TableSchema class, which represents the metadata of a database table as a
25
 * whole.
26
 *
27
 * Here is an example of how to use the `ColumnSchema` class:
28
 *
29
 * ```php
30
 * use Yiisoft\Db\Schema\ColumnSchema;
31
 *
32
 * $column = new ColumnSchema();
33
 * $column->name('id');
34
 * $column->allowNull(false);
35
 * $column->dbType('int(11)');
36
 * $column->phpType('integer');
37
 * $column->type('integer');
38
 * $column->defaultValue(0);
39
 * $column->autoIncrement(true);
40
 * $column->primaryKey(true);
41
 * ``
42
 */
43
abstract class AbstractColumnSchema implements ColumnSchemaInterface
44
{
45
    public function __construct(string $name)
46
    {
47
        $this->name = $name;
48
    }
49
50
    private bool $allowNull = false;
51
    private bool $autoIncrement = false;
52
    private string|null $comment = null;
53
    private bool $computed = false;
54
    private string|null $dbType = null;
55
    private mixed $defaultValue = null;
56
    private array|null $enumValues = null;
57
    private string|null $extra = null;
58
    private bool $isPrimaryKey = false;
59
    private string $name;
60
    private string|null $phpType = null;
61
    private int|null $precision = null;
62
    private int|null $scale = null;
63
    private int|null $size = null;
64
    private string $type = '';
65
    private bool $unsigned = false;
66
67
    public function allowNull(bool $value): void
68
    {
69
        $this->allowNull = $value;
70
    }
71
72
    public function autoIncrement(bool $value): void
73
    {
74
        $this->autoIncrement = $value;
75
    }
76
77
    public function comment(string|null $value): void
78
    {
79
        $this->comment = $value;
80
    }
81
82
    public function computed(bool $value): void
83
    {
84
        $this->computed = $value;
85
    }
86
87
    public function dbType(string|null $value): void
88
    {
89
        $this->dbType = $value;
90
    }
91
92
    public function dbTypecast(mixed $value): mixed
93
    {
94
        /**
95
         * The default implementation does the same as casting for PHP, but it should be possible to override this with
96
         * annotation of an explicit PDO type.
97
         */
98
        return $this->typecast($value);
99
    }
100
101
    public function defaultValue(mixed $value): void
102
    {
103
        $this->defaultValue = $value;
104
    }
105
106
    public function enumValues(array|null $value): void
107
    {
108
        $this->enumValues = $value;
109
    }
110
111
    public function extra(string|null $value): void
112
    {
113
        $this->extra = $value;
114
    }
115
116
    public function getComment(): string|null
117
    {
118
        return $this->comment;
119
    }
120
121
    public function getDbType(): string|null
122
    {
123
        return $this->dbType;
124
    }
125
126
    public function getDefaultValue(): mixed
127
    {
128
        return $this->defaultValue;
129
    }
130
131
    public function getEnumValues(): array|null
132
    {
133
        return $this->enumValues;
134
    }
135
136
    public function getExtra(): string|null
137
    {
138
        return $this->extra;
139
    }
140
141
    public function getName(): string
142
    {
143
        return $this->name;
144
    }
145
146
    public function getPrecision(): int|null
147
    {
148
        return $this->precision;
149
    }
150
151
    public function getPhpType(): string|null
152
    {
153
        return $this->phpType;
154
    }
155
156
    public function getScale(): int|null
157
    {
158
        return $this->scale;
159
    }
160
161
    public function getSize(): int|null
162
    {
163
        return $this->size;
164
    }
165
166
    public function getType(): string
167
    {
168
        return $this->type;
169
    }
170
171
    public function isAllowNull(): bool
172
    {
173
        return $this->allowNull;
174
    }
175
176
    public function isAutoIncrement(): bool
177
    {
178
        return $this->autoIncrement;
179
    }
180
181
    public function isComputed(): bool
182
    {
183
        return $this->computed;
184
    }
185
186
    public function isPrimaryKey(): bool
187
    {
188
        return $this->isPrimaryKey;
189
    }
190
191
    public function isUnsigned(): bool
192
    {
193
        return $this->unsigned;
194
    }
195
196
    public function phpType(string|null $value): void
197
    {
198
        $this->phpType = $value;
199
    }
200
201
    public function phpTypecast(mixed $value): mixed
202
    {
203
        return $this->typecast($value);
204
    }
205
206
    public function precision(int|null $value): void
207
    {
208
        $this->precision = $value;
209
    }
210
211
    public function primaryKey(bool $value): void
212
    {
213
        $this->isPrimaryKey = $value;
214
    }
215
216
    public function scale(int|null $value): void
217
    {
218
        $this->scale = $value;
219
    }
220
221
    public function size(int|null $value): void
222
    {
223
        $this->size = $value;
224
    }
225
226
    public function type(string $value): void
227
    {
228
        $this->type = $value;
229
    }
230
231
    public function unsigned(bool $value): void
232
    {
233
        $this->unsigned = $value;
234
    }
235
236
    /**
237
     * Converts the input value according to {@see phpType} after retrieval from the database.
238
     *
239
     * If the value is null or an {@see Expression}, it won't be converted.
240
     *
241
     * @param mixed $value The value to be converted.
242
     *
243
     * @return mixed The converted value.
244
     */
245
    protected function typecast(mixed $value): mixed
246
    {
247
        if (
248
            $value === ''
249
            && !in_array(
250
                $this->type,
251
                [
252
                    SchemaInterface::TYPE_TEXT,
253
                    SchemaInterface::TYPE_STRING,
254
                    SchemaInterface::TYPE_BINARY,
255
                    SchemaInterface::TYPE_CHAR,
256
                ],
257
                true
258
            )
259
        ) {
260
            return null;
261
        }
262
263
        if (
264
            $value === null
265
            || $value instanceof ExpressionInterface
266
            || gettype($value) === $this->phpType
267
        ) {
268
            return $value;
269
        }
270
271
        switch ($this->phpType) {
272
            case SchemaInterface::PHP_TYPE_RESOURCE:
273
            case SchemaInterface::PHP_TYPE_STRING:
274
                if (is_resource($value)) {
275
                    return $value;
276
                }
277
278
                if (is_float($value)) {
279
                    /** ensure type cast always has . as decimal separator in all locales */
280
                    return DbStringHelper::normalizeFloat($value);
281
                }
282
283
                if (is_bool($value)) {
284
                    return $value ? '1' : '0';
285
                }
286
287
                return (string) $value;
288
            case SchemaInterface::PHP_TYPE_INTEGER:
289
                return (int) $value;
290
            case SchemaInterface::PHP_TYPE_BOOLEAN:
291
                /**
292
                 * Treating a 0-bit value as false too.
293
                 *
294
                 * @link https://github.com/yiisoft/yii2/issues/9006
295
                 */
296
                return (bool) $value && $value !== "\0";
297
            case SchemaInterface::PHP_TYPE_DOUBLE:
298
                return (float) $value;
299
        }
300
301
        return $value;
302
    }
303
}
304