Passed
Push — master ( 1f4c93...dcd4be )
by Alexander
13:16 queued 10:08
created

DDLQueryBuilder::addCommentOnColumn()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4.026

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 21
c 1
b 0
f 0
nc 8
nop 3
dl 0
loc 33
ccs 15
cts 17
cp 0.8824
crap 4.026
rs 9.584
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\QueryBuilder\DDLQueryBuilder as AbstractDDLQueryBuilder;
12
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
13
use Yiisoft\Db\Schema\QuoterInterface;
14
use Yiisoft\Db\Schema\SchemaInterface;
15
16
use function preg_match;
17
use function preg_replace;
18
use function trim;
19
20
final class DDLQueryBuilder extends AbstractDDLQueryBuilder
21
{
22 356
    public function __construct(
23
        private QueryBuilderInterface $queryBuilder,
24
        private QuoterInterface $quoter,
25
        private SchemaInterface $schema
26
    ) {
27 356
        parent::__construct($queryBuilder, $quoter, $schema);
28
    }
29
30
    /**
31
     * @throws NotSupportedException
32
     */
33 1
    public function addCheck(string $name, string $table, string $expression): string
34
    {
35 1
        throw new NotSupportedException(__METHOD__ . ' is not supported by MySQL.');
36
    }
37
38
    /**
39
     * @throws Exception|Throwable
40
     */
41 1
    public function addCommentOnColumn(string $table, string $column, string $comment): string
42
    {
43
        /* Strip existing comment which may include escaped quotes */
44 1
        $definition = trim(
45 1
            preg_replace(
46
                "/COMMENT '(?:''|[^'])*'/i",
47
                '',
48 1
                $this->getColumnDefinition($table, $column)
49
            )
50
        );
51
52 1
        $checkRegex = '/CHECK *(\(([^()]|(?-2))*\))/';
53 1
        $check = preg_match($checkRegex, $definition, $checkMatches);
54
55 1
        if ($check === 1) {
56
            $definition = preg_replace($checkRegex, '', $definition);
57
        }
58
59 1
        $alterSql = 'ALTER TABLE '
60 1
            . $this->quoter->quoteTableName($table)
61
            . ' CHANGE '
62 1
            . $this->quoter->quoteColumnName($column)
63
            . ' '
64 1
            . $this->quoter->quoteColumnName($column)
65 1
            . (empty($definition) ? '' : ' ' . $definition)
66
            . ' COMMENT '
67 1
            . (string) $this->quoter->quoteValue($comment);
68
69 1
        if ($check === 1) {
70
            $alterSql .= ' ' . $checkMatches[0];
71
        }
72
73 1
        return $alterSql;
74
    }
75
76
    /**
77
     * @throws \Exception
78
     */
79 1
    public function addCommentOnTable(string $table, string $comment): string
80
    {
81
        return 'ALTER TABLE '
82 1
            . $this->quoter->quoteTableName($table)
83
            . ' COMMENT '
84 1
            . (string) $this->quoter->quoteValue($comment);
85
    }
86
87
    /**
88
     * @throws Exception|InvalidArgumentException
89
     */
90 6
    public function createIndex(string $name, string $table, array|string $columns, ?string $indexType = null, ?string $indexMethod = null): string
91
    {
92 6
        return 'CREATE ' . ($indexType ? ($indexType . ' ') : '') . 'INDEX '
93 6
            . $this->quoter->quoteTableName($name)
94 6
            . ($indexMethod !== null ? " USING $indexMethod" : '')
95 6
            . ' ON ' . $this->quoter->quoteTableName($table)
96 6
            . ' (' . $this->queryBuilder->buildColumns($columns) . ')';
97
    }
98
99 2
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
100
    {
101 2
        return 'SET FOREIGN_KEY_CHECKS = ' . ($check ? 1 : 0);
102
    }
103
104
    /**
105
     * @throws NotSupportedException
106
     */
107 1
    public function dropCheck(string $name, string $table): string
108
    {
109 1
        throw new NotSupportedException(__METHOD__ . ' is not supported by MySQL.');
110
    }
111
112
    /**
113
     * @throws Exception|Throwable
114
     */
115 1
    public function dropCommentFromColumn(string $table, string $column): string
116
    {
117 1
        return $this->addCommentOnColumn($table, $column, '');
118
    }
119
120
    /**
121
     * @throws \Exception
122
     */
123 1
    public function dropCommentFromTable(string $table): string
124
    {
125 1
        return $this->addCommentOnTable($table, '');
126
    }
127
128 2
    public function dropForeignKey(string $name, string $table): string
129
    {
130
        return 'ALTER TABLE '
131 2
            . $this->quoter->quoteTableName($table)
132
            . ' DROP FOREIGN KEY '
133 2
            . $this->quoter->quoteColumnName($name);
134
    }
135
136 2
    public function dropPrimaryKey(string $name, string $table): string
137
    {
138 2
        return 'ALTER TABLE ' . $this->quoter->quoteTableName($table) . ' DROP PRIMARY KEY';
139
    }
140
141 2
    public function dropUnique(string $name, string $table): string
142
    {
143 2
        return $this->dropIndex($name, $table);
144
    }
145
146
    /**
147
     * @throws Exception|Throwable
148
     */
149 1
    public function renameColumn(string $table, string $oldName, string $newName): string
150
    {
151 1
        $quotedTable = $this->quoter->quoteTableName($table);
152
153 1
        $columnDefinition = $this->getColumnDefinition($table, $oldName);
154
155
        /* try to give back a SQL anyway */
156 1
        return "ALTER TABLE $quotedTable CHANGE "
157 1
            . $this->quoter->quoteColumnName($oldName) . ' '
158 1
            . $this->quoter->quoteColumnName($newName)
159 1
            . (!empty($columnDefinition) ? ' ' . $columnDefinition : '');
160
    }
161
162
    /**
163
     * Gets column definition.
164
     *
165
     * @param string $table table name.
166
     * @param string $column column name.
167
     *
168
     * @throws Exception|Throwable in case when table does not contain column.
169
     *
170
     * @return string the column definition.
171
     */
172 2
    public function getColumnDefinition(string $table, string $column): string
173
    {
174 2
        $result = '';
175
176 2
        $sql = $this->schema->getTableSchema($table)?->getCreateSql();
177
178 2
        if (empty($sql)) {
179
            return '';
180
        }
181
182 2
        if (preg_match_all('/^\s*`(.*?)`\s+(.*?),?$/m', $sql, $matches)) {
183 2
            foreach ($matches[1] as $i => $c) {
184 2
                if ($c === $column) {
185 2
                    $result = $matches[2][$i];
186
                }
187
            }
188
        }
189
190 2
        return $result;
191
    }
192
}
193