Completed
Push — master ( ead087...20edd5 )
by smiley
02:40
created

SelectAbstract   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 198
Duplicated Lines 3.03 %

Coupling/Cohesion

Components 5
Dependencies 2

Importance

Changes 0
Metric Value
wmc 36
lcom 5
dl 6
loc 198
rs 8.8
c 0
b 0
f 0
cbo 2

13 Methods

Rating   Name   Duplication   Size   Complexity  
A where() 0 3 1
A openBracket() 0 3 1
A closeBracket() 0 3 1
A distinct() 0 5 1
B addColumn() 6 16 9
B cols() 0 19 5
A _addFrom() 0 10 2
B from() 0 22 4
A limit() 0 5 1
A offset() 0 5 1
C orderby() 0 32 7
A groupBy() 0 8 2
A union() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Class SelectAbstract
4
 *
5
 * @filesource   SelectAbstract.php
6
 * @created      03.06.2017
7
 * @package      chillerlan\Database\Query\Dialects
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database\Query;
14
15
16
use chillerlan\Database\Query\Traits\WhereTrait;
17
18
abstract class SelectAbstract extends StatementAbstract implements SelectInterface{
19
	use WhereTrait;
20
21
	protected $distinct = false;
22
23
	protected $cols = [];
24
	protected $from = [];
25
	protected $where = [];
26
	protected $orderby = [];
27
	protected $groupby = [];
28
29
	public function where($val1, $val2, $operator = '=', $bind = true, $join = 'AND'):SelectInterface{
30
		return $this->_addWhere($val1, $val2, $operator, $bind, $join);
31
	}
32
33
	public function openBracket($join = null):SelectInterface{
34
		return $this->_openBracket($join);
35
	}
36
37
	public function closeBracket():SelectInterface{
38
		return $this->_closeBracket();
39
	}
40
41
	/**
42
	 * @return \chillerlan\Database\Query\SelectInterface
43
	 */
44
	public function distinct():SelectInterface{
45
		$this->distinct = true;
46
47
		return $this;
48
	}
49
50
	/**
51
	 * @param      $expr1
52
	 * @param null $expr2
53
	 * @param null $func
54
	 *
55
	 * @return void
56
	 */
57
	protected function addColumn($expr1, $expr2 = null, $func = null){
58
		// @todo: quotes
59
		switch(true){
60 View Code Duplication
			case  $expr2 && $func:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
As per coding-style, case should be followed by a single space.

As per the PSR-2 coding standard, there must be a space after the case keyword, instead of the test immediately following it.

switch (true) {
    case!isset($a):  //wrong
        doSomething();
        break;
    case !isset($b):  //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
61
				$col = sprintf('%s(%s) AS %s', strtoupper($func), $this->quote($expr1), $this->quote($expr2)); break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
62 View Code Duplication
			case  $expr2 && !$func:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
As per coding-style, case should be followed by a single space.

As per the PSR-2 coding standard, there must be a space after the case keyword, instead of the test immediately following it.

switch (true) {
    case!isset($a):  //wrong
        doSomething();
        break;
    case !isset($b):  //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
63
				$col = sprintf('%s AS %s', $this->quote($expr1), $this->quote($expr2)); break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
64 View Code Duplication
			case !$expr2 && $func:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
				$col = sprintf('%s(%s)', strtoupper($func), $this->quote($expr1)); break;
0 ignored issues
show
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
66
			case !$expr2 && !$func:
67
			default:
68
				$col = $this->quote($expr1);
69
		}
70
71
		$this->cols[$expr2 ?? $expr1] = $col;
72
	}
73
74
	/**
75
	 * @param array $expressions
76
	 *
77
	 * @return \chillerlan\Database\Query\SelectInterface
78
	 */
79
	public function cols(array $expressions):SelectInterface{
80
81
		foreach($expressions as $k => $ref){
82
83
			if(is_string($k)){
84
				is_array($ref)
85
					? $this->addColumn($ref[0], $k, $ref[1] ?? null)
86
					: $this->addColumn($ref ,$k);
87
			}
88
			else{
89
				is_array($ref)
90
					? $this->addColumn($ref[0], null, $ref[1] ?? null)
91
					: $this->addColumn($ref);
92
			}
93
94
		}
95
96
		return $this;
97
	}
98
99
	/**
100
	 * @param string      $table
101
	 * @param string|null $ref
102
	 */
103
	protected function _addFrom(string $table, string $ref = null){
104
		// @todo: quotes
105
		$from = $this->quote($table);
106
107
		if($ref){
0 ignored issues
show
Bug Best Practice introduced by
The expression $ref of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
108
			$from = sprintf('%s AS %s', $this->quote($ref), $this->quote($table));// @todo: index hint
109
		}
110
111
		$this->from[$ref ?? $table] = $from;
112
	}
113
114
	/**
115
	 * @param array $expressions
116
	 *
117
	 * @return \chillerlan\Database\Query\SelectInterface
118
	 */
119
	public function from(array $expressions):SelectInterface{
120
121
		foreach($expressions as $k => $ref){
122
123
			if(is_string($k)){
124
				$this->_addFrom($k, $ref);
125
			}
126
			else{
127
				$x = explode(' ', $ref);
128
129
				if(count($x) === 2){
130
					$this->_addFrom($x[0], $x[1]);
131
				}
132
				else{
133
					$this->_addFrom($ref);
134
				}
135
			}
136
137
		}
138
139
		return $this;
140
	}
141
142
	/**
143
	 * @param int $limit
144
	 *
145
	 * @return \chillerlan\Database\Query\SelectInterface
146
	 */
147
	public function limit(int $limit):SelectInterface{
148
		$this->limit = $limit;
149
150
		return $this;
151
	}
152
153
	/**
154
	 * @param int $offset
155
	 *
156
	 * @return \chillerlan\Database\Query\SelectInterface
157
	 */
158
	public function offset(int $offset):SelectInterface{
159
		$this->offset = $offset;
160
161
		return $this;
162
	}
163
164
	/**
165
	 * @param array $expressions
166
	 *
167
	 * @return \chillerlan\Database\Query\SelectInterface
168
	 */
169
	public function orderby(array $expressions):SelectInterface{
170
171
		foreach($expressions as $alias => $expression){
172
173
			if(is_string($alias)){
174
175
				if(is_array($expression)){
176
					$dir = strtoupper($expression[0]);
177
178
					if(in_array($dir, ['ASC', 'DESC'])){
179
						$this->orderby[] =  isset($expression[1]) ? strtoupper($expression[1]).'('.$this->quote($alias).') '.$dir : $dir;
180
					}
181
182
				}
183
				else{
184
					$dir = strtoupper($expression);
185
186
					if(in_array($dir, ['ASC', 'DESC'])){
187
						$this->orderby[] =  $this->quote($alias).' '.$dir;
188
					}
189
190
				}
191
192
			}
193
			else{
194
				$this->orderby[] = $this->quote($expression);
195
			}
196
197
		}
198
199
		return $this;
200
	}
201
202
	public function groupBy(array $expressions):SelectInterface{
203
204
		foreach($expressions as $expression){
205
			$this->groupby[] = $expression;
206
		}
207
208
		return $this;
209
	}
210
211
	public function union():SelectInterface{
212
		// TODO: Implement union() method.
213
	}
214
215
}
216