Passed
Branch dev (7c494b)
by Wilmer
04:53
created

DDLQueryBuilder::addDefaultValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
nc 1
nop 4
dl 0
loc 8
ccs 6
cts 6
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 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
    /**
109
     * Builds a SQL command for adding or updating a comment to a table or a column. The command built will check if a
110
     * comment already exists. If so, it will be updated, otherwise, it will be added.
111
     *
112
     * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method.
113
     * @param string $table the table to be commented or whose column is to be commented. The table name will be
114
     * properly quoted by the method.
115
     * @param string|null $column optional. The name of the column to be commented. If empty, the command will add the
116
     * comment to the table instead. The column name will be properly quoted by the method.
117
     *
118
     * @throws Exception|InvalidArgumentException if the table does not exist.
119
     *
120
     * @return string the SQL statement for adding a comment.
121
     */
122 4
    private function buildAddCommentSql(string $comment, string $table, ?string $column = null): string
123
    {
124 4
        $tableSchema = $this->queryBuilder->schema()->getTableSchema($table);
125
126 4
        if ($tableSchema === null) {
127
            throw new InvalidArgumentException("Table not found: $table");
128
        }
129
130 4
        $schemaName = $tableSchema->getSchemaName()
131 4
            ? "N'" . (string) $tableSchema->getSchemaName() . "'" : 'SCHEMA_NAME()';
132 4
        $tableName = 'N' . (string) $this->queryBuilder->quoter()->quoteValue($tableSchema->getName());
133 4
        $columnName = $column ? 'N' . (string) $this->queryBuilder->quoter()->quoteValue($column) : null;
134 4
        $comment = 'N' . (string) $this->queryBuilder->quoter()->quoteValue($comment);
135 4
        $functionParams = "
136
            @name = N'MS_description',
137 4
            @value = $comment,
138 4
            @level0type = N'SCHEMA', @level0name = $schemaName,
139 4
            @level1type = N'TABLE', @level1name = $tableName"
140 4
            . ($column ? ", @level2type = N'COLUMN', @level2name = $columnName" : '') . ';';
141
142 4
        return "
143
            IF NOT EXISTS (
144
                    SELECT 1
145
                    FROM fn_listextendedproperty (
146
                        N'MS_description',
147 4
                        'SCHEMA', $schemaName,
148 4
                        'TABLE', $tableName,
149 4
                        " . ($column ? "'COLUMN', $columnName " : ' DEFAULT, DEFAULT ') . "
150
                    )
151
            )
152 4
                EXEC sys.sp_addextendedproperty $functionParams
153
            ELSE
154 4
                EXEC sys.sp_updateextendedproperty $functionParams
155
        ";
156
    }
157
158
    /**
159
     * Builds a SQL command for removing a comment from a table or a column. The command built will check if a comment
160
     * already exists before trying to perform the removal.
161
     *
162
     * @param string $table the table that will have the comment removed or whose column will have the comment removed.
163
     * The table name will be properly quoted by the method.
164
     * @param string|null $column optional. The name of the column whose comment will be removed. If empty, the command
165
     * will remove the comment from the table instead. The column name will be properly quoted by the method.
166
     *
167
     * @throws Exception|InvalidArgumentException if the table does not exist.
168
     *
169
     * @return string the SQL statement for removing the comment.
170
     */
171 2
    private function buildRemoveCommentSql(string $table, ?string $column = null): string
172
    {
173 2
        $tableSchema = $this->queryBuilder->schema()->getTableSchema($table);
174
175 2
        if ($tableSchema === null) {
176
            throw new InvalidArgumentException("Table not found: $table");
177
        }
178
179 2
        $schemaName = $tableSchema->getSchemaName()
180 2
            ? "N'" . (string) $tableSchema->getSchemaName() . "'" : 'SCHEMA_NAME()';
181 2
        $tableName = 'N' . (string) $this->queryBuilder->quoter()->quoteValue($tableSchema->getName());
182 2
        $columnName = $column ? 'N' . (string) $this->queryBuilder->quoter()->quoteValue($column) : null;
183
184 2
        return "
185
            IF EXISTS (
186
                    SELECT 1
187
                    FROM fn_listextendedproperty (
188
                        N'MS_description',
189 2
                        'SCHEMA', $schemaName,
190 2
                        'TABLE', $tableName,
191 2
                        " . ($column ? "'COLUMN', $columnName " : ' DEFAULT, DEFAULT ') . "
192
                    )
193
            )
194
                EXEC sys.sp_dropextendedproperty
195
                    @name = N'MS_description',
196 2
                    @level0type = N'SCHEMA', @level0name = $schemaName,
197 2
                    @level1type = N'TABLE', @level1name = $tableName"
198 2
                    . ($column ? ", @level2type = N'COLUMN', @level2name = $columnName" : '') . ';';
199
    }
200
}
201