MSSQL   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 72
dl 0
loc 136
rs 10
c 0
b 0
f 0
wmc 28

5 Methods

Rating   Name   Duplication   Size   Complexity  
A createDatabase() 0 10 2
C fieldspec() 0 54 15
A createTable() 0 16 3
A showDatabases() 0 4 1
B select() 0 35 7
1
<?php
2
/**
3
 * Class MSSQL
4
 *
5
 * @filesource   MSSQL.php
6
 * @created      11.01.2018
7
 * @package      chillerlan\Database\Dialects
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2018 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database\Dialects;
14
15
class MSSQL extends DialectAbstract{
16
17
	protected array $quotes = ['[', ']'];
18
19
	/** @inheritdoc */
20
	public function select(array $cols, array $from, string $where = null, $limit = null, $offset = null, bool $distinct = null, array $groupby = null, array $orderby = null):array{
21
		$sql = ['SELECT'];
22
23
		if($distinct){
24
			$sql[] = 'DISTINCT';
25
		}
26
27
		!empty($cols)
28
			? $sql[] = implode(', ', $cols)
29
			: $sql[] = '*';
30
31
		$sql[] = 'FROM';
32
		$sql[] = implode(', ', $from);
33
		$sql[] = $where;
34
35
		if(!empty($groupby)){
36
			$sql[] = 'GROUP BY';
37
			$sql[] = implode(', ', $groupby);
38
		}
39
40
		if(!empty($orderby)){
41
			$sql[] = 'ORDER BY';
42
			$sql[] = implode(', ', $orderby);
43
		}
44
45
		if($limit !== null){
46
47
			if(empty($orderby)){
48
				$sql[] = 'ORDER BY 1';
49
			}
50
51
			$sql[] = 'OFFSET ? ROWS FETCH NEXT ? ROWS ONLY';
52
		}
53
54
		return $sql;
55
	}
56
57
	/** @inheritdoc */
58
	public function createDatabase(string $dbname, bool $ifNotExists = null, string $collate = null):array{
59
		$sql = [ 'CREATE DATABASE'];
60
		$sql[] = $this->quote($dbname);
61
62
		if($collate){
63
			$sql[] = 'COLLATE';
64
			$sql[] = $collate;
65
		}
66
67
		return $sql;
68
	}
69
70
	/** @inheritdoc */
71
	public function createTable(string $table, array $cols, string $primaryKey = null, bool $ifNotExists = null, bool $temp = null, string $dir = null):array{
72
		$sql = ['CREATE TABLE'];
73
		$sql[] = $this->quote($table);
74
75
		if(!empty($this->cols)){
76
			$sql[] = '(';
77
			$sql[] = implode(',', $cols);
78
79
			if($primaryKey){
80
				$sql[] = ', PRIMARY KEY ('.$this->quote($primaryKey).')';
81
			}
82
83
			$sql[] = ')';
84
		}
85
86
		return $sql;
87
	}
88
89
	/** @inheritdoc */
90
	public function fieldspec(string $name, string $type, $length = null, string $attribute = null, string $collation = null, bool $isNull = null, string $defaultType = null, $defaultValue = null, string $extra = null):string{
91
		$type = strtolower(trim($type));
92
93
		$field = [$this->quote(trim($name))];
94
95
		$type_translation = [
96
			'boolean'    => 'tinyint',
97
			'bool   '    => 'tinyint',
98
			'mediumint'  => 'int',
99
			'double'     => 'float',
100
			'tinytext'   => 'text',
101
			'mediumtext' => 'text',
102
			'longtext'   => 'text',
103
			'timestamp'  => 'datetime2',
104
		][$type] ?? $type;
105
106
		if((is_int($length) || is_string($length) && (count(explode(',', $length)) === 2 || $length === 'max'))
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (is_int($length) || is_s...etime2', 'time'), true), Probably Intended Meaning: is_int($length) || (is_s...time2', 'time'), true))
Loading history...
107
		   && in_array($type, ['char', 'varchar', 'nchar', 'nvarchar', 'decimal', 'numeric', 'datetime2', 'time'], true)){
108
			$field[] = $type_translation.'('.$length.')';
109
		}
110
		else{
111
			$field[] = $type_translation;
112
		}
113
114
		if($isNull !== null){
115
			$field[] = $isNull ? 'NULL' : 'NOT NULL';
116
		}
117
118
		$defaultType = strtoupper($defaultType);
0 ignored issues
show
Bug introduced by
It seems like $defaultType can also be of type null; however, parameter $string of strtoupper() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
		$defaultType = strtoupper(/** @scrutinizer ignore-type */ $defaultType);
Loading history...
119
120
		if($defaultType === 'USER_DEFINED'){
121
122
			// @todo
123
			switch(true){
124
				case $type === 'BOOLEAN':
125
					$field[] = 'DEFAULT '.(preg_match('/^1|T|TRUE|YES$/i', $defaultValue) ? '1' : '0');
126
					break;
127
				default:
128
					$field[] = 'DEFAULT \''.$defaultValue.'\'';
129
			}
130
131
		}
132
		elseif($defaultType === 'CURRENT_TIMESTAMP'){
133
			$field[] = 'DEFAULT CURRENT_TIMESTAMP';
134
		}
135
		elseif($defaultType === 'NULL' && $isNull === true){
136
			$field[] = 'DEFAULT NULL';
137
		}
138
139
		if($extra){
140
			$field[] = $extra;
141
		}
142
143
		return implode(' ', $field);
144
	}
145
146
	/** @inheritdoc */
147
	public function showDatabases():array{
148
		// https://stackoverflow.com/questions/147659/get-list-of-databases-from-sql-server
149
		// EXEC sp_databases
150
		return ['SELECT name AS [Database] FROM master.dbo.sysdatabases WHERE name NOT IN (\'master\', \'tempdb\', \'model\', \'msdb\')'];
151
	}
152
153
}
154