Test Failed
Pull Request — master (#98)
by Wilmer
21:47 queued 09:55
created

DDLQueryBuilder::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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