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