Test Failed
Pull Request — dev (#118)
by Def
09:16 queued 06:49
created

DDLQueryBuilder::dropCommentFromTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Mysql;
6
7
use Throwable;
8
use Yiisoft\Db\Exception\Exception;
9
use Yiisoft\Db\Exception\InvalidArgumentException;
10
use Yiisoft\Db\Exception\NotSupportedException;
11
use Yiisoft\Db\Mysql\PDO\QueryBuilderPDOMysql;
12
use Yiisoft\Db\Query\DDLQueryBuilder as AbstractDDLQueryBuilder;
13
use Yiisoft\Db\Query\QueryBuilderInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Query\QueryBuilderInterface 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...
14
15 355
use function array_values;
16
use function in_array;
17 355
use function preg_match;
18
use function preg_replace;
19
use function trim;
20
21
final class DDLQueryBuilder extends AbstractDDLQueryBuilder
22
{
23 1
    public function __construct(private QueryBuilderInterface $queryBuilder)
24
    {
25
        parent::__construct($queryBuilder);
26 1
    }
27 1
28
    public function addCheck(string $name, string $table, string $expression): string
29
    {
30 1
        throw new NotSupportedException(__METHOD__ . ' is not supported by MySQL.');
31
    }
32
33
    /**
34 1
     * @throws Exception|Throwable
35 1
     */
36
    public function addCommentOnColumn(string $table, string $column, string $comment): string
37 1
    {
38
        /* Strip existing comment which may include escaped quotes */
39
        $definition = trim(
40
            preg_replace(
41 1
                "/COMMENT '(?:''|[^'])*'/i",
42 1
                '',
43
                $this->getColumnDefinition($table, $column)
44 1
            )
45
        );
46 1
47 1
        $checkRegex = '/CHECK *(\(([^()]|(?-2))*\))/';
48
        $check = preg_match($checkRegex, $definition, $checkMatches);
49 1
50
        if ($check === 1) {
51 1
            $definition = preg_replace($checkRegex, '', $definition);
52
        }
53
54
        $alterSql = 'ALTER TABLE '
55 1
            . $this->quoter->quoteTableName($table)
0 ignored issues
show
Bug Best Practice introduced by
The property quoter does not exist on Yiisoft\Db\Mysql\DDLQueryBuilder. Did you maybe forget to declare it?
Loading history...
56
            . ' CHANGE '
57
            . $this->quoter->quoteColumnName($column)
58
            . ' '
59
            . $this->quoter->quoteColumnName($column)
60
            . (empty($definition) ? '' : ' ' . $definition)
61 1
            . ' COMMENT '
62
            . (string) $this->quoter->quoteValue($comment);
63
64 1
        if ($check === 1) {
65
            $alterSql .= ' ' . $checkMatches[0];
66 1
        }
67
68
        return $alterSql;
69
    }
70
71
    /**
72 6
     * @throws \Exception
73
     */
74
    public function addCommentOnTable(string $table, string $comment): string
75 6
    {
76 6
        return 'ALTER TABLE '
77 6
            . $this->quoter->quoteTableName($table)
0 ignored issues
show
Bug Best Practice introduced by
The property quoter does not exist on Yiisoft\Db\Mysql\DDLQueryBuilder. Did you maybe forget to declare it?
Loading history...
78 6
            . ' COMMENT '
79
            . (string) $this->quoter->quoteValue($comment);
80
    }
81 2
82
    /**
83
     * @throws Exception|InvalidArgumentException
84 2
     */
85
    public function createIndex(string $name, string $table, array|string $columns, bool $unique = false): string
86 2
    {
87
        return 'ALTER TABLE '
88
            . $this->quoter->quoteTableName($table)
0 ignored issues
show
Bug Best Practice introduced by
The property quoter does not exist on Yiisoft\Db\Mysql\DDLQueryBuilder. Did you maybe forget to declare it?
Loading history...
89 2
            . ($unique ? ' ADD UNIQUE INDEX ' : ' ADD INDEX ')
90
            . $this->quoter->quoteTableName($name)
91 2
            . ' (' . $this->queryBuilder->buildColumns($columns) . ')';
92
    }
93
94
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
95
    {
96
        return 'SET FOREIGN_KEY_CHECKS = ' . ($check ? 1 : 0);
97 2
    }
98
99 2
    public function dropCheck(string $name, string $table): string
100
    {
101
        throw new NotSupportedException(__METHOD__ . ' is not supported by MySQL.');
102 2
    }
103
104 1
    public function dropCommentFromColumn(string $table, string $column): string
105 1
    {
106
        return $this->addCommentOnColumn($table, $column, '');
107
    }
108
109
    /**
110
     * @throws \Exception
111 1
     */
112 1
    public function dropCommentFromTable(string $table): string
113 1
    {
114 1
        return $this->addCommentOnTable($table, '');
115 1
    }
116 1
117 1
    public function dropForeignKey(string $name, string $table): string
118
    {
119
        return 'ALTER TABLE '
120
            . $this->quoter->quoteTableName($table)
0 ignored issues
show
Bug Best Practice introduced by
The property quoter does not exist on Yiisoft\Db\Mysql\DDLQueryBuilder. Did you maybe forget to declare it?
Loading history...
121
            . ' DROP FOREIGN KEY '
122
            . $this->quoter->quoteColumnName($name);
123 1
    }
124 1
125 1
    public function dropPrimaryKey(string $name, string $table): string
126
    {
127
        return 'ALTER TABLE ' . $this->quoter->quoteTableName($table) . ' DROP PRIMARY KEY';
0 ignored issues
show
Bug Best Practice introduced by
The property quoter does not exist on Yiisoft\Db\Mysql\DDLQueryBuilder. Did you maybe forget to declare it?
Loading history...
128
    }
129
130
    public function dropUnique(string $name, string $table): string
131
    {
132
        return $this->dropIndex($name, $table);
133
    }
134
135
    /**
136
     * @throws Exception|Throwable
137
     */
138 1
    public function renameColumn(string $table, string $oldName, string $newName): string
139
    {
140 1
        $quotedTable = $this->quoter->quoteTableName($table);
0 ignored issues
show
Bug Best Practice introduced by
The property quoter does not exist on Yiisoft\Db\Mysql\DDLQueryBuilder. Did you maybe forget to declare it?
Loading history...
141 1
142
        $columnDefinition = $this->getColumnDefinition($table, $oldName);
143
144 1
        /* try to give back a SQL anyway */
145
        return "ALTER TABLE $quotedTable CHANGE "
146 1
            . $this->quoter->quoteColumnName($oldName) . ' '
147
            . $this->quoter->quoteColumnName($newName)
148
            . (!empty($columnDefinition) ? ' ' . $columnDefinition : '');
149
    }
150 1
151
    /**
152
     * @todo need work with bit, tinybit and other new not suppoerted types (v.5.7 and later)
153 1
     */
154 1
//    public function getColumnDefinitionFromSchema($table, $oldName): string
155 1
//    {
156 1
//        $schema = $this->schema;
157
//        $tableSchema = $schema->getTableSchema($table, true);
158
//        if ($tableSchema === null) {
159
//            throw new InvalidArgumentException("Table not found: $table");
160
//        }
161 1
//
162
//        $oldColumnSchema = $tableSchema->getColumn($oldName);
163
//        if ($oldColumnSchema === null) {
164
//            return '';
165
//        }
166
//
167
//        $columnSchemaBuilder = $this->schema->createColumnSchemaBuilder(
168
//            $oldColumnSchema->getType(),
169
//            $oldColumnSchema->getPrecision() ?? $oldColumnSchema->getSize()
170
//        );
171
//
172
//        $defaultValue = $oldColumnSchema->getDefaultValue();
173
//
174
//        if ($oldColumnSchema->isAllowNull()) {
175
//            if ($defaultValue === null) {
176
//                if (!in_array($oldColumnSchema->getType(), [Schema::TYPE_TEXT, Schema::TYPE_BINARY], true)) {
177
//                    $columnSchemaBuilder->defaultValue('NULL');
178
//                }
179
//                if ($oldColumnSchema->getType() === Schema::TYPE_TIMESTAMP) {
180
//                    $columnSchemaBuilder->null();
181
//                }
182
//            } elseif ($oldColumnSchema->getType() !== Schema::TYPE_BINARY) {
183
//                $columnSchemaBuilder->defaultValue($defaultValue);
184
//            }
185
//        } else {
186
//            $columnSchemaBuilder->notNull();
187
//            if ($defaultValue !== null && ($oldColumnSchema->getDbType() !== 'bit(1)' || !empty($defaultValue))) {
188
//                $columnSchemaBuilder->defaultValue($defaultValue);
189
//            }
190
//        }
191
//
192
//        if (!empty($oldColumnSchema->getComment())) {
193
//            $columnSchemaBuilder->comment($oldColumnSchema->getComment());
194
//        }
195
//
196
//        if ($oldColumnSchema->isUnsigned()) {
197
//            $columnSchemaBuilder->unsigned();
198
//        }
199
//
200
//        if ($oldColumnSchema->isAutoIncrement()) {
201
//            $columnSchemaBuilder->append('AUTO_INCREMENT');
202
//        } elseif (!empty($oldColumnSchema->getExtra())) {
203
//            $columnSchemaBuilder->append($oldColumnSchema->getExtra());
204
//        }
205
//
206
//        return $this->queryBuilder->getColumnType($columnSchemaBuilder);
207
//    }
208
209
    /**
210
     * Gets column definition.
211
     *
212
     * @param string $table table name.
213
     * @param string $column column name.
214
     *
215
     * @throws Exception|Throwable in case when table does not contain column.
216
     *
217
     * @return string the column definition.
218
     *
219
     * @todo need change to getColumnDefinitionFromSchema with deep research
220
     */
221
    public function getColumnDefinition(string $table, string $column): string
222
    {
223
        $result = '';
224
        $quotedTable = $this->quoter->quoteTableName($table);
0 ignored issues
show
Bug Best Practice introduced by
The property quoter does not exist on Yiisoft\Db\Mysql\DDLQueryBuilder. Did you maybe forget to declare it?
Loading history...
225
226
        /** @var QueryBuilderPDOMysql $qb */
227
        $qb = $this->queryBuilder;
228
229
        /** @var array<array-key, string> $row */
230
        $row = $qb->command()->setSql('SHOW CREATE TABLE ' . $quotedTable)->queryOne();
231
232
        if (!isset($row['Create Table'])) {
233
            $row = array_values($row);
0 ignored issues
show
Bug introduced by
$row of type false is incompatible with the type array expected by parameter $array of array_values(). ( Ignorable by Annotation )

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

233
            $row = array_values(/** @scrutinizer ignore-type */ $row);
Loading history...
234
            $sql = $row[1];
235
        } else {
236
            $sql = $row['Create Table'];
237
        }
238
239
        if (preg_match_all('/^\s*`(.*?)`\s+(.*?),?$/m', $sql, $matches)) {
240
            foreach ($matches[1] as $i => $c) {
241
                if ($c === $column) {
242
                    $result = $matches[2][$i];
243
                }
244
            }
245
        }
246
247
        return $result;
248
    }
249
}
250