Passed
Pull Request — master (#13)
by Vincent
07:15
created

Resolver   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Test Coverage

Coverage 94.94%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 24
eloc 71
c 1
b 0
f 0
dl 0
loc 220
ccs 75
cts 79
cp 0.9494
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A table() 0 20 2
A schema() 0 7 2
A sequence() 0 15 2
A __construct() 0 5 1
A schemaSequence() 0 11 3
A connection() 0 3 2
A migrate() 0 10 2
A insertSequenceId() 0 13 3
A truncate() 0 3 1
A diff() 0 21 2
A drop() 0 16 4
1
<?php
2
3
namespace Bdf\Prime\Schema;
4
5
use Bdf\Prime\Connection\ConnectionInterface;
6
use Bdf\Prime\Exception\DBALException;
7
use Bdf\Prime\Exception\PrimeException;
8
use Bdf\Prime\Schema\Adapter\ConstraintTable;
9
use Bdf\Prime\Schema\Adapter\MapperInfo\MapperInfoConstraintSet;
10
use Bdf\Prime\Schema\Adapter\MapperInfo\Resolver\MapperInfoForeignKeyResolver;
11
use Bdf\Prime\Schema\Adapter\Metadata\MetadataTable;
12
use Bdf\Prime\Schema\Builder\TableBuilder;
13
use Bdf\Prime\ServiceLocator;
14
use Bdf\Prime\Mapper\Metadata;
15
use Doctrine\DBAL\Exception\TableNotFoundException;
16
17
/**
18
 * Schema resolver
19
 * 
20
 * manage update on schema
0 ignored issues
show
Coding Style introduced by
Doc comment long description must start with a capital letter
Loading history...
introduced by
Doc comment long description must end with a full stop
Loading history...
21
 * 
22
 * @todo gestion du renommage de champs dans le cas où d'autres attributs ont été changés
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
Coding Style Documentation introduced by
@todo tag is not allowed in class comment
Loading history...
23
 */
24
class Resolver implements ResolverInterface
25
{
26
    /**
27
     * @var ServiceLocator 
0 ignored issues
show
introduced by
Expected "ServiceLocator" but found "ServiceLocator " for @var tag in member variable comment
Loading history...
28
     */
29
    protected $service;
30
    
31
    /**
32
     * @var Metadata 
0 ignored issues
show
introduced by
Expected "Metadata" but found "Metadata " for @var tag in member variable comment
Loading history...
33
     */
34
    protected $metadata;
35
36
    /**
37
     * @var SchemaManagerInterface
38
     */
39
    protected $schema;
40
41
42
    /**
43
     * @param ServiceLocator $service Prime service
44
     * @param Metadata $metadata The entity metadata
45
     * @param SchemaManagerInterface|null $schema If given, force using this schema manager instead of resolving using the configured connection name
46
     */
47 592
    public function __construct(ServiceLocator $service, Metadata $metadata, SchemaManagerInterface $schema = null)
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line before function; 2 found
Loading history...
48
    {
49 592
        $this->service  = $service;
50 592
        $this->metadata = $metadata;
51 592
        $this->schema   = $schema;
52 592
    }
53
    
54
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $listDrop should have a doc-comment as per coding-style.
Loading history...
55
     * {@inheritdoc}
56
     */
57 584
    public function migrate($listDrop = true)
58
    {
59 584
        $schema = $this->schema()->useDrop($listDrop);
60 584
        $schema->add($this->table());
61
62 584
        if (($schemaSequence = $this->schemaSequence()) !== null) {
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
Coding Style introduced by
Assignments must be the first block of code on a line
Loading history...
63 306
            $schemaSequence->useDrop($listDrop);
64 306
            $schemaSequence->add($this->sequence());
65
66 306
            $this->insertSequenceId();
67
        }
68 584
    }
69
    
70
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $listDrop should have a doc-comment as per coding-style.
Loading history...
71
     * {@inheritdoc}
72
     */
73 2
    public function diff($listDrop = true)
74
    {
75 2
        $queries = $this->schema()
76
            ->simulate(function (SchemaManagerInterface $schema) use ($listDrop) {
0 ignored issues
show
Coding Style introduced by
Space found before object operator
Loading history...
introduced by
Object operator not indented correctly; expected 10 spaces but found 12
Loading history...
77 2
                $schema->useDrop($listDrop);
78 2
                $schema->add($this->table());
79 2
            })
80 2
            ->pending();
0 ignored issues
show
Coding Style introduced by
Space found before object operator
Loading history...
81
82 2
        if (($schemaSequence = $this->schemaSequence()) === null) {
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
Coding Style introduced by
Assignments must be the first block of code on a line
Loading history...
83 1
            return $queries;
84
        }
85
86
        $sequenceQueries = $schemaSequence
87
            ->simulate(function (SchemaManagerInterface $schema) use ($listDrop) {
0 ignored issues
show
Coding Style introduced by
Space found before object operator
Loading history...
introduced by
Object operator not indented correctly; expected 10 spaces but found 12
Loading history...
88 1
                $schema->useDrop($listDrop);
89 1
                $schema->add($this->sequence());
90 1
            })
91 1
            ->pending();
0 ignored issues
show
Coding Style introduced by
Space found before object operator
Loading history...
92
93 1
        return array_merge($queries, $sequenceQueries);
94
    }
95
96
    /**
97
     * Create table schema from meta
98
     *
99
     * @param bool $foreignKeys Add foreign key constraints to the schema ?
0 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for parameter type
Loading history...
100
     *
101
     * @return TableInterface
102
     * @throws PrimeException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
103
     */
104 587
    public function table($foreignKeys = false)
105
    {
106 587
        $table = new MetadataTable(
107 587
            $this->metadata,
108 587
            $this->connection()->platform()->types()
109
        );
110
111 587
        if ($foreignKeys) {
112 1
            $table = new ConstraintTable(
113 1
                $table,
114 1
                new MapperInfoConstraintSet(
115 1
                    $this->service->repository($this->metadata->entityName)->mapper()->info(),
116
                    [
117 1
                        new MapperInfoForeignKeyResolver($this->service)
0 ignored issues
show
introduced by
A comma should follow the last multiline array item. Found: )
Loading history...
118
                    ]
119
                )
120
            );
121
        }
122
123 587
        return $table;
124
    }
125
126
    /**
127
     * Create sequence schema from meta
128
     *
129
     * @return null|TableInterface
130
     * @throws PrimeException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
131
     */
132 309
    public function sequence()
133
    {
134 309
        if (!$this->metadata->isSequencePrimaryKey()) {
135 1
            return null;
136
        }
137
138 308
        $table = new TableBuilder($this->metadata->sequence['table']);
139 308
        $table->options($this->metadata->sequence['options']);
140 308
        $table->add(
141 308
            $this->metadata->sequence['column'],
142 308
            $this->connection($this->metadata->sequence['connection'])->platform()->types()->native('bigint')
143
        );
144 308
        $table->primary($this->metadata->sequence['column']);
145
146 308
        return $table->build();
147
    }
148
    
149
    /**
150
     * Insert sequence id into sequence table
151
     *
152
     * @throws PrimeException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
153
     */
154 306
    public function insertSequenceId()
155
    {
156 306
        if (!$this->metadata->isSequencePrimaryKey()) {
157
            return;
158
        }
159
        
160 306
        $connection = $this->connection($this->metadata->sequence['connection']);
161 306
        $table  = $this->metadata->sequence['table'];
0 ignored issues
show
introduced by
Equals sign not aligned with surrounding assignments; expected 1 space but found 2 spaces
Loading history...
162
        
163 306
        $nb = $connection->from($table)->count();
0 ignored issues
show
Bug introduced by
The method count() does not exist on Bdf\Prime\Query\QueryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Bdf\Prime\Query\QueryInterface. ( Ignorable by Annotation )

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

163
        $nb = $connection->from($table)->/** @scrutinizer ignore-call */ count();
Loading history...
164
        
165 306
        if ($nb == 0) {
166 306
            $connection->insert($table, [$this->metadata->sequence['column'] => 0]);
0 ignored issues
show
Bug introduced by
The method insert() does not exist on Bdf\Prime\Connection\ConnectionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Bdf\Prime\Connection\ConnectionInterface. ( Ignorable by Annotation )

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

166
            $connection->/** @scrutinizer ignore-call */ 
167
                         insert($table, [$this->metadata->sequence['column'] => 0]);
Loading history...
167
        }
168 306
    }
169
    
170
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $cascade should have a doc-comment as per coding-style.
Loading history...
171
     * {@inheritdoc}
172
     */
173 1
    public function truncate($cascade =false)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$cascade"; expected 1 but found 0
Loading history...
174
    {
175 1
        return $this->schema()->truncate($this->metadata->table, $cascade);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->schema()->...adata->table, $cascade) returns the type Bdf\Prime\Schema\SchemaManagerInterface which is incompatible with the return type mandated by Bdf\Prime\Schema\ResolverInterface::truncate() of boolean.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
176
    }
177
    
178
    /**
179
     * {@inheritdoc}
180
     */
0 ignored issues
show
Coding Style Documentation introduced by
Missing @throws tag in function comment
Loading history...
181 560
    public function drop()
182
    {
183
        try {
184 560
            $this->schema()->drop($this->metadata->table);
185
186 556
            if (($schemaSequence = $this->schemaSequence()) !== null) {
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
Coding Style introduced by
Assignments must be the first block of code on a line
Loading history...
187 298
                $schemaSequence->drop($this->metadata->sequence['table']);
188
            }
189
            
190 556
            return true;
191 25
        } catch (DBALException $e) {
192 25
            if ($e->getPrevious() instanceof TableNotFoundException) {
193 25
                return false;
194
            }
195
196
            throw $e;
197
        }
198
    }
199
200
    /**
201
     * Get the schema builder
202
     * 
203
     * @return SchemaManagerInterface
204
     * @throws PrimeException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
205
     */
206 588
    protected function schema()
207
    {
208 588
        if ($this->schema !== null) {
209
            return $this->schema;
210
        }
211
212 588
        return $this->connection()->schema();
213
    }
214
215
    /**
216
     * Get the schema builder for sequence
217
     *
218
     * @return SchemaManagerInterface
219
     * @throws PrimeException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
220
     */
221 586
    protected function schemaSequence()
222
    {
223 586
        if (!$this->metadata->isSequencePrimaryKey()) {
224 578
            return null;
225
        }
226
227 307
        if ($this->schema !== null) {
228
            return $this->schema;
229
        }
230
231 307
        return $this->connection($this->metadata->sequence['connection'])->schema();
232
    }
233
234
    /**
235
     * Get the connection
236
     * 
237
     * @param string $profile
238
     *
239
     * @return ConnectionInterface
240
     */
241 591
    protected function connection($profile = null)
242
    {
243 591
        return $this->service->connection($profile ?: $this->metadata->connection);
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
244
    }
245
}
246