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