1
|
|
|
<?php /** MicroQuery */ |
2
|
|
|
|
3
|
|
|
namespace Micro\Mvc\Models; |
4
|
|
|
|
5
|
|
|
use Micro\Db\IConnection; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Query class file. |
9
|
|
|
* |
10
|
|
|
* @author Oleg Lunegov <[email protected]> |
11
|
|
|
* @link https://github.com/linpax/microphp-framework |
12
|
|
|
* @copyright Copyright (c) 2013 Oleg Lunegov |
13
|
|
|
* @license https://github.com/linpax/microphp-framework/blob/master/LICENSE |
14
|
|
|
* @package Micro |
15
|
|
|
* @subpackage Mvc\Models |
16
|
|
|
* @version 1.0 |
17
|
|
|
* @since 1.0 |
18
|
|
|
*/ |
19
|
|
|
class Query implements IQuery |
20
|
|
|
{ |
21
|
|
|
/** @var IConnection $db Connection */ |
22
|
|
|
public $db; |
23
|
|
|
|
24
|
|
|
/** @var string $select selectable columns */ |
25
|
|
|
public $select = '*'; |
26
|
|
|
/** @var boolean $distinct unique rows */ |
27
|
|
|
public $distinct = false; |
28
|
|
|
/** @var string $where condition */ |
29
|
|
|
public $where = ''; |
30
|
|
|
/** @var string $join joins tables */ |
31
|
|
|
public $join = ''; |
32
|
|
|
/** @var string $order sorting result rows */ |
33
|
|
|
public $order = ''; |
34
|
|
|
/** @var string $group grouping result rows */ |
35
|
|
|
public $group = ''; |
36
|
|
|
/** @var string $having condition for result rows */ |
37
|
|
|
public $having = ''; |
38
|
|
|
/** @var integer $limit count result rows */ |
39
|
|
|
public $limit = -1; |
40
|
|
|
/** @var integer $offset offset on start result rows */ |
41
|
|
|
public $offset = -1; |
42
|
|
|
/** @var array $params masks for where */ |
43
|
|
|
public $params = []; |
44
|
|
|
/** @var string $table table for query */ |
45
|
|
|
public $table = ''; |
46
|
|
|
/** @var string $objectName class name form fetching */ |
47
|
|
|
public $objectName = ''; |
48
|
|
|
/** @var boolean $single is one result? */ |
49
|
|
|
public $single = false; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Construct class |
53
|
|
|
* |
54
|
|
|
* @access public |
55
|
|
|
* |
56
|
|
|
* @param IConnection $db |
57
|
|
|
* |
58
|
|
|
* @result void |
59
|
|
|
*/ |
60
|
|
|
public function __construct(IConnection $db) |
61
|
|
|
{ |
62
|
|
|
$this->db = $db; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @inheritdoc |
67
|
|
|
*/ |
68
|
|
|
public function addSearch($column, $keyword, $escaped = false, $operand = 'AND') |
69
|
|
|
{ |
70
|
|
|
$keyword = $escaped ? $keyword : '"%'.$keyword.'%"'; |
71
|
|
|
$this->addWhere($column.' LIKE '.$keyword, $operand); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @inheritdoc |
76
|
|
|
*/ |
77
|
|
|
public function addWhere($sql, $operand = 'AND') |
78
|
|
|
{ |
79
|
|
|
$this->where .= $this->where ? ' '.$operand.' ('.$sql.')' : ' '.$this->where.' ('.$sql.')'; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* @inheritdoc |
84
|
|
|
*/ |
85
|
|
|
public function addNotSearch($column, $keyword, $escaped, $operand = 'AND') |
86
|
|
|
{ |
87
|
|
|
$keyword = $escaped ? $keyword : '"%'.$keyword.'%"'; |
88
|
|
|
$this->addWhere($column.' NOT LIKE '.$keyword, $operand); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* @inheritdoc |
93
|
|
|
*/ |
94
|
|
View Code Duplication |
public function addIn($column, $params, $operand = 'AND') |
|
|
|
|
95
|
|
|
{ |
96
|
|
|
if (is_array($params)) { |
97
|
|
|
$params = "'".implode('\',\'', $params).'\''; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
$this->addWhere($column.' IN ('.$params.')', $operand); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* @inheritdoc |
105
|
|
|
*/ |
106
|
|
View Code Duplication |
public function addNotIn($column, $params, $operand = 'AND') |
|
|
|
|
107
|
|
|
{ |
108
|
|
|
if (is_array($params)) { |
109
|
|
|
$params = "'".implode('\',\'', $params).'\''; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
$this->addWhere($column.' NOT IN ('.$params.')', $operand); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* @inheritdoc |
117
|
|
|
*/ |
118
|
|
|
public function addBetween($column, $start, $stop, $operand = 'AND') |
119
|
|
|
{ |
120
|
|
|
$this->addWhere($column.' BETWEEN '.$start.' AND '.$stop, $operand); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @inheritdoc |
125
|
|
|
*/ |
126
|
|
|
public function addNotBetween($column, $start, $stop, $operand = 'AND') |
127
|
|
|
{ |
128
|
|
|
$this->addWhere($column.' BETWEEN '.$start.' AND '.$stop, $operand); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* @inheritdoc |
133
|
|
|
*/ |
134
|
|
|
public function addJoin($table, $condition, $type = 'LEFT') |
135
|
|
|
{ |
136
|
|
|
$this->join .= ' '.$type.' JOIN '.$table.' ON '.$condition; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @inheritdoc |
141
|
|
|
*/ |
142
|
|
|
public function run($as = \PDO::FETCH_CLASS) |
143
|
|
|
{ |
144
|
|
|
$res = $this->db->rawQuery($this->getQuery(), $this->params, $as, $this->objectName); |
145
|
|
|
if ($this->single) { |
146
|
|
|
return !empty($res[0]) ? $res[0] : false; |
147
|
|
|
} else { |
148
|
|
|
return $res; |
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* @inheritdoc |
154
|
|
|
*/ |
155
|
|
|
public function getQuery() |
156
|
|
|
{ |
157
|
|
|
$query = 'SELECT '; |
158
|
|
|
$query .= $this->distinct ? 'DISTINCT ' : ''; |
159
|
|
|
$query .= $this->select.' FROM '.$this->table; |
160
|
|
|
$query .= $this->join ? ' '.$this->join : ''; |
161
|
|
|
$query .= $this->where ? ' WHERE '.$this->where : ''; |
162
|
|
|
$query .= $this->group ? ' GROUP BY '.$this->group : ''; |
163
|
|
|
$query .= $this->having ? ' HAVING '.$this->having : ''; |
164
|
|
|
$query .= $this->order ? ' ORDER BY '.$this->order : ''; |
165
|
|
|
|
166
|
|
|
if ($this->db->getDriverType() === 'pgsql') { |
167
|
|
|
if ($this->limit !== -1) { |
168
|
|
|
$query .= ' LIMIT ' . $this->limit . ' '; |
169
|
|
|
} |
170
|
|
|
if ($this->offset !== -1) { |
171
|
|
|
$query .= ' OFFSET ' . $this->offset . ' '; |
172
|
|
|
} |
173
|
|
|
} else { |
174
|
|
|
if ($this->limit !== -1) { |
175
|
|
|
$query .= ' LIMIT '; |
176
|
|
|
|
177
|
|
|
if ($this->offset !== -1) { |
178
|
|
|
$query .= $this->offset . ','; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
$query .= $this->limit; |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
return $query; |
186
|
|
|
} |
187
|
|
|
} |
188
|
|
|
|
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.