Passed
Push — temp ( ae651e...c74d19 )
by Wilmer
23:03 queued 20:07
created

DDLQueryBuilder::dropDefaultValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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