Passed
Push — develop ( e333c2...b3554d )
by nguereza
02:25
created

SQLServer::getTypeEnum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Platine Database
5
 *
6
 * Platine Database is the abstraction layer using PDO with support of query and schema builder
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine Database
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
13
 * of this software and associated documentation files (the "Software"), to deal
14
 * in the Software without restriction, including without limitation the rights
15
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
 * copies of the Software, and to permit persons to whom the Software is
17
 * furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included in all
20
 * copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
 * SOFTWARE.
29
 */
30
31
/**
32
 *  @file SQLServer.php
33
 *
34
 *  The SQLServer Driver class
35
 *
36
 *  @package    Platine\Database\Driver
37
 *  @author Platine Developers Team
38
 *  @copyright  Copyright (c) 2020
39
 *  @license    http://opensource.org/licenses/MIT  MIT License
40
 *  @link   http://www.iacademy.cf
41
 *  @version 1.0.0
42
 *  @filesource
43
 */
44
45
declare(strict_types=1);
46
47
namespace Platine\Database\Driver;
48
49
use Platine\Database\Query\QueryStatement;
50
use Platine\Database\Schema\AlterTable;
51
use Platine\Database\Schema\BaseColumn;
52
use Platine\Database\Schema\CreateTable;
53
54
/**
55
 * Class SQLServer
56
 * @package Platine\Database\Driver
57
 */
58
class SQLServer extends Driver
59
{
0 ignored issues
show
Coding Style introduced by
Opening brace must not be followed by a blank line
Loading history...
60
61
    /**
62
     * @inheritdoc
63
     * @var string
64
     */
65
    protected string $dateFormat = 'Y-m-d H:i:s.0000000';
66
67
    /**
68
     * @inheritdoc
69
     * @var string
70
     */
71
    protected string $identifier = '[%s]';
72
73
    /**
74
     * @inheritDoc
75
     */
76
    protected array $modifiers = [
77
        'nullable',
78
        'default',
79
        'autoincrement',
80
        'description'
81
    ];
82
83
    /**
84
     * @inheritDoc
85
     */
86
    protected string $autoincrement = 'IDENTITY';
87
88
    /**
89
     * @inheritDoc
90
     */
91
    public function select(QueryStatement $select): string
92
    {
93
        $limit = $select->getLimit();
94
        if ($limit <= 0) {
95
            return parent::select($select);
96
        }
97
        $offset = $select->getOffset();
98
99
        if ($offset < 0) {
100
            $sql = $select->hasDistinct() ? 'SELECT DISTINCT ' : 'SELECT ';
101
            $sql .= 'TOP ' . $limit . ' ';
102
            $sql .= $this->getColumnList($select->getColumns());
103
            $sql .= $this->getInto($select->getIntoTable());
104
            $sql .= ' FROM ';
105
            $sql .= $this->getTableList($select->getTables());
106
            $sql .= $this->getJoins($select->getJoins());
107
            $sql .= $this->getWheres($select->getWheres());
108
            $sql .= $this->getGroupBy($select->getGroupBy());
109
            $sql .= $this->getHaving($select->getHaving());
110
            $sql .= $this->getOrders($select->getOrder());
111
112
            return $sql;
113
        }
114
115
        $order = trim($this->getOrders($select->getOrder()));
116
117
        if (empty($order)) {
118
            $order = 'ORDER BY (SELECT 0)';
119
        }
120
121
        $sql = $select->hasDistinct() ? 'SELECT DISTINCT ' : 'SELECT ';
122
        $sql .= $this->getColumnList($select->getColumns());
123
        $sql .= ', ROW_NUMBER() OVER (' . $order . ') AS P_ROWNUM';
124
        $sql .= ' FROM ';
125
        $sql .= $this->getTableList($select->getTables());
126
        $sql .= $this->getJoins($select->getJoins());
127
        $sql .= $this->getWheres($select->getWheres());
128
        $sql .= $this->getGroupBy($select->getGroupBy());
129
        $sql .= $this->getHaving($select->getHaving());
130
131
        $limit += $offset;
132
        $offset++;
133
134
        return sprintf(
135
            'SELECT * FROM (%s) AS A1 WHERE P_ROWNUM BETWEEN %d AND %d',
136
            $sql,
137
            $offset,
138
            $limit
139
        );
140
    }
141
142
    /**
143
     * @inheritDoc
144
     */
145
    public function update(QueryStatement $update): string
146
    {
147
        $joins = $this->getJoins($update->getJoins());
148
        $tables = $update->getTables();
149
150
        if ($joins !== '') {
151
            $joins = ' FROM ' . $this->getTableList($tables) . ' ' . $joins;
152
            $tables = array_values($tables);
153
        }
154
        $sql = 'UPDATE ';
155
        $sql .= $this->getTableList($tables);
156
        $sql .= $this->getSetColumns($update->getColumns());
157
        $sql .= $joins;
158
        $sql .= $this->getWheres($update->getWheres());
159
160
        return $sql;
161
    }
162
163
    /**
164
     * @inheritdoc
165
     */
166
    public function renameTable(string $current, string $new): array
167
    {
168
        return [
169
            'sql' => 'sp_rename ' . $this->quoteIdentifier($current)
170
            . ', ' . $this->quoteIdentifier($new),
171
            'params' => []
172
        ];
173
    }
174
175
    /**
176
     * @inheritDoc
177
     */
178
    public function getDatabaseName(): array
179
    {
180
        return [
181
            'sql' => 'SELECT SCHEMA_NAME()',
182
            'params' => []
183
        ];
184
    }
185
186
    /**
187
     * @inheritDoc
188
     */
189
    public function getColumns(string $database, string $table): array
190
    {
191
        $sql = sprintf(
192
            'SELECT %s AS %s, %s AS %s FROM %s.%s WHERE %s = ? '
193
                . 'AND %s = ? ORDER BY %s ASC',
194
            $this->quoteIdentifier('column_name'),
195
            $this->quoteIdentifier('name'),
196
            $this->quoteIdentifier('data_type'),
197
            $this->quoteIdentifier('type'),
198
            $this->quoteIdentifier('information_schema'),
199
            $this->quoteIdentifier('columns'),
200
            $this->quoteIdentifier('table_schema'),
201
            $this->quoteIdentifier('table_name'),
202
            $this->quoteIdentifier('ordinal_position'),
203
        );
204
205
        return [
206
            'sql' => $sql,
207
            'params' => [$database, $table]
208
        ];
209
    }
210
211
    /**
212
     * @inheritdoc
213
     */
214
    protected function getTypeInteger(BaseColumn $column): string
215
    {
216
        $type = 'INTEGER';
217
        switch ($column->get('size', 'normal')) {
218
            case 'tiny':
219
                $type = 'TINYINT';
220
                break;
221
            case 'small':
222
                $type = 'SMALLINT';
223
                break;
224
            case 'medium':
225
                $type = 'INTEGER';
226
                break;
227
            case 'big':
228
                $type = 'BIGINT';
229
                break;
230
        }
231
        return $type;
232
    }
233
234
    /**
235
     * @inheritdoc
236
     */
237
    protected function getTypeDecimal(BaseColumn $column): string
238
    {
239
        $type = 'DECIMAL';
240
        $length = $column->get('length');
241
        $precision = $column->get('precision');
242
        if ($length !== null) {
243
            if ($precision === null) {
244
                $type = 'DECIMAL(' . $this->value($length) . ')';
245
            } else {
246
                $type = 'DECIMAL(' . $this->value($length) . ', '
247
                        . $this->value($precision) . ')';
248
            }
249
        }
250
251
        return $type;
252
    }
253
    
254
    /**
255
     * @inheritdoc
256
     */
257
    protected function getTypeEnum(BaseColumn $column): string
258
    {
259
        // TODO
260
261
        return '';
262
    }
263
264
    /**
265
     * @inheritdoc
266
     */
267
    protected function getTypeBoolean(BaseColumn $column): string
268
    {
269
        return 'BIT';
270
    }
271
272
    /**
273
     * @inheritdoc
274
     */
275
    protected function getTypeString(BaseColumn $column): string
276
    {
277
        return 'NVARCHAR(' . $this->value($column->get('length', 255)) . ')';
278
    }
279
280
    /**
281
     * @inheritdoc
282
     */
283
    protected function getTypeFixed(BaseColumn $column): string
284
    {
285
        return 'NCHAR(' . $this->value($column->get('length', 255)) . ')';
286
    }
287
288
    /**
289
     * @inheritdoc
290
     */
291
    protected function getTypeText(BaseColumn $column): string
292
    {
293
        return 'NVARCHAR(max)';
294
    }
295
296
    /**
297
     * @inheritdoc
298
     */
299
    protected function getTypeBinary(BaseColumn $column): string
300
    {
301
        return 'VARBINARY(max)';
302
    }
303
304
    /**
305
     * @inheritdoc
306
     */
307
    protected function getTypeTimestamp(BaseColumn $column): string
308
    {
309
        return 'DATETIME';
310
    }
311
312
    /**
313
     * @inheritdoc
314
     */
315
    protected function getRenameColumn(AlterTable $schema, $data): string
316
    {
317
        $column = $data['column'];
318
        return sprintf(
319
            'sp_rename %s.%s, %s, COLUMN',
320
            $this->quoteIdentifier($schema->getTableName()),
321
            $this->quoteIdentifier($data['from']),
322
            $this->quoteIdentifier($column->getName())
323
        );
324
    }
325
326
    /**
327
     * @inheritdoc
328
     */
329
    protected function getEngine(CreateTable $schema): string
330
    {
331
        return '';
332
    }
333
}
334