Completed
Pull Request — 4.x (#12)
by Kit Loong
04:42
created

SchemaGenerator::getTables()   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 1
Bugs 0 Features 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 1
b 0
f 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: liow.kitloong
5
 */
6
7
namespace KitLoong\MigrationsGenerator\Generators;
8
9
use Doctrine\DBAL\Schema\Table;
10
use Doctrine\DBAL\Types\Type;
11
use Illuminate\Support\Collection;
12
use KitLoong\MigrationsGenerator\MigrationsGeneratorSetting;
13
use KitLoong\MigrationsGenerator\Types\DoubleType;
14
use KitLoong\MigrationsGenerator\Types\EnumType;
15
use KitLoong\MigrationsGenerator\Types\GeographyType;
16
use KitLoong\MigrationsGenerator\Types\GeomCollectionType;
17
use KitLoong\MigrationsGenerator\Types\GeometryCollectionType;
18
use KitLoong\MigrationsGenerator\Types\GeometryType;
19
use KitLoong\MigrationsGenerator\Types\IpAddressType;
20
use KitLoong\MigrationsGenerator\Types\JsonbType;
21
use KitLoong\MigrationsGenerator\Types\LineStringType;
22
use KitLoong\MigrationsGenerator\Types\LongTextType;
23
use KitLoong\MigrationsGenerator\Types\MacAddressType;
24
use KitLoong\MigrationsGenerator\Types\MediumIntegerType;
25
use KitLoong\MigrationsGenerator\Types\MediumTextType;
26
use KitLoong\MigrationsGenerator\Types\MultiLineStringType;
27
use KitLoong\MigrationsGenerator\Types\MultiPointType;
28
use KitLoong\MigrationsGenerator\Types\MultiPolygonType;
29
use KitLoong\MigrationsGenerator\Types\PointType;
30
use KitLoong\MigrationsGenerator\Types\PolygonType;
31
use KitLoong\MigrationsGenerator\Types\SetType;
32
use KitLoong\MigrationsGenerator\Types\TimestampType;
33
use KitLoong\MigrationsGenerator\Types\TimestampTzType;
34
use KitLoong\MigrationsGenerator\Types\TimeTzType;
35
use KitLoong\MigrationsGenerator\Types\TinyIntegerType;
36
use KitLoong\MigrationsGenerator\Types\UUIDType;
37
use KitLoong\MigrationsGenerator\Types\YearType;
38
39
class SchemaGenerator
40
{
41
    /**
42
     * @var FieldGenerator
43
     */
44
    private $fieldGenerator;
45
46
    /**
47
     * @var ForeignKeyGenerator
48
     */
49
    private $foreignKeyGenerator;
50
51
    private $indexGenerator;
52
53
    /**
54
     * Custom doctrine type
55
     * ['class', 'name', 'type']
56
     * @see registerCustomDoctrineType()
57
     *
58
     * @var array
59
     */
60
    private static $customDoctrineTypes = [
61
        [DoubleType::class, 'double', 'double'],
62
        [EnumType::class, 'enum', 'enum'],
63
        [GeometryType::class, 'geometry', 'geometry'],
64
        [GeomCollectionType::class, 'geomcollection', 'geomcollection'],
65
        [GeometryCollectionType::class, 'geometrycollection', 'geometrycollection'],
66
        [LineStringType::class, 'linestring', 'linestring'],
67
        [LongTextType::class, 'longtext', 'longtext'],
68
        [MediumIntegerType::class, 'mediumint', 'mediumint'],
69
        [MediumTextType::class, 'mediumtext', 'mediumtext'],
70
        [MultiLineStringType::class, 'multilinestring', 'multilinestring'],
71
        [MultiPointType::class, 'multipoint', 'multipoint'],
72
        [MultiPolygonType::class, 'multipolygon', 'multipolygon'],
73
        [PointType::class, 'point', 'point'],
74
        [PolygonType::class, 'polygon', 'polygon'],
75
        [SetType::class, 'set', 'set'],
76
        [TimestampType::class, 'timestamp', 'timestamp'],
77
        [TinyIntegerType::class, 'tinyint', 'tinyint'],
78
        [UUIDType::class, 'uuid', 'uuid'],
79
        [YearType::class, 'year', 'year'],
80
81
        // Postgres types
82
        [GeographyType::class, 'geography', 'geography'],
83
        [IpAddressType::class, 'ipaddress', 'inet'],
84
        [JsonbType::class, 'jsonb', 'jsonb'],
85
        [MacAddressType::class, 'macaddress', 'macaddr'],
86
        [TimeTzType::class, 'timetz', 'timetz'],
87
        [TimestampTzType::class, 'timestamptz', 'timestamptz'],
88
    ];
89
90
    /**
91
     * @var \Doctrine\DBAL\Schema\AbstractSchemaManager
92
     */
93
    protected $schema;
94
95 24
    public function __construct(
96
        FieldGenerator $fieldGenerator,
97
        IndexGenerator $indexGenerator,
98
        ForeignKeyGenerator $foreignKeyGenerator
99
    ) {
100 24
        $this->fieldGenerator = $fieldGenerator;
101 24
        $this->indexGenerator = $indexGenerator;
102 24
        $this->foreignKeyGenerator = $foreignKeyGenerator;
103 24
    }
104
105
    /**
106
     * @throws \Doctrine\DBAL\DBALException
107
     */
108 3
    public function initialize()
109
    {
110 3
        $setting = app(MigrationsGeneratorSetting::class);
111
112 3
        foreach (self::$customDoctrineTypes as $doctrineType) {
113 3
            $this->registerCustomDoctrineType(...$doctrineType);
0 ignored issues
show
Bug introduced by
The call to KitLoong\MigrationsGener...terCustomDoctrineType() has too few arguments starting with name. ( Ignorable by Annotation )

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

113
            $this->/** @scrutinizer ignore-call */ 
114
                   registerCustomDoctrineType(...$doctrineType);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
114
        }
115
116 3
        $this->addNewDoctrineType('bit', 'boolean');
117 3
        $this->addNewDoctrineType('json', 'json');
118
119 3
        switch ($setting->getPlatform()) {
120 3
            case Platform::POSTGRESQL:
121 3
                $this->addNewDoctrineType('_text', 'text');
122 3
                $this->addNewDoctrineType('_int4', 'integer');
123 3
                $this->addNewDoctrineType('_numeric', 'float');
124 3
                $this->addNewDoctrineType('cidr', 'string');
125 3
                break;
126
            default:
127
        }
128
129 3
        $this->schema = $setting->getConnection()->getDoctrineConnection()->getSchemaManager();
130 3
    }
131
132
    /**
133
     * @return string[]
134
     */
135 3
    public function getTables(): array
136
    {
137 3
        return $this->schema->listTableNames();
138
    }
139
140 3
    public function getTable(string $tableName): Table
141
    {
142 3
        return $this->schema->listTableDetails($tableName);
143
    }
144
145
    /**
146
     * @param  Table  $table
147
     * @return array|\Illuminate\Support\Collection[]
148
     * [
149
     *  'single' => Collection of single column indexes, with column name as key
150
     *  'multi' => Collection of multi columns indexes
151
     * ]
152
     */
153 3
    public function getIndexes(Table $table): array
154
    {
155 3
        return $this->indexGenerator->generate(
156 3
            $table,
157 3
            app(MigrationsGeneratorSetting::class)->isIgnoreIndexNames()
158
        );
159
    }
160
161 3
    public function getFields(Table $table, Collection $singleColIndexes): array
162
    {
163 3
        return $this->fieldGenerator->generate($table, $singleColIndexes);
164
    }
165
166 3
    public function getForeignKeyConstraints(string $table): array
167
    {
168 3
        return $this->foreignKeyGenerator->generate(
169 3
            $table,
170 3
            $this->schema,
171 3
            app(MigrationsGeneratorSetting::class)->isIgnoreForeignKeyNames()
172
        );
173
    }
174
175
    /**
176
     * Register custom doctrineType
177
     * Will override if exists
178
     *
179
     * @param  string  $class
180
     * @param  string  $name
181
     * @param  string  $type
182
     * @throws \Doctrine\DBAL\DBALException
183
     */
184 6
    protected function registerCustomDoctrineType(string $class, string $name, string $type): void
185
    {
186 6
        if (!Type::hasType($name)) {
187 3
            Type::addType($name, $class);
188
        } else {
189 3
            Type::overrideType($name, $class);
190
        }
191
192 6
        $this->addNewDoctrineType($type, $name);
193 6
    }
194
195
    /**
196
     * @param  string  $type
197
     * @param  string  $name
198
     * @throws \Doctrine\DBAL\DBALException
199
     */
200 9
    protected function addNewDoctrineType(string $type, string $name): void
201
    {
202 9
        app(MigrationsGeneratorSetting::class)->getConnection()
203 9
            ->getDoctrineConnection()
204 9
            ->getDatabasePlatform()
205 9
            ->registerDoctrineTypeMapping($type, $name);
206 9
    }
207
}
208