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