Test Failed
Push — temp ( 23cb4b...ea73cc )
by Wilmer
08:07 queued 05:34
created

DDLQueryBuilder::dropDefaultValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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