Passed
Push — feature/collation ( e2b273...7d249b )
by Kit Loong
64:57
created

DatetimeField::getLength()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 12
rs 9.9666
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: liow.kitloong
5
 * Date: 2020/03/29
6
 */
7
8
namespace KitLoong\MigrationsGenerator\Generators;
9
10
use Doctrine\DBAL\Schema\Column;
11
use KitLoong\MigrationsGenerator\MigrationMethod\ColumnModifier;
12
use KitLoong\MigrationsGenerator\MigrationMethod\ColumnName;
13
use KitLoong\MigrationsGenerator\MigrationMethod\ColumnType;
14
use KitLoong\MigrationsGenerator\MigrationsGeneratorSetting;
15
use KitLoong\MigrationsGenerator\Repositories\MySQLRepository;
16
use KitLoong\MigrationsGenerator\Repositories\PgSQLRepository;
17
use KitLoong\MigrationsGenerator\Support\Regex;
18
use KitLoong\MigrationsGenerator\Types\DBALTypes;
19
20
class DatetimeField
21
{
22
    private $decorator;
23
    private $mySQLRepository;
24
    private $pgSQLRepository;
25
    private $regex;
26
27
    public function __construct(
28
        Decorator $decorator,
29
        MySQLRepository $mySQLRepository,
30
        PgSQLRepository $pgSQLRepository,
31
        Regex $regex
32
    ) {
33
        $this->decorator = $decorator;
34
        $this->mySQLRepository = $mySQLRepository;
35
        $this->pgSQLRepository = $pgSQLRepository;
36
        $this->regex = $regex;
37
    }
38
39
    public function makeField(string $table, array $field, Column $column, bool $useTimestamps): array
40
    {
41
        if ($useTimestamps) {
42
            if ($field['field'] === ColumnName::CREATED_AT) {
43
                return [];
44
            } elseif ($field['field'] === ColumnName::UPDATED_AT) {
45
                $field['type'] = ColumnType::TIMESTAMPS;
46
                $field['field'] = null;
47
            }
48
        }
49
50
        if ($field['field'] === ColumnName::DELETED_AT && !$column->getNotnull()) {
51
            $field['type'] = ColumnType::SOFT_DELETES;
52
            $field['field'] = null;
53
        }
54
55
        if (isset(FieldGenerator::$fieldTypeMap[$field['type']])) {
56
            $field['type'] = FieldGenerator::$fieldTypeMap[$field['type']];
57
        }
58
59
        $length = $this->getLength($table, $column);
60
        if ($length !== null && $length > 0) {
61
            if ($field['type'] === ColumnType::SOFT_DELETES) {
62
                $field['field'] = ColumnName::DELETED_AT;
63
            }
64
            $field['args'][] = $length;
65
        }
66
67
        if (app(MigrationsGeneratorSetting::class)->getPlatform() === Platform::MYSQL) {
68
            if ($column->getType()->getName() === DBALTypes::TIMESTAMP) {
69
                if ($this->mySQLRepository->useOnUpdateCurrentTimestamp($table, $column->getName())) {
70
                    $field['decorators'][] = ColumnModifier::USE_CURRENT_ON_UPDATE;
71
                }
72
            }
73
        }
74
75
        return $field;
76
    }
77
78
    public function makeDefault(Column $column): string
79
    {
80
        if (in_array($column->getDefault(), ['CURRENT_TIMESTAMP'], true)) {
81
            return ColumnModifier::USE_CURRENT;
82
        } else {
83
            $default = $this->decorator->columnDefaultToString($column->getDefault());
0 ignored issues
show
Bug introduced by
It seems like $column->getDefault() can also be of type null; however, parameter $args of KitLoong\MigrationsGener...columnDefaultToString() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

83
            $default = $this->decorator->columnDefaultToString(/** @scrutinizer ignore-type */ $column->getDefault());
Loading history...
84
            return $this->decorator->decorate(ColumnModifier::DEFAULT, [$default]);
85
        }
86
    }
87
88
    /**
89
     * @param  Column[]  $columns
90
     * @return bool
91
     */
92
    public function isUseTimestamps($columns): bool
93
    {
94
        /** @var Column[] $timestampsColumns */
95
        $timestampsColumns = [];
96
        foreach ($columns as $column) {
97
            if ($column->getName() === ColumnName::CREATED_AT || $column->getName() === ColumnName::UPDATED_AT) {
98
                $timestampsColumns[] = $column;
99
            }
100
        }
101
102
        $useTimestamps = false;
103
104
        if (count($timestampsColumns) === 2) {
105
            $useTimestamps = true;
106
            foreach ($timestampsColumns as $timestamp) {
107
                if ($timestamp->getNotnull() || $timestamp->getDefault() !== null) {
108
                    $useTimestamps = false;
109
                }
110
            }
111
        }
112
        return $useTimestamps;
113
    }
114
115
    private function getLength(string $table, Column $column): ?int
116
    {
117
        if (app(MigrationsGeneratorSetting::class)->getPlatform() === Platform::POSTGRESQL) {
118
            $rawType = ($this->pgSQLRepository->getTypeByColumnName($table, $column->getName()));
119
            $length = $this->regex->getTextBetween($rawType);
0 ignored issues
show
Bug introduced by
It seems like $rawType can also be of type null; however, parameter $text of KitLoong\MigrationsGener...Regex::getTextBetween() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

119
            $length = $this->regex->getTextBetween(/** @scrutinizer ignore-type */ $rawType);
Loading history...
120
            if ($length !== null) {
121
                return (int) $length;
122
            } else {
123
                return null;
124
            }
125
        } else {
126
            return $column->getLength();
127
        }
128
    }
129
}
130