Test Failed
Push — dev ( 7c494b...cc6591 )
by Wilmer
04:08
created

DDLQueryBuilder::renameTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 5
ccs 0
cts 0
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Mssql;
6
7
use Exception;
8
use Yiisoft\Db\Exception\InvalidArgumentException;
9
use Yiisoft\Db\Exception\NotSupportedException;
10
use Yiisoft\Db\Mssql\PDO\SchemaPDOMssql;
11
use Yiisoft\Db\Query\DDLQueryBuilder as AbstractDDLQueryBuilder;
12
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...
13
14
final class DDLQueryBuilder extends AbstractDDLQueryBuilder
15
{
16 360
    public function __construct(private QueryBuilderInterface $queryBuilder)
17
    {
18 360
        parent::__construct($queryBuilder);
19 360
    }
20
21
    /**
22
     * @throws InvalidArgumentException
23
     */
24 4
    public function addCommentOnColumn(string $table, string $column, string $comment): string
25
    {
26 4
        return $this->buildAddCommentSql($comment, $table, $column);
27
    }
28
29
    /**
30
     * @throws InvalidArgumentException
31
     */
32 4
    public function addCommentOnTable(string $table, string $comment): string
33
    {
34 4
        return $this->buildAddCommentSql($comment, $table);
35
    }
36
37
    /**
38
     * @throws Exception
39
     */
40 1
    public function addDefaultValue(string $name, string $table, string $column, mixed $value): string
41
    {
42
        return 'ALTER TABLE '
43 1
            . $this->queryBuilder->quoter()->quoteTableName($table)
44 1
            . ' ADD CONSTRAINT '
45 1
            . $this->queryBuilder->quoter()->quoteColumnName($name)
46 1
            . ' DEFAULT ' . (string) $this->queryBuilder->quoter()->quoteValue($value)
47 1
            . ' FOR ' . $this->queryBuilder->quoter()->quoteColumnName($column);
48
    }
49
50 1
    public function alterColumn(string $table, string $column, string $type): string
51
    {
52
        return 'ALTER TABLE '
53 1
            . $this->queryBuilder->quoter()->quoteTableName($table)
54 1
            . ' ALTER COLUMN '
55 1
            . $this->queryBuilder->quoter()->quoteColumnName($column)
56 1
            . ' '
57 1
            . $this->queryBuilder->getColumnType($type);
58
    }
59
60
    /**
61
     * @throws NotSupportedException
62
     */
63
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
64
    {
65
        $enable = $check ? 'CHECK' : 'NOCHECK';
66
67
        /** @var SchemaPDOMssql */
68
        $schemaInstance = $this->queryBuilder->schema();
69
        $defaultSchema = $schema ?: $schemaInstance->getDefaultSchema() ?? '';
70
        $tableNames = $schemaInstance->getTableSchema($table)
71
             ? [$table] : $schemaInstance->getTableNames($defaultSchema);
72
        $viewNames = $schemaInstance->getViewNames($defaultSchema);
73
        $tableNames = array_diff($tableNames, $viewNames);
74
        $command = '';
75
76
        foreach ($tableNames as $tableName) {
77
            $tableName = $this->queryBuilder->quoter()->quoteTableName("$defaultSchema.$tableName");
78
            $command .= "ALTER TABLE $tableName $enable CONSTRAINT ALL; ";
79
        }
80
81
        return $command;
82
    }
83
84
    /**
85
     * @throws InvalidArgumentException
86
     */
87 2
    public function dropCommentFromColumn(string $table, string $column): string
88
    {
89 2
        return $this->buildRemoveCommentSql($table, $column);
90
    }
91
92
    /**
93
     * @throws InvalidArgumentException
94
     */
95 2
    public function dropCommentFromTable(string $table): string
96
    {
97 2
        return $this->buildRemoveCommentSql($table);
98
    }
99
100 1
    public function dropDefaultValue(string $name, string $table): string
101
    {
102
        return 'ALTER TABLE '
103 1
            . $this->queryBuilder->quoter()->quoteTableName($table)
104 1
            . ' DROP CONSTRAINT '
105 1
            . $this->queryBuilder->quoter()->quoteColumnName($name);
106
    }
107
108
    public function renameTable(string $oldName, string $newName): string
109
    {
110
        return 'sp_rename '
111
            . $this->queryBuilder->quoter()->quoteTableName($oldName) . ', '
112
            . $this->queryBuilder->quoter()->quoteTableName($newName);
113
    }
114
115
    public function renameColumn(string $table, string $oldName, string $newName): string
116
    {
117
        return 'sp_rename '
118
            . $this->queryBuilder->quoter()->quoteTableName($table) . '.'
119
            . $this->queryBuilder->quoter()->quoteColumnName($oldName) . ', '
120
            . $this->queryBuilder->quoter()->quoteColumnName($newName)
121
            . ' COLUMN';
122 4
    }
123
124 4
    /**
125
     * Builds a SQL command for adding or updating a comment to a table or a column. The command built will check if a
126 4
     * comment already exists. If so, it will be updated, otherwise, it will be added.
127
     *
128
     * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method.
129
     * @param string $table the table to be commented or whose column is to be commented. The table name will be
130 4
     * properly quoted by the method.
131 4
     * @param string|null $column optional. The name of the column to be commented. If empty, the command will add the
132 4
     * comment to the table instead. The column name will be properly quoted by the method.
133 4
     *
134 4
     * @throws Exception|InvalidArgumentException if the table does not exist.
135 4
     *
136
     * @return string the SQL statement for adding a comment.
137 4
     */
138 4
    private function buildAddCommentSql(string $comment, string $table, ?string $column = null): string
139 4
    {
140 4
        $tableSchema = $this->queryBuilder->schema()->getTableSchema($table);
141
142 4
        if ($tableSchema === null) {
143
            throw new InvalidArgumentException("Table not found: $table");
144
        }
145
146
        $schemaName = $tableSchema->getSchemaName()
147 4
            ? "N'" . (string) $tableSchema->getSchemaName() . "'" : 'SCHEMA_NAME()';
148 4
        $tableName = 'N' . (string) $this->queryBuilder->quoter()->quoteValue($tableSchema->getName());
149 4
        $columnName = $column ? 'N' . (string) $this->queryBuilder->quoter()->quoteValue($column) : null;
150
        $comment = 'N' . (string) $this->queryBuilder->quoter()->quoteValue($comment);
151
        $functionParams = "
152 4
            @name = N'MS_description',
153
            @value = $comment,
154 4
            @level0type = N'SCHEMA', @level0name = $schemaName,
155
            @level1type = N'TABLE', @level1name = $tableName"
156
            . ($column ? ", @level2type = N'COLUMN', @level2name = $columnName" : '') . ';';
157
158
        return "
159
            IF NOT EXISTS (
160
                    SELECT 1
161
                    FROM fn_listextendedproperty (
162
                        N'MS_description',
163
                        'SCHEMA', $schemaName,
164
                        'TABLE', $tableName,
165
                        " . ($column ? "'COLUMN', $columnName " : ' DEFAULT, DEFAULT ') . "
166
                    )
167
            )
168
                EXEC sys.sp_addextendedproperty $functionParams
169
            ELSE
170
                EXEC sys.sp_updateextendedproperty $functionParams
171 2
        ";
172
    }
173 2
174
    /**
175 2
     * Builds a SQL command for removing a comment from a table or a column. The command built will check if a comment
176
     * already exists before trying to perform the removal.
177
     *
178
     * @param string $table the table that will have the comment removed or whose column will have the comment removed.
179 2
     * The table name will be properly quoted by the method.
180 2
     * @param string|null $column optional. The name of the column whose comment will be removed. If empty, the command
181 2
     * will remove the comment from the table instead. The column name will be properly quoted by the method.
182 2
     *
183
     * @throws Exception|InvalidArgumentException if the table does not exist.
184 2
     *
185
     * @return string the SQL statement for removing the comment.
186
     */
187
    private function buildRemoveCommentSql(string $table, ?string $column = null): string
188
    {
189 2
        $tableSchema = $this->queryBuilder->schema()->getTableSchema($table);
190 2
191 2
        if ($tableSchema === null) {
192
            throw new InvalidArgumentException("Table not found: $table");
193
        }
194
195
        $schemaName = $tableSchema->getSchemaName()
196 2
            ? "N'" . (string) $tableSchema->getSchemaName() . "'" : 'SCHEMA_NAME()';
197 2
        $tableName = 'N' . (string) $this->queryBuilder->quoter()->quoteValue($tableSchema->getName());
198 2
        $columnName = $column ? 'N' . (string) $this->queryBuilder->quoter()->quoteValue($column) : null;
199
200
        return "
201
            IF EXISTS (
202
                    SELECT 1
203
                    FROM fn_listextendedproperty (
204
                        N'MS_description',
205
                        'SCHEMA', $schemaName,
206
                        'TABLE', $tableName,
207
                        " . ($column ? "'COLUMN', $columnName " : ' DEFAULT, DEFAULT ') . "
208
                    )
209
            )
210
                EXEC sys.sp_dropextendedproperty
211
                    @name = N'MS_description',
212
                    @level0type = N'SCHEMA', @level0name = $schemaName,
213
                    @level1type = N'TABLE', @level1name = $tableName"
214
                    . ($column ? ", @level2type = N'COLUMN', @level2name = $columnName" : '') . ';';
215
    }
216
}
217