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