FieldGenerator   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 82
c 3
b 0
f 0
dl 0
loc 161
ccs 63
cts 63
cp 1
rs 10
wmc 26

3 Methods

Rating   Name   Duplication   Size   Complexity  
B generate() 0 56 9
A __construct() 0 28 1
C makeLaravelFieldTypeMethod() 0 32 16
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: liow.kitloong
5
 * Date: 2020/03/28
6
 */
7
8
namespace KitLoong\MigrationsGenerator\Generators;
9
10
use Doctrine\DBAL\Schema\Column;
11
use Illuminate\Support\Collection;
12
use KitLoong\MigrationsGenerator\Generators\Modifier\CommentModifier;
13
use KitLoong\MigrationsGenerator\Generators\Modifier\DefaultModifier;
14
use KitLoong\MigrationsGenerator\Generators\Modifier\IndexModifier;
15
use KitLoong\MigrationsGenerator\Generators\Modifier\NullableModifier;
16
use KitLoong\MigrationsGenerator\MigrationMethod\ColumnModifier;
17
use KitLoong\MigrationsGenerator\MigrationMethod\ColumnType;
18
use KitLoong\MigrationsGenerator\Types\DBALTypes;
19
20
class FieldGenerator
21
{
22
    private $decorator;
23
    private $integerField;
24
    private $datetimeField;
25
    private $decimalField;
26
    private $geometryField;
27
    private $stringField;
28
    private $enumField;
29
    private $setField;
30
    private $otherField;
31
    private $nullableModifier;
32
    private $defaultModifier;
33
    private $indexModifier;
34
    private $commentModifier;
35
36 54
    public function __construct(
37
        Decorator $decorator,
38
        IntegerField $integerField,
39
        DatetimeField $datetimeField,
40
        DecimalField $decimalField,
41
        GeometryField $geometryField,
42
        StringField $stringField,
43
        EnumField $enumField,
44
        SetField $setField,
45
        OtherField $otherField,
46
        NullableModifier $nullableModifier,
47
        DefaultModifier $defaultModifier,
48
        IndexModifier $indexModifier,
49
        CommentModifier $commentModifier
50
    ) {
51 54
        $this->decorator = $decorator;
52 54
        $this->integerField = $integerField;
53 54
        $this->datetimeField = $datetimeField;
54 54
        $this->decimalField = $decimalField;
55 54
        $this->geometryField = $geometryField;
56 54
        $this->stringField = $stringField;
57 54
        $this->enumField = $enumField;
58 54
        $this->setField = $setField;
59 54
        $this->otherField = $otherField;
60 54
        $this->nullableModifier = $nullableModifier;
61 54
        $this->defaultModifier = $defaultModifier;
62 54
        $this->indexModifier = $indexModifier;
63 54
        $this->commentModifier = $commentModifier;
64 54
    }
65
66
    /**
67
     * Convert dbal types to Laravel Migration Types
68
     * @var array
69
     */
70
    public static $fieldTypeMap = [
71
        DBALTypes::SMALLINT => ColumnType::SMALL_INTEGER,
72
        DBALTypes::BIGINT => ColumnType::BIG_INTEGER,
73
        DBALTypes::DATETIME_MUTABLE => ColumnType::DATETIME,
74
        DBALTypes::BLOB => ColumnType::BINARY,
75
    ];
76
77
    /**
78
     * @param  string  $table
79
     * @param  Column[]  $columns
80
     * @param  Collection  $indexes
81
     * @return array
82
     */
83 33
    public function generate(string $table, $columns, Collection $indexes): array
84
    {
85 33
        if (count($columns) === 0) {
86 3
            return [];
87
        }
88
89 30
        $useTimestamps = $this->datetimeField->isUseTimestamps($columns);
90
91 30
        $fields = [];
92
93 30
        foreach ($columns as $column) {
94
            /**
95
             * return [
96
             *  field : Field name,
97
             *  type  : Migration type method, eg: increments, string
98
             *  args  : Migration type arguments,
99
             *      eg: decimal('amount', 8, 2) => decimal('amount', args[0], args[1])
100
             *  decorators
101
             * ]
102
             */
103 30
            $dbalType = $column->getType()->getName();
104
105
            $field = [
106 30
                'field' => $this->decorator->addSlash($column->getName()),
107 30
                'type' => $dbalType,
108
                'args' => [],
109
                'decorators' => []
110
            ];
111
112 30
            $field = $this->makeLaravelFieldTypeMethod($table, $field, $column, $indexes, $useTimestamps);
113
114 30
            if (empty($field)) {
115 3
                continue;
116
            }
117
118 27
            if (!$column->getNotnull()) {
119 3
                if ($this->nullableModifier->shouldAddNullableModifier($field['type'])) {
120 3
                    $field['decorators'][] = ColumnModifier::NULLABLE;
121
                }
122
            }
123
124 27
            if ($column->getDefault() !== null) {
125 3
                $field['decorators'][] = $this->defaultModifier->generate($dbalType, $column);
126
            }
127
128 27
            if ($indexes->has($field['field'])) {
129 3
                $field['decorators'][] = $this->indexModifier->generate($indexes->get($field['field']));
130
            }
131
132 27
            if ($column->getComment() !== null) {
133 3
                $field['decorators'][] = $this->commentModifier->generate($column->getComment());
134
            }
135
136 27
            $fields[] = $field;
137
        }
138 30
        return $fields;
139
    }
140
141
    /**
142
     * @param  string  $tableName
143
     * @param  array  $field
144
     * @param  Column  $column
145
     * @param  Collection  $indexes
146
     * @param  bool  $useTimestamps
147
     * @return array
148
     */
149 30
    private function makeLaravelFieldTypeMethod(
150
        string $tableName,
151
        array $field,
152
        Column $column,
153
        Collection $indexes,
154
        bool $useTimestamps
155
    ): array {
156 30
        switch ($field['type']) {
157 30
            case DBALTypes::INTEGER:
158 24
            case DBALTypes::BIGINT:
159 24
            case DBALTypes::MEDIUMINT:
160 24
            case DBALTypes::SMALLINT:
161 24
            case DBALTypes::TINYINT:
162 9
                return $this->integerField->makeField($tableName, $field, $column, $indexes);
163 21
            case DBALTypes::DATETIME_MUTABLE:
164 21
            case DBALTypes::TIMESTAMP:
165 21
            case DBALTypes::TIME_MUTABLE:
166 3
                return $this->datetimeField->makeField($field, $column, $useTimestamps);
167 18
            case DBALTypes::DECIMAL:
168 18
            case DBALTypes::FLOAT:
169 18
            case DBALTypes::DOUBLE:
170 3
                return $this->decimalField->makeField($field, $column);
171 15
            case DBALTypes::ENUM:
172 3
                return $this->enumField->makeField($tableName, $field);
173 12
            case DBALTypes::GEOMETRY:
174 3
                return $this->geometryField->makeField($tableName, $field);
175 9
            case DBALTypes::SET:
176 3
                return $this->setField->makeField($tableName, $field);
177 6
            case DBALTypes::STRING:
178 3
                return $this->stringField->makeField($field, $column);
179
            default:
180 3
                return $this->otherField->makeField($field);
181
        }
182
    }
183
}
184