Issues (265)

src/Driver/MySQL/MySQLHandler.php (7 issues)

1
<?php
2
3
/**
4
 * This file is part of Cycle ORM package.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Cycle\Database\Driver\MySQL;
13
14
use Cycle\Database\Driver\Handler;
15
use Cycle\Database\Driver\MySQL\Exception\MySQLException;
16
use Cycle\Database\Driver\MySQL\Schema\MySQLTable;
17
use Cycle\Database\Exception\SchemaException;
18
use Cycle\Database\Schema\AbstractColumn;
0 ignored issues
show
The type Cycle\Database\Schema\AbstractColumn was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Cycle\Database\Schema\AbstractForeignKey;
20
use Cycle\Database\Schema\AbstractIndex;
21
use Cycle\Database\Schema\AbstractTable;
22
23
class MySQLHandler extends Handler
24
{
25
    /**
26
     * @psalm-param non-empty-string $table
27
     */
28
    public function getSchema(string $table, ?string $prefix = null): AbstractTable
29 484
    {
30
        return new MySQLTable($this->driver, $table, $prefix ?? '');
0 ignored issues
show
It seems like $this->driver can also be of type null; however, parameter $driver of Cycle\Database\Driver\My...SQLTable::__construct() does only seem to accept Cycle\Database\Driver\DriverInterface, 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

30
        return new MySQLTable(/** @scrutinizer ignore-type */ $this->driver, $table, $prefix ?? '');
Loading history...
31 484
    }
32
33
    public function getTableNames(string $prefix = ''): array
34 906
    {
35
        $result = [];
36 906
        foreach ($this->driver->query('SHOW TABLES')->fetchAll(\PDO::FETCH_NUM) as $row) {
0 ignored issues
show
The method query() does not exist on null. ( Ignorable by Annotation )

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

36
        foreach ($this->driver->/** @scrutinizer ignore-call */ query('SHOW TABLES')->fetchAll(\PDO::FETCH_NUM) as $row) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
37 906
            if ($prefix !== '' && !\str_starts_with($row[0], $prefix)) {
38 446
                continue;
39 2
            }
40
41
            $result[] = $row[0];
42 446
        }
43
44
        return $result;
45 906
    }
46
47
    /**
48
     * @psalm-param non-empty-string $table
49
     */
50
    public function hasTable(string $table): bool
51 484
    {
52
        $query = 'SELECT COUNT(*) FROM `information_schema`.`tables` WHERE `table_schema` = ? AND `table_name` = ?';
53 484
54
        return (bool) $this->driver->query(
55 484
            $query,
56
            [$this->driver->getSource(), $table],
0 ignored issues
show
The method getSource() does not exist on Cycle\Database\Driver\DriverInterface. It seems like you code against a sub-type of Cycle\Database\Driver\DriverInterface such as Cycle\Database\Driver\Driver. ( Ignorable by Annotation )

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

56
            [$this->driver->/** @scrutinizer ignore-call */ getSource(), $table],
Loading history...
57 484
        )->fetchColumn();
58 484
    }
59
60
    public function eraseTable(AbstractTable $table): void
61 4
    {
62
        $this->driver->execute(
63 4
            "TRUNCATE TABLE {$this->driver->identifier($table->getFullName())}",
0 ignored issues
show
The method identifier() does not exist on Cycle\Database\Driver\DriverInterface. It seems like you code against a sub-type of Cycle\Database\Driver\DriverInterface such as Cycle\Database\Driver\Driver. ( Ignorable by Annotation )

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

63
            "TRUNCATE TABLE {$this->driver->/** @scrutinizer ignore-call */ identifier($table->getFullName())}",
Loading history...
64 4
        );
65
    }
66 2
67
    public function alterColumn(
68 38
        AbstractTable $table,
69
        AbstractColumn $initial,
70
        AbstractColumn $column,
71
    ): void {
72
        $foreignBackup = [];
73 38
        foreach ($table->getForeignKeys() as $foreign) {
74 38
            if ($column->getName() === $foreign->getColumns()) {
75 2
                $foreignBackup[] = $foreign;
76
                $this->dropForeignKey($table, $foreign);
77
            }
78
        }
79
80
        $this->run(
81 38
            "ALTER TABLE {$this->identify($table)}
82 38
                    CHANGE {$this->identify($initial)} {$column->sqlStatement($this->driver)}",
83 38
        );
84
85
        //Restoring FKs
86
        foreach ($foreignBackup as $foreign) {
87 38
            $this->createForeignKey($table, $foreign);
88
        }
89
    }
90 38
91
    public function dropIndex(AbstractTable $table, AbstractIndex $index): void
92 10
    {
93
        $this->run(
94 10
            "DROP INDEX {$this->identify($index)} ON {$this->identify($table)}",
95 10
        );
96
    }
97 10
98
    public function alterIndex(AbstractTable $table, AbstractIndex $initial, AbstractIndex $index): void
99 2
    {
100
        $this->run(
101 2
            "ALTER TABLE {$this->identify($table)}
102 2
                    DROP INDEX  {$this->identify($initial)},
103 2
                    ADD {$index->sqlStatement($this->driver, false)}",
0 ignored issues
show
It seems like $this->driver can also be of type null; however, parameter $driver of Cycle\Database\Schema\Ab...ctIndex::sqlStatement() does only seem to accept Cycle\Database\Driver\DriverInterface, 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

103
                    ADD {$index->sqlStatement(/** @scrutinizer ignore-type */ $this->driver, false)}",
Loading history...
104 2
        );
105
    }
106 2
107
    public function dropForeignKey(AbstractTable $table, AbstractForeignKey $foreignKey): void
108 56
    {
109
        $this->run(
110 56
            "ALTER TABLE {$this->identify($table)} DROP FOREIGN KEY {$this->identify($foreignKey)}",
111 56
        );
112
    }
113 56
114
    public function enableForeignKeyConstraints(): void
115
    {
116
        $this->run('SET FOREIGN_KEY_CHECKS=1;');
117
    }
118
119
    public function disableForeignKeyConstraints(): void
120 478
    {
121
        $this->run('SET FOREIGN_KEY_CHECKS=0;');
122 478
    }
123
124 478
    /**
125
     * Get statement needed to create table.
126
     *
127
     * @throws SchemaException
128
     */
129
    protected function createStatement(AbstractTable $table): string
130 478
    {
131
        $table instanceof MySQLTable or throw new SchemaException('MySQLHandler can process only MySQL tables');
132
133 478
        return parent::createStatement($table) . " ENGINE {$table->getEngine()}";
0 ignored issues
show
The method getEngine() does not exist on Cycle\Database\Schema\AbstractTable. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

133
        return parent::createStatement($table) . " ENGINE {$table->/** @scrutinizer ignore-call */ getEngine()}";
Loading history...
134
    }
135 478
136
    /**
137
     * @throws MySQLException
138
     */
139 4
    protected function assertValid(AbstractColumn $column): void
140 4
    {
141
        if (
142
            $column->getDefaultValue() !== null
143 474
            && \in_array(
144
                $column->getAbstractType(),
145
                ['text', 'tinyText', 'longText', 'blob', 'tinyBlob', 'longBlob', 'json'],
146
            )
147
        ) {
148
            throw new MySQLException(
149
                "Column {$column} of type text/blob/json can not have non empty default value",
150
            );
151
        }
152
    }
153
}
154