Completed
Push — master ( a8d9bf...b4cf55 )
by Lukas
23:32 queued 12:39
created

QueryBuilder::automaticTablePrefix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Robin Appelman <[email protected]>
7
 * @author Thomas Müller <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC\DB\QueryBuilder;
26
27
use Doctrine\DBAL\Platforms\MySqlPlatform;
28
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
29
use OC\DB\OracleConnection;
30
use OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder;
31
use OC\DB\QueryBuilder\ExpressionBuilder\MySqlExpressionBuilder;
32
use OC\DB\QueryBuilder\ExpressionBuilder\OCIExpressionBuilder;
33
use OC\DB\QueryBuilder\ExpressionBuilder\PgSqlExpressionBuilder;
34
use OC\SystemConfig;
35
use OCP\DB\QueryBuilder\IQueryBuilder;
36
use OCP\DB\QueryBuilder\IQueryFunction;
37
use OCP\DB\QueryBuilder\IParameter;
38
use OCP\IDBConnection;
39
use OCP\ILogger;
40
41
class QueryBuilder implements IQueryBuilder {
42
43
	/** @var \OCP\IDBConnection */
44
	private $connection;
45
46
	/** @var SystemConfig */
47
	private $systemConfig;
48
49
	/** @var ILogger */
50
	private $logger;
51
52
	/** @var \Doctrine\DBAL\Query\QueryBuilder */
53
	private $queryBuilder;
54
55
	/** @var QuoteHelper */
56
	private $helper;
57
58
	/** @var bool */
59
	private $automaticTablePrefix = true;
60
61
	/** @var string */
62
	protected $lastInsertedTable;
63
64
	/**
65
	 * Initializes a new QueryBuilder.
66
	 *
67
	 * @param IDBConnection $connection
68
	 * @param SystemConfig $systemConfig
69
	 * @param ILogger $logger
70
	 */
71
	public function __construct(IDBConnection $connection, SystemConfig $systemConfig, ILogger $logger) {
72
		$this->connection = $connection;
73
		$this->systemConfig = $systemConfig;
74
		$this->logger = $logger;
75
		$this->queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder($this->connection);
76
		$this->helper = new QuoteHelper();
77
	}
78
79
	/**
80
	 * Enable/disable automatic prefixing of table names with the oc_ prefix
81
	 *
82
	 * @param bool $enabled If set to true table names will be prefixed with the
83
	 * owncloud database prefix automatically.
84
	 * @since 8.2.0
85
	 */
86
	public function automaticTablePrefix($enabled) {
87
		$this->automaticTablePrefix = (bool) $enabled;
88
	}
89
90
	/**
91
	 * Gets an ExpressionBuilder used for object-oriented construction of query expressions.
92
	 * This producer method is intended for convenient inline usage. Example:
93
	 *
94
	 * <code>
95
	 *     $qb = $conn->getQueryBuilder()
96
	 *         ->select('u')
97
	 *         ->from('users', 'u')
98
	 *         ->where($qb->expr()->eq('u.id', 1));
99
	 * </code>
100
	 *
101
	 * For more complex expression construction, consider storing the expression
102
	 * builder object in a local variable.
103
	 *
104
	 * @return \OCP\DB\QueryBuilder\IExpressionBuilder
105
	 */
106
	public function expr() {
107
		if ($this->connection instanceof OracleConnection) {
108
			return new OCIExpressionBuilder($this->connection);
109
		} else if ($this->connection->getDatabasePlatform() instanceof PostgreSqlPlatform) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\Platforms\PostgreSqlPlatform does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
110
			return new PgSqlExpressionBuilder($this->connection);
111
		} else if ($this->connection->getDatabasePlatform() instanceof MySqlPlatform) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\Platforms\MySqlPlatform does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
112
			return new MySqlExpressionBuilder($this->connection);
113
		} else {
114
			return new ExpressionBuilder($this->connection);
115
		}
116
	}
117
118
	/**
119
	 * Gets the type of the currently built query.
120
	 *
121
	 * @return integer
122
	 */
123
	public function getType() {
124
		return $this->queryBuilder->getType();
125
	}
126
127
	/**
128
	 * Gets the associated DBAL Connection for this query builder.
129
	 *
130
	 * @return \OCP\IDBConnection
131
	 */
132
	public function getConnection() {
133
		return $this->connection;
134
	}
135
136
	/**
137
	 * Gets the state of this query builder instance.
138
	 *
139
	 * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
140
	 */
141
	public function getState() {
142
		return $this->queryBuilder->getState();
143
	}
144
145
	/**
146
	 * Executes this query using the bound parameters and their types.
147
	 *
148
	 * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
149
	 * for insert, update and delete statements.
150
	 *
151
	 * @return \Doctrine\DBAL\Driver\Statement|int
152
	 */
153
	public function execute() {
154
		if ($this->systemConfig->getValue('log_query', false)) {
155
			$params = [];
156
			foreach ($this->getParameters() as $placeholder => $value) {
157
				if (is_array($value)) {
158
					$params[] = $placeholder . ' => (\'' . implode('\', \'', $value) . '\')';
159
				} else {
160
					$params[] = $placeholder . ' => \'' . $value . '\'';
161
				}
162
			}
163
			if (empty($params)) {
164
				$this->logger->debug('DB QueryBuilder: \'{query}\'', [
165
					'query' => $this->getSQL(),
166
					'app' => 'core',
167
				]);
168
			} else {
169
				$this->logger->debug('DB QueryBuilder: \'{query}\' with parameters: {params}', [
170
					'query' => $this->getSQL(),
171
					'params' => implode(', ', $params),
172
					'app' => 'core',
173
				]);
174
			}
175
		}
176
177
		return $this->queryBuilder->execute();
178
	}
179
180
	/**
181
	 * Gets the complete SQL string formed by the current specifications of this QueryBuilder.
182
	 *
183
	 * <code>
184
	 *     $qb = $conn->getQueryBuilder()
185
	 *         ->select('u')
186
	 *         ->from('User', 'u')
187
	 *     echo $qb->getSQL(); // SELECT u FROM User u
188
	 * </code>
189
	 *
190
	 * @return string The SQL query string.
191
	 */
192
	public function getSQL() {
193
		return $this->queryBuilder->getSQL();
194
	}
195
196
	/**
197
	 * Sets a query parameter for the query being constructed.
198
	 *
199
	 * <code>
200
	 *     $qb = $conn->getQueryBuilder()
201
	 *         ->select('u')
202
	 *         ->from('users', 'u')
203
	 *         ->where('u.id = :user_id')
204
	 *         ->setParameter(':user_id', 1);
205
	 * </code>
206
	 *
207
	 * @param string|integer $key The parameter position or name.
208
	 * @param mixed $value The parameter value.
209
	 * @param string|null $type One of the IQueryBuilder::PARAM_* constants.
210
	 *
211
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
212
	 */
213
	public function setParameter($key, $value, $type = null) {
214
		$this->queryBuilder->setParameter($key, $value, $type);
215
216
		return $this;
217
	}
218
219
	/**
220
	 * Sets a collection of query parameters for the query being constructed.
221
	 *
222
	 * <code>
223
	 *     $qb = $conn->getQueryBuilder()
224
	 *         ->select('u')
225
	 *         ->from('users', 'u')
226
	 *         ->where('u.id = :user_id1 OR u.id = :user_id2')
227
	 *         ->setParameters(array(
228
	 *             ':user_id1' => 1,
229
	 *             ':user_id2' => 2
230
	 *         ));
231
	 * </code>
232
	 *
233
	 * @param array $params The query parameters to set.
234
	 * @param array $types The query parameters types to set.
235
	 *
236
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
237
	 */
238
	public function setParameters(array $params, array $types = array()) {
239
		$this->queryBuilder->setParameters($params, $types);
240
241
		return $this;
242
	}
243
244
	/**
245
	 * Gets all defined query parameters for the query being constructed indexed by parameter index or name.
246
	 *
247
	 * @return array The currently defined query parameters indexed by parameter index or name.
248
	 */
249
	public function getParameters() {
250
		return $this->queryBuilder->getParameters();
251
	}
252
253
	/**
254
	 * Gets a (previously set) query parameter of the query being constructed.
255
	 *
256
	 * @param mixed $key The key (index or name) of the bound parameter.
257
	 *
258
	 * @return mixed The value of the bound parameter.
259
	 */
260
	public function getParameter($key) {
261
		return $this->queryBuilder->getParameter($key);
262
	}
263
264
	/**
265
	 * Gets all defined query parameter types for the query being constructed indexed by parameter index or name.
266
	 *
267
	 * @return array The currently defined query parameter types indexed by parameter index or name.
268
	 */
269
	public function getParameterTypes() {
270
		return $this->queryBuilder->getParameterTypes();
271
	}
272
273
	/**
274
	 * Gets a (previously set) query parameter type of the query being constructed.
275
	 *
276
	 * @param mixed $key The key (index or name) of the bound parameter type.
277
	 *
278
	 * @return mixed The value of the bound parameter type.
279
	 */
280
	public function getParameterType($key) {
281
		return $this->queryBuilder->getParameterType($key);
282
	}
283
284
	/**
285
	 * Sets the position of the first result to retrieve (the "offset").
286
	 *
287
	 * @param integer $firstResult The first result to return.
288
	 *
289
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
290
	 */
291
	public function setFirstResult($firstResult) {
292
		$this->queryBuilder->setFirstResult($firstResult);
293
294
		return $this;
295
	}
296
297
	/**
298
	 * Gets the position of the first result the query object was set to retrieve (the "offset").
299
	 * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
300
	 *
301
	 * @return integer The position of the first result.
302
	 */
303
	public function getFirstResult() {
304
		return $this->queryBuilder->getFirstResult();
305
	}
306
307
	/**
308
	 * Sets the maximum number of results to retrieve (the "limit").
309
	 *
310
	 * NOTE: Setting max results to "0" will cause mixed behaviour. While most
311
	 * of the databases will just return an empty result set, Oracle will return
312
	 * all entries.
313
	 *
314
	 * @param integer $maxResults The maximum number of results to retrieve.
315
	 *
316
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
317
	 */
318
	public function setMaxResults($maxResults) {
319
		$this->queryBuilder->setMaxResults($maxResults);
320
321
		return $this;
322
	}
323
324
	/**
325
	 * Gets the maximum number of results the query object was set to retrieve (the "limit").
326
	 * Returns NULL if {@link setMaxResults} was not applied to this query builder.
327
	 *
328
	 * @return integer The maximum number of results.
329
	 */
330
	public function getMaxResults() {
331
		return $this->queryBuilder->getMaxResults();
332
	}
333
334
	/**
335
	 * Specifies an item that is to be returned in the query result.
336
	 * Replaces any previously specified selections, if any.
337
	 *
338
	 * <code>
339
	 *     $qb = $conn->getQueryBuilder()
340
	 *         ->select('u.id', 'p.id')
341
	 *         ->from('users', 'u')
342
	 *         ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
343
	 * </code>
344
	 *
345
	 * @param mixed $select The selection expressions.
346
	 *
347
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
348
	 */
349 View Code Duplication
	public function select($select = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
350
		$selects = is_array($select) ? $select : func_get_args();
351
352
		$this->queryBuilder->select(
353
			$this->helper->quoteColumnNames($selects)
354
		);
355
356
		return $this;
357
	}
358
359
	/**
360
	 * Specifies an item that is to be returned with a different name in the query result.
361
	 *
362
	 * <code>
363
	 *     $qb = $conn->getQueryBuilder()
364
	 *         ->selectAlias('u.id', 'user_id')
365
	 *         ->from('users', 'u')
366
	 *         ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
367
	 * </code>
368
	 *
369
	 * @param mixed $select The selection expressions.
370
	 * @param string $alias The column alias used in the constructed query.
371
	 *
372
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
373
	 */
374
	public function selectAlias($select, $alias) {
375
376
		$this->queryBuilder->addSelect(
377
			$this->helper->quoteColumnName($select) . ' AS ' . $this->helper->quoteColumnName($alias)
378
		);
379
380
		return $this;
381
	}
382
383
	/**
384
	 * Specifies an item that is to be returned uniquely in the query result.
385
	 *
386
	 * <code>
387
	 *     $qb = $conn->getQueryBuilder()
388
	 *         ->selectDistinct('type')
389
	 *         ->from('users');
390
	 * </code>
391
	 *
392
	 * @param mixed $select The selection expressions.
393
	 *
394
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
395
	 */
396
	public function selectDistinct($select) {
397
398
		$this->queryBuilder->addSelect(
399
			'DISTINCT ' . $this->helper->quoteColumnName($select)
400
		);
401
402
		return $this;
403
	}
404
405
	/**
406
	 * Adds an item that is to be returned in the query result.
407
	 *
408
	 * <code>
409
	 *     $qb = $conn->getQueryBuilder()
410
	 *         ->select('u.id')
411
	 *         ->addSelect('p.id')
412
	 *         ->from('users', 'u')
413
	 *         ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
414
	 * </code>
415
	 *
416
	 * @param mixed $select The selection expression.
417
	 *
418
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
419
	 */
420 View Code Duplication
	public function addSelect($select = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
421
		$selects = is_array($select) ? $select : func_get_args();
422
423
		$this->queryBuilder->addSelect(
424
			$this->helper->quoteColumnNames($selects)
425
		);
426
427
		return $this;
428
	}
429
430
	/**
431
	 * Turns the query being built into a bulk delete query that ranges over
432
	 * a certain table.
433
	 *
434
	 * <code>
435
	 *     $qb = $conn->getQueryBuilder()
436
	 *         ->delete('users', 'u')
437
	 *         ->where('u.id = :user_id');
438
	 *         ->setParameter(':user_id', 1);
439
	 * </code>
440
	 *
441
	 * @param string $delete The table whose rows are subject to the deletion.
442
	 * @param string $alias The table alias used in the constructed query.
443
	 *
444
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
445
	 */
446
	public function delete($delete = null, $alias = null) {
447
		$this->queryBuilder->delete(
448
			$this->getTableName($delete),
449
			$alias
450
		);
451
452
		return $this;
453
	}
454
455
	/**
456
	 * Turns the query being built into a bulk update query that ranges over
457
	 * a certain table
458
	 *
459
	 * <code>
460
	 *     $qb = $conn->getQueryBuilder()
461
	 *         ->update('users', 'u')
462
	 *         ->set('u.password', md5('password'))
463
	 *         ->where('u.id = ?');
464
	 * </code>
465
	 *
466
	 * @param string $update The table whose rows are subject to the update.
467
	 * @param string $alias The table alias used in the constructed query.
468
	 *
469
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
470
	 */
471
	public function update($update = null, $alias = null) {
472
		$this->queryBuilder->update(
473
			$this->getTableName($update),
474
			$alias
475
		);
476
477
		return $this;
478
	}
479
480
	/**
481
	 * Turns the query being built into an insert query that inserts into
482
	 * a certain table
483
	 *
484
	 * <code>
485
	 *     $qb = $conn->getQueryBuilder()
486
	 *         ->insert('users')
487
	 *         ->values(
488
	 *             array(
489
	 *                 'name' => '?',
490
	 *                 'password' => '?'
491
	 *             )
492
	 *         );
493
	 * </code>
494
	 *
495
	 * @param string $insert The table into which the rows should be inserted.
496
	 *
497
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
498
	 */
499
	public function insert($insert = null) {
500
		$this->queryBuilder->insert(
501
			$this->getTableName($insert)
502
		);
503
504
		$this->lastInsertedTable = $insert;
505
506
		return $this;
507
	}
508
509
	/**
510
	 * Creates and adds a query root corresponding to the table identified by the
511
	 * given alias, forming a cartesian product with any existing query roots.
512
	 *
513
	 * <code>
514
	 *     $qb = $conn->getQueryBuilder()
515
	 *         ->select('u.id')
516
	 *         ->from('users', 'u')
517
	 * </code>
518
	 *
519
	 * @param string $from The table.
520
	 * @param string|null $alias The alias of the table.
521
	 *
522
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
523
	 */
524
	public function from($from, $alias = null) {
525
		$this->queryBuilder->from(
526
			$this->getTableName($from),
527
			$alias
528
		);
529
530
		return $this;
531
	}
532
533
	/**
534
	 * Creates and adds a join to the query.
535
	 *
536
	 * <code>
537
	 *     $qb = $conn->getQueryBuilder()
538
	 *         ->select('u.name')
539
	 *         ->from('users', 'u')
540
	 *         ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1');
541
	 * </code>
542
	 *
543
	 * @param string $fromAlias The alias that points to a from clause.
544
	 * @param string $join The table name to join.
545
	 * @param string $alias The alias of the join table.
546
	 * @param string $condition The condition for the join.
547
	 *
548
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
549
	 */
550
	public function join($fromAlias, $join, $alias, $condition = null) {
551
		$this->queryBuilder->join(
552
			$fromAlias,
553
			$this->getTableName($join),
554
			$alias,
555
			$condition
556
		);
557
558
		return $this;
559
	}
560
561
	/**
562
	 * Creates and adds a join to the query.
563
	 *
564
	 * <code>
565
	 *     $qb = $conn->getQueryBuilder()
566
	 *         ->select('u.name')
567
	 *         ->from('users', 'u')
568
	 *         ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
569
	 * </code>
570
	 *
571
	 * @param string $fromAlias The alias that points to a from clause.
572
	 * @param string $join The table name to join.
573
	 * @param string $alias The alias of the join table.
574
	 * @param string $condition The condition for the join.
575
	 *
576
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
577
	 */
578
	public function innerJoin($fromAlias, $join, $alias, $condition = null) {
579
		$this->queryBuilder->innerJoin(
580
			$fromAlias,
581
			$this->getTableName($join),
582
			$alias,
583
			$condition
584
		);
585
586
		return $this;
587
	}
588
589
	/**
590
	 * Creates and adds a left join to the query.
591
	 *
592
	 * <code>
593
	 *     $qb = $conn->getQueryBuilder()
594
	 *         ->select('u.name')
595
	 *         ->from('users', 'u')
596
	 *         ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
597
	 * </code>
598
	 *
599
	 * @param string $fromAlias The alias that points to a from clause.
600
	 * @param string $join The table name to join.
601
	 * @param string $alias The alias of the join table.
602
	 * @param string $condition The condition for the join.
603
	 *
604
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
605
	 */
606
	public function leftJoin($fromAlias, $join, $alias, $condition = null) {
607
		$this->queryBuilder->leftJoin(
608
			$fromAlias,
609
			$this->getTableName($join),
610
			$alias,
611
			$condition
612
		);
613
614
		return $this;
615
	}
616
617
	/**
618
	 * Creates and adds a right join to the query.
619
	 *
620
	 * <code>
621
	 *     $qb = $conn->getQueryBuilder()
622
	 *         ->select('u.name')
623
	 *         ->from('users', 'u')
624
	 *         ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
625
	 * </code>
626
	 *
627
	 * @param string $fromAlias The alias that points to a from clause.
628
	 * @param string $join The table name to join.
629
	 * @param string $alias The alias of the join table.
630
	 * @param string $condition The condition for the join.
631
	 *
632
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
633
	 */
634
	public function rightJoin($fromAlias, $join, $alias, $condition = null) {
635
		$this->queryBuilder->rightJoin(
636
			$fromAlias,
637
			$this->getTableName($join),
638
			$alias,
639
			$condition
640
		);
641
642
		return $this;
643
	}
644
645
	/**
646
	 * Sets a new value for a column in a bulk update query.
647
	 *
648
	 * <code>
649
	 *     $qb = $conn->getQueryBuilder()
650
	 *         ->update('users', 'u')
651
	 *         ->set('u.password', md5('password'))
652
	 *         ->where('u.id = ?');
653
	 * </code>
654
	 *
655
	 * @param string $key The column to set.
656
	 * @param string $value The value, expression, placeholder, etc.
657
	 *
658
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
659
	 */
660
	public function set($key, $value) {
661
		$this->queryBuilder->set(
662
			$this->helper->quoteColumnName($key),
663
			$this->helper->quoteColumnName($value)
664
		);
665
666
		return $this;
667
	}
668
669
	/**
670
	 * Specifies one or more restrictions to the query result.
671
	 * Replaces any previously specified restrictions, if any.
672
	 *
673
	 * <code>
674
	 *     $qb = $conn->getQueryBuilder()
675
	 *         ->select('u.name')
676
	 *         ->from('users', 'u')
677
	 *         ->where('u.id = ?');
678
	 *
679
	 *     // You can optionally programatically build and/or expressions
680
	 *     $qb = $conn->getQueryBuilder();
681
	 *
682
	 *     $or = $qb->expr()->orx();
683
	 *     $or->add($qb->expr()->eq('u.id', 1));
684
	 *     $or->add($qb->expr()->eq('u.id', 2));
685
	 *
686
	 *     $qb->update('users', 'u')
687
	 *         ->set('u.password', md5('password'))
688
	 *         ->where($or);
689
	 * </code>
690
	 *
691
	 * @param mixed $predicates The restriction predicates.
692
	 *
693
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
694
	 */
695
	public function where($predicates) {
696
		call_user_func_array(
697
			[$this->queryBuilder, 'where'],
698
			func_get_args()
699
		);
700
701
		return $this;
702
	}
703
704
	/**
705
	 * Adds one or more restrictions to the query results, forming a logical
706
	 * conjunction with any previously specified restrictions.
707
	 *
708
	 * <code>
709
	 *     $qb = $conn->getQueryBuilder()
710
	 *         ->select('u')
711
	 *         ->from('users', 'u')
712
	 *         ->where('u.username LIKE ?')
713
	 *         ->andWhere('u.is_active = 1');
714
	 * </code>
715
	 *
716
	 * @param mixed $where The query restrictions.
717
	 *
718
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
719
	 *
720
	 * @see where()
721
	 */
722
	public function andWhere($where) {
723
		call_user_func_array(
724
			[$this->queryBuilder, 'andWhere'],
725
			func_get_args()
726
		);
727
728
		return $this;
729
	}
730
731
	/**
732
	 * Adds one or more restrictions to the query results, forming a logical
733
	 * disjunction with any previously specified restrictions.
734
	 *
735
	 * <code>
736
	 *     $qb = $conn->getQueryBuilder()
737
	 *         ->select('u.name')
738
	 *         ->from('users', 'u')
739
	 *         ->where('u.id = 1')
740
	 *         ->orWhere('u.id = 2');
741
	 * </code>
742
	 *
743
	 * @param mixed $where The WHERE statement.
744
	 *
745
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
746
	 *
747
	 * @see where()
748
	 */
749
	public function orWhere($where) {
750
		call_user_func_array(
751
			[$this->queryBuilder, 'orWhere'],
752
			func_get_args()
753
		);
754
755
		return $this;
756
	}
757
758
	/**
759
	 * Specifies a grouping over the results of the query.
760
	 * Replaces any previously specified groupings, if any.
761
	 *
762
	 * <code>
763
	 *     $qb = $conn->getQueryBuilder()
764
	 *         ->select('u.name')
765
	 *         ->from('users', 'u')
766
	 *         ->groupBy('u.id');
767
	 * </code>
768
	 *
769
	 * @param mixed $groupBy The grouping expression.
770
	 *
771
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
772
	 */
773 View Code Duplication
	public function groupBy($groupBy) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
774
		$groupBys = is_array($groupBy) ? $groupBy : func_get_args();
775
776
		call_user_func_array(
777
			[$this->queryBuilder, 'groupBy'],
778
			$this->helper->quoteColumnNames($groupBys)
779
		);
780
781
		return $this;
782
	}
783
784
	/**
785
	 * Adds a grouping expression to the query.
786
	 *
787
	 * <code>
788
	 *     $qb = $conn->getQueryBuilder()
789
	 *         ->select('u.name')
790
	 *         ->from('users', 'u')
791
	 *         ->groupBy('u.lastLogin');
792
	 *         ->addGroupBy('u.createdAt')
793
	 * </code>
794
	 *
795
	 * @param mixed $groupBy The grouping expression.
796
	 *
797
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
798
	 */
799 View Code Duplication
	public function addGroupBy($groupBy) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
800
		$groupBys = is_array($groupBy) ? $groupBy : func_get_args();
801
802
		call_user_func_array(
803
			[$this->queryBuilder, 'addGroupBy'],
804
			$this->helper->quoteColumnNames($groupBys)
805
		);
806
807
		return $this;
808
	}
809
810
	/**
811
	 * Sets a value for a column in an insert query.
812
	 *
813
	 * <code>
814
	 *     $qb = $conn->getQueryBuilder()
815
	 *         ->insert('users')
816
	 *         ->values(
817
	 *             array(
818
	 *                 'name' => '?'
819
	 *             )
820
	 *         )
821
	 *         ->setValue('password', '?');
822
	 * </code>
823
	 *
824
	 * @param string $column The column into which the value should be inserted.
825
	 * @param string $value The value that should be inserted into the column.
826
	 *
827
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
828
	 */
829
	public function setValue($column, $value) {
830
		$this->queryBuilder->setValue(
831
			$this->helper->quoteColumnName($column),
832
			$value
833
		);
834
835
		return $this;
836
	}
837
838
	/**
839
	 * Specifies values for an insert query indexed by column names.
840
	 * Replaces any previous values, if any.
841
	 *
842
	 * <code>
843
	 *     $qb = $conn->getQueryBuilder()
844
	 *         ->insert('users')
845
	 *         ->values(
846
	 *             array(
847
	 *                 'name' => '?',
848
	 *                 'password' => '?'
849
	 *             )
850
	 *         );
851
	 * </code>
852
	 *
853
	 * @param array $values The values to specify for the insert query indexed by column names.
854
	 *
855
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
856
	 */
857
	public function values(array $values) {
858
		$quotedValues = [];
859
		foreach ($values as $key => $value) {
860
			$quotedValues[$this->helper->quoteColumnName($key)] = $value;
861
		}
862
863
		$this->queryBuilder->values($quotedValues);
864
865
		return $this;
866
	}
867
868
	/**
869
	 * Specifies a restriction over the groups of the query.
870
	 * Replaces any previous having restrictions, if any.
871
	 *
872
	 * @param mixed $having The restriction over the groups.
873
	 *
874
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
875
	 */
876
	public function having($having) {
877
		call_user_func_array(
878
			[$this->queryBuilder, 'having'],
879
			func_get_args()
880
		);
881
882
		return $this;
883
	}
884
885
	/**
886
	 * Adds a restriction over the groups of the query, forming a logical
887
	 * conjunction with any existing having restrictions.
888
	 *
889
	 * @param mixed $having The restriction to append.
890
	 *
891
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
892
	 */
893
	public function andHaving($having) {
894
		call_user_func_array(
895
			[$this->queryBuilder, 'andHaving'],
896
			func_get_args()
897
		);
898
899
		return $this;
900
	}
901
902
	/**
903
	 * Adds a restriction over the groups of the query, forming a logical
904
	 * disjunction with any existing having restrictions.
905
	 *
906
	 * @param mixed $having The restriction to add.
907
	 *
908
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
909
	 */
910
	public function orHaving($having) {
911
		call_user_func_array(
912
			[$this->queryBuilder, 'orHaving'],
913
			func_get_args()
914
		);
915
916
		return $this;
917
	}
918
919
	/**
920
	 * Specifies an ordering for the query results.
921
	 * Replaces any previously specified orderings, if any.
922
	 *
923
	 * @param string $sort The ordering expression.
924
	 * @param string $order The ordering direction.
925
	 *
926
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
927
	 */
928
	public function orderBy($sort, $order = null) {
929
		$this->queryBuilder->orderBy(
930
			$this->helper->quoteColumnName($sort),
931
			$order
932
		);
933
934
		return $this;
935
	}
936
937
	/**
938
	 * Adds an ordering to the query results.
939
	 *
940
	 * @param string $sort The ordering expression.
941
	 * @param string $order The ordering direction.
942
	 *
943
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
944
	 */
945
	public function addOrderBy($sort, $order = null) {
946
		$this->queryBuilder->addOrderBy(
947
			$this->helper->quoteColumnName($sort),
948
			$order
949
		);
950
951
		return $this;
952
	}
953
954
	/**
955
	 * Gets a query part by its name.
956
	 *
957
	 * @param string $queryPartName
958
	 *
959
	 * @return mixed
960
	 */
961
	public function getQueryPart($queryPartName) {
962
		return $this->queryBuilder->getQueryPart($queryPartName);
963
	}
964
965
	/**
966
	 * Gets all query parts.
967
	 *
968
	 * @return array
969
	 */
970
	public function getQueryParts() {
971
		return $this->queryBuilder->getQueryParts();
972
	}
973
974
	/**
975
	 * Resets SQL parts.
976
	 *
977
	 * @param array|null $queryPartNames
978
	 *
979
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
980
	 */
981
	public function resetQueryParts($queryPartNames = null) {
982
		$this->queryBuilder->resetQueryParts($queryPartNames);
983
984
		return $this;
985
	}
986
987
	/**
988
	 * Resets a single SQL part.
989
	 *
990
	 * @param string $queryPartName
991
	 *
992
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
993
	 */
994
	public function resetQueryPart($queryPartName) {
995
		$this->queryBuilder->resetQueryPart($queryPartName);
996
997
		return $this;
998
	}
999
1000
	/**
1001
	 * Creates a new named parameter and bind the value $value to it.
1002
	 *
1003
	 * This method provides a shortcut for PDOStatement::bindValue
1004
	 * when using prepared statements.
1005
	 *
1006
	 * The parameter $value specifies the value that you want to bind. If
1007
	 * $placeholder is not provided bindValue() will automatically create a
1008
	 * placeholder for you. An automatic placeholder will be of the name
1009
	 * ':dcValue1', ':dcValue2' etc.
1010
	 *
1011
	 * For more information see {@link http://php.net/pdostatement-bindparam}
1012
	 *
1013
	 * Example:
1014
	 * <code>
1015
	 * $value = 2;
1016
	 * $q->eq( 'id', $q->bindValue( $value ) );
1017
	 * $stmt = $q->executeQuery(); // executed with 'id = 2'
1018
	 * </code>
1019
	 *
1020
	 * @license New BSD License
1021
	 * @link http://www.zetacomponents.org
1022
	 *
1023
	 * @param mixed $value
1024
	 * @param mixed $type
1025
	 * @param string $placeHolder The name to bind with. The string must start with a colon ':'.
1026
	 *
1027
	 * @return IParameter the placeholder name used.
1028
	 */
1029
	public function createNamedParameter($value, $type = IQueryBuilder::PARAM_STR, $placeHolder = null) {
1030
		return new Parameter($this->queryBuilder->createNamedParameter($value, $type, $placeHolder));
1031
	}
1032
1033
	/**
1034
	 * Creates a new positional parameter and bind the given value to it.
1035
	 *
1036
	 * Attention: If you are using positional parameters with the query builder you have
1037
	 * to be very careful to bind all parameters in the order they appear in the SQL
1038
	 * statement , otherwise they get bound in the wrong order which can lead to serious
1039
	 * bugs in your code.
1040
	 *
1041
	 * Example:
1042
	 * <code>
1043
	 *  $qb = $conn->getQueryBuilder();
1044
	 *  $qb->select('u.*')
1045
	 *     ->from('users', 'u')
1046
	 *     ->where('u.username = ' . $qb->createPositionalParameter('Foo', IQueryBuilder::PARAM_STR))
1047
	 *     ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', IQueryBuilder::PARAM_STR))
1048
	 * </code>
1049
	 *
1050
	 * @param mixed $value
1051
	 * @param integer $type
1052
	 *
1053
	 * @return IParameter
1054
	 */
1055
	public function createPositionalParameter($value, $type = IQueryBuilder::PARAM_STR) {
1056
		return new Parameter($this->queryBuilder->createPositionalParameter($value, $type));
1057
	}
1058
1059
	/**
1060
	 * Creates a new parameter
1061
	 *
1062
	 * Example:
1063
	 * <code>
1064
	 *  $qb = $conn->getQueryBuilder();
1065
	 *  $qb->select('u.*')
1066
	 *     ->from('users', 'u')
1067
	 *     ->where('u.username = ' . $qb->createParameter('name'))
1068
	 *     ->setParameter('name', 'Bar', IQueryBuilder::PARAM_STR))
1069
	 * </code>
1070
	 *
1071
	 * @param string $name
1072
	 *
1073
	 * @return IParameter
1074
	 */
1075
	public function createParameter($name) {
1076
		return new Parameter(':' . $name);
1077
	}
1078
1079
	/**
1080
	 * Creates a new function
1081
	 *
1082
	 * Attention: Column names inside the call have to be quoted before hand
1083
	 *
1084
	 * Example:
1085
	 * <code>
1086
	 *  $qb = $conn->getQueryBuilder();
1087
	 *  $qb->select($qb->createFunction('COUNT(*)'))
1088
	 *     ->from('users', 'u')
1089
	 *  echo $qb->getSQL(); // SELECT COUNT(*) FROM `users` u
1090
	 * </code>
1091
	 * <code>
1092
	 *  $qb = $conn->getQueryBuilder();
1093
	 *  $qb->select($qb->createFunction('COUNT(`column`)'))
1094
	 *     ->from('users', 'u')
1095
	 *  echo $qb->getSQL(); // SELECT COUNT(`column`) FROM `users` u
1096
	 * </code>
1097
	 *
1098
	 * @param string $call
1099
	 *
1100
	 * @return IQueryFunction
1101
	 */
1102
	public function createFunction($call) {
1103
		return new QueryFunction($call);
1104
	}
1105
1106
	/**
1107
	 * Used to get the id of the last inserted element
1108
	 * @return int
1109
	 * @throws \BadMethodCallException When being called before an insert query has been run.
1110
	 */
1111
	public function getLastInsertId() {
1112
		if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::INSERT && $this->lastInsertedTable) {
1113
			// lastInsertId() needs the prefix but no quotes
1114
			$table = $this->prefixTableName($this->lastInsertedTable);
1115
			return (int) $this->connection->lastInsertId($table);
1116
		}
1117
1118
		throw new \BadMethodCallException('Invalid call to getLastInsertId without using insert() before.');
1119
	}
1120
1121
	/**
1122
	 * Returns the table name quoted and with database prefix as needed by the implementation
1123
	 *
1124
	 * @param string $table
1125
	 * @return string
1126
	 */
1127
	public function getTableName($table) {
1128
		$table = $this->prefixTableName($table);
1129
		return $this->helper->quoteColumnName($table);
1130
	}
1131
1132
	/**
1133
	 * Returns the table name with database prefix as needed by the implementation
1134
	 *
1135
	 * @param string $table
1136
	 * @return string
1137
	 */
1138
	protected function prefixTableName($table) {
1139
		if ($this->automaticTablePrefix === false || strpos($table, '*PREFIX*') === 0) {
1140
			return $table;
1141
		}
1142
1143
		return '*PREFIX*' . $table;
1144
	}
1145
1146
	/**
1147
	 * Returns the column name quoted and with table alias prefix as needed by the implementation
1148
	 *
1149
	 * @param string $column
1150
	 * @param string $tableAlias
1151
	 * @return string
1152
	 */
1153
	public function getColumnName($column, $tableAlias = '') {
1154
		if ($tableAlias !== '') {
1155
			$tableAlias .= '.';
1156
		}
1157
1158
		return $this->helper->quoteColumnName($tableAlias . $column);
1159
	}
1160
}
1161