Passed
Pull Request — master (#229)
by Def
15:58 queued 12:13
created

DDLQueryBuilder::alterColumn()   B

Complexity

Conditions 8
Paths 50

Size

Total Lines 53
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 8.0032

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 8
eloc 27
c 2
b 0
f 0
nc 50
nop 3
dl 0
loc 53
ccs 26
cts 27
cp 0.963
crap 8.0032
rs 8.4444

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql;
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\AbstractDDLQueryBuilder;
12
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
13
use Yiisoft\Db\Schema\ColumnSchemaBuilderInterface;
14
use Yiisoft\Db\Schema\QuoterInterface;
15
use Yiisoft\Db\Schema\SchemaInterface;
16
17
use function array_diff;
18
use function array_unshift;
19
use function explode;
20
use function implode;
21
use function preg_match;
22
use function preg_replace;
23
use function str_contains;
24
25
final class DDLQueryBuilder extends AbstractDDLQueryBuilder
26
{
27 561
    public function __construct(
28
        private QueryBuilderInterface $queryBuilder,
29
        private QuoterInterface $quoter,
30
        private SchemaInterface $schema
31
    ) {
32 561
        parent::__construct($queryBuilder, $quoter, $schema);
33
    }
34
35
    /**
36
     * @throws NotSupportedException
37
     */
38 3
    public function addDefaultValue(string $name, string $table, string $column, mixed $value): string
39
    {
40 3
        throw new NotSupportedException(__METHOD__ . ' is not supported by PostgreSQL.');
41
    }
42
43 1
    public function alterColumn(string $table, string $column, ColumnSchemaBuilderInterface|string $type): string
44
    {
45 1
        $columnName = $this->quoter->quoteColumnName($column);
46 1
        $tableName = $this->quoter->quoteTableName($table);
47
48 1
        if ($type instanceof ColumnSchemaBuilderInterface) {
49
            $type = $type->asString();
50
        }
51
52
        /**
53
         * {@see https://github.com/yiisoft/yii2/issues/4492}
54
         * {@see http://www.postgresql.org/docs/9.1/static/sql-altertable.html}
55
         */
56 1
        if (preg_match('/^(DROP|SET|RESET|USING)\s+/i', $type)) {
57 1
            return "ALTER TABLE $tableName ALTER COLUMN $columnName $type";
58
        }
59
60 1
        $type = 'TYPE ' . $this->queryBuilder->getColumnType($type);
61 1
        $multiAlterStatement = [];
62 1
        $constraintPrefix = preg_replace('/[^a-z0-9_]/i', '', $table . '_' . $column);
63
64 1
        if (preg_match('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', $type, $matches)) {
65 1
            $type = preg_replace('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', '', $type);
66 1
            $multiAlterStatement[] = "ALTER COLUMN $columnName SET DEFAULT $matches[1]";
67
        }
68
69 1
        $type = preg_replace('/\s+NOT\s+NULL/i', '', $type, -1, $count);
70
71 1
        if ($count) {
72 1
            $multiAlterStatement[] = "ALTER COLUMN $columnName SET NOT NULL";
73
        } else {
74
            /** remove additional null if any */
75 1
            $type = preg_replace('/\s+NULL/i', '', $type, -1, $count);
76 1
            if ($count) {
77 1
                $multiAlterStatement[] = "ALTER COLUMN $columnName DROP NOT NULL";
78
            }
79
        }
80
81 1
        if (preg_match('/\s+CHECK\s+\((.+)\)/i', $type, $matches)) {
82 1
            $type = preg_replace('/\s+CHECK\s+\((.+)\)/i', '', $type);
83 1
            $multiAlterStatement[] = "ADD CONSTRAINT {$constraintPrefix}_check CHECK ($matches[1])";
84
        }
85
86 1
        $type = preg_replace('/\s+UNIQUE/i', '', $type, -1, $count);
87
88 1
        if ($count) {
89 1
            $multiAlterStatement[] = "ADD UNIQUE ($columnName)";
90
        }
91
92
        /** add what's left at the beginning */
93 1
        array_unshift($multiAlterStatement, "ALTER COLUMN $columnName $type");
94
95 1
        return 'ALTER TABLE ' . $tableName . ' ' . implode(', ', $multiAlterStatement);
96
    }
97
98
    /**
99
     * @throws Exception
100
     * @throws NotSupportedException
101
     * @throws Throwable
102
     */
103 2
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
104
    {
105
        /** @psalm-var Schema $schemaInstance */
106 2
        $schemaInstance = $this->schema;
107 2
        $enable = $check ? 'ENABLE' : 'DISABLE';
108 2
        $schema = $schema ?: $schemaInstance->getDefaultSchema();
109 2
        $tableNames = [];
110 2
        $viewNames = [];
111
112 2
        if ($schema !== null) {
113 2
            $tableNames = $table ? [$table] : $schemaInstance->getTableNames($schema);
114 2
            $viewNames = $schemaInstance->getViewNames($schema);
115
        }
116
117 2
        $tableNames = array_diff($tableNames, $viewNames);
118 2
        $command = '';
119
120
        /** @psalm-var string[] $tableNames */
121 2
        foreach ($tableNames as $tableName) {
122 2
            $tableName = $this->quoter->quoteTableName("$schema.$tableName");
123 2
            $command .= "ALTER TABLE $tableName $enable TRIGGER ALL; ";
124
        }
125
126
        /** enable to have ability to alter several tables */
127
        //$pdo = $db->getSlavePdo();
128
        //$pdo?->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
129
130 2
        return $command;
131
    }
132
133
    /**
134
     * @throws Exception|InvalidArgumentException
135
     */
136 10
    public function createIndex(string $name, string $table, array|string $columns, ?string $indexType = null, ?string $indexMethod = null): string
137
    {
138 10
        return 'CREATE ' . ($indexType ? ($indexType . ' ') : '') . 'INDEX '
139 10
            . $this->quoter->quoteTableName($name) . ' ON '
140 10
            . $this->quoter->quoteTableName($table)
141 10
            . ($indexMethod !== null ? " USING $indexMethod" : '')
142 10
            . ' (' . $this->queryBuilder->buildColumns($columns) . ')';
143
    }
144
145
    /**
146
     * @throws NotSupportedException
147
     */
148 2
    public function dropDefaultValue(string $name, string $table): string
149
    {
150 2
        throw new NotSupportedException(__METHOD__ . ' is not supported by PostgreSQL.');
151
    }
152
153 2
    public function dropIndex(string $name, string $table): string
154
    {
155 2
        if (str_contains($table, '.') && !str_contains($name, '.')) {
156 1
            if (str_contains($table, '{{')) {
157 1
                $table = preg_replace('/{{(.*?)}}/', '\1', $table);
158 1
                [$schema] = explode('.', $table);
159 1
                if (!str_contains($schema, '%')) {
160 1
                    $name = $schema . '.' . $name;
161
                } else {
162 1
                    $name = '{{' . $schema . '.' . $name . '}}';
163
                }
164
            } else {
165 1
                [$schema] = explode('.', $table);
166 1
                $name = $schema . '.' . $name;
167
            }
168
        }
169
170 2
        return 'DROP INDEX ' . $this->quoter->quoteTableName($name);
171
    }
172
173 2
    public function truncateTable(string $table): string
174
    {
175 2
        return 'TRUNCATE TABLE ' . $this->quoter->quoteTableName($table) . ' RESTART IDENTITY';
176
    }
177
178 3
    public function renameTable(string $oldName, string $newName): string
179
    {
180 3
        return 'ALTER TABLE '
181 3
            . $this->quoter->quoteTableName($oldName)
182 3
            . ' RENAME TO '
183 3
            . $this->quoter->quoteTableName($newName);
184
    }
185
}
186