1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace BfwSql\Queries; |
4
|
|
|
|
5
|
|
|
use \BfwSql\SqlConnect; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Class to write SELECT queries |
9
|
|
|
* |
10
|
|
|
* @package bfw-sql |
11
|
|
|
* @author Vermeulen Maxime <[email protected]> |
12
|
|
|
* @version 2.0 |
13
|
|
|
*/ |
14
|
|
|
class Select extends AbstractQuery |
15
|
|
|
{ |
16
|
|
|
use JoinTrait; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Constructor |
20
|
|
|
* |
21
|
|
|
* @param \BfwSql\SqlConnect $sqlConnect Instance of SGBD connexion |
22
|
|
|
* @param string $returnType PHP type used for return result |
23
|
|
|
*/ |
24
|
|
|
public function __construct(SqlConnect $sqlConnect, string $returnType) |
25
|
|
|
{ |
26
|
|
|
parent::__construct($sqlConnect); |
27
|
|
|
|
28
|
|
|
$this->executer = new \BfwSql\Executers\Select($this); |
29
|
|
|
$this->executer->setReturnType($returnType); |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* {@inheritdoc} |
34
|
|
|
*/ |
35
|
|
|
protected function defineQueriesParts() |
36
|
|
|
{ |
37
|
|
|
parent::defineQueriesParts(); |
38
|
|
|
|
39
|
|
|
$this->queriesParts['subQuery'] = new Parts\SubQueryList($this); |
40
|
|
|
$this->queriesParts['from'] = $this->queriesParts['table']; |
41
|
|
|
$this->queriesParts['join'] = new Parts\JoinList($this); |
42
|
|
|
$this->queriesParts['joinLeft'] = new Parts\JoinList($this); |
43
|
|
|
$this->queriesParts['joinRight'] = new Parts\JoinList($this); |
44
|
|
|
$this->queriesParts['order'] = new Parts\OrderList($this); |
45
|
|
|
$this->queriesParts['limit'] = new Parts\Limit($this); |
46
|
|
|
$this->queriesParts['group'] = new Parts\CommonList($this); |
47
|
|
|
|
48
|
|
|
$this->joinDefinePrefix(); |
49
|
|
|
$this->queriesParts['group']->setSeparator(','); |
50
|
|
|
$this->queriesParts['group']->setPartPrefix('GROUP BY'); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* {@inheritdoc} |
55
|
|
|
*/ |
56
|
|
|
protected function obtainGenerateOrder(): array |
57
|
|
|
{ |
58
|
|
|
return [ |
59
|
|
|
'select' => [ |
60
|
|
|
'prefix' => 'SELECT', |
61
|
|
|
'callback' => [$this, 'generateSelect'], |
62
|
|
|
'canBeEmpty' => false |
63
|
|
|
], |
64
|
|
|
'from' => [ |
65
|
|
|
'prefix' => 'FROM', |
66
|
|
|
'canBeEmpty' => false |
67
|
|
|
], |
68
|
|
|
'join' => [], |
69
|
|
|
'joinLeft' => [], |
70
|
|
|
'joinRight' => [], |
71
|
|
|
'where' => [], |
72
|
|
|
'group' => [], |
73
|
|
|
'order' => [], |
74
|
|
|
'limit' => [] |
75
|
|
|
]; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Callback used by assembleRequestPart method |
80
|
|
|
* Generate the sql query for the SELECT part who contains all columns to |
81
|
|
|
* return and all sub-queries defined. |
82
|
|
|
* |
83
|
|
|
* @return string |
84
|
|
|
*/ |
85
|
|
|
protected function generateSelect(): string |
86
|
|
|
{ |
87
|
|
|
$sqlParts = $this->queriesParts['from']->getColumns()->generate(); |
88
|
|
|
|
89
|
|
|
$joinKeyList = ['join', 'joinLeft', 'joinRight']; |
90
|
|
View Code Duplication |
foreach ($joinKeyList as $joinKeyName) { |
|
|
|
|
91
|
|
|
foreach ($this->queriesParts[$joinKeyName] as $join) { |
92
|
|
|
$joinSql = $join->getColumns()->generate(); |
93
|
|
|
|
94
|
|
|
if (empty($joinSql)) { |
95
|
|
|
continue; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
if ($sqlParts !== '') { |
99
|
|
|
$sqlParts .= ','; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$sqlParts .= $joinSql; |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
$sqlSubQueries = $this->queriesParts['subQuery']->generate(); |
107
|
|
|
if ($sqlParts !== '' && $sqlSubQueries !== '') { |
108
|
|
|
$sqlParts .= ','; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
$sqlParts .= $sqlSubQueries; |
112
|
|
|
|
113
|
|
|
return $sqlParts; |
114
|
|
|
} |
115
|
|
|
} |
116
|
|
|
|
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.