Passed
Push — 2.0 ( 21259a...8b13d0 )
by Sébastien
19:00
created

SchemaManager::push()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.6111
c 0
b 0
f 0
cc 5
nc 8
nop 1
crap 5
1
<?php
2
3
namespace Bdf\Prime\Schema;
4
5
use Bdf\Prime\Exception\DBALException;
6
use Bdf\Prime\Schema\Adapter\Doctrine\DoctrineTable as PrimeTableAdapter;
7
use Bdf\Prime\Schema\Transformer\Doctrine\TableTransformer;
8
use Doctrine\DBAL\Exception as DoctrineDBALException;
9
use Doctrine\DBAL\Schema\Schema as DoctrineSchema;
10
use Doctrine\DBAL\Schema\SchemaConfig;
11
use Doctrine\DBAL\Schema\SchemaDiff as DoctrineSchemaDiff;
12
use Doctrine\DBAL\Schema\TableDiff as DoctrineTableDiff;
13
use Doctrine\DBAL\Schema\Table as DoctrineTable;
14
15
/**
16
 * SchemaManager using doctrine schemas
17
 *
18
 * @extends AbstractSchemaManager<\Bdf\Prime\Connection\ConnectionInterface&\Doctrine\DBAL\Connection>
19
 * @property \Bdf\Prime\Connection\ConnectionInterface&\Doctrine\DBAL\Connection $connection protected
20
 */
21
class SchemaManager extends AbstractSchemaManager
22
{
23
    /**
24
     * Queries to execute
25
     *
26
     * @var array
27
     */
28
    private $queries = [];
29
30
31
    /**
32
     * Get the doctrine schema manager
33
     *
34
     * @return \Doctrine\DBAL\Schema\AbstractSchemaManager
35
     */
36 1081
    public function getDoctrineManager()
37
    {
38 1081
        return $this->connection->getSchemaManager();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Connection::getSchemaManager() has been deprecated: Use {@see createSchemaManager()} instead. ( Ignorable by Annotation )

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

38
        return /** @scrutinizer ignore-deprecated */ $this->connection->getSchemaManager();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
39
    }
40
41
    /**
42
     * Get the queries to execute
43
     *
44
     * @return array
45
     */
46 5
    public function toSql()
47
    {
48 5
        return $this->queries;
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54 15
    public function pending(): array
55
    {
56 15
        return $this->queries;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62 1081
    public function clear()
63
    {
64 1081
        $this->queries = [];
65
66 1081
        return $this;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 1081
    public function flush(): bool
73
    {
74 1081
        $lastResult = false;
75 1081
        $queries = $this->queries;
76
77 1081
        $this->clear();
78
79 1081
        foreach ($queries as $query) {
80 1081
            $lastResult = $this->connection->executeStatement($query);
81
        }
82
83 1078
        return (bool) $lastResult;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89 1067
    public function schema($tables = [])
90
    {
91 1067
        if (!is_array($tables)) {
92 1067
            $tables = [$tables];
93
        }
94
95 1067
        $tables = array_map(function ($table) {
96 1067
            if ($table instanceof TableInterface) {
97 1067
                return (new TableTransformer($table, $this->platform))->toDoctrine();
98
            }
99
100
            return $table;
101 1067
        }, $tables);
102
103 1067
        $config = new SchemaConfig();
104 1067
        $config->setName($this->connection->getDatabase());
105
106 1067
        return new DoctrineSchema($tables, [], $config);
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112 1
    public function loadSchema()
113
    {
114 1
        return $this->getDoctrineManager()->createSchema();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Schema\Abs...Manager::createSchema() has been deprecated: Use {@link introspectSchema()} instead. ( Ignorable by Annotation )

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

114
        return /** @scrutinizer ignore-deprecated */ $this->getDoctrineManager()->createSchema();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function hasDatabase(string $database): bool
121
    {
122
        try {
123
            $databases = $this->getDoctrineManager()->listDatabases();
124
        } catch (DoctrineDBALException $e) {
125
            /** @psalm-suppress InvalidScalarArgument */
126
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
127
        }
128
129
        return in_array(strtolower($database), array_map('strtolower', $databases));
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function getDatabases(): array
136
    {
137
        try {
138
            return $this->getDoctrineManager()->listDatabases();
139
        } catch (DoctrineDBALException $e) {
140
            /** @psalm-suppress InvalidScalarArgument */
141
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
142
        }
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function createDatabase(string $database)
149
    {
150
        try {
151
            return $this->push(
152
                $this->platform->grammar()->getCreateDatabaseSQL($database)
153
            );
154
        } catch (DoctrineDBALException $e) {
155
            /** @psalm-suppress InvalidScalarArgument */
156
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
157
        }
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163
    public function dropDatabase(string $database)
164
    {
165
        try {
166
            return $this->push(
167
                $this->platform->grammar()->getDropDatabaseSQL($database)
168
            );
169
        } catch (DoctrineDBALException $e) {
170
            /** @psalm-suppress InvalidScalarArgument */
171
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
172
        }
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178 1081
    public function has(string $tableName): bool
179
    {
180
        try {
181 1081
            return $this->getDoctrineManager()->tablesExist($tableName);
182
        } catch (DoctrineDBALException $e) {
183
            /** @psalm-suppress InvalidScalarArgument */
184
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
185
        }
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191 127
    public function load(string $name): TableInterface
192
    {
193
        try {
194 127
            $manager = $this->getDoctrineManager();
195
196 127
            $foreignKeys = [];
197
198 127
            if ($this->platform->grammar()->supportsForeignKeyConstraints()) {
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Platforms\...ForeignKeyConstraints() has been deprecated: All platforms should support foreign key constraints. ( Ignorable by Annotation )

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

198
            if (/** @scrutinizer ignore-deprecated */ $this->platform->grammar()->supportsForeignKeyConstraints()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
199 127
                $foreignKeys = $manager->listTableForeignKeys($name);
200
            }
201
202 127
            return new PrimeTableAdapter(
0 ignored issues
show
Bug Best Practice introduced by
The expression return new Bdf\Prime\Sch...n->platform()->types()) returns the type Bdf\Prime\Schema\Adapter\Doctrine\DoctrineTable which is incompatible with the return type mandated by Bdf\Prime\Schema\Manager...anagerInterface::load() of Bdf\Prime\Schema\Manager\T.

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...
203 127
                new DoctrineTable(
204 127
                    $name,
205 127
                    $manager->listTableColumns($name),
206 127
                    $manager->listTableIndexes($name),
207 127
                    [],
208 127
                    $foreignKeys
209 127
                ),
210 127
                $this->connection->platform()->types()
211 127
            );
212
        } catch (DoctrineDBALException $e) {
213
            /** @psalm-suppress InvalidScalarArgument */
214
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
215
        }
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     */
221 911
    public function drop(string $tableName)
222
    {
223
        try {
224 911
            return $this->push(
225 911
                $this->platform->grammar()->getDropTableSQL($tableName)
226 911
            );
227 61
        } catch (DoctrineDBALException $e) {
228
            /** @psalm-suppress InvalidScalarArgument */
229
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
230
        }
231
    }
232
233
    /**
234
     * {@inheritdoc}
235
     */
236 53
    public function truncate(string $tableName, bool $cascade = false)
237
    {
238
        try {
239 53
            return $this->push(
240 53
                $this->platform->grammar()->getTruncateTableSQL($tableName, $cascade)
241 53
            );
242
        } catch (DoctrineDBALException $e) {
243
            /** @psalm-suppress InvalidScalarArgument */
244
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
245
        }
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     */
251 124
    public function diff($new, $old)
252
    {
253
        /** @psalm-suppress InternalMethod */
254 124
        $comparator = new Comparator();
0 ignored issues
show
Deprecated Code introduced by
The class Bdf\Prime\Schema\Comparator has been deprecated: since 1.3 Use Prime comparators instead ( Ignorable by Annotation )

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

254
        $comparator = /** @scrutinizer ignore-deprecated */ new Comparator();
Loading history...
255 124
        $comparator->setListDropColumn($this->useDrop);
256
257 124
        return $comparator->compare(
258 124
            $this->schema($old),
259 124
            $this->schema($new)
260 124
        );
261
    }
262
263
    /**
264
     * {@inheritdoc}
265
     */
266 2
    public function rename(string $from, string $to)
267
    {
268
        /** @psalm-suppress InternalMethod */
269 2
        $diff = new DoctrineTableDiff($from);
270 2
        $diff->newName = $to;
0 ignored issues
show
Deprecated Code introduced by
The property Doctrine\DBAL\Schema\TableDiff::$newName has been deprecated: Rename tables via {@link AbstractSchemaManager::renameTable()} instead. ( Ignorable by Annotation )

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

270
        /** @scrutinizer ignore-deprecated */ $diff->newName = $to;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
271
272
        try {
273 2
            return $this->push(
274 2
                $this->platform->grammar()->getAlterTableSQL($diff)
275 2
            );
276
        } catch (DoctrineDBALException $e) {
277
            /** @psalm-suppress InvalidScalarArgument */
278
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
279
        }
280
    }
281
282
    /**
283
     * {@inheritdoc}
284
     */
285 1082
    public function push($queries)
286
    {
287 1082
        if ($queries instanceof DoctrineSchema || $queries instanceof DoctrineSchemaDiff) {
288 1067
            $queries = $queries->toSql($this->platform->grammar());
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Schema\SchemaDiff::toSql() has been deprecated: Use {@link AbstractPlatform::getAlterSchemaSQL()} instead. ( Ignorable by Annotation )

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

288
            $queries = /** @scrutinizer ignore-deprecated */ $queries->toSql($this->platform->grammar());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
289
        }
290
291 1082
        foreach ((array)$queries as $query) {
292 1082
            $this->queries[] = $query;
293
        }
294
295 1082
        if ($this->autoFlush) {
296 1081
            $this->flush();
297
        }
298
299 1080
        return $this;
300
    }
301
}
302