Issues (590)

src/Schema/AbstractSchemaManager.php (5 issues)

1
<?php
2
3
namespace Bdf\Prime\Schema;
4
5
use BadMethodCallException;
6
use Bdf\Prime\Connection\ConnectionInterface;
7
use Bdf\Prime\Connection\TransactionManagerInterface;
8
use Bdf\Prime\Exception\DBALException;
9
use Bdf\Prime\Exception\PrimeException;
10
use Bdf\Prime\Platform\PlatformInterface;
11
use Bdf\Prime\Schema\Builder\TableBuilder;
12
use Bdf\Prime\Schema\Builder\TypesHelperTableBuilder;
13
use Doctrine\DBAL\Exception as DoctrineDBALException;
14
15
/**
16
 * Class AbstractSchemaManager
17
 *
18
 * @template C as ConnectionInterface
19
 * @implements SchemaManagerInterface<C>
20
 */
21
abstract class AbstractSchemaManager implements SchemaManagerInterface
22
{
23
    /**
24
     * The database connection instance.
25
     *
26
     * @var C
27
     */
28
    protected $connection;
29
30
    /**
31
     * The connection platform.
32
     *
33
     * @var PlatformInterface
34
     */
35
    protected $platform;
36
37
    /**
38
     * The use drop flag. Allows builder to use drop command on diff
39
     *
40
     * @var bool
41
     */
42
    protected $useDrop = true;
43
44
    /**
45
     * The auto flush flag. Allows builder execute query
46
     *
47
     * @var bool
48
     * @internal
49
     */
50
    protected $autoFlush = true;
51
52
53
    /**
54
     * Create a new schema builder.
55
     *
56
     * @param C $connection
57
     * @throws PrimeException
58
     */
59 402
    public function __construct(ConnectionInterface $connection)
60
    {
61 402
        $this->connection = $connection;
0 ignored issues
show
Documentation Bug introduced by
It seems like $connection of type Bdf\Prime\Connection\ConnectionInterface is incompatible with the declared type Bdf\Prime\Schema\C of property $connection.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
62 402
        $this->platform = $connection->platform();
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 1
    public function getConnection(): ConnectionInterface
69
    {
70 1
        return $this->connection;
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 863
    public function useDrop(bool $flag = true)
77
    {
78 863
        $this->useDrop = $flag;
79
80 863
        return $this;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86 1
    public function getUseDrop(): bool
87
    {
88 1
        return $this->useDrop;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94 216
    public function table(string $tableName, callable $callback)
95
    {
96 216
        $table = new TypesHelperTableBuilder(
97 216
            new TableBuilder($tableName),
98 216
            $this->platform->types()
99 216
        );
100
101 216
        $callback($table);
102
103 216
        return $this->add($table->build());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->add($table->build()) returns the type Bdf\Prime\Schema\Manager\QueryManagerInterface which is incompatible with the return type mandated by Bdf\Prime\Schema\Manager...nagerInterface::table() of Bdf\Prime\Schema\Manager\TableManagerInterface.

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...
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     * @deprecated
109
     */
110
    public function hasTable($tableName)
111
    {
112
        return $this->has($tableName);
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    public function loadTable($tableName)
119
    {
120
        return $this->load($tableName);
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 1071
    public function add($structure)
127
    {
128 1071
        if ($this->has($structure->name())) {
129 122
            return $this->push(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->push($this...d($structure->name()))) returns the type Bdf\Prime\Schema\Manager\QueryManagerInterface which is incompatible with the return type mandated by Bdf\Prime\Schema\Manager...ManagerInterface::add() of Bdf\Prime\Schema\Manager\TableManagerInterface.

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...
130 122
                $this->diff($structure, $this->load($structure->name()))
131 122
            );
132
        }
133
134 1030
        return $this->push($this->schema($structure));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->push($this->schema($structure)) returns the type Bdf\Prime\Schema\Manager\QueryManagerInterface which is incompatible with the return type mandated by Bdf\Prime\Schema\Manager...ManagerInterface::add() of Bdf\Prime\Schema\Manager\TableManagerInterface.

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...
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 2
    public function change(string $tableName, callable $callback)
141
    {
142 2
        $table = $this->load($tableName);
143 2
        $builder = TableBuilder::fromTable($table);
144
145 2
        $callback(
146 2
            new TypesHelperTableBuilder(
147 2
                $builder,
148 2
                $this->platform->types()
149 2
            )
150 2
        );
151
152 2
        return $this->push(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->push($this...lder->build(), $table)) returns the type Bdf\Prime\Schema\Manager\QueryManagerInterface which is incompatible with the return type mandated by Bdf\Prime\Schema\Manager...agerInterface::change() of Bdf\Prime\Schema\Manager\TableManagerInterface.

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...
153 2
            $this->diff($builder->build(), $table)
154 2
        );
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 19
    public function simulate(callable $operations = null)
161
    {
162 19
        $newSchema = clone $this;
163 19
        $newSchema->autoFlush = false;
164
165 19
        if ($operations !== null) {
166 7
            $operations($newSchema);
167
        }
168
169 19
        return $newSchema;
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175 2
    public function transaction(callable $operations)
176
    {
177 2
        $last = $this->autoFlush;
178 2
        $this->autoFlush = false;
179
180 2
        if (!$this->connection instanceof TransactionManagerInterface) {
181
            throw new BadMethodCallException('The connection '.$this->connection->getName().' do not handle transactions');
182
        }
183
184
        try {
185 2
            $operations($this);
186
187 2
            $this->connection->beginTransaction();
188 2
            $this->flush();
189 1
            $this->connection->commit();
190 1
        } catch (DoctrineDBALException $e) {
191
            $this->connection->rollBack();
192
193
            /** @psalm-suppress InvalidScalarArgument */
194
            throw new DBALException($e->getMessage(), $e->getCode(), $e);
195 1
        } catch (\Exception $e) {
196 1
            $this->connection->rollBack();
197
198 1
            throw $e;
199
        } finally {
200 2
            $this->autoFlush = $last;
201 2
            $this->clear();
202
        }
203
204 1
        return $this;
205
    }
206
207
    /**
208
     * {@inheritdoc}
209
     */
210 4
    public function isBuffered(): bool
211
    {
212 4
        return !$this->autoFlush;
213
    }
214
}
215