Passed
Push — dev ( cc6591...c9f34d )
by Wilmer
04:23 queued 23s
created

DDLQueryBuilder::addCommentOnColumn()   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 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 3
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
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 367
    public function __construct(private QueryBuilderInterface $queryBuilder)
17
    {
18 367
        parent::__construct($queryBuilder);
19
    }
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 1
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
64
    {
65 1
        $enable = $check ? 'CHECK' : 'NOCHECK';
66
67
        /** @var SchemaPDOMssql */
68 1
        $schemaInstance = $this->queryBuilder->schema();
69 1
        $defaultSchema = $schema ?: $schemaInstance->getDefaultSchema() ?? '';
70 1
        $tableNames = $schemaInstance->getTableSchema($table)
71 1
             ? [$table] : $schemaInstance->getTableNames($defaultSchema);
72 1
        $viewNames = $schemaInstance->getViewNames($defaultSchema);
73 1
        $tableNames = array_diff($tableNames, $viewNames);
74 1
        $command = '';
75
76 1
        foreach ($tableNames as $tableName) {
77 1
            $tableName = $this->queryBuilder->quoter()->quoteTableName("$defaultSchema.$tableName");
78 1
            $command .= "ALTER TABLE $tableName $enable CONSTRAINT ALL; ";
79
        }
80
81 1
        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 2
    public function renameTable(string $oldName, string $newName): string
109
    {
110
        return 'sp_rename '
111 2
            . $this->queryBuilder->quoter()->quoteTableName($oldName) . ', '
112 2
            . $this->queryBuilder->quoter()->quoteTableName($newName);
113
    }
114
115 1
    public function renameColumn(string $table, string $oldName, string $newName): string
116
    {
117
        return 'sp_rename '
118 1
            . $this->queryBuilder->quoter()->quoteTableName($table) . '.'
119 1
            . $this->queryBuilder->quoter()->quoteColumnName($oldName) . ', '
120 1
            . $this->queryBuilder->quoter()->quoteColumnName($newName)
121 1
            . ' COLUMN';
122
    }
123
124
    /**
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
     * 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
     * properly quoted by the method.
131
     * @param string|null $column optional. The name of the column to be commented. If empty, the command will add the
132
     * comment to the table instead. The column name will be properly quoted by the method.
133
     *
134
     * @throws Exception|InvalidArgumentException if the table does not exist.
135
     *
136
     * @return string the SQL statement for adding a comment.
137
     */
138 5
    private function buildAddCommentSql(string $comment, string $table, ?string $column = null): string
139
    {
140 5
        $tableSchema = $this->queryBuilder->schema()->getTableSchema($table);
141
142 5
        if ($tableSchema === null) {
143 1
            throw new InvalidArgumentException("Table not found: $table");
144
        }
145
146 4
        $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 4
        $comment = 'N' . (string) $this->queryBuilder->quoter()->quoteValue($comment);
151 4
        $functionParams = "
152
            @name = N'MS_description',
153 4
            @value = $comment,
154 4
            @level0type = N'SCHEMA', @level0name = $schemaName,
155
            @level1type = N'TABLE', @level1name = $tableName"
156 4
            . ($column ? ", @level2type = N'COLUMN', @level2name = $columnName" : '') . ';';
157
158 4
        return "
159
            IF NOT EXISTS (
160
                    SELECT 1
161
                    FROM fn_listextendedproperty (
162
                        N'MS_description',
163 4
                        'SCHEMA', $schemaName,
164 4
                        'TABLE', $tableName,
165 4
                        " . ($column ? "'COLUMN', $columnName " : ' DEFAULT, DEFAULT ') . "
166
                    )
167
            )
168 4
                EXEC sys.sp_addextendedproperty $functionParams
169
            ELSE
170 4
                EXEC sys.sp_updateextendedproperty $functionParams
171
        ";
172
    }
173
174
    /**
175
     * 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
     * The table name will be properly quoted by the method.
180
     * @param string|null $column optional. The name of the column whose comment will be removed. If empty, the command
181
     * will remove the comment from the table instead. The column name will be properly quoted by the method.
182
     *
183
     * @throws Exception|InvalidArgumentException if the table does not exist.
184
     *
185
     * @return string the SQL statement for removing the comment.
186
     */
187 3
    private function buildRemoveCommentSql(string $table, ?string $column = null): string
188
    {
189 3
        $tableSchema = $this->queryBuilder->schema()->getTableSchema($table);
190
191 3
        if ($tableSchema === null) {
192 1
            throw new InvalidArgumentException("Table not found: $table");
193
        }
194
195 2
        $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 2
        return "
201
            IF EXISTS (
202
                    SELECT 1
203
                    FROM fn_listextendedproperty (
204
                        N'MS_description',
205 2
                        'SCHEMA', $schemaName,
206 2
                        'TABLE', $tableName,
207 2
                        " . ($column ? "'COLUMN', $columnName " : ' DEFAULT, DEFAULT ') . "
208
                    )
209
            )
210
                EXEC sys.sp_dropextendedproperty
211
                    @name = N'MS_description',
212 2
                    @level0type = N'SCHEMA', @level0name = $schemaName,
213
                    @level1type = N'TABLE', @level1name = $tableName"
214 2
                    . ($column ? ", @level2type = N'COLUMN', @level2name = $columnName" : '') . ';';
215
    }
216
}
217