Completed
Push — develop ( d41f6b...ea130d )
by Michael
03:07
created

Query   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 279
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 8
Bugs 0 Features 4
Metric Value
wmc 31
c 8
b 0
f 4
lcom 1
cbo 2
dl 0
loc 279
ccs 85
cts 85
cp 1
rs 9.8

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A __toString() 0 4 1
A select() 0 6 2
A insert() 0 7 1
A update() 0 6 1
A delete() 0 6 1
A join() 0 6 1
A leftJoin() 0 6 1
A rightJoin() 0 6 1
A crossJoin() 0 6 1
A where() 0 10 3
A groupBy() 0 6 1
A orderBy() 0 6 1
A limit() 0 6 1
A offset() 0 6 1
A execute() 0 14 3
A getPdoDataType() 0 14 4
A addBinding() 0 6 1
A addBindings() 0 10 2
A setBinding() 0 4 1
A setBindings() 0 4 1
A removeBindings() 0 6 1
1
<?php
2
3
/**
4
 * This file is part of the miBadger package.
5
 *
6
 * @author Michael Webbers <[email protected]>
7
 * @license http://opensource.org/licenses/Apache-2.0 Apache v2 License
8
 * @version 1.0.0
9
 */
10
11
namespace miBadger\Query;
12
13
/**
14
 * The query class.
15
 *
16
 * @since 1.0.0
17
 */
18
class Query implements QueryInterface
19
{
20
	/* @var \PDO The PDO. */
21
	private $pdo;
22
23
	/* @var array The bindings. */
24
	private $bindings;
25
26
	/* @var QueryBuilder The query builder. */
27
	private $queryBuilder;
28
29
	/**
30
	 * Construct a query object with the given pdo and table.
31
	 *
32
	 * @param \PDO $pdo
33
	 * @param string $table
34
	 */
35 21
	public function __construct(\PDO $pdo, $table)
36
	{
37 21
		$this->pdo = $pdo;
38 21
		$this->bindings = [];
39 21
		$this->queryBuilder = new QueryBuilder($table);
40 21
	}
41
42
	/**
43
	 * Returns a string representation of the query object.
44
	 *
45
	 * @return string a string representation of the query object.
46
	 */
47 21
	public function __toString()
48
	{
49 21
		return $this->queryBuilder->__toString();
50
	}
51
52
	/**
53
	 * {@inheritdoc}
54
	 */
55 17
	public function select($columns = ['*'])
56
	{
57 17
		$this->queryBuilder->select(is_array($columns) ? $columns : func_get_args());
58
59 17
		return $this;
60
	}
61
62
	/**
63
	 * {@inheritdoc}
64
	 */
65 1
	public function insert(array $values)
66
	{
67 1
		$this->bindings['insert'] = [];
68 1
		$this->queryBuilder->insert($this->setBindings('insert', $values));
69
70 1
		return $this;
71
	}
72
73
	/**
74
	 * {@inheritdoc}
75
	 */
76 1
	public function update(array $values)
77
	{
78 1
		$this->queryBuilder->update($this->setBindings('update', $values));
79
80 1
		return $this;
81
	}
82
83
	/**
84
	 * {@inheritdoc}
85
	 */
86 1
	public function delete()
87
	{
88 1
		$this->queryBuilder->delete();
89
90 1
		return $this;
91
	}
92
93
	/**
94
	 * {@inheritdoc}
95
	 */
96 1
	public function join($table, $primary, $operator, $secondary)
97
	{
98 1
		$this->queryBuilder->join($table, $primary, $operator, $secondary);
99
100 1
		return $this;
101
	}
102
103
	/**
104
	 * {@inheritdoc}
105
	 */
106 1
	public function leftJoin($table, $primary, $operator, $secondary)
107
	{
108 1
		$this->queryBuilder->leftJoin($table, $primary, $operator, $secondary);
109
110 1
		return $this;
111
	}
112
113
	/**
114
	 * {@inheritdoc}
115
	 */
116 1
	public function rightJoin($table, $primary, $operator, $secondary)
117
	{
118 1
		$this->queryBuilder->rightJoin($table, $primary, $operator, $secondary);
119
120 1
		return $this;
121
	}
122
123
	/**
124
	 * {@inheritdoc}
125
	 */
126 1
	public function crossJoin($table, $primary, $operator, $secondary)
127
	{
128 1
		$this->queryBuilder->crossJoin($table, $primary, $operator, $secondary);
129
130 1
		return $this;
131
	}
132
133
	/**
134
	 * {@inheritdoc}
135
	 */
136 7
	public function where($column, $operator, $value)
137
	{
138 7
		if ($operator == 'IN' && is_array($value)) {
139 1
			$this->queryBuilder->where($column, 'IN', $this->addBindings('where', $value));
140 1
		} else {
141 6
			$this->queryBuilder->where($column, $operator, $this->addBinding('where', $value));
142
		}
143
144 7
		return $this;
145
	}
146
147
	/**
148
	 * {@inheritdoc}
149
	 */
150 1
	public function groupBy($column)
151
	{
152 1
		$this->queryBuilder->groupBy($column);
153
154 1
		return $this;
155
	}
156
157
	/**
158
	 * {@inheritdoc}
159
	 */
160 1
	public function orderBy($column, $order = null)
161
	{
162 1
		$this->queryBuilder->orderBy($column, $order);
163
164 1
		return $this;
165
	}
166
167
	/**
168
	 * {@inheritdoc}
169
	 */
170 2
	public function limit($limit)
171
	{
172 2
		$this->queryBuilder->limit($this->setBinding('limit', (int) $limit));
173
174 2
		return $this;
175
	}
176
177
	/**
178
	 * {@inheritdoc}
179
	 */
180 1
	public function offset($offset)
181
	{
182 1
		$this->queryBuilder->offset($this->setBinding('offset', (int) $offset));
183
184 1
		return $this;
185
	}
186
187
	/**
188
	 * Returns the result of the executed prepared query.
189
	 *
190
	 * @return QueryResult the result of the executed prepared query.
191
	 */
192 4
	public function execute()
193
	{
194 4
		$pdoStatement = $this->pdo->prepare((string) $this);
195
196 4
		foreach ($this->bindings as $clause => $predicate) {
197 1
			foreach ($predicate as $key => $value) {
198 1
				$pdoStatement->bindValue(sprintf(':%s%d', $clause, $key + 1), $value, $this->getPdoDataType($value));
199 1
			}
200 4
		}
201
202 4
		$pdoStatement->execute();
203
204 4
		return new QueryResult($pdoStatement);
205
	}
206
207
	/**
208
	 * Returns the data type of the given value.
209
	 *
210
	 * @param mixed $value
211
	 * @return int the data type of the given value.
212
	 */
213 1
	private function getPdoDataType($value)
214
	{
215 1
		$result = \PDO::PARAM_STR;
216
217 1
		if (is_bool($value)) {
218 1
			$result = \PDO::PARAM_BOOL;
219 1
		} elseif (is_null($value)) {
220 1
			$result = \PDO::PARAM_NULL;
221 1
		} elseif (is_int($value)) {
222 1
			$result = \PDO::PARAM_INT;
223 1
		}
224
225 1
		return $result;
226
	}
227
228
	/**
229
	 * TODO (Returns the bindings that are associated with the given clause.)
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
230
	 *
231
	 * @param array $values
0 ignored issues
show
Documentation introduced by
There is no parameter named $values. Did you maybe mean $value?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
232
	 * @param string $clause
233
	 * @return string TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
234
	 */
235 10
	private function addBinding($clause, $value)
236
	{
237 10
		$this->bindings[$clause][] = $value;
238
239 10
		return sprintf(':%s%d', $clause, count($this->bindings[$clause]));
240
	}
241
242
	/**
243
	 * TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
244
	 *
245
	 * @param array $values
246
	 * @param string $clause
247
	 * @return array TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
248
	 */
249 3
	private function addBindings($clause, array $values)
250
	{
251 3
		$result = [];
252
253 3
		foreach ($values as $key => $value) {
254 3
			$result[$key] = $this->addBinding($clause, $value);
255 3
		}
256
257 3
		return $result;
258
	}
259
260
	/**
261
	 * TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
262
	 *
263
	 * @param array $values
0 ignored issues
show
Documentation introduced by
There is no parameter named $values. Did you maybe mean $value?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
264
	 * @param string $clause
265
	 * @return string TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
266
	 */
267 2
	private function setBinding($clause, $value)
268
	{
269 2
		return $this->removeBindings($clause)->addBinding($clause, $value);
270
	}
271
272
	/**
273
	 * TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
274
	 *
275
	 * @param array $values
276
	 * @param string $clause
277
	 * @return array TODO
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
278
	 */
279 2
	private function setBindings($clause, array $values)
280
	{
281 2
		return $this->removeBindings($clause)->addBindings($clause, $values);
282
	}
283
284
	/**
285
	 * Remove the bindings that are associated with the given caluse.
286
	 *
287
	 * @param string $clause
288
	 * @return $this
289
	 */
290 4
	private function removeBindings($clause)
291
	{
292 4
		$this->bindings[$clause] = [];
293
294 4
		return $this;
295
	}
296
}
297