Passed
Push — master ( 5a141b...b9287f )
by Christoph
23:29 queued 08:32
created
lib/public/IDBConnection.php 1 patch
Indentation   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -51,295 +51,295 @@
 block discarded – undo
51 51
  * @since 6.0.0
52 52
  */
53 53
 interface IDBConnection {
54
-	public const ADD_MISSING_INDEXES_EVENT = self::class . '::ADD_MISSING_INDEXES';
55
-	public const CHECK_MISSING_INDEXES_EVENT = self::class . '::CHECK_MISSING_INDEXES';
56
-	public const ADD_MISSING_PRIMARY_KEYS_EVENT = self::class . '::ADD_MISSING_PRIMARY_KEYS';
57
-	public const CHECK_MISSING_PRIMARY_KEYS_EVENT = self::class . '::CHECK_MISSING_PRIMARY_KEYS';
58
-	public const ADD_MISSING_COLUMNS_EVENT = self::class . '::ADD_MISSING_COLUMNS';
59
-	public const CHECK_MISSING_COLUMNS_EVENT = self::class . '::CHECK_MISSING_COLUMNS';
60
-
61
-	/**
62
-	 * Gets the QueryBuilder for the connection.
63
-	 *
64
-	 * @return \OCP\DB\QueryBuilder\IQueryBuilder
65
-	 * @since 8.2.0
66
-	 */
67
-	public function getQueryBuilder();
68
-
69
-	/**
70
-	 * Used to abstract the ownCloud database access away
71
-	 * @param string $sql the sql query with ? placeholder for params
72
-	 * @param int $limit the maximum number of rows
73
-	 * @param int $offset from which row we want to start
74
-	 * @return IPreparedStatement The prepared statement.
75
-	 * @since 6.0.0
76
-	 * @throws Exception since 21.0.0
77
-	 */
78
-	public function prepare($sql, $limit = null, $offset = null): IPreparedStatement;
79
-
80
-	/**
81
-	 * Executes an, optionally parameterized, SQL query.
82
-	 *
83
-	 * If the query is parameterized, a prepared statement is used.
84
-	 * If an SQLLogger is configured, the execution is logged.
85
-	 *
86
-	 * @param string $sql The SQL query to execute.
87
-	 * @param string[] $params The parameters to bind to the query, if any.
88
-	 * @param array $types The types the previous parameters are in.
89
-	 * @return IResult The executed statement.
90
-	 * @since 8.0.0
91
-	 * @throws Exception since 21.0.0
92
-	 */
93
-	public function executeQuery(string $sql, array $params = [], $types = []): IResult;
94
-
95
-	/**
96
-	 * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
97
-	 * and returns the number of affected rows.
98
-	 *
99
-	 * This method supports PDO binding types as well as DBAL mapping types.
100
-	 *
101
-	 * @param string $sql The SQL query.
102
-	 * @param array $params The query parameters.
103
-	 * @param array $types The parameter types.
104
-	 * @return int The number of affected rows.
105
-	 * @since 8.0.0
106
-	 * @throws Exception since 21.0.0
107
-	 *
108
-	 * @deprecated 21.0.0 use executeStatement
109
-	 */
110
-	public function executeUpdate(string $sql, array $params = [], array $types = []): int;
111
-
112
-	/**
113
-	 * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
114
-	 * and returns the number of affected rows.
115
-	 *
116
-	 * This method supports PDO binding types as well as DBAL mapping types.
117
-	 *
118
-	 * @param string $sql The SQL query.
119
-	 * @param array $params The query parameters.
120
-	 * @param array $types The parameter types.
121
-	 * @return int The number of affected rows.
122
-	 * @since 21.0.0
123
-	 * @throws Exception since 21.0.0
124
-	 */
125
-	public function executeStatement($sql, array $params = [], array $types = []): int;
126
-
127
-	/**
128
-	 * Used to get the id of the just inserted element
129
-	 * @param string $table the name of the table where we inserted the item
130
-	 * @return int the id of the inserted element
131
-	 * @since 6.0.0
132
-	 * @throws Exception since 21.0.0
133
-	 * @deprecated 21.0.0 use \OCP\DB\QueryBuilder\IQueryBuilder::getLastInsertId
134
-	 */
135
-	public function lastInsertId(string $table): int;
136
-
137
-	/**
138
-	 * Insert a row if the matching row does not exists. To accomplish proper race condition avoidance
139
-	 * it is needed that there is also a unique constraint on the values. Then this method will
140
-	 * catch the exception and return 0.
141
-	 *
142
-	 * @param string $table The table name (will replace *PREFIX* with the actual prefix)
143
-	 * @param array $input data that should be inserted into the table  (column name => value)
144
-	 * @param array|null $compare List of values that should be checked for "if not exists"
145
-	 *				If this is null or an empty array, all keys of $input will be compared
146
-	 *				Please note: text fields (clob) must not be used in the compare array
147
-	 * @return int number of inserted rows
148
-	 * @throws Exception used to be the removed dbal exception, since 21.0.0 it's \OCP\DB\Exception
149
-	 * @since 6.0.0 - parameter $compare was added in 8.1.0, return type changed from boolean in 8.1.0
150
-	 * @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
151
-	 */
152
-	public function insertIfNotExist(string $table, array $input, array $compare = null);
153
-
154
-
155
-	/**
156
-	 *
157
-	 * Insert a row if the row does not exist. Eventual conflicts during insert will be ignored.
158
-	 *
159
-	 * Implementation is not fully finished and should not be used!
160
-	 *
161
-	 * @param string $table The table name (will replace *PREFIX* with the actual prefix)
162
-	 * @param array $values data that should be inserted into the table  (column name => value)
163
-	 * @return int number of inserted rows
164
-	 * @since 16.0.0
165
-	 */
166
-	public function insertIgnoreConflict(string $table,array $values) : int;
167
-
168
-	/**
169
-	 * Insert or update a row value
170
-	 *
171
-	 * @param string $table
172
-	 * @param array $keys (column name => value)
173
-	 * @param array $values (column name => value)
174
-	 * @param array $updatePreconditionValues ensure values match preconditions (column name => value)
175
-	 * @return int number of new rows
176
-	 * @throws Exception used to be the removed dbal exception, since 21.0.0 it's \OCP\DB\Exception
177
-	 * @throws PreconditionNotMetException
178
-	 * @since 9.0.0
179
-	 */
180
-	public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int;
181
-
182
-	/**
183
-	 * Create an exclusive read+write lock on a table
184
-	 *
185
-	 * Important Note: Due to the nature how locks work on different DBs, it is
186
-	 * only possible to lock one table at a time. You should also NOT start a
187
-	 * transaction while holding a lock.
188
-	 *
189
-	 * @param string $tableName
190
-	 * @throws Exception since 21.0.0
191
-	 * @since 9.1.0
192
-	 */
193
-	public function lockTable($tableName): void;
194
-
195
-	/**
196
-	 * Release a previous acquired lock again
197
-	 *
198
-	 * @throws Exception since 21.0.0
199
-	 * @since 9.1.0
200
-	 */
201
-	public function unlockTable(): void;
202
-
203
-	/**
204
-	 * Start a transaction
205
-	 * @since 6.0.0
206
-	 * @throws Exception since 21.0.0
207
-	 */
208
-	public function beginTransaction(): void;
209
-
210
-	/**
211
-	 * Check if a transaction is active
212
-	 *
213
-	 * @return bool
214
-	 * @since 8.2.0
215
-	 */
216
-	public function inTransaction(): bool;
217
-
218
-	/**
219
-	 * Commit the database changes done during a transaction that is in progress
220
-	 * @since 6.0.0
221
-	 * @throws Exception since 21.0.0
222
-	 */
223
-	public function commit(): void;
224
-
225
-	/**
226
-	 * Rollback the database changes done during a transaction that is in progress
227
-	 * @since 6.0.0
228
-	 * @throws Exception since 21.0.0
229
-	 */
230
-	public function rollBack(): void;
231
-
232
-	/**
233
-	 * Gets the error code and message as a string for logging
234
-	 * @return string
235
-	 * @since 6.0.0
236
-	 * @deprecated 21.0.0 doesn't return anything meaningful
237
-	 */
238
-	public function getError(): string;
239
-
240
-	/**
241
-	 * Fetch the SQLSTATE associated with the last database operation.
242
-	 *
243
-	 * @return integer The last error code.
244
-	 * @since 8.0.0
245
-	 * @deprecated 21.0.0 doesn't return anything anymore
246
-	 */
247
-	public function errorCode();
248
-
249
-	/**
250
-	 * Fetch extended error information associated with the last database operation.
251
-	 *
252
-	 * @return array The last error information.
253
-	 * @since 8.0.0
254
-	 * @deprecated 21.0.0 doesn't return anything anymore
255
-	 */
256
-	public function errorInfo();
257
-
258
-	/**
259
-	 * Establishes the connection with the database.
260
-	 *
261
-	 * @return bool
262
-	 * @throws Exception since 21.0.0
263
-	 * @since 8.0.0
264
-	 */
265
-	public function connect(): bool;
266
-
267
-	/**
268
-	 * Close the database connection
269
-	 * @since 8.0.0
270
-	 */
271
-	public function close(): void;
272
-
273
-	/**
274
-	 * Quotes a given input parameter.
275
-	 *
276
-	 * @param mixed $input Parameter to be quoted.
277
-	 * @param int $type Type of the parameter.
278
-	 * @return mixed The quoted parameter.
279
-	 * @since 8.0.0
280
-	 */
281
-	public function quote($input, $type = IQueryBuilder::PARAM_STR);
282
-
283
-	/**
284
-	 * Gets the DatabasePlatform instance that provides all the metadata about
285
-	 * the platform this driver connects to.
286
-	 *
287
-	 * @return \Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
288
-	 * @since 8.0.0
289
-	 */
290
-	public function getDatabasePlatform();
291
-
292
-	/**
293
-	 * Drop a table from the database if it exists
294
-	 *
295
-	 * @param string $table table name without the prefix
296
-	 * @throws Exception since 21.0.0
297
-	 * @since 8.0.0
298
-	 */
299
-	public function dropTable(string $table): void;
300
-
301
-	/**
302
-	 * Check if a table exists
303
-	 *
304
-	 * @param string $table table name without the prefix
305
-	 * @return bool
306
-	 * @throws Exception since 21.0.0
307
-	 * @since 8.0.0
308
-	 */
309
-	public function tableExists(string $table): bool;
310
-
311
-	/**
312
-	 * Escape a parameter to be used in a LIKE query
313
-	 *
314
-	 * @param string $param
315
-	 * @return string
316
-	 * @since 9.0.0
317
-	 */
318
-	public function escapeLikeParameter(string $param): string;
319
-
320
-	/**
321
-	 * Check whether or not the current database support 4byte wide unicode
322
-	 *
323
-	 * @return bool
324
-	 * @since 11.0.0
325
-	 */
326
-	public function supports4ByteText(): bool;
327
-
328
-	/**
329
-	 * Create the schema of the connected database
330
-	 *
331
-	 * @return Schema
332
-	 * @throws Exception since 21.0.0
333
-	 * @since 13.0.0
334
-	 */
335
-	public function createSchema(): Schema;
336
-
337
-	/**
338
-	 * Migrate the database to the given schema
339
-	 *
340
-	 * @param Schema $toSchema
341
-	 * @throws Exception since 21.0.0
342
-	 * @since 13.0.0
343
-	 */
344
-	public function migrateToSchema(Schema $toSchema): void;
54
+    public const ADD_MISSING_INDEXES_EVENT = self::class . '::ADD_MISSING_INDEXES';
55
+    public const CHECK_MISSING_INDEXES_EVENT = self::class . '::CHECK_MISSING_INDEXES';
56
+    public const ADD_MISSING_PRIMARY_KEYS_EVENT = self::class . '::ADD_MISSING_PRIMARY_KEYS';
57
+    public const CHECK_MISSING_PRIMARY_KEYS_EVENT = self::class . '::CHECK_MISSING_PRIMARY_KEYS';
58
+    public const ADD_MISSING_COLUMNS_EVENT = self::class . '::ADD_MISSING_COLUMNS';
59
+    public const CHECK_MISSING_COLUMNS_EVENT = self::class . '::CHECK_MISSING_COLUMNS';
60
+
61
+    /**
62
+     * Gets the QueryBuilder for the connection.
63
+     *
64
+     * @return \OCP\DB\QueryBuilder\IQueryBuilder
65
+     * @since 8.2.0
66
+     */
67
+    public function getQueryBuilder();
68
+
69
+    /**
70
+     * Used to abstract the ownCloud database access away
71
+     * @param string $sql the sql query with ? placeholder for params
72
+     * @param int $limit the maximum number of rows
73
+     * @param int $offset from which row we want to start
74
+     * @return IPreparedStatement The prepared statement.
75
+     * @since 6.0.0
76
+     * @throws Exception since 21.0.0
77
+     */
78
+    public function prepare($sql, $limit = null, $offset = null): IPreparedStatement;
79
+
80
+    /**
81
+     * Executes an, optionally parameterized, SQL query.
82
+     *
83
+     * If the query is parameterized, a prepared statement is used.
84
+     * If an SQLLogger is configured, the execution is logged.
85
+     *
86
+     * @param string $sql The SQL query to execute.
87
+     * @param string[] $params The parameters to bind to the query, if any.
88
+     * @param array $types The types the previous parameters are in.
89
+     * @return IResult The executed statement.
90
+     * @since 8.0.0
91
+     * @throws Exception since 21.0.0
92
+     */
93
+    public function executeQuery(string $sql, array $params = [], $types = []): IResult;
94
+
95
+    /**
96
+     * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
97
+     * and returns the number of affected rows.
98
+     *
99
+     * This method supports PDO binding types as well as DBAL mapping types.
100
+     *
101
+     * @param string $sql The SQL query.
102
+     * @param array $params The query parameters.
103
+     * @param array $types The parameter types.
104
+     * @return int The number of affected rows.
105
+     * @since 8.0.0
106
+     * @throws Exception since 21.0.0
107
+     *
108
+     * @deprecated 21.0.0 use executeStatement
109
+     */
110
+    public function executeUpdate(string $sql, array $params = [], array $types = []): int;
111
+
112
+    /**
113
+     * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
114
+     * and returns the number of affected rows.
115
+     *
116
+     * This method supports PDO binding types as well as DBAL mapping types.
117
+     *
118
+     * @param string $sql The SQL query.
119
+     * @param array $params The query parameters.
120
+     * @param array $types The parameter types.
121
+     * @return int The number of affected rows.
122
+     * @since 21.0.0
123
+     * @throws Exception since 21.0.0
124
+     */
125
+    public function executeStatement($sql, array $params = [], array $types = []): int;
126
+
127
+    /**
128
+     * Used to get the id of the just inserted element
129
+     * @param string $table the name of the table where we inserted the item
130
+     * @return int the id of the inserted element
131
+     * @since 6.0.0
132
+     * @throws Exception since 21.0.0
133
+     * @deprecated 21.0.0 use \OCP\DB\QueryBuilder\IQueryBuilder::getLastInsertId
134
+     */
135
+    public function lastInsertId(string $table): int;
136
+
137
+    /**
138
+     * Insert a row if the matching row does not exists. To accomplish proper race condition avoidance
139
+     * it is needed that there is also a unique constraint on the values. Then this method will
140
+     * catch the exception and return 0.
141
+     *
142
+     * @param string $table The table name (will replace *PREFIX* with the actual prefix)
143
+     * @param array $input data that should be inserted into the table  (column name => value)
144
+     * @param array|null $compare List of values that should be checked for "if not exists"
145
+     *				If this is null or an empty array, all keys of $input will be compared
146
+     *				Please note: text fields (clob) must not be used in the compare array
147
+     * @return int number of inserted rows
148
+     * @throws Exception used to be the removed dbal exception, since 21.0.0 it's \OCP\DB\Exception
149
+     * @since 6.0.0 - parameter $compare was added in 8.1.0, return type changed from boolean in 8.1.0
150
+     * @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
151
+     */
152
+    public function insertIfNotExist(string $table, array $input, array $compare = null);
153
+
154
+
155
+    /**
156
+     *
157
+     * Insert a row if the row does not exist. Eventual conflicts during insert will be ignored.
158
+     *
159
+     * Implementation is not fully finished and should not be used!
160
+     *
161
+     * @param string $table The table name (will replace *PREFIX* with the actual prefix)
162
+     * @param array $values data that should be inserted into the table  (column name => value)
163
+     * @return int number of inserted rows
164
+     * @since 16.0.0
165
+     */
166
+    public function insertIgnoreConflict(string $table,array $values) : int;
167
+
168
+    /**
169
+     * Insert or update a row value
170
+     *
171
+     * @param string $table
172
+     * @param array $keys (column name => value)
173
+     * @param array $values (column name => value)
174
+     * @param array $updatePreconditionValues ensure values match preconditions (column name => value)
175
+     * @return int number of new rows
176
+     * @throws Exception used to be the removed dbal exception, since 21.0.0 it's \OCP\DB\Exception
177
+     * @throws PreconditionNotMetException
178
+     * @since 9.0.0
179
+     */
180
+    public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int;
181
+
182
+    /**
183
+     * Create an exclusive read+write lock on a table
184
+     *
185
+     * Important Note: Due to the nature how locks work on different DBs, it is
186
+     * only possible to lock one table at a time. You should also NOT start a
187
+     * transaction while holding a lock.
188
+     *
189
+     * @param string $tableName
190
+     * @throws Exception since 21.0.0
191
+     * @since 9.1.0
192
+     */
193
+    public function lockTable($tableName): void;
194
+
195
+    /**
196
+     * Release a previous acquired lock again
197
+     *
198
+     * @throws Exception since 21.0.0
199
+     * @since 9.1.0
200
+     */
201
+    public function unlockTable(): void;
202
+
203
+    /**
204
+     * Start a transaction
205
+     * @since 6.0.0
206
+     * @throws Exception since 21.0.0
207
+     */
208
+    public function beginTransaction(): void;
209
+
210
+    /**
211
+     * Check if a transaction is active
212
+     *
213
+     * @return bool
214
+     * @since 8.2.0
215
+     */
216
+    public function inTransaction(): bool;
217
+
218
+    /**
219
+     * Commit the database changes done during a transaction that is in progress
220
+     * @since 6.0.0
221
+     * @throws Exception since 21.0.0
222
+     */
223
+    public function commit(): void;
224
+
225
+    /**
226
+     * Rollback the database changes done during a transaction that is in progress
227
+     * @since 6.0.0
228
+     * @throws Exception since 21.0.0
229
+     */
230
+    public function rollBack(): void;
231
+
232
+    /**
233
+     * Gets the error code and message as a string for logging
234
+     * @return string
235
+     * @since 6.0.0
236
+     * @deprecated 21.0.0 doesn't return anything meaningful
237
+     */
238
+    public function getError(): string;
239
+
240
+    /**
241
+     * Fetch the SQLSTATE associated with the last database operation.
242
+     *
243
+     * @return integer The last error code.
244
+     * @since 8.0.0
245
+     * @deprecated 21.0.0 doesn't return anything anymore
246
+     */
247
+    public function errorCode();
248
+
249
+    /**
250
+     * Fetch extended error information associated with the last database operation.
251
+     *
252
+     * @return array The last error information.
253
+     * @since 8.0.0
254
+     * @deprecated 21.0.0 doesn't return anything anymore
255
+     */
256
+    public function errorInfo();
257
+
258
+    /**
259
+     * Establishes the connection with the database.
260
+     *
261
+     * @return bool
262
+     * @throws Exception since 21.0.0
263
+     * @since 8.0.0
264
+     */
265
+    public function connect(): bool;
266
+
267
+    /**
268
+     * Close the database connection
269
+     * @since 8.0.0
270
+     */
271
+    public function close(): void;
272
+
273
+    /**
274
+     * Quotes a given input parameter.
275
+     *
276
+     * @param mixed $input Parameter to be quoted.
277
+     * @param int $type Type of the parameter.
278
+     * @return mixed The quoted parameter.
279
+     * @since 8.0.0
280
+     */
281
+    public function quote($input, $type = IQueryBuilder::PARAM_STR);
282
+
283
+    /**
284
+     * Gets the DatabasePlatform instance that provides all the metadata about
285
+     * the platform this driver connects to.
286
+     *
287
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
288
+     * @since 8.0.0
289
+     */
290
+    public function getDatabasePlatform();
291
+
292
+    /**
293
+     * Drop a table from the database if it exists
294
+     *
295
+     * @param string $table table name without the prefix
296
+     * @throws Exception since 21.0.0
297
+     * @since 8.0.0
298
+     */
299
+    public function dropTable(string $table): void;
300
+
301
+    /**
302
+     * Check if a table exists
303
+     *
304
+     * @param string $table table name without the prefix
305
+     * @return bool
306
+     * @throws Exception since 21.0.0
307
+     * @since 8.0.0
308
+     */
309
+    public function tableExists(string $table): bool;
310
+
311
+    /**
312
+     * Escape a parameter to be used in a LIKE query
313
+     *
314
+     * @param string $param
315
+     * @return string
316
+     * @since 9.0.0
317
+     */
318
+    public function escapeLikeParameter(string $param): string;
319
+
320
+    /**
321
+     * Check whether or not the current database support 4byte wide unicode
322
+     *
323
+     * @return bool
324
+     * @since 11.0.0
325
+     */
326
+    public function supports4ByteText(): bool;
327
+
328
+    /**
329
+     * Create the schema of the connected database
330
+     *
331
+     * @return Schema
332
+     * @throws Exception since 21.0.0
333
+     * @since 13.0.0
334
+     */
335
+    public function createSchema(): Schema;
336
+
337
+    /**
338
+     * Migrate the database to the given schema
339
+     *
340
+     * @param Schema $toSchema
341
+     * @throws Exception since 21.0.0
342
+     * @since 13.0.0
343
+     */
344
+    public function migrateToSchema(Schema $toSchema): void;
345 345
 }
Please login to merge, or discard this patch.
lib/public/DB/QueryBuilder/IQueryBuilder.php 1 patch
Indentation   +872 added lines, -872 removed lines patch added patch discarded remove patch
@@ -38,876 +38,876 @@
 block discarded – undo
38 38
  */
39 39
 interface IQueryBuilder {
40 40
 
41
-	/**
42
-	 * @since 9.0.0
43
-	 */
44
-	public const PARAM_NULL = \PDO::PARAM_NULL;
45
-	/**
46
-	 * @since 9.0.0
47
-	 */
48
-	public const PARAM_BOOL = \PDO::PARAM_BOOL;
49
-	/**
50
-	 * @since 9.0.0
51
-	 */
52
-	public const PARAM_INT = \PDO::PARAM_INT;
53
-	/**
54
-	 * @since 9.0.0
55
-	 */
56
-	public const PARAM_STR = \PDO::PARAM_STR;
57
-	/**
58
-	 * @since 9.0.0
59
-	 */
60
-	public const PARAM_LOB = \PDO::PARAM_LOB;
61
-	/**
62
-	 * @since 9.0.0
63
-	 */
64
-	public const PARAM_DATE = 'datetime';
65
-
66
-	/**
67
-	 * @since 9.0.0
68
-	 */
69
-	public const PARAM_INT_ARRAY = Connection::PARAM_INT_ARRAY;
70
-	/**
71
-	 * @since 9.0.0
72
-	 */
73
-	public const PARAM_STR_ARRAY = Connection::PARAM_STR_ARRAY;
74
-
75
-
76
-	/**
77
-	 * Enable/disable automatic prefixing of table names with the oc_ prefix
78
-	 *
79
-	 * @param bool $enabled If set to true table names will be prefixed with the
80
-	 * owncloud database prefix automatically.
81
-	 * @since 8.2.0
82
-	 */
83
-	public function automaticTablePrefix($enabled);
84
-
85
-	/**
86
-	 * Gets an ExpressionBuilder used for object-oriented construction of query expressions.
87
-	 * This producer method is intended for convenient inline usage. Example:
88
-	 *
89
-	 * <code>
90
-	 *     $qb = $conn->getQueryBuilder()
91
-	 *         ->select('u')
92
-	 *         ->from('users', 'u')
93
-	 *         ->where($qb->expr()->eq('u.id', 1));
94
-	 * </code>
95
-	 *
96
-	 * For more complex expression construction, consider storing the expression
97
-	 * builder object in a local variable.
98
-	 *
99
-	 * @return \OCP\DB\QueryBuilder\IExpressionBuilder
100
-	 * @since 8.2.0
101
-	 */
102
-	public function expr();
103
-
104
-	/**
105
-	 * Gets an FunctionBuilder used for object-oriented construction of query functions.
106
-	 * This producer method is intended for convenient inline usage. Example:
107
-	 *
108
-	 * <code>
109
-	 *     $qb = $conn->getQueryBuilder()
110
-	 *         ->select('u')
111
-	 *         ->from('users', 'u')
112
-	 *         ->where($qb->fun()->md5('u.id'));
113
-	 * </code>
114
-	 *
115
-	 * For more complex function construction, consider storing the function
116
-	 * builder object in a local variable.
117
-	 *
118
-	 * @return \OCP\DB\QueryBuilder\IFunctionBuilder
119
-	 * @since 12.0.0
120
-	 */
121
-	public function func();
122
-
123
-	/**
124
-	 * Gets the type of the currently built query.
125
-	 *
126
-	 * @return integer
127
-	 * @since 8.2.0
128
-	 */
129
-	public function getType();
130
-
131
-	/**
132
-	 * Gets the associated DBAL Connection for this query builder.
133
-	 *
134
-	 * @return \OCP\IDBConnection
135
-	 * @since 8.2.0
136
-	 */
137
-	public function getConnection();
138
-
139
-	/**
140
-	 * Gets the state of this query builder instance.
141
-	 *
142
-	 * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
143
-	 * @since 8.2.0
144
-	 */
145
-	public function getState();
146
-
147
-	/**
148
-	 * Executes this query using the bound parameters and their types.
149
-	 *
150
-	 * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
151
-	 * for insert, update and delete statements.
152
-	 *
153
-	 * Warning: until Nextcloud 20, this method could return a \Doctrine\DBAL\Driver\Statement but since
154
-	 *          that interface changed in a breaking way the adapter \OCP\DB\QueryBuilder\IStatement is returned
155
-	 *          to bridge old code to the new API
156
-	 *
157
-	 * @return IResult|int
158
-	 * @throws Exception since 21.0.0
159
-	 * @since 8.2.0
160
-	 */
161
-	public function execute();
162
-
163
-	/**
164
-	 * Gets the complete SQL string formed by the current specifications of this QueryBuilder.
165
-	 *
166
-	 * <code>
167
-	 *     $qb = $conn->getQueryBuilder()
168
-	 *         ->select('u')
169
-	 *         ->from('User', 'u')
170
-	 *     echo $qb->getSQL(); // SELECT u FROM User u
171
-	 * </code>
172
-	 *
173
-	 * @return string The SQL query string.
174
-	 * @since 8.2.0
175
-	 */
176
-	public function getSQL();
177
-
178
-	/**
179
-	 * Sets a query parameter for the query being constructed.
180
-	 *
181
-	 * <code>
182
-	 *     $qb = $conn->getQueryBuilder()
183
-	 *         ->select('u')
184
-	 *         ->from('users', 'u')
185
-	 *         ->where('u.id = :user_id')
186
-	 *         ->setParameter(':user_id', 1);
187
-	 * </code>
188
-	 *
189
-	 * @param string|integer $key The parameter position or name.
190
-	 * @param mixed $value The parameter value.
191
-	 * @param string|null|int $type One of the IQueryBuilder::PARAM_* constants.
192
-	 *
193
-	 * @return $this This QueryBuilder instance.
194
-	 * @since 8.2.0
195
-	 */
196
-	public function setParameter($key, $value, $type = null);
197
-
198
-	/**
199
-	 * Sets a collection of query parameters for the query being constructed.
200
-	 *
201
-	 * <code>
202
-	 *     $qb = $conn->getQueryBuilder()
203
-	 *         ->select('u')
204
-	 *         ->from('users', 'u')
205
-	 *         ->where('u.id = :user_id1 OR u.id = :user_id2')
206
-	 *         ->setParameters(array(
207
-	 *             ':user_id1' => 1,
208
-	 *             ':user_id2' => 2
209
-	 *         ));
210
-	 * </code>
211
-	 *
212
-	 * @param array $params The query parameters to set.
213
-	 * @param array $types The query parameters types to set.
214
-	 *
215
-	 * @return $this This QueryBuilder instance.
216
-	 * @since 8.2.0
217
-	 */
218
-	public function setParameters(array $params, array $types = []);
219
-
220
-	/**
221
-	 * Gets all defined query parameters for the query being constructed indexed by parameter index or name.
222
-	 *
223
-	 * @return array The currently defined query parameters indexed by parameter index or name.
224
-	 * @since 8.2.0
225
-	 */
226
-	public function getParameters();
227
-
228
-	/**
229
-	 * Gets a (previously set) query parameter of the query being constructed.
230
-	 *
231
-	 * @param mixed $key The key (index or name) of the bound parameter.
232
-	 *
233
-	 * @return mixed The value of the bound parameter.
234
-	 * @since 8.2.0
235
-	 */
236
-	public function getParameter($key);
237
-
238
-	/**
239
-	 * Gets all defined query parameter types for the query being constructed indexed by parameter index or name.
240
-	 *
241
-	 * @return array The currently defined query parameter types indexed by parameter index or name.
242
-	 * @since 8.2.0
243
-	 */
244
-	public function getParameterTypes();
245
-
246
-	/**
247
-	 * Gets a (previously set) query parameter type of the query being constructed.
248
-	 *
249
-	 * @param mixed $key The key (index or name) of the bound parameter type.
250
-	 *
251
-	 * @return mixed The value of the bound parameter type.
252
-	 * @since 8.2.0
253
-	 */
254
-	public function getParameterType($key);
255
-
256
-	/**
257
-	 * Sets the position of the first result to retrieve (the "offset").
258
-	 *
259
-	 * @param integer $firstResult The first result to return.
260
-	 *
261
-	 * @return $this This QueryBuilder instance.
262
-	 * @since 8.2.0
263
-	 */
264
-	public function setFirstResult($firstResult);
265
-
266
-	/**
267
-	 * Gets the position of the first result the query object was set to retrieve (the "offset").
268
-	 * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
269
-	 *
270
-	 * @return integer The position of the first result.
271
-	 * @since 8.2.0
272
-	 */
273
-	public function getFirstResult();
274
-
275
-	/**
276
-	 * Sets the maximum number of results to retrieve (the "limit").
277
-	 *
278
-	 * @param integer $maxResults The maximum number of results to retrieve.
279
-	 *
280
-	 * @return $this This QueryBuilder instance.
281
-	 * @since 8.2.0
282
-	 */
283
-	public function setMaxResults($maxResults);
284
-
285
-	/**
286
-	 * Gets the maximum number of results the query object was set to retrieve (the "limit").
287
-	 * Returns NULL if {@link setMaxResults} was not applied to this query builder.
288
-	 *
289
-	 * @return int|null The maximum number of results.
290
-	 * @since 8.2.0
291
-	 */
292
-	public function getMaxResults();
293
-
294
-	/**
295
-	 * Specifies an item that is to be returned in the query result.
296
-	 * Replaces any previously specified selections, if any.
297
-	 *
298
-	 * <code>
299
-	 *     $qb = $conn->getQueryBuilder()
300
-	 *         ->select('u.id', 'p.id')
301
-	 *         ->from('users', 'u')
302
-	 *         ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
303
-	 * </code>
304
-	 *
305
-	 * @param mixed ...$selects The selection expressions.
306
-	 *
307
-	 * @return $this This QueryBuilder instance.
308
-	 * @since 8.2.0
309
-	 */
310
-	public function select(...$selects);
311
-
312
-	/**
313
-	 * Specifies an item that is to be returned with a different name in the query result.
314
-	 *
315
-	 * <code>
316
-	 *     $qb = $conn->getQueryBuilder()
317
-	 *         ->selectAlias('u.id', 'user_id')
318
-	 *         ->from('users', 'u')
319
-	 *         ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
320
-	 * </code>
321
-	 *
322
-	 * @param mixed $select The selection expressions.
323
-	 * @param string $alias The column alias used in the constructed query.
324
-	 *
325
-	 * @return $this This QueryBuilder instance.
326
-	 * @since 8.2.1
327
-	 */
328
-	public function selectAlias($select, $alias);
329
-
330
-	/**
331
-	 * Specifies an item that is to be returned uniquely in the query result.
332
-	 *
333
-	 * <code>
334
-	 *     $qb = $conn->getQueryBuilder()
335
-	 *         ->selectDistinct('type')
336
-	 *         ->from('users');
337
-	 * </code>
338
-	 *
339
-	 * @param mixed $select The selection expressions.
340
-	 *
341
-	 * @return $this This QueryBuilder instance.
342
-	 * @since 9.0.0
343
-	 */
344
-	public function selectDistinct($select);
345
-
346
-	/**
347
-	 * Adds an item that is to be returned in the query result.
348
-	 *
349
-	 * <code>
350
-	 *     $qb = $conn->getQueryBuilder()
351
-	 *         ->select('u.id')
352
-	 *         ->addSelect('p.id')
353
-	 *         ->from('users', 'u')
354
-	 *         ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
355
-	 * </code>
356
-	 *
357
-	 * @param mixed ...$select The selection expression.
358
-	 *
359
-	 * @return $this This QueryBuilder instance.
360
-	 * @since 8.2.0
361
-	 */
362
-	public function addSelect(...$select);
363
-
364
-	/**
365
-	 * Turns the query being built into a bulk delete query that ranges over
366
-	 * a certain table.
367
-	 *
368
-	 * <code>
369
-	 *     $qb = $conn->getQueryBuilder()
370
-	 *         ->delete('users', 'u')
371
-	 *         ->where('u.id = :user_id');
372
-	 *         ->setParameter(':user_id', 1);
373
-	 * </code>
374
-	 *
375
-	 * @param string $delete The table whose rows are subject to the deletion.
376
-	 * @param string $alias The table alias used in the constructed query.
377
-	 *
378
-	 * @return $this This QueryBuilder instance.
379
-	 * @since 8.2.0
380
-	 */
381
-	public function delete($delete = null, $alias = null);
382
-
383
-	/**
384
-	 * Turns the query being built into a bulk update query that ranges over
385
-	 * a certain table
386
-	 *
387
-	 * <code>
388
-	 *     $qb = $conn->getQueryBuilder()
389
-	 *         ->update('users', 'u')
390
-	 *         ->set('u.password', md5('password'))
391
-	 *         ->where('u.id = ?');
392
-	 * </code>
393
-	 *
394
-	 * @param string $update The table whose rows are subject to the update.
395
-	 * @param string $alias The table alias used in the constructed query.
396
-	 *
397
-	 * @return $this This QueryBuilder instance.
398
-	 * @since 8.2.0
399
-	 */
400
-	public function update($update = null, $alias = null);
401
-
402
-	/**
403
-	 * Turns the query being built into an insert query that inserts into
404
-	 * a certain table
405
-	 *
406
-	 * <code>
407
-	 *     $qb = $conn->getQueryBuilder()
408
-	 *         ->insert('users')
409
-	 *         ->values(
410
-	 *             array(
411
-	 *                 'name' => '?',
412
-	 *                 'password' => '?'
413
-	 *             )
414
-	 *         );
415
-	 * </code>
416
-	 *
417
-	 * @param string $insert The table into which the rows should be inserted.
418
-	 *
419
-	 * @return $this This QueryBuilder instance.
420
-	 * @since 8.2.0
421
-	 */
422
-	public function insert($insert = null);
423
-
424
-	/**
425
-	 * Creates and adds a query root corresponding to the table identified by the
426
-	 * given alias, forming a cartesian product with any existing query roots.
427
-	 *
428
-	 * <code>
429
-	 *     $qb = $conn->getQueryBuilder()
430
-	 *         ->select('u.id')
431
-	 *         ->from('users', 'u')
432
-	 * </code>
433
-	 *
434
-	 * @param string $from The table.
435
-	 * @param string|null $alias The alias of the table.
436
-	 *
437
-	 * @return $this This QueryBuilder instance.
438
-	 * @since 8.2.0
439
-	 */
440
-	public function from($from, $alias = null);
441
-
442
-	/**
443
-	 * Creates and adds a join to the query.
444
-	 *
445
-	 * <code>
446
-	 *     $qb = $conn->getQueryBuilder()
447
-	 *         ->select('u.name')
448
-	 *         ->from('users', 'u')
449
-	 *         ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1');
450
-	 * </code>
451
-	 *
452
-	 * @param string $fromAlias The alias that points to a from clause.
453
-	 * @param string $join The table name to join.
454
-	 * @param string $alias The alias of the join table.
455
-	 * @param string $condition The condition for the join.
456
-	 *
457
-	 * @return $this This QueryBuilder instance.
458
-	 * @since 8.2.0
459
-	 */
460
-	public function join($fromAlias, $join, $alias, $condition = null);
461
-
462
-	/**
463
-	 * Creates and adds a join to the query.
464
-	 *
465
-	 * <code>
466
-	 *     $qb = $conn->getQueryBuilder()
467
-	 *         ->select('u.name')
468
-	 *         ->from('users', 'u')
469
-	 *         ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
470
-	 * </code>
471
-	 *
472
-	 * @param string $fromAlias The alias that points to a from clause.
473
-	 * @param string $join The table name to join.
474
-	 * @param string $alias The alias of the join table.
475
-	 * @param string $condition The condition for the join.
476
-	 *
477
-	 * @return $this This QueryBuilder instance.
478
-	 * @since 8.2.0
479
-	 */
480
-	public function innerJoin($fromAlias, $join, $alias, $condition = null);
481
-
482
-	/**
483
-	 * Creates and adds a left join to the query.
484
-	 *
485
-	 * <code>
486
-	 *     $qb = $conn->getQueryBuilder()
487
-	 *         ->select('u.name')
488
-	 *         ->from('users', 'u')
489
-	 *         ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
490
-	 * </code>
491
-	 *
492
-	 * @param string $fromAlias The alias that points to a from clause.
493
-	 * @param string $join The table name to join.
494
-	 * @param string $alias The alias of the join table.
495
-	 * @param string $condition The condition for the join.
496
-	 *
497
-	 * @return $this This QueryBuilder instance.
498
-	 * @since 8.2.0
499
-	 */
500
-	public function leftJoin($fromAlias, $join, $alias, $condition = null);
501
-
502
-	/**
503
-	 * Creates and adds a right join to the query.
504
-	 *
505
-	 * <code>
506
-	 *     $qb = $conn->getQueryBuilder()
507
-	 *         ->select('u.name')
508
-	 *         ->from('users', 'u')
509
-	 *         ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
510
-	 * </code>
511
-	 *
512
-	 * @param string $fromAlias The alias that points to a from clause.
513
-	 * @param string $join The table name to join.
514
-	 * @param string $alias The alias of the join table.
515
-	 * @param string $condition The condition for the join.
516
-	 *
517
-	 * @return $this This QueryBuilder instance.
518
-	 * @since 8.2.0
519
-	 */
520
-	public function rightJoin($fromAlias, $join, $alias, $condition = null);
521
-
522
-	/**
523
-	 * Sets a new value for a column in a bulk update query.
524
-	 *
525
-	 * <code>
526
-	 *     $qb = $conn->getQueryBuilder()
527
-	 *         ->update('users', 'u')
528
-	 *         ->set('u.password', md5('password'))
529
-	 *         ->where('u.id = ?');
530
-	 * </code>
531
-	 *
532
-	 * @param string $key The column to set.
533
-	 * @param ILiteral|IParameter|IQueryFunction|string $value The value, expression, placeholder, etc.
534
-	 *
535
-	 * @return $this This QueryBuilder instance.
536
-	 * @since 8.2.0
537
-	 */
538
-	public function set($key, $value);
539
-
540
-	/**
541
-	 * Specifies one or more restrictions to the query result.
542
-	 * Replaces any previously specified restrictions, if any.
543
-	 *
544
-	 * <code>
545
-	 *     $qb = $conn->getQueryBuilder()
546
-	 *         ->select('u.name')
547
-	 *         ->from('users', 'u')
548
-	 *         ->where('u.id = ?');
549
-	 *
550
-	 *     // You can optionally programatically build and/or expressions
551
-	 *     $qb = $conn->getQueryBuilder();
552
-	 *
553
-	 *     $or = $qb->expr()->orx();
554
-	 *     $or->add($qb->expr()->eq('u.id', 1));
555
-	 *     $or->add($qb->expr()->eq('u.id', 2));
556
-	 *
557
-	 *     $qb->update('users', 'u')
558
-	 *         ->set('u.password', md5('password'))
559
-	 *         ->where($or);
560
-	 * </code>
561
-	 *
562
-	 * @param mixed $predicates The restriction predicates.
563
-	 *
564
-	 * @return $this This QueryBuilder instance.
565
-	 * @since 8.2.0
566
-	 */
567
-	public function where(...$predicates);
568
-
569
-	/**
570
-	 * Adds one or more restrictions to the query results, forming a logical
571
-	 * conjunction with any previously specified restrictions.
572
-	 *
573
-	 * <code>
574
-	 *     $qb = $conn->getQueryBuilder()
575
-	 *         ->select('u')
576
-	 *         ->from('users', 'u')
577
-	 *         ->where('u.username LIKE ?')
578
-	 *         ->andWhere('u.is_active = 1');
579
-	 * </code>
580
-	 *
581
-	 * @param mixed ...$where The query restrictions.
582
-	 *
583
-	 * @return $this This QueryBuilder instance.
584
-	 *
585
-	 * @see where()
586
-	 * @since 8.2.0
587
-	 */
588
-	public function andWhere(...$where);
589
-
590
-	/**
591
-	 * Adds one or more restrictions to the query results, forming a logical
592
-	 * disjunction with any previously specified restrictions.
593
-	 *
594
-	 * <code>
595
-	 *     $qb = $conn->getQueryBuilder()
596
-	 *         ->select('u.name')
597
-	 *         ->from('users', 'u')
598
-	 *         ->where('u.id = 1')
599
-	 *         ->orWhere('u.id = 2');
600
-	 * </code>
601
-	 *
602
-	 * @param mixed ...$where The WHERE statement.
603
-	 *
604
-	 * @return $this This QueryBuilder instance.
605
-	 *
606
-	 * @see where()
607
-	 * @since 8.2.0
608
-	 */
609
-	public function orWhere(...$where);
610
-
611
-	/**
612
-	 * Specifies a grouping over the results of the query.
613
-	 * Replaces any previously specified groupings, if any.
614
-	 *
615
-	 * <code>
616
-	 *     $qb = $conn->getQueryBuilder()
617
-	 *         ->select('u.name')
618
-	 *         ->from('users', 'u')
619
-	 *         ->groupBy('u.id');
620
-	 * </code>
621
-	 *
622
-	 * @param mixed ...$groupBys The grouping expression.
623
-	 *
624
-	 * @return $this This QueryBuilder instance.
625
-	 * @since 8.2.0
626
-	 */
627
-	public function groupBy(...$groupBys);
628
-
629
-	/**
630
-	 * Adds a grouping expression to the query.
631
-	 *
632
-	 * <code>
633
-	 *     $qb = $conn->getQueryBuilder()
634
-	 *         ->select('u.name')
635
-	 *         ->from('users', 'u')
636
-	 *         ->groupBy('u.lastLogin');
637
-	 *         ->addGroupBy('u.createdAt')
638
-	 * </code>
639
-	 *
640
-	 * @param mixed ...$groupBy The grouping expression.
641
-	 *
642
-	 * @return $this This QueryBuilder instance.
643
-	 * @since 8.2.0
644
-	 */
645
-	public function addGroupBy(...$groupBy);
646
-
647
-	/**
648
-	 * Sets a value for a column in an insert query.
649
-	 *
650
-	 * <code>
651
-	 *     $qb = $conn->getQueryBuilder()
652
-	 *         ->insert('users')
653
-	 *         ->values(
654
-	 *             array(
655
-	 *                 'name' => '?'
656
-	 *             )
657
-	 *         )
658
-	 *         ->setValue('password', '?');
659
-	 * </code>
660
-	 *
661
-	 * @param string $column The column into which the value should be inserted.
662
-	 * @param IParameter|string $value The value that should be inserted into the column.
663
-	 *
664
-	 * @return $this This QueryBuilder instance.
665
-	 * @since 8.2.0
666
-	 */
667
-	public function setValue($column, $value);
668
-
669
-	/**
670
-	 * Specifies values for an insert query indexed by column names.
671
-	 * Replaces any previous values, if any.
672
-	 *
673
-	 * <code>
674
-	 *     $qb = $conn->getQueryBuilder()
675
-	 *         ->insert('users')
676
-	 *         ->values(
677
-	 *             array(
678
-	 *                 'name' => '?',
679
-	 *                 'password' => '?'
680
-	 *             )
681
-	 *         );
682
-	 * </code>
683
-	 *
684
-	 * @param array $values The values to specify for the insert query indexed by column names.
685
-	 *
686
-	 * @return $this This QueryBuilder instance.
687
-	 * @since 8.2.0
688
-	 */
689
-	public function values(array $values);
690
-
691
-	/**
692
-	 * Specifies a restriction over the groups of the query.
693
-	 * Replaces any previous having restrictions, if any.
694
-	 *
695
-	 * @param mixed ...$having The restriction over the groups.
696
-	 *
697
-	 * @return $this This QueryBuilder instance.
698
-	 * @since 8.2.0
699
-	 */
700
-	public function having(...$having);
701
-
702
-	/**
703
-	 * Adds a restriction over the groups of the query, forming a logical
704
-	 * conjunction with any existing having restrictions.
705
-	 *
706
-	 * @param mixed ...$having The restriction to append.
707
-	 *
708
-	 * @return $this This QueryBuilder instance.
709
-	 * @since 8.2.0
710
-	 */
711
-	public function andHaving(...$having);
712
-
713
-	/**
714
-	 * Adds a restriction over the groups of the query, forming a logical
715
-	 * disjunction with any existing having restrictions.
716
-	 *
717
-	 * @param mixed ...$having The restriction to add.
718
-	 *
719
-	 * @return $this This QueryBuilder instance.
720
-	 * @since 8.2.0
721
-	 */
722
-	public function orHaving(...$having);
723
-
724
-	/**
725
-	 * Specifies an ordering for the query results.
726
-	 * Replaces any previously specified orderings, if any.
727
-	 *
728
-	 * @param string $sort The ordering expression.
729
-	 * @param string $order The ordering direction.
730
-	 *
731
-	 * @return $this This QueryBuilder instance.
732
-	 * @since 8.2.0
733
-	 */
734
-	public function orderBy($sort, $order = null);
735
-
736
-	/**
737
-	 * Adds an ordering to the query results.
738
-	 *
739
-	 * @param string $sort The ordering expression.
740
-	 * @param string $order The ordering direction.
741
-	 *
742
-	 * @return $this This QueryBuilder instance.
743
-	 * @since 8.2.0
744
-	 */
745
-	public function addOrderBy($sort, $order = null);
746
-
747
-	/**
748
-	 * Gets a query part by its name.
749
-	 *
750
-	 * @param string $queryPartName
751
-	 *
752
-	 * @return mixed
753
-	 * @since 8.2.0
754
-	 */
755
-	public function getQueryPart($queryPartName);
756
-
757
-	/**
758
-	 * Gets all query parts.
759
-	 *
760
-	 * @return array
761
-	 * @since 8.2.0
762
-	 */
763
-	public function getQueryParts();
764
-
765
-	/**
766
-	 * Resets SQL parts.
767
-	 *
768
-	 * @param array|null $queryPartNames
769
-	 *
770
-	 * @return $this This QueryBuilder instance.
771
-	 * @since 8.2.0
772
-	 */
773
-	public function resetQueryParts($queryPartNames = null);
774
-
775
-	/**
776
-	 * Resets a single SQL part.
777
-	 *
778
-	 * @param string $queryPartName
779
-	 *
780
-	 * @return $this This QueryBuilder instance.
781
-	 * @since 8.2.0
782
-	 */
783
-	public function resetQueryPart($queryPartName);
784
-
785
-	/**
786
-	 * Creates a new named parameter and bind the value $value to it.
787
-	 *
788
-	 * This method provides a shortcut for PDOStatement::bindValue
789
-	 * when using prepared statements.
790
-	 *
791
-	 * The parameter $value specifies the value that you want to bind. If
792
-	 * $placeholder is not provided bindValue() will automatically create a
793
-	 * placeholder for you. An automatic placeholder will be of the name
794
-	 * ':dcValue1', ':dcValue2' etc.
795
-	 *
796
-	 * For more information see {@link https://www.php.net/pdostatement-bindparam}
797
-	 *
798
-	 * Example:
799
-	 * <code>
800
-	 * $value = 2;
801
-	 * $q->eq( 'id', $q->bindValue( $value ) );
802
-	 * $stmt = $q->executeQuery(); // executed with 'id = 2'
803
-	 * </code>
804
-	 *
805
-	 * @license New BSD License
806
-	 * @link http://www.zetacomponents.org
807
-	 *
808
-	 * @param mixed $value
809
-	 * @param mixed $type
810
-	 * @param string $placeHolder The name to bind with. The string must start with a colon ':'.
811
-	 *
812
-	 * @return IParameter
813
-	 * @since 8.2.0
814
-	 */
815
-	public function createNamedParameter($value, $type = self::PARAM_STR, $placeHolder = null);
816
-
817
-	/**
818
-	 * Creates a new positional parameter and bind the given value to it.
819
-	 *
820
-	 * Attention: If you are using positional parameters with the query builder you have
821
-	 * to be very careful to bind all parameters in the order they appear in the SQL
822
-	 * statement , otherwise they get bound in the wrong order which can lead to serious
823
-	 * bugs in your code.
824
-	 *
825
-	 * Example:
826
-	 * <code>
827
-	 *  $qb = $conn->getQueryBuilder();
828
-	 *  $qb->select('u.*')
829
-	 *     ->from('users', 'u')
830
-	 *     ->where('u.username = ' . $qb->createPositionalParameter('Foo', IQueryBuilder::PARAM_STR))
831
-	 *     ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', IQueryBuilder::PARAM_STR))
832
-	 * </code>
833
-	 *
834
-	 * @param mixed $value
835
-	 * @param integer $type
836
-	 *
837
-	 * @return IParameter
838
-	 * @since 8.2.0
839
-	 */
840
-	public function createPositionalParameter($value, $type = self::PARAM_STR);
841
-
842
-	/**
843
-	 * Creates a new parameter
844
-	 *
845
-	 * Example:
846
-	 * <code>
847
-	 *  $qb = $conn->getQueryBuilder();
848
-	 *  $qb->select('u.*')
849
-	 *     ->from('users', 'u')
850
-	 *     ->where('u.username = ' . $qb->createParameter('name'))
851
-	 *     ->setParameter('name', 'Bar', IQueryBuilder::PARAM_STR))
852
-	 * </code>
853
-	 *
854
-	 * @param string $name
855
-	 *
856
-	 * @return IParameter
857
-	 * @since 8.2.0
858
-	 */
859
-	public function createParameter($name);
860
-
861
-	/**
862
-	 * Creates a new function
863
-	 *
864
-	 * Attention: Column names inside the call have to be quoted before hand
865
-	 *
866
-	 * Example:
867
-	 * <code>
868
-	 *  $qb = $conn->getQueryBuilder();
869
-	 *  $qb->select($qb->createFunction('COUNT(*)'))
870
-	 *     ->from('users', 'u')
871
-	 *  echo $qb->getSQL(); // SELECT COUNT(*) FROM `users` u
872
-	 * </code>
873
-	 * <code>
874
-	 *  $qb = $conn->getQueryBuilder();
875
-	 *  $qb->select($qb->createFunction('COUNT(`column`)'))
876
-	 *     ->from('users', 'u')
877
-	 *  echo $qb->getSQL(); // SELECT COUNT(`column`) FROM `users` u
878
-	 * </code>
879
-	 *
880
-	 * @param string $call
881
-	 *
882
-	 * @return IQueryFunction
883
-	 * @since 8.2.0
884
-	 */
885
-	public function createFunction($call);
886
-
887
-	/**
888
-	 * Used to get the id of the last inserted element
889
-	 * @return int
890
-	 * @throws \BadMethodCallException When being called before an insert query has been run.
891
-	 * @since 9.0.0
892
-	 */
893
-	public function getLastInsertId();
894
-
895
-	/**
896
-	 * Returns the table name quoted and with database prefix as needed by the implementation
897
-	 *
898
-	 * @param string $table
899
-	 * @return string
900
-	 * @since 9.0.0
901
-	 */
902
-	public function getTableName($table);
903
-
904
-	/**
905
-	 * Returns the column name quoted and with table alias prefix as needed by the implementation
906
-	 *
907
-	 * @param string $column
908
-	 * @param string $tableAlias
909
-	 * @return string
910
-	 * @since 9.0.0
911
-	 */
912
-	public function getColumnName($column, $tableAlias = '');
41
+    /**
42
+     * @since 9.0.0
43
+     */
44
+    public const PARAM_NULL = \PDO::PARAM_NULL;
45
+    /**
46
+     * @since 9.0.0
47
+     */
48
+    public const PARAM_BOOL = \PDO::PARAM_BOOL;
49
+    /**
50
+     * @since 9.0.0
51
+     */
52
+    public const PARAM_INT = \PDO::PARAM_INT;
53
+    /**
54
+     * @since 9.0.0
55
+     */
56
+    public const PARAM_STR = \PDO::PARAM_STR;
57
+    /**
58
+     * @since 9.0.0
59
+     */
60
+    public const PARAM_LOB = \PDO::PARAM_LOB;
61
+    /**
62
+     * @since 9.0.0
63
+     */
64
+    public const PARAM_DATE = 'datetime';
65
+
66
+    /**
67
+     * @since 9.0.0
68
+     */
69
+    public const PARAM_INT_ARRAY = Connection::PARAM_INT_ARRAY;
70
+    /**
71
+     * @since 9.0.0
72
+     */
73
+    public const PARAM_STR_ARRAY = Connection::PARAM_STR_ARRAY;
74
+
75
+
76
+    /**
77
+     * Enable/disable automatic prefixing of table names with the oc_ prefix
78
+     *
79
+     * @param bool $enabled If set to true table names will be prefixed with the
80
+     * owncloud database prefix automatically.
81
+     * @since 8.2.0
82
+     */
83
+    public function automaticTablePrefix($enabled);
84
+
85
+    /**
86
+     * Gets an ExpressionBuilder used for object-oriented construction of query expressions.
87
+     * This producer method is intended for convenient inline usage. Example:
88
+     *
89
+     * <code>
90
+     *     $qb = $conn->getQueryBuilder()
91
+     *         ->select('u')
92
+     *         ->from('users', 'u')
93
+     *         ->where($qb->expr()->eq('u.id', 1));
94
+     * </code>
95
+     *
96
+     * For more complex expression construction, consider storing the expression
97
+     * builder object in a local variable.
98
+     *
99
+     * @return \OCP\DB\QueryBuilder\IExpressionBuilder
100
+     * @since 8.2.0
101
+     */
102
+    public function expr();
103
+
104
+    /**
105
+     * Gets an FunctionBuilder used for object-oriented construction of query functions.
106
+     * This producer method is intended for convenient inline usage. Example:
107
+     *
108
+     * <code>
109
+     *     $qb = $conn->getQueryBuilder()
110
+     *         ->select('u')
111
+     *         ->from('users', 'u')
112
+     *         ->where($qb->fun()->md5('u.id'));
113
+     * </code>
114
+     *
115
+     * For more complex function construction, consider storing the function
116
+     * builder object in a local variable.
117
+     *
118
+     * @return \OCP\DB\QueryBuilder\IFunctionBuilder
119
+     * @since 12.0.0
120
+     */
121
+    public function func();
122
+
123
+    /**
124
+     * Gets the type of the currently built query.
125
+     *
126
+     * @return integer
127
+     * @since 8.2.0
128
+     */
129
+    public function getType();
130
+
131
+    /**
132
+     * Gets the associated DBAL Connection for this query builder.
133
+     *
134
+     * @return \OCP\IDBConnection
135
+     * @since 8.2.0
136
+     */
137
+    public function getConnection();
138
+
139
+    /**
140
+     * Gets the state of this query builder instance.
141
+     *
142
+     * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
143
+     * @since 8.2.0
144
+     */
145
+    public function getState();
146
+
147
+    /**
148
+     * Executes this query using the bound parameters and their types.
149
+     *
150
+     * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
151
+     * for insert, update and delete statements.
152
+     *
153
+     * Warning: until Nextcloud 20, this method could return a \Doctrine\DBAL\Driver\Statement but since
154
+     *          that interface changed in a breaking way the adapter \OCP\DB\QueryBuilder\IStatement is returned
155
+     *          to bridge old code to the new API
156
+     *
157
+     * @return IResult|int
158
+     * @throws Exception since 21.0.0
159
+     * @since 8.2.0
160
+     */
161
+    public function execute();
162
+
163
+    /**
164
+     * Gets the complete SQL string formed by the current specifications of this QueryBuilder.
165
+     *
166
+     * <code>
167
+     *     $qb = $conn->getQueryBuilder()
168
+     *         ->select('u')
169
+     *         ->from('User', 'u')
170
+     *     echo $qb->getSQL(); // SELECT u FROM User u
171
+     * </code>
172
+     *
173
+     * @return string The SQL query string.
174
+     * @since 8.2.0
175
+     */
176
+    public function getSQL();
177
+
178
+    /**
179
+     * Sets a query parameter for the query being constructed.
180
+     *
181
+     * <code>
182
+     *     $qb = $conn->getQueryBuilder()
183
+     *         ->select('u')
184
+     *         ->from('users', 'u')
185
+     *         ->where('u.id = :user_id')
186
+     *         ->setParameter(':user_id', 1);
187
+     * </code>
188
+     *
189
+     * @param string|integer $key The parameter position or name.
190
+     * @param mixed $value The parameter value.
191
+     * @param string|null|int $type One of the IQueryBuilder::PARAM_* constants.
192
+     *
193
+     * @return $this This QueryBuilder instance.
194
+     * @since 8.2.0
195
+     */
196
+    public function setParameter($key, $value, $type = null);
197
+
198
+    /**
199
+     * Sets a collection of query parameters for the query being constructed.
200
+     *
201
+     * <code>
202
+     *     $qb = $conn->getQueryBuilder()
203
+     *         ->select('u')
204
+     *         ->from('users', 'u')
205
+     *         ->where('u.id = :user_id1 OR u.id = :user_id2')
206
+     *         ->setParameters(array(
207
+     *             ':user_id1' => 1,
208
+     *             ':user_id2' => 2
209
+     *         ));
210
+     * </code>
211
+     *
212
+     * @param array $params The query parameters to set.
213
+     * @param array $types The query parameters types to set.
214
+     *
215
+     * @return $this This QueryBuilder instance.
216
+     * @since 8.2.0
217
+     */
218
+    public function setParameters(array $params, array $types = []);
219
+
220
+    /**
221
+     * Gets all defined query parameters for the query being constructed indexed by parameter index or name.
222
+     *
223
+     * @return array The currently defined query parameters indexed by parameter index or name.
224
+     * @since 8.2.0
225
+     */
226
+    public function getParameters();
227
+
228
+    /**
229
+     * Gets a (previously set) query parameter of the query being constructed.
230
+     *
231
+     * @param mixed $key The key (index or name) of the bound parameter.
232
+     *
233
+     * @return mixed The value of the bound parameter.
234
+     * @since 8.2.0
235
+     */
236
+    public function getParameter($key);
237
+
238
+    /**
239
+     * Gets all defined query parameter types for the query being constructed indexed by parameter index or name.
240
+     *
241
+     * @return array The currently defined query parameter types indexed by parameter index or name.
242
+     * @since 8.2.0
243
+     */
244
+    public function getParameterTypes();
245
+
246
+    /**
247
+     * Gets a (previously set) query parameter type of the query being constructed.
248
+     *
249
+     * @param mixed $key The key (index or name) of the bound parameter type.
250
+     *
251
+     * @return mixed The value of the bound parameter type.
252
+     * @since 8.2.0
253
+     */
254
+    public function getParameterType($key);
255
+
256
+    /**
257
+     * Sets the position of the first result to retrieve (the "offset").
258
+     *
259
+     * @param integer $firstResult The first result to return.
260
+     *
261
+     * @return $this This QueryBuilder instance.
262
+     * @since 8.2.0
263
+     */
264
+    public function setFirstResult($firstResult);
265
+
266
+    /**
267
+     * Gets the position of the first result the query object was set to retrieve (the "offset").
268
+     * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
269
+     *
270
+     * @return integer The position of the first result.
271
+     * @since 8.2.0
272
+     */
273
+    public function getFirstResult();
274
+
275
+    /**
276
+     * Sets the maximum number of results to retrieve (the "limit").
277
+     *
278
+     * @param integer $maxResults The maximum number of results to retrieve.
279
+     *
280
+     * @return $this This QueryBuilder instance.
281
+     * @since 8.2.0
282
+     */
283
+    public function setMaxResults($maxResults);
284
+
285
+    /**
286
+     * Gets the maximum number of results the query object was set to retrieve (the "limit").
287
+     * Returns NULL if {@link setMaxResults} was not applied to this query builder.
288
+     *
289
+     * @return int|null The maximum number of results.
290
+     * @since 8.2.0
291
+     */
292
+    public function getMaxResults();
293
+
294
+    /**
295
+     * Specifies an item that is to be returned in the query result.
296
+     * Replaces any previously specified selections, if any.
297
+     *
298
+     * <code>
299
+     *     $qb = $conn->getQueryBuilder()
300
+     *         ->select('u.id', 'p.id')
301
+     *         ->from('users', 'u')
302
+     *         ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
303
+     * </code>
304
+     *
305
+     * @param mixed ...$selects The selection expressions.
306
+     *
307
+     * @return $this This QueryBuilder instance.
308
+     * @since 8.2.0
309
+     */
310
+    public function select(...$selects);
311
+
312
+    /**
313
+     * Specifies an item that is to be returned with a different name in the query result.
314
+     *
315
+     * <code>
316
+     *     $qb = $conn->getQueryBuilder()
317
+     *         ->selectAlias('u.id', 'user_id')
318
+     *         ->from('users', 'u')
319
+     *         ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
320
+     * </code>
321
+     *
322
+     * @param mixed $select The selection expressions.
323
+     * @param string $alias The column alias used in the constructed query.
324
+     *
325
+     * @return $this This QueryBuilder instance.
326
+     * @since 8.2.1
327
+     */
328
+    public function selectAlias($select, $alias);
329
+
330
+    /**
331
+     * Specifies an item that is to be returned uniquely in the query result.
332
+     *
333
+     * <code>
334
+     *     $qb = $conn->getQueryBuilder()
335
+     *         ->selectDistinct('type')
336
+     *         ->from('users');
337
+     * </code>
338
+     *
339
+     * @param mixed $select The selection expressions.
340
+     *
341
+     * @return $this This QueryBuilder instance.
342
+     * @since 9.0.0
343
+     */
344
+    public function selectDistinct($select);
345
+
346
+    /**
347
+     * Adds an item that is to be returned in the query result.
348
+     *
349
+     * <code>
350
+     *     $qb = $conn->getQueryBuilder()
351
+     *         ->select('u.id')
352
+     *         ->addSelect('p.id')
353
+     *         ->from('users', 'u')
354
+     *         ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
355
+     * </code>
356
+     *
357
+     * @param mixed ...$select The selection expression.
358
+     *
359
+     * @return $this This QueryBuilder instance.
360
+     * @since 8.2.0
361
+     */
362
+    public function addSelect(...$select);
363
+
364
+    /**
365
+     * Turns the query being built into a bulk delete query that ranges over
366
+     * a certain table.
367
+     *
368
+     * <code>
369
+     *     $qb = $conn->getQueryBuilder()
370
+     *         ->delete('users', 'u')
371
+     *         ->where('u.id = :user_id');
372
+     *         ->setParameter(':user_id', 1);
373
+     * </code>
374
+     *
375
+     * @param string $delete The table whose rows are subject to the deletion.
376
+     * @param string $alias The table alias used in the constructed query.
377
+     *
378
+     * @return $this This QueryBuilder instance.
379
+     * @since 8.2.0
380
+     */
381
+    public function delete($delete = null, $alias = null);
382
+
383
+    /**
384
+     * Turns the query being built into a bulk update query that ranges over
385
+     * a certain table
386
+     *
387
+     * <code>
388
+     *     $qb = $conn->getQueryBuilder()
389
+     *         ->update('users', 'u')
390
+     *         ->set('u.password', md5('password'))
391
+     *         ->where('u.id = ?');
392
+     * </code>
393
+     *
394
+     * @param string $update The table whose rows are subject to the update.
395
+     * @param string $alias The table alias used in the constructed query.
396
+     *
397
+     * @return $this This QueryBuilder instance.
398
+     * @since 8.2.0
399
+     */
400
+    public function update($update = null, $alias = null);
401
+
402
+    /**
403
+     * Turns the query being built into an insert query that inserts into
404
+     * a certain table
405
+     *
406
+     * <code>
407
+     *     $qb = $conn->getQueryBuilder()
408
+     *         ->insert('users')
409
+     *         ->values(
410
+     *             array(
411
+     *                 'name' => '?',
412
+     *                 'password' => '?'
413
+     *             )
414
+     *         );
415
+     * </code>
416
+     *
417
+     * @param string $insert The table into which the rows should be inserted.
418
+     *
419
+     * @return $this This QueryBuilder instance.
420
+     * @since 8.2.0
421
+     */
422
+    public function insert($insert = null);
423
+
424
+    /**
425
+     * Creates and adds a query root corresponding to the table identified by the
426
+     * given alias, forming a cartesian product with any existing query roots.
427
+     *
428
+     * <code>
429
+     *     $qb = $conn->getQueryBuilder()
430
+     *         ->select('u.id')
431
+     *         ->from('users', 'u')
432
+     * </code>
433
+     *
434
+     * @param string $from The table.
435
+     * @param string|null $alias The alias of the table.
436
+     *
437
+     * @return $this This QueryBuilder instance.
438
+     * @since 8.2.0
439
+     */
440
+    public function from($from, $alias = null);
441
+
442
+    /**
443
+     * Creates and adds a join to the query.
444
+     *
445
+     * <code>
446
+     *     $qb = $conn->getQueryBuilder()
447
+     *         ->select('u.name')
448
+     *         ->from('users', 'u')
449
+     *         ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1');
450
+     * </code>
451
+     *
452
+     * @param string $fromAlias The alias that points to a from clause.
453
+     * @param string $join The table name to join.
454
+     * @param string $alias The alias of the join table.
455
+     * @param string $condition The condition for the join.
456
+     *
457
+     * @return $this This QueryBuilder instance.
458
+     * @since 8.2.0
459
+     */
460
+    public function join($fromAlias, $join, $alias, $condition = null);
461
+
462
+    /**
463
+     * Creates and adds a join to the query.
464
+     *
465
+     * <code>
466
+     *     $qb = $conn->getQueryBuilder()
467
+     *         ->select('u.name')
468
+     *         ->from('users', 'u')
469
+     *         ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
470
+     * </code>
471
+     *
472
+     * @param string $fromAlias The alias that points to a from clause.
473
+     * @param string $join The table name to join.
474
+     * @param string $alias The alias of the join table.
475
+     * @param string $condition The condition for the join.
476
+     *
477
+     * @return $this This QueryBuilder instance.
478
+     * @since 8.2.0
479
+     */
480
+    public function innerJoin($fromAlias, $join, $alias, $condition = null);
481
+
482
+    /**
483
+     * Creates and adds a left join to the query.
484
+     *
485
+     * <code>
486
+     *     $qb = $conn->getQueryBuilder()
487
+     *         ->select('u.name')
488
+     *         ->from('users', 'u')
489
+     *         ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
490
+     * </code>
491
+     *
492
+     * @param string $fromAlias The alias that points to a from clause.
493
+     * @param string $join The table name to join.
494
+     * @param string $alias The alias of the join table.
495
+     * @param string $condition The condition for the join.
496
+     *
497
+     * @return $this This QueryBuilder instance.
498
+     * @since 8.2.0
499
+     */
500
+    public function leftJoin($fromAlias, $join, $alias, $condition = null);
501
+
502
+    /**
503
+     * Creates and adds a right join to the query.
504
+     *
505
+     * <code>
506
+     *     $qb = $conn->getQueryBuilder()
507
+     *         ->select('u.name')
508
+     *         ->from('users', 'u')
509
+     *         ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
510
+     * </code>
511
+     *
512
+     * @param string $fromAlias The alias that points to a from clause.
513
+     * @param string $join The table name to join.
514
+     * @param string $alias The alias of the join table.
515
+     * @param string $condition The condition for the join.
516
+     *
517
+     * @return $this This QueryBuilder instance.
518
+     * @since 8.2.0
519
+     */
520
+    public function rightJoin($fromAlias, $join, $alias, $condition = null);
521
+
522
+    /**
523
+     * Sets a new value for a column in a bulk update query.
524
+     *
525
+     * <code>
526
+     *     $qb = $conn->getQueryBuilder()
527
+     *         ->update('users', 'u')
528
+     *         ->set('u.password', md5('password'))
529
+     *         ->where('u.id = ?');
530
+     * </code>
531
+     *
532
+     * @param string $key The column to set.
533
+     * @param ILiteral|IParameter|IQueryFunction|string $value The value, expression, placeholder, etc.
534
+     *
535
+     * @return $this This QueryBuilder instance.
536
+     * @since 8.2.0
537
+     */
538
+    public function set($key, $value);
539
+
540
+    /**
541
+     * Specifies one or more restrictions to the query result.
542
+     * Replaces any previously specified restrictions, if any.
543
+     *
544
+     * <code>
545
+     *     $qb = $conn->getQueryBuilder()
546
+     *         ->select('u.name')
547
+     *         ->from('users', 'u')
548
+     *         ->where('u.id = ?');
549
+     *
550
+     *     // You can optionally programatically build and/or expressions
551
+     *     $qb = $conn->getQueryBuilder();
552
+     *
553
+     *     $or = $qb->expr()->orx();
554
+     *     $or->add($qb->expr()->eq('u.id', 1));
555
+     *     $or->add($qb->expr()->eq('u.id', 2));
556
+     *
557
+     *     $qb->update('users', 'u')
558
+     *         ->set('u.password', md5('password'))
559
+     *         ->where($or);
560
+     * </code>
561
+     *
562
+     * @param mixed $predicates The restriction predicates.
563
+     *
564
+     * @return $this This QueryBuilder instance.
565
+     * @since 8.2.0
566
+     */
567
+    public function where(...$predicates);
568
+
569
+    /**
570
+     * Adds one or more restrictions to the query results, forming a logical
571
+     * conjunction with any previously specified restrictions.
572
+     *
573
+     * <code>
574
+     *     $qb = $conn->getQueryBuilder()
575
+     *         ->select('u')
576
+     *         ->from('users', 'u')
577
+     *         ->where('u.username LIKE ?')
578
+     *         ->andWhere('u.is_active = 1');
579
+     * </code>
580
+     *
581
+     * @param mixed ...$where The query restrictions.
582
+     *
583
+     * @return $this This QueryBuilder instance.
584
+     *
585
+     * @see where()
586
+     * @since 8.2.0
587
+     */
588
+    public function andWhere(...$where);
589
+
590
+    /**
591
+     * Adds one or more restrictions to the query results, forming a logical
592
+     * disjunction with any previously specified restrictions.
593
+     *
594
+     * <code>
595
+     *     $qb = $conn->getQueryBuilder()
596
+     *         ->select('u.name')
597
+     *         ->from('users', 'u')
598
+     *         ->where('u.id = 1')
599
+     *         ->orWhere('u.id = 2');
600
+     * </code>
601
+     *
602
+     * @param mixed ...$where The WHERE statement.
603
+     *
604
+     * @return $this This QueryBuilder instance.
605
+     *
606
+     * @see where()
607
+     * @since 8.2.0
608
+     */
609
+    public function orWhere(...$where);
610
+
611
+    /**
612
+     * Specifies a grouping over the results of the query.
613
+     * Replaces any previously specified groupings, if any.
614
+     *
615
+     * <code>
616
+     *     $qb = $conn->getQueryBuilder()
617
+     *         ->select('u.name')
618
+     *         ->from('users', 'u')
619
+     *         ->groupBy('u.id');
620
+     * </code>
621
+     *
622
+     * @param mixed ...$groupBys The grouping expression.
623
+     *
624
+     * @return $this This QueryBuilder instance.
625
+     * @since 8.2.0
626
+     */
627
+    public function groupBy(...$groupBys);
628
+
629
+    /**
630
+     * Adds a grouping expression to the query.
631
+     *
632
+     * <code>
633
+     *     $qb = $conn->getQueryBuilder()
634
+     *         ->select('u.name')
635
+     *         ->from('users', 'u')
636
+     *         ->groupBy('u.lastLogin');
637
+     *         ->addGroupBy('u.createdAt')
638
+     * </code>
639
+     *
640
+     * @param mixed ...$groupBy The grouping expression.
641
+     *
642
+     * @return $this This QueryBuilder instance.
643
+     * @since 8.2.0
644
+     */
645
+    public function addGroupBy(...$groupBy);
646
+
647
+    /**
648
+     * Sets a value for a column in an insert query.
649
+     *
650
+     * <code>
651
+     *     $qb = $conn->getQueryBuilder()
652
+     *         ->insert('users')
653
+     *         ->values(
654
+     *             array(
655
+     *                 'name' => '?'
656
+     *             )
657
+     *         )
658
+     *         ->setValue('password', '?');
659
+     * </code>
660
+     *
661
+     * @param string $column The column into which the value should be inserted.
662
+     * @param IParameter|string $value The value that should be inserted into the column.
663
+     *
664
+     * @return $this This QueryBuilder instance.
665
+     * @since 8.2.0
666
+     */
667
+    public function setValue($column, $value);
668
+
669
+    /**
670
+     * Specifies values for an insert query indexed by column names.
671
+     * Replaces any previous values, if any.
672
+     *
673
+     * <code>
674
+     *     $qb = $conn->getQueryBuilder()
675
+     *         ->insert('users')
676
+     *         ->values(
677
+     *             array(
678
+     *                 'name' => '?',
679
+     *                 'password' => '?'
680
+     *             )
681
+     *         );
682
+     * </code>
683
+     *
684
+     * @param array $values The values to specify for the insert query indexed by column names.
685
+     *
686
+     * @return $this This QueryBuilder instance.
687
+     * @since 8.2.0
688
+     */
689
+    public function values(array $values);
690
+
691
+    /**
692
+     * Specifies a restriction over the groups of the query.
693
+     * Replaces any previous having restrictions, if any.
694
+     *
695
+     * @param mixed ...$having The restriction over the groups.
696
+     *
697
+     * @return $this This QueryBuilder instance.
698
+     * @since 8.2.0
699
+     */
700
+    public function having(...$having);
701
+
702
+    /**
703
+     * Adds a restriction over the groups of the query, forming a logical
704
+     * conjunction with any existing having restrictions.
705
+     *
706
+     * @param mixed ...$having The restriction to append.
707
+     *
708
+     * @return $this This QueryBuilder instance.
709
+     * @since 8.2.0
710
+     */
711
+    public function andHaving(...$having);
712
+
713
+    /**
714
+     * Adds a restriction over the groups of the query, forming a logical
715
+     * disjunction with any existing having restrictions.
716
+     *
717
+     * @param mixed ...$having The restriction to add.
718
+     *
719
+     * @return $this This QueryBuilder instance.
720
+     * @since 8.2.0
721
+     */
722
+    public function orHaving(...$having);
723
+
724
+    /**
725
+     * Specifies an ordering for the query results.
726
+     * Replaces any previously specified orderings, if any.
727
+     *
728
+     * @param string $sort The ordering expression.
729
+     * @param string $order The ordering direction.
730
+     *
731
+     * @return $this This QueryBuilder instance.
732
+     * @since 8.2.0
733
+     */
734
+    public function orderBy($sort, $order = null);
735
+
736
+    /**
737
+     * Adds an ordering to the query results.
738
+     *
739
+     * @param string $sort The ordering expression.
740
+     * @param string $order The ordering direction.
741
+     *
742
+     * @return $this This QueryBuilder instance.
743
+     * @since 8.2.0
744
+     */
745
+    public function addOrderBy($sort, $order = null);
746
+
747
+    /**
748
+     * Gets a query part by its name.
749
+     *
750
+     * @param string $queryPartName
751
+     *
752
+     * @return mixed
753
+     * @since 8.2.0
754
+     */
755
+    public function getQueryPart($queryPartName);
756
+
757
+    /**
758
+     * Gets all query parts.
759
+     *
760
+     * @return array
761
+     * @since 8.2.0
762
+     */
763
+    public function getQueryParts();
764
+
765
+    /**
766
+     * Resets SQL parts.
767
+     *
768
+     * @param array|null $queryPartNames
769
+     *
770
+     * @return $this This QueryBuilder instance.
771
+     * @since 8.2.0
772
+     */
773
+    public function resetQueryParts($queryPartNames = null);
774
+
775
+    /**
776
+     * Resets a single SQL part.
777
+     *
778
+     * @param string $queryPartName
779
+     *
780
+     * @return $this This QueryBuilder instance.
781
+     * @since 8.2.0
782
+     */
783
+    public function resetQueryPart($queryPartName);
784
+
785
+    /**
786
+     * Creates a new named parameter and bind the value $value to it.
787
+     *
788
+     * This method provides a shortcut for PDOStatement::bindValue
789
+     * when using prepared statements.
790
+     *
791
+     * The parameter $value specifies the value that you want to bind. If
792
+     * $placeholder is not provided bindValue() will automatically create a
793
+     * placeholder for you. An automatic placeholder will be of the name
794
+     * ':dcValue1', ':dcValue2' etc.
795
+     *
796
+     * For more information see {@link https://www.php.net/pdostatement-bindparam}
797
+     *
798
+     * Example:
799
+     * <code>
800
+     * $value = 2;
801
+     * $q->eq( 'id', $q->bindValue( $value ) );
802
+     * $stmt = $q->executeQuery(); // executed with 'id = 2'
803
+     * </code>
804
+     *
805
+     * @license New BSD License
806
+     * @link http://www.zetacomponents.org
807
+     *
808
+     * @param mixed $value
809
+     * @param mixed $type
810
+     * @param string $placeHolder The name to bind with. The string must start with a colon ':'.
811
+     *
812
+     * @return IParameter
813
+     * @since 8.2.0
814
+     */
815
+    public function createNamedParameter($value, $type = self::PARAM_STR, $placeHolder = null);
816
+
817
+    /**
818
+     * Creates a new positional parameter and bind the given value to it.
819
+     *
820
+     * Attention: If you are using positional parameters with the query builder you have
821
+     * to be very careful to bind all parameters in the order they appear in the SQL
822
+     * statement , otherwise they get bound in the wrong order which can lead to serious
823
+     * bugs in your code.
824
+     *
825
+     * Example:
826
+     * <code>
827
+     *  $qb = $conn->getQueryBuilder();
828
+     *  $qb->select('u.*')
829
+     *     ->from('users', 'u')
830
+     *     ->where('u.username = ' . $qb->createPositionalParameter('Foo', IQueryBuilder::PARAM_STR))
831
+     *     ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', IQueryBuilder::PARAM_STR))
832
+     * </code>
833
+     *
834
+     * @param mixed $value
835
+     * @param integer $type
836
+     *
837
+     * @return IParameter
838
+     * @since 8.2.0
839
+     */
840
+    public function createPositionalParameter($value, $type = self::PARAM_STR);
841
+
842
+    /**
843
+     * Creates a new parameter
844
+     *
845
+     * Example:
846
+     * <code>
847
+     *  $qb = $conn->getQueryBuilder();
848
+     *  $qb->select('u.*')
849
+     *     ->from('users', 'u')
850
+     *     ->where('u.username = ' . $qb->createParameter('name'))
851
+     *     ->setParameter('name', 'Bar', IQueryBuilder::PARAM_STR))
852
+     * </code>
853
+     *
854
+     * @param string $name
855
+     *
856
+     * @return IParameter
857
+     * @since 8.2.0
858
+     */
859
+    public function createParameter($name);
860
+
861
+    /**
862
+     * Creates a new function
863
+     *
864
+     * Attention: Column names inside the call have to be quoted before hand
865
+     *
866
+     * Example:
867
+     * <code>
868
+     *  $qb = $conn->getQueryBuilder();
869
+     *  $qb->select($qb->createFunction('COUNT(*)'))
870
+     *     ->from('users', 'u')
871
+     *  echo $qb->getSQL(); // SELECT COUNT(*) FROM `users` u
872
+     * </code>
873
+     * <code>
874
+     *  $qb = $conn->getQueryBuilder();
875
+     *  $qb->select($qb->createFunction('COUNT(`column`)'))
876
+     *     ->from('users', 'u')
877
+     *  echo $qb->getSQL(); // SELECT COUNT(`column`) FROM `users` u
878
+     * </code>
879
+     *
880
+     * @param string $call
881
+     *
882
+     * @return IQueryFunction
883
+     * @since 8.2.0
884
+     */
885
+    public function createFunction($call);
886
+
887
+    /**
888
+     * Used to get the id of the last inserted element
889
+     * @return int
890
+     * @throws \BadMethodCallException When being called before an insert query has been run.
891
+     * @since 9.0.0
892
+     */
893
+    public function getLastInsertId();
894
+
895
+    /**
896
+     * Returns the table name quoted and with database prefix as needed by the implementation
897
+     *
898
+     * @param string $table
899
+     * @return string
900
+     * @since 9.0.0
901
+     */
902
+    public function getTableName($table);
903
+
904
+    /**
905
+     * Returns the column name quoted and with table alias prefix as needed by the implementation
906
+     *
907
+     * @param string $column
908
+     * @param string $tableAlias
909
+     * @return string
910
+     * @since 9.0.0
911
+     */
912
+    public function getColumnName($column, $tableAlias = '');
913 913
 }
Please login to merge, or discard this patch.
lib/public/DB/Exception.php 1 patch
Indentation   +106 added lines, -106 removed lines patch added patch discarded remove patch
@@ -40,110 +40,110 @@
 block discarded – undo
40 40
  */
41 41
 class Exception extends BaseException {
42 42
 
43
-	/**
44
-	 * Nextcloud lost connection to the database
45
-	 *
46
-	 * @since 21.0.0
47
-	 */
48
-	public const REASON_CONNECTION_LOST = 1;
49
-
50
-	/**
51
-	 * A database constraint was violated
52
-	 *
53
-	 * @since 21.0.0
54
-	 */
55
-	public const REASON_CONSTRAINT_VIOLATION = 2;
56
-
57
-	/**
58
-	 * A database object (table, column, index) already exists
59
-	 *
60
-	 * @since 21.0.0
61
-	 */
62
-	public const REASON_DATABASE_OBJECT_EXISTS = 3;
63
-
64
-	/**
65
-	 * A database object (table, column, index) can't be found
66
-	 *
67
-	 * @since 21.0.0
68
-	 */
69
-	public const REASON_DATABASE_OBJECT_NOT_FOUND = 4;
70
-
71
-	/**
72
-	 * The database ran into a deadlock
73
-	 *
74
-	 * @since 21.0.0
75
-	 */
76
-	public const REASON_DEADLOCK = 5;
77
-
78
-	/**
79
-	 * The database driver encountered an issue
80
-	 *
81
-	 * @since 21.0.0
82
-	 */
83
-	public const REASON_DRIVER = 6;
84
-
85
-	/**
86
-	 * A foreign key constraint was violated
87
-	 *
88
-	 * @since 21.0.0
89
-	 */
90
-	public const REASON_FOREIGN_KEY_VIOLATION = 7;
91
-
92
-	/**
93
-	 * An invalid argument was passed to the database abstraction
94
-	 *
95
-	 * @since 21.0.0
96
-	 */
97
-	public const REASON_INVALID_ARGUMENT = 8;
98
-
99
-	/**
100
-	 * A field name was invalid
101
-	 *
102
-	 * @since 21.0.0
103
-	 */
104
-	public const REASON_INVALID_FIELD_NAME = 9;
105
-
106
-	/**
107
-	 * A name in the query was ambiguous
108
-	 *
109
-	 * @since 21.0.0
110
-	 */
111
-	public const REASON_NON_UNIQUE_FIELD_NAME = 10;
112
-
113
-	/**
114
-	 * A not null contraint was violated
115
-	 *
116
-	 * @since 21.0.0
117
-	 */
118
-	public const REASON_NOT_NULL_CONSTRAINT_VIOLATION = 11;
119
-
120
-	/**
121
-	 * A generic server error was encountered
122
-	 *
123
-	 * @since 21.0.0
124
-	 */
125
-	public const REASON_SERVER = 12;
126
-
127
-	/**
128
-	 * A syntax error was reported by the server
129
-	 *
130
-	 * @since 21.0.0
131
-	 */
132
-	public const REASON_SYNTAX_ERROR = 13;
133
-
134
-	/**
135
-	 * A unique constraint was violated
136
-	 *
137
-	 * @since 21.0.0
138
-	 */
139
-	public const REASON_UNIQUE_CONSTRAINT_VIOLATION = 14;
140
-
141
-	/**
142
-	 * @return int|null
143
-	 * @psalm-return Exception::REASON_*
144
-	 * @since 21.0.0
145
-	 */
146
-	public function getReason(): ?int {
147
-		return null;
148
-	}
43
+    /**
44
+     * Nextcloud lost connection to the database
45
+     *
46
+     * @since 21.0.0
47
+     */
48
+    public const REASON_CONNECTION_LOST = 1;
49
+
50
+    /**
51
+     * A database constraint was violated
52
+     *
53
+     * @since 21.0.0
54
+     */
55
+    public const REASON_CONSTRAINT_VIOLATION = 2;
56
+
57
+    /**
58
+     * A database object (table, column, index) already exists
59
+     *
60
+     * @since 21.0.0
61
+     */
62
+    public const REASON_DATABASE_OBJECT_EXISTS = 3;
63
+
64
+    /**
65
+     * A database object (table, column, index) can't be found
66
+     *
67
+     * @since 21.0.0
68
+     */
69
+    public const REASON_DATABASE_OBJECT_NOT_FOUND = 4;
70
+
71
+    /**
72
+     * The database ran into a deadlock
73
+     *
74
+     * @since 21.0.0
75
+     */
76
+    public const REASON_DEADLOCK = 5;
77
+
78
+    /**
79
+     * The database driver encountered an issue
80
+     *
81
+     * @since 21.0.0
82
+     */
83
+    public const REASON_DRIVER = 6;
84
+
85
+    /**
86
+     * A foreign key constraint was violated
87
+     *
88
+     * @since 21.0.0
89
+     */
90
+    public const REASON_FOREIGN_KEY_VIOLATION = 7;
91
+
92
+    /**
93
+     * An invalid argument was passed to the database abstraction
94
+     *
95
+     * @since 21.0.0
96
+     */
97
+    public const REASON_INVALID_ARGUMENT = 8;
98
+
99
+    /**
100
+     * A field name was invalid
101
+     *
102
+     * @since 21.0.0
103
+     */
104
+    public const REASON_INVALID_FIELD_NAME = 9;
105
+
106
+    /**
107
+     * A name in the query was ambiguous
108
+     *
109
+     * @since 21.0.0
110
+     */
111
+    public const REASON_NON_UNIQUE_FIELD_NAME = 10;
112
+
113
+    /**
114
+     * A not null contraint was violated
115
+     *
116
+     * @since 21.0.0
117
+     */
118
+    public const REASON_NOT_NULL_CONSTRAINT_VIOLATION = 11;
119
+
120
+    /**
121
+     * A generic server error was encountered
122
+     *
123
+     * @since 21.0.0
124
+     */
125
+    public const REASON_SERVER = 12;
126
+
127
+    /**
128
+     * A syntax error was reported by the server
129
+     *
130
+     * @since 21.0.0
131
+     */
132
+    public const REASON_SYNTAX_ERROR = 13;
133
+
134
+    /**
135
+     * A unique constraint was violated
136
+     *
137
+     * @since 21.0.0
138
+     */
139
+    public const REASON_UNIQUE_CONSTRAINT_VIOLATION = 14;
140
+
141
+    /**
142
+     * @return int|null
143
+     * @psalm-return Exception::REASON_*
144
+     * @since 21.0.0
145
+     */
146
+    public function getReason(): ?int {
147
+        return null;
148
+    }
149 149
 }
Please login to merge, or discard this patch.
lib/private/DB/Connection.php 2 patches
Indentation   +469 added lines, -469 removed lines patch added patch discarded remove patch
@@ -54,473 +54,473 @@
 block discarded – undo
54 54
 use OCP\PreConditionNotMetException;
55 55
 
56 56
 class Connection extends ReconnectWrapper {
57
-	/** @var string */
58
-	protected $tablePrefix;
59
-
60
-	/** @var \OC\DB\Adapter $adapter */
61
-	protected $adapter;
62
-
63
-	/** @var SystemConfig */
64
-	private $systemConfig;
65
-
66
-	/** @var ILogger */
67
-	private $logger;
68
-
69
-	protected $lockedTable = null;
70
-
71
-	/** @var int */
72
-	protected $queriesBuilt = 0;
73
-
74
-	/** @var int */
75
-	protected $queriesExecuted = 0;
76
-
77
-	/**
78
-	 * @throws Exception
79
-	 */
80
-	public function connect() {
81
-		try {
82
-			return parent::connect();
83
-		} catch (Exception $e) {
84
-			// throw a new exception to prevent leaking info from the stacktrace
85
-			throw new Exception('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
86
-		}
87
-	}
88
-
89
-	public function getStats(): array {
90
-		return [
91
-			'built' => $this->queriesBuilt,
92
-			'executed' => $this->queriesExecuted,
93
-		];
94
-	}
95
-
96
-	/**
97
-	 * Returns a QueryBuilder for the connection.
98
-	 */
99
-	public function getQueryBuilder(): IQueryBuilder {
100
-		$this->queriesBuilt++;
101
-		return new QueryBuilder(
102
-			new ConnectionAdapter($this),
103
-			$this->systemConfig,
104
-			$this->logger
105
-		);
106
-	}
107
-
108
-	/**
109
-	 * Gets the QueryBuilder for the connection.
110
-	 *
111
-	 * @return \Doctrine\DBAL\Query\QueryBuilder
112
-	 * @deprecated please use $this->getQueryBuilder() instead
113
-	 */
114
-	public function createQueryBuilder() {
115
-		$backtrace = $this->getCallerBacktrace();
116
-		\OC::$server->getLogger()->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
117
-		$this->queriesBuilt++;
118
-		return parent::createQueryBuilder();
119
-	}
120
-
121
-	/**
122
-	 * Gets the ExpressionBuilder for the connection.
123
-	 *
124
-	 * @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
125
-	 * @deprecated please use $this->getQueryBuilder()->expr() instead
126
-	 */
127
-	public function getExpressionBuilder() {
128
-		$backtrace = $this->getCallerBacktrace();
129
-		\OC::$server->getLogger()->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
130
-		$this->queriesBuilt++;
131
-		return parent::getExpressionBuilder();
132
-	}
133
-
134
-	/**
135
-	 * Get the file and line that called the method where `getCallerBacktrace()` was used
136
-	 *
137
-	 * @return string
138
-	 */
139
-	protected function getCallerBacktrace() {
140
-		$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
141
-
142
-		// 0 is the method where we use `getCallerBacktrace`
143
-		// 1 is the target method which uses the method we want to log
144
-		if (isset($traces[1])) {
145
-			return $traces[1]['file'] . ':' . $traces[1]['line'];
146
-		}
147
-
148
-		return '';
149
-	}
150
-
151
-	/**
152
-	 * @return string
153
-	 */
154
-	public function getPrefix() {
155
-		return $this->tablePrefix;
156
-	}
157
-
158
-	/**
159
-	 * Initializes a new instance of the Connection class.
160
-	 *
161
-	 * @param array $params  The connection parameters.
162
-	 * @param \Doctrine\DBAL\Driver $driver
163
-	 * @param \Doctrine\DBAL\Configuration $config
164
-	 * @param \Doctrine\Common\EventManager $eventManager
165
-	 * @throws \Exception
166
-	 */
167
-	public function __construct(array $params, Driver $driver, Configuration $config = null,
168
-		EventManager $eventManager = null) {
169
-		if (!isset($params['adapter'])) {
170
-			throw new \Exception('adapter not set');
171
-		}
172
-		if (!isset($params['tablePrefix'])) {
173
-			throw new \Exception('tablePrefix not set');
174
-		}
175
-		parent::__construct($params, $driver, $config, $eventManager);
176
-		$this->adapter = new $params['adapter']($this);
177
-		$this->tablePrefix = $params['tablePrefix'];
178
-
179
-		$this->systemConfig = \OC::$server->getSystemConfig();
180
-		$this->logger = \OC::$server->getLogger();
181
-	}
182
-
183
-	/**
184
-	 * Prepares an SQL statement.
185
-	 *
186
-	 * @param string $statement The SQL statement to prepare.
187
-	 * @param int $limit
188
-	 * @param int $offset
189
-	 *
190
-	 * @return Statement The prepared statement.
191
-	 * @throws Exception
192
-	 */
193
-	public function prepare($statement, $limit = null, $offset = null): Statement {
194
-		if ($limit === -1) {
195
-			$limit = null;
196
-		}
197
-		if (!is_null($limit)) {
198
-			$platform = $this->getDatabasePlatform();
199
-			$statement = $platform->modifyLimitQuery($statement, $limit, $offset);
200
-		}
201
-		$statement = $this->replaceTablePrefix($statement);
202
-		$statement = $this->adapter->fixupStatement($statement);
203
-
204
-		return parent::prepare($statement);
205
-	}
206
-
207
-	/**
208
-	 * Executes an, optionally parametrized, SQL query.
209
-	 *
210
-	 * If the query is parametrized, a prepared statement is used.
211
-	 * If an SQLLogger is configured, the execution is logged.
212
-	 *
213
-	 * @param string                                      $sql  The SQL query to execute.
214
-	 * @param array                                       $params The parameters to bind to the query, if any.
215
-	 * @param array                                       $types  The types the previous parameters are in.
216
-	 * @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp    The query cache profile, optional.
217
-	 *
218
-	 * @return Result The executed statement.
219
-	 *
220
-	 * @throws \Doctrine\DBAL\Exception
221
-	 */
222
-	public function executeQuery(string $sql, array $params = [], $types = [], QueryCacheProfile $qcp = null): Result {
223
-		$sql = $this->replaceTablePrefix($sql);
224
-		$sql = $this->adapter->fixupStatement($sql);
225
-		$this->queriesExecuted++;
226
-		return parent::executeQuery($sql, $params, $types, $qcp);
227
-	}
228
-
229
-	/**
230
-	 * @throws Exception
231
-	 */
232
-	public function executeUpdate(string $sql, array $params = [], array $types = []): int {
233
-		$sql = $this->replaceTablePrefix($sql);
234
-		$sql = $this->adapter->fixupStatement($sql);
235
-		$this->queriesExecuted++;
236
-		return parent::executeUpdate($sql, $params, $types);
237
-	}
238
-
239
-	/**
240
-	 * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
241
-	 * and returns the number of affected rows.
242
-	 *
243
-	 * This method supports PDO binding types as well as DBAL mapping types.
244
-	 *
245
-	 * @param string $sql  The SQL query.
246
-	 * @param array  $params The query parameters.
247
-	 * @param array  $types  The parameter types.
248
-	 *
249
-	 * @return int The number of affected rows.
250
-	 *
251
-	 * @throws \Doctrine\DBAL\Exception
252
-	 */
253
-	public function executeStatement($sql, array $params = [], array $types = []): int {
254
-		$sql = $this->replaceTablePrefix($sql);
255
-		$sql = $this->adapter->fixupStatement($sql);
256
-		$this->queriesExecuted++;
257
-		return parent::executeStatement($sql, $params, $types);
258
-	}
259
-
260
-	/**
261
-	 * Returns the ID of the last inserted row, or the last value from a sequence object,
262
-	 * depending on the underlying driver.
263
-	 *
264
-	 * Note: This method may not return a meaningful or consistent result across different drivers,
265
-	 * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
266
-	 * columns or sequences.
267
-	 *
268
-	 * @param string $seqName Name of the sequence object from which the ID should be returned.
269
-	 *
270
-	 * @return string the last inserted ID.
271
-	 * @throws Exception
272
-	 */
273
-	public function lastInsertId($seqName = null) {
274
-		if ($seqName) {
275
-			$seqName = $this->replaceTablePrefix($seqName);
276
-		}
277
-		return $this->adapter->lastInsertId($seqName);
278
-	}
279
-
280
-	/**
281
-	 * @internal
282
-	 * @throws Exception
283
-	 */
284
-	public function realLastInsertId($seqName = null) {
285
-		return parent::lastInsertId($seqName);
286
-	}
287
-
288
-	/**
289
-	 * Insert a row if the matching row does not exists. To accomplish proper race condition avoidance
290
-	 * it is needed that there is also a unique constraint on the values. Then this method will
291
-	 * catch the exception and return 0.
292
-	 *
293
-	 * @param string $table The table name (will replace *PREFIX* with the actual prefix)
294
-	 * @param array $input data that should be inserted into the table  (column name => value)
295
-	 * @param array|null $compare List of values that should be checked for "if not exists"
296
-	 *				If this is null or an empty array, all keys of $input will be compared
297
-	 *				Please note: text fields (clob) must not be used in the compare array
298
-	 * @return int number of inserted rows
299
-	 * @throws \Doctrine\DBAL\Exception
300
-	 * @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
301
-	 */
302
-	public function insertIfNotExist($table, $input, array $compare = null) {
303
-		return $this->adapter->insertIfNotExist($table, $input, $compare);
304
-	}
305
-
306
-	public function insertIgnoreConflict(string $table, array $values) : int {
307
-		return $this->adapter->insertIgnoreConflict($table, $values);
308
-	}
309
-
310
-	private function getType($value) {
311
-		if (is_bool($value)) {
312
-			return IQueryBuilder::PARAM_BOOL;
313
-		} elseif (is_int($value)) {
314
-			return IQueryBuilder::PARAM_INT;
315
-		} else {
316
-			return IQueryBuilder::PARAM_STR;
317
-		}
318
-	}
319
-
320
-	/**
321
-	 * Insert or update a row value
322
-	 *
323
-	 * @param string $table
324
-	 * @param array $keys (column name => value)
325
-	 * @param array $values (column name => value)
326
-	 * @param array $updatePreconditionValues ensure values match preconditions (column name => value)
327
-	 * @return int number of new rows
328
-	 * @throws \Doctrine\DBAL\Exception
329
-	 * @throws PreConditionNotMetException
330
-	 */
331
-	public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) {
332
-		try {
333
-			$insertQb = $this->getQueryBuilder();
334
-			$insertQb->insert($table)
335
-				->values(
336
-					array_map(function ($value) use ($insertQb) {
337
-						return $insertQb->createNamedParameter($value, $this->getType($value));
338
-					}, array_merge($keys, $values))
339
-				);
340
-			return $insertQb->execute();
341
-		} catch (NotNullConstraintViolationException $e) {
342
-			throw $e;
343
-		} catch (ConstraintViolationException $e) {
344
-			// value already exists, try update
345
-			$updateQb = $this->getQueryBuilder();
346
-			$updateQb->update($table);
347
-			foreach ($values as $name => $value) {
348
-				$updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value)));
349
-			}
350
-			$where = $updateQb->expr()->andX();
351
-			$whereValues = array_merge($keys, $updatePreconditionValues);
352
-			foreach ($whereValues as $name => $value) {
353
-				if ($value === '') {
354
-					$where->add($updateQb->expr()->emptyString(
355
-						$name
356
-					));
357
-				} else {
358
-					$where->add($updateQb->expr()->eq(
359
-						$name,
360
-						$updateQb->createNamedParameter($value, $this->getType($value)),
361
-						$this->getType($value)
362
-					));
363
-				}
364
-			}
365
-			$updateQb->where($where);
366
-			$affected = $updateQb->execute();
367
-
368
-			if ($affected === 0 && !empty($updatePreconditionValues)) {
369
-				throw new PreConditionNotMetException();
370
-			}
371
-
372
-			return 0;
373
-		}
374
-	}
375
-
376
-	/**
377
-	 * Create an exclusive read+write lock on a table
378
-	 *
379
-	 * @param string $tableName
380
-	 *
381
-	 * @throws \BadMethodCallException When trying to acquire a second lock
382
-	 * @throws Exception
383
-	 * @since 9.1.0
384
-	 */
385
-	public function lockTable($tableName) {
386
-		if ($this->lockedTable !== null) {
387
-			throw new \BadMethodCallException('Can not lock a new table until the previous lock is released.');
388
-		}
389
-
390
-		$tableName = $this->tablePrefix . $tableName;
391
-		$this->lockedTable = $tableName;
392
-		$this->adapter->lockTable($tableName);
393
-	}
394
-
395
-	/**
396
-	 * Release a previous acquired lock again
397
-	 *
398
-	 * @throws Exception
399
-	 * @since 9.1.0
400
-	 */
401
-	public function unlockTable() {
402
-		$this->adapter->unlockTable();
403
-		$this->lockedTable = null;
404
-	}
405
-
406
-	/**
407
-	 * returns the error code and message as a string for logging
408
-	 * works with DoctrineException
409
-	 * @return string
410
-	 */
411
-	public function getError() {
412
-		$msg = $this->errorCode() . ': ';
413
-		$errorInfo = $this->errorInfo();
414
-		if (!empty($errorInfo)) {
415
-			$msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
416
-			$msg .= 'Driver Code = '.$errorInfo[1] . ', ';
417
-			$msg .= 'Driver Message = '.$errorInfo[2];
418
-		}
419
-		return $msg;
420
-	}
421
-
422
-	public function errorCode() {
423
-		return -1;
424
-	}
425
-
426
-	public function errorInfo() {
427
-		return [];
428
-	}
429
-
430
-	/**
431
-	 * Drop a table from the database if it exists
432
-	 *
433
-	 * @param string $table table name without the prefix
434
-	 *
435
-	 * @throws Exception
436
-	 */
437
-	public function dropTable($table) {
438
-		$table = $this->tablePrefix . trim($table);
439
-		$schema = $this->getSchemaManager();
440
-		if ($schema->tablesExist([$table])) {
441
-			$schema->dropTable($table);
442
-		}
443
-	}
444
-
445
-	/**
446
-	 * Check if a table exists
447
-	 *
448
-	 * @param string $table table name without the prefix
449
-	 *
450
-	 * @return bool
451
-	 * @throws Exception
452
-	 */
453
-	public function tableExists($table) {
454
-		$table = $this->tablePrefix . trim($table);
455
-		$schema = $this->getSchemaManager();
456
-		return $schema->tablesExist([$table]);
457
-	}
458
-
459
-	// internal use
460
-	/**
461
-	 * @param string $statement
462
-	 * @return string
463
-	 */
464
-	protected function replaceTablePrefix($statement) {
465
-		return str_replace('*PREFIX*', $this->tablePrefix, $statement);
466
-	}
467
-
468
-	/**
469
-	 * Check if a transaction is active
470
-	 *
471
-	 * @return bool
472
-	 * @since 8.2.0
473
-	 */
474
-	public function inTransaction() {
475
-		return $this->getTransactionNestingLevel() > 0;
476
-	}
477
-
478
-	/**
479
-	 * Escape a parameter to be used in a LIKE query
480
-	 *
481
-	 * @param string $param
482
-	 * @return string
483
-	 */
484
-	public function escapeLikeParameter($param) {
485
-		return addcslashes($param, '\\_%');
486
-	}
487
-
488
-	/**
489
-	 * Check whether or not the current database support 4byte wide unicode
490
-	 *
491
-	 * @return bool
492
-	 * @since 11.0.0
493
-	 */
494
-	public function supports4ByteText() {
495
-		if (!$this->getDatabasePlatform() instanceof MySQLPlatform) {
496
-			return true;
497
-		}
498
-		return $this->getParams()['charset'] === 'utf8mb4';
499
-	}
500
-
501
-
502
-	/**
503
-	 * Create the schema of the connected database
504
-	 *
505
-	 * @return Schema
506
-	 * @throws Exception
507
-	 */
508
-	public function createSchema() {
509
-		$schemaManager = new MDB2SchemaManager($this);
510
-		$migrator = $schemaManager->getMigrator();
511
-		return $migrator->createSchema();
512
-	}
513
-
514
-	/**
515
-	 * Migrate the database to the given schema
516
-	 *
517
-	 * @param Schema $toSchema
518
-	 *
519
-	 * @throws Exception
520
-	 */
521
-	public function migrateToSchema(Schema $toSchema) {
522
-		$schemaManager = new MDB2SchemaManager($this);
523
-		$migrator = $schemaManager->getMigrator();
524
-		$migrator->migrate($toSchema);
525
-	}
57
+    /** @var string */
58
+    protected $tablePrefix;
59
+
60
+    /** @var \OC\DB\Adapter $adapter */
61
+    protected $adapter;
62
+
63
+    /** @var SystemConfig */
64
+    private $systemConfig;
65
+
66
+    /** @var ILogger */
67
+    private $logger;
68
+
69
+    protected $lockedTable = null;
70
+
71
+    /** @var int */
72
+    protected $queriesBuilt = 0;
73
+
74
+    /** @var int */
75
+    protected $queriesExecuted = 0;
76
+
77
+    /**
78
+     * @throws Exception
79
+     */
80
+    public function connect() {
81
+        try {
82
+            return parent::connect();
83
+        } catch (Exception $e) {
84
+            // throw a new exception to prevent leaking info from the stacktrace
85
+            throw new Exception('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
86
+        }
87
+    }
88
+
89
+    public function getStats(): array {
90
+        return [
91
+            'built' => $this->queriesBuilt,
92
+            'executed' => $this->queriesExecuted,
93
+        ];
94
+    }
95
+
96
+    /**
97
+     * Returns a QueryBuilder for the connection.
98
+     */
99
+    public function getQueryBuilder(): IQueryBuilder {
100
+        $this->queriesBuilt++;
101
+        return new QueryBuilder(
102
+            new ConnectionAdapter($this),
103
+            $this->systemConfig,
104
+            $this->logger
105
+        );
106
+    }
107
+
108
+    /**
109
+     * Gets the QueryBuilder for the connection.
110
+     *
111
+     * @return \Doctrine\DBAL\Query\QueryBuilder
112
+     * @deprecated please use $this->getQueryBuilder() instead
113
+     */
114
+    public function createQueryBuilder() {
115
+        $backtrace = $this->getCallerBacktrace();
116
+        \OC::$server->getLogger()->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
117
+        $this->queriesBuilt++;
118
+        return parent::createQueryBuilder();
119
+    }
120
+
121
+    /**
122
+     * Gets the ExpressionBuilder for the connection.
123
+     *
124
+     * @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
125
+     * @deprecated please use $this->getQueryBuilder()->expr() instead
126
+     */
127
+    public function getExpressionBuilder() {
128
+        $backtrace = $this->getCallerBacktrace();
129
+        \OC::$server->getLogger()->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
130
+        $this->queriesBuilt++;
131
+        return parent::getExpressionBuilder();
132
+    }
133
+
134
+    /**
135
+     * Get the file and line that called the method where `getCallerBacktrace()` was used
136
+     *
137
+     * @return string
138
+     */
139
+    protected function getCallerBacktrace() {
140
+        $traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
141
+
142
+        // 0 is the method where we use `getCallerBacktrace`
143
+        // 1 is the target method which uses the method we want to log
144
+        if (isset($traces[1])) {
145
+            return $traces[1]['file'] . ':' . $traces[1]['line'];
146
+        }
147
+
148
+        return '';
149
+    }
150
+
151
+    /**
152
+     * @return string
153
+     */
154
+    public function getPrefix() {
155
+        return $this->tablePrefix;
156
+    }
157
+
158
+    /**
159
+     * Initializes a new instance of the Connection class.
160
+     *
161
+     * @param array $params  The connection parameters.
162
+     * @param \Doctrine\DBAL\Driver $driver
163
+     * @param \Doctrine\DBAL\Configuration $config
164
+     * @param \Doctrine\Common\EventManager $eventManager
165
+     * @throws \Exception
166
+     */
167
+    public function __construct(array $params, Driver $driver, Configuration $config = null,
168
+        EventManager $eventManager = null) {
169
+        if (!isset($params['adapter'])) {
170
+            throw new \Exception('adapter not set');
171
+        }
172
+        if (!isset($params['tablePrefix'])) {
173
+            throw new \Exception('tablePrefix not set');
174
+        }
175
+        parent::__construct($params, $driver, $config, $eventManager);
176
+        $this->adapter = new $params['adapter']($this);
177
+        $this->tablePrefix = $params['tablePrefix'];
178
+
179
+        $this->systemConfig = \OC::$server->getSystemConfig();
180
+        $this->logger = \OC::$server->getLogger();
181
+    }
182
+
183
+    /**
184
+     * Prepares an SQL statement.
185
+     *
186
+     * @param string $statement The SQL statement to prepare.
187
+     * @param int $limit
188
+     * @param int $offset
189
+     *
190
+     * @return Statement The prepared statement.
191
+     * @throws Exception
192
+     */
193
+    public function prepare($statement, $limit = null, $offset = null): Statement {
194
+        if ($limit === -1) {
195
+            $limit = null;
196
+        }
197
+        if (!is_null($limit)) {
198
+            $platform = $this->getDatabasePlatform();
199
+            $statement = $platform->modifyLimitQuery($statement, $limit, $offset);
200
+        }
201
+        $statement = $this->replaceTablePrefix($statement);
202
+        $statement = $this->adapter->fixupStatement($statement);
203
+
204
+        return parent::prepare($statement);
205
+    }
206
+
207
+    /**
208
+     * Executes an, optionally parametrized, SQL query.
209
+     *
210
+     * If the query is parametrized, a prepared statement is used.
211
+     * If an SQLLogger is configured, the execution is logged.
212
+     *
213
+     * @param string                                      $sql  The SQL query to execute.
214
+     * @param array                                       $params The parameters to bind to the query, if any.
215
+     * @param array                                       $types  The types the previous parameters are in.
216
+     * @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp    The query cache profile, optional.
217
+     *
218
+     * @return Result The executed statement.
219
+     *
220
+     * @throws \Doctrine\DBAL\Exception
221
+     */
222
+    public function executeQuery(string $sql, array $params = [], $types = [], QueryCacheProfile $qcp = null): Result {
223
+        $sql = $this->replaceTablePrefix($sql);
224
+        $sql = $this->adapter->fixupStatement($sql);
225
+        $this->queriesExecuted++;
226
+        return parent::executeQuery($sql, $params, $types, $qcp);
227
+    }
228
+
229
+    /**
230
+     * @throws Exception
231
+     */
232
+    public function executeUpdate(string $sql, array $params = [], array $types = []): int {
233
+        $sql = $this->replaceTablePrefix($sql);
234
+        $sql = $this->adapter->fixupStatement($sql);
235
+        $this->queriesExecuted++;
236
+        return parent::executeUpdate($sql, $params, $types);
237
+    }
238
+
239
+    /**
240
+     * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
241
+     * and returns the number of affected rows.
242
+     *
243
+     * This method supports PDO binding types as well as DBAL mapping types.
244
+     *
245
+     * @param string $sql  The SQL query.
246
+     * @param array  $params The query parameters.
247
+     * @param array  $types  The parameter types.
248
+     *
249
+     * @return int The number of affected rows.
250
+     *
251
+     * @throws \Doctrine\DBAL\Exception
252
+     */
253
+    public function executeStatement($sql, array $params = [], array $types = []): int {
254
+        $sql = $this->replaceTablePrefix($sql);
255
+        $sql = $this->adapter->fixupStatement($sql);
256
+        $this->queriesExecuted++;
257
+        return parent::executeStatement($sql, $params, $types);
258
+    }
259
+
260
+    /**
261
+     * Returns the ID of the last inserted row, or the last value from a sequence object,
262
+     * depending on the underlying driver.
263
+     *
264
+     * Note: This method may not return a meaningful or consistent result across different drivers,
265
+     * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
266
+     * columns or sequences.
267
+     *
268
+     * @param string $seqName Name of the sequence object from which the ID should be returned.
269
+     *
270
+     * @return string the last inserted ID.
271
+     * @throws Exception
272
+     */
273
+    public function lastInsertId($seqName = null) {
274
+        if ($seqName) {
275
+            $seqName = $this->replaceTablePrefix($seqName);
276
+        }
277
+        return $this->adapter->lastInsertId($seqName);
278
+    }
279
+
280
+    /**
281
+     * @internal
282
+     * @throws Exception
283
+     */
284
+    public function realLastInsertId($seqName = null) {
285
+        return parent::lastInsertId($seqName);
286
+    }
287
+
288
+    /**
289
+     * Insert a row if the matching row does not exists. To accomplish proper race condition avoidance
290
+     * it is needed that there is also a unique constraint on the values. Then this method will
291
+     * catch the exception and return 0.
292
+     *
293
+     * @param string $table The table name (will replace *PREFIX* with the actual prefix)
294
+     * @param array $input data that should be inserted into the table  (column name => value)
295
+     * @param array|null $compare List of values that should be checked for "if not exists"
296
+     *				If this is null or an empty array, all keys of $input will be compared
297
+     *				Please note: text fields (clob) must not be used in the compare array
298
+     * @return int number of inserted rows
299
+     * @throws \Doctrine\DBAL\Exception
300
+     * @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
301
+     */
302
+    public function insertIfNotExist($table, $input, array $compare = null) {
303
+        return $this->adapter->insertIfNotExist($table, $input, $compare);
304
+    }
305
+
306
+    public function insertIgnoreConflict(string $table, array $values) : int {
307
+        return $this->adapter->insertIgnoreConflict($table, $values);
308
+    }
309
+
310
+    private function getType($value) {
311
+        if (is_bool($value)) {
312
+            return IQueryBuilder::PARAM_BOOL;
313
+        } elseif (is_int($value)) {
314
+            return IQueryBuilder::PARAM_INT;
315
+        } else {
316
+            return IQueryBuilder::PARAM_STR;
317
+        }
318
+    }
319
+
320
+    /**
321
+     * Insert or update a row value
322
+     *
323
+     * @param string $table
324
+     * @param array $keys (column name => value)
325
+     * @param array $values (column name => value)
326
+     * @param array $updatePreconditionValues ensure values match preconditions (column name => value)
327
+     * @return int number of new rows
328
+     * @throws \Doctrine\DBAL\Exception
329
+     * @throws PreConditionNotMetException
330
+     */
331
+    public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) {
332
+        try {
333
+            $insertQb = $this->getQueryBuilder();
334
+            $insertQb->insert($table)
335
+                ->values(
336
+                    array_map(function ($value) use ($insertQb) {
337
+                        return $insertQb->createNamedParameter($value, $this->getType($value));
338
+                    }, array_merge($keys, $values))
339
+                );
340
+            return $insertQb->execute();
341
+        } catch (NotNullConstraintViolationException $e) {
342
+            throw $e;
343
+        } catch (ConstraintViolationException $e) {
344
+            // value already exists, try update
345
+            $updateQb = $this->getQueryBuilder();
346
+            $updateQb->update($table);
347
+            foreach ($values as $name => $value) {
348
+                $updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value)));
349
+            }
350
+            $where = $updateQb->expr()->andX();
351
+            $whereValues = array_merge($keys, $updatePreconditionValues);
352
+            foreach ($whereValues as $name => $value) {
353
+                if ($value === '') {
354
+                    $where->add($updateQb->expr()->emptyString(
355
+                        $name
356
+                    ));
357
+                } else {
358
+                    $where->add($updateQb->expr()->eq(
359
+                        $name,
360
+                        $updateQb->createNamedParameter($value, $this->getType($value)),
361
+                        $this->getType($value)
362
+                    ));
363
+                }
364
+            }
365
+            $updateQb->where($where);
366
+            $affected = $updateQb->execute();
367
+
368
+            if ($affected === 0 && !empty($updatePreconditionValues)) {
369
+                throw new PreConditionNotMetException();
370
+            }
371
+
372
+            return 0;
373
+        }
374
+    }
375
+
376
+    /**
377
+     * Create an exclusive read+write lock on a table
378
+     *
379
+     * @param string $tableName
380
+     *
381
+     * @throws \BadMethodCallException When trying to acquire a second lock
382
+     * @throws Exception
383
+     * @since 9.1.0
384
+     */
385
+    public function lockTable($tableName) {
386
+        if ($this->lockedTable !== null) {
387
+            throw new \BadMethodCallException('Can not lock a new table until the previous lock is released.');
388
+        }
389
+
390
+        $tableName = $this->tablePrefix . $tableName;
391
+        $this->lockedTable = $tableName;
392
+        $this->adapter->lockTable($tableName);
393
+    }
394
+
395
+    /**
396
+     * Release a previous acquired lock again
397
+     *
398
+     * @throws Exception
399
+     * @since 9.1.0
400
+     */
401
+    public function unlockTable() {
402
+        $this->adapter->unlockTable();
403
+        $this->lockedTable = null;
404
+    }
405
+
406
+    /**
407
+     * returns the error code and message as a string for logging
408
+     * works with DoctrineException
409
+     * @return string
410
+     */
411
+    public function getError() {
412
+        $msg = $this->errorCode() . ': ';
413
+        $errorInfo = $this->errorInfo();
414
+        if (!empty($errorInfo)) {
415
+            $msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
416
+            $msg .= 'Driver Code = '.$errorInfo[1] . ', ';
417
+            $msg .= 'Driver Message = '.$errorInfo[2];
418
+        }
419
+        return $msg;
420
+    }
421
+
422
+    public function errorCode() {
423
+        return -1;
424
+    }
425
+
426
+    public function errorInfo() {
427
+        return [];
428
+    }
429
+
430
+    /**
431
+     * Drop a table from the database if it exists
432
+     *
433
+     * @param string $table table name without the prefix
434
+     *
435
+     * @throws Exception
436
+     */
437
+    public function dropTable($table) {
438
+        $table = $this->tablePrefix . trim($table);
439
+        $schema = $this->getSchemaManager();
440
+        if ($schema->tablesExist([$table])) {
441
+            $schema->dropTable($table);
442
+        }
443
+    }
444
+
445
+    /**
446
+     * Check if a table exists
447
+     *
448
+     * @param string $table table name without the prefix
449
+     *
450
+     * @return bool
451
+     * @throws Exception
452
+     */
453
+    public function tableExists($table) {
454
+        $table = $this->tablePrefix . trim($table);
455
+        $schema = $this->getSchemaManager();
456
+        return $schema->tablesExist([$table]);
457
+    }
458
+
459
+    // internal use
460
+    /**
461
+     * @param string $statement
462
+     * @return string
463
+     */
464
+    protected function replaceTablePrefix($statement) {
465
+        return str_replace('*PREFIX*', $this->tablePrefix, $statement);
466
+    }
467
+
468
+    /**
469
+     * Check if a transaction is active
470
+     *
471
+     * @return bool
472
+     * @since 8.2.0
473
+     */
474
+    public function inTransaction() {
475
+        return $this->getTransactionNestingLevel() > 0;
476
+    }
477
+
478
+    /**
479
+     * Escape a parameter to be used in a LIKE query
480
+     *
481
+     * @param string $param
482
+     * @return string
483
+     */
484
+    public function escapeLikeParameter($param) {
485
+        return addcslashes($param, '\\_%');
486
+    }
487
+
488
+    /**
489
+     * Check whether or not the current database support 4byte wide unicode
490
+     *
491
+     * @return bool
492
+     * @since 11.0.0
493
+     */
494
+    public function supports4ByteText() {
495
+        if (!$this->getDatabasePlatform() instanceof MySQLPlatform) {
496
+            return true;
497
+        }
498
+        return $this->getParams()['charset'] === 'utf8mb4';
499
+    }
500
+
501
+
502
+    /**
503
+     * Create the schema of the connected database
504
+     *
505
+     * @return Schema
506
+     * @throws Exception
507
+     */
508
+    public function createSchema() {
509
+        $schemaManager = new MDB2SchemaManager($this);
510
+        $migrator = $schemaManager->getMigrator();
511
+        return $migrator->createSchema();
512
+    }
513
+
514
+    /**
515
+     * Migrate the database to the given schema
516
+     *
517
+     * @param Schema $toSchema
518
+     *
519
+     * @throws Exception
520
+     */
521
+    public function migrateToSchema(Schema $toSchema) {
522
+        $schemaManager = new MDB2SchemaManager($this);
523
+        $migrator = $schemaManager->getMigrator();
524
+        $migrator->migrate($toSchema);
525
+    }
526 526
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -82,7 +82,7 @@  discard block
 block discarded – undo
82 82
 			return parent::connect();
83 83
 		} catch (Exception $e) {
84 84
 			// throw a new exception to prevent leaking info from the stacktrace
85
-			throw new Exception('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
85
+			throw new Exception('Failed to connect to the database: '.$e->getMessage(), $e->getCode());
86 86
 		}
87 87
 	}
88 88
 
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
 		// 0 is the method where we use `getCallerBacktrace`
143 143
 		// 1 is the target method which uses the method we want to log
144 144
 		if (isset($traces[1])) {
145
-			return $traces[1]['file'] . ':' . $traces[1]['line'];
145
+			return $traces[1]['file'].':'.$traces[1]['line'];
146 146
 		}
147 147
 
148 148
 		return '';
@@ -333,7 +333,7 @@  discard block
 block discarded – undo
333 333
 			$insertQb = $this->getQueryBuilder();
334 334
 			$insertQb->insert($table)
335 335
 				->values(
336
-					array_map(function ($value) use ($insertQb) {
336
+					array_map(function($value) use ($insertQb) {
337 337
 						return $insertQb->createNamedParameter($value, $this->getType($value));
338 338
 					}, array_merge($keys, $values))
339 339
 				);
@@ -387,7 +387,7 @@  discard block
 block discarded – undo
387 387
 			throw new \BadMethodCallException('Can not lock a new table until the previous lock is released.');
388 388
 		}
389 389
 
390
-		$tableName = $this->tablePrefix . $tableName;
390
+		$tableName = $this->tablePrefix.$tableName;
391 391
 		$this->lockedTable = $tableName;
392 392
 		$this->adapter->lockTable($tableName);
393 393
 	}
@@ -409,11 +409,11 @@  discard block
 block discarded – undo
409 409
 	 * @return string
410 410
 	 */
411 411
 	public function getError() {
412
-		$msg = $this->errorCode() . ': ';
412
+		$msg = $this->errorCode().': ';
413 413
 		$errorInfo = $this->errorInfo();
414 414
 		if (!empty($errorInfo)) {
415
-			$msg .= 'SQLSTATE = '.$errorInfo[0] . ', ';
416
-			$msg .= 'Driver Code = '.$errorInfo[1] . ', ';
415
+			$msg .= 'SQLSTATE = '.$errorInfo[0].', ';
416
+			$msg .= 'Driver Code = '.$errorInfo[1].', ';
417 417
 			$msg .= 'Driver Message = '.$errorInfo[2];
418 418
 		}
419 419
 		return $msg;
@@ -435,7 +435,7 @@  discard block
 block discarded – undo
435 435
 	 * @throws Exception
436 436
 	 */
437 437
 	public function dropTable($table) {
438
-		$table = $this->tablePrefix . trim($table);
438
+		$table = $this->tablePrefix.trim($table);
439 439
 		$schema = $this->getSchemaManager();
440 440
 		if ($schema->tablesExist([$table])) {
441 441
 			$schema->dropTable($table);
@@ -451,7 +451,7 @@  discard block
 block discarded – undo
451 451
 	 * @throws Exception
452 452
 	 */
453 453
 	public function tableExists($table) {
454
-		$table = $this->tablePrefix . trim($table);
454
+		$table = $this->tablePrefix.trim($table);
455 455
 		$schema = $this->getSchemaManager();
456 456
 		return $schema->tablesExist([$table]);
457 457
 	}
Please login to merge, or discard this patch.
lib/private/DB/Adapter.php 2 patches
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -39,115 +39,115 @@
 block discarded – undo
39 39
  */
40 40
 class Adapter {
41 41
 
42
-	/**
43
-	 * @var \OC\DB\Connection $conn
44
-	 */
45
-	protected $conn;
42
+    /**
43
+     * @var \OC\DB\Connection $conn
44
+     */
45
+    protected $conn;
46 46
 
47
-	public function __construct($conn) {
48
-		$this->conn = $conn;
49
-	}
47
+    public function __construct($conn) {
48
+        $this->conn = $conn;
49
+    }
50 50
 
51
-	/**
52
-	 * @param string $table name
53
-	 *
54
-	 * @return int id of last insert statement
55
-	 * @throws Exception
56
-	 */
57
-	public function lastInsertId($table) {
58
-		return (int) $this->conn->realLastInsertId($table);
59
-	}
51
+    /**
52
+     * @param string $table name
53
+     *
54
+     * @return int id of last insert statement
55
+     * @throws Exception
56
+     */
57
+    public function lastInsertId($table) {
58
+        return (int) $this->conn->realLastInsertId($table);
59
+    }
60 60
 
61
-	/**
62
-	 * @param string $statement that needs to be changed so the db can handle it
63
-	 * @return string changed statement
64
-	 */
65
-	public function fixupStatement($statement) {
66
-		return $statement;
67
-	}
61
+    /**
62
+     * @param string $statement that needs to be changed so the db can handle it
63
+     * @return string changed statement
64
+     */
65
+    public function fixupStatement($statement) {
66
+        return $statement;
67
+    }
68 68
 
69
-	/**
70
-	 * Create an exclusive read+write lock on a table
71
-	 *
72
-	 * @param string $tableName
73
-	 * @throws Exception
74
-	 * @since 9.1.0
75
-	 */
76
-	public function lockTable($tableName) {
77
-		$this->conn->beginTransaction();
78
-		$this->conn->executeUpdate('LOCK TABLE `' .$tableName . '` IN EXCLUSIVE MODE');
79
-	}
69
+    /**
70
+     * Create an exclusive read+write lock on a table
71
+     *
72
+     * @param string $tableName
73
+     * @throws Exception
74
+     * @since 9.1.0
75
+     */
76
+    public function lockTable($tableName) {
77
+        $this->conn->beginTransaction();
78
+        $this->conn->executeUpdate('LOCK TABLE `' .$tableName . '` IN EXCLUSIVE MODE');
79
+    }
80 80
 
81
-	/**
82
-	 * Release a previous acquired lock again
83
-	 *
84
-	 * @throws Exception
85
-	 * @since 9.1.0
86
-	 */
87
-	public function unlockTable() {
88
-		$this->conn->commit();
89
-	}
81
+    /**
82
+     * Release a previous acquired lock again
83
+     *
84
+     * @throws Exception
85
+     * @since 9.1.0
86
+     */
87
+    public function unlockTable() {
88
+        $this->conn->commit();
89
+    }
90 90
 
91
-	/**
92
-	 * Insert a row if the matching row does not exists. To accomplish proper race condition avoidance
93
-	 * it is needed that there is also a unique constraint on the values. Then this method will
94
-	 * catch the exception and return 0.
95
-	 *
96
-	 * @param string $table The table name (will replace *PREFIX* with the actual prefix)
97
-	 * @param array $input data that should be inserted into the table  (column name => value)
98
-	 * @param array|null $compare List of values that should be checked for "if not exists"
99
-	 *				If this is null or an empty array, all keys of $input will be compared
100
-	 *				Please note: text fields (clob) must not be used in the compare array
101
-	 * @return int number of inserted rows
102
-	 * @throws Exception
103
-	 * @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
104
-	 */
105
-	public function insertIfNotExist($table, $input, array $compare = null) {
106
-		if (empty($compare)) {
107
-			$compare = array_keys($input);
108
-		}
109
-		$query = 'INSERT INTO `' .$table . '` (`'
110
-			. implode('`,`', array_keys($input)) . '`) SELECT '
111
-			. str_repeat('?,', count($input) - 1).'? ' // Is there a prettier alternative?
112
-			. 'FROM `' . $table . '` WHERE ';
91
+    /**
92
+     * Insert a row if the matching row does not exists. To accomplish proper race condition avoidance
93
+     * it is needed that there is also a unique constraint on the values. Then this method will
94
+     * catch the exception and return 0.
95
+     *
96
+     * @param string $table The table name (will replace *PREFIX* with the actual prefix)
97
+     * @param array $input data that should be inserted into the table  (column name => value)
98
+     * @param array|null $compare List of values that should be checked for "if not exists"
99
+     *				If this is null or an empty array, all keys of $input will be compared
100
+     *				Please note: text fields (clob) must not be used in the compare array
101
+     * @return int number of inserted rows
102
+     * @throws Exception
103
+     * @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
104
+     */
105
+    public function insertIfNotExist($table, $input, array $compare = null) {
106
+        if (empty($compare)) {
107
+            $compare = array_keys($input);
108
+        }
109
+        $query = 'INSERT INTO `' .$table . '` (`'
110
+            . implode('`,`', array_keys($input)) . '`) SELECT '
111
+            . str_repeat('?,', count($input) - 1).'? ' // Is there a prettier alternative?
112
+            . 'FROM `' . $table . '` WHERE ';
113 113
 
114
-		$inserts = array_values($input);
115
-		foreach ($compare as $key) {
116
-			$query .= '`' . $key . '`';
117
-			if (is_null($input[$key])) {
118
-				$query .= ' IS NULL AND ';
119
-			} else {
120
-				$inserts[] = $input[$key];
121
-				$query .= ' = ? AND ';
122
-			}
123
-		}
124
-		$query = substr($query, 0, -5);
125
-		$query .= ' HAVING COUNT(*) = 0';
114
+        $inserts = array_values($input);
115
+        foreach ($compare as $key) {
116
+            $query .= '`' . $key . '`';
117
+            if (is_null($input[$key])) {
118
+                $query .= ' IS NULL AND ';
119
+            } else {
120
+                $inserts[] = $input[$key];
121
+                $query .= ' = ? AND ';
122
+            }
123
+        }
124
+        $query = substr($query, 0, -5);
125
+        $query .= ' HAVING COUNT(*) = 0';
126 126
 
127
-		try {
128
-			return $this->conn->executeUpdate($query, $inserts);
129
-		} catch (UniqueConstraintViolationException $e) {
130
-			// if this is thrown then a concurrent insert happened between the insert and the sub-select in the insert, that should have avoided it
131
-			// it's fine to ignore this then
132
-			//
133
-			// more discussions about this can be found at https://github.com/nextcloud/server/pull/12315
134
-			return 0;
135
-		}
136
-	}
127
+        try {
128
+            return $this->conn->executeUpdate($query, $inserts);
129
+        } catch (UniqueConstraintViolationException $e) {
130
+            // if this is thrown then a concurrent insert happened between the insert and the sub-select in the insert, that should have avoided it
131
+            // it's fine to ignore this then
132
+            //
133
+            // more discussions about this can be found at https://github.com/nextcloud/server/pull/12315
134
+            return 0;
135
+        }
136
+    }
137 137
 
138
-	/**
139
-	 * @throws \OCP\DB\Exception
140
-	 */
141
-	public function insertIgnoreConflict(string $table,array $values) : int {
142
-		try {
143
-			$builder = $this->conn->getQueryBuilder();
144
-			$builder->insert($table);
145
-			foreach ($values as $key => $value) {
146
-				$builder->setValue($key, $builder->createNamedParameter($value));
147
-			}
148
-			return $builder->execute();
149
-		} catch (UniqueConstraintViolationException $e) {
150
-			return 0;
151
-		}
152
-	}
138
+    /**
139
+     * @throws \OCP\DB\Exception
140
+     */
141
+    public function insertIgnoreConflict(string $table,array $values) : int {
142
+        try {
143
+            $builder = $this->conn->getQueryBuilder();
144
+            $builder->insert($table);
145
+            foreach ($values as $key => $value) {
146
+                $builder->setValue($key, $builder->createNamedParameter($value));
147
+            }
148
+            return $builder->execute();
149
+        } catch (UniqueConstraintViolationException $e) {
150
+            return 0;
151
+        }
152
+    }
153 153
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
 	 */
76 76
 	public function lockTable($tableName) {
77 77
 		$this->conn->beginTransaction();
78
-		$this->conn->executeUpdate('LOCK TABLE `' .$tableName . '` IN EXCLUSIVE MODE');
78
+		$this->conn->executeUpdate('LOCK TABLE `'.$tableName.'` IN EXCLUSIVE MODE');
79 79
 	}
80 80
 
81 81
 	/**
@@ -106,14 +106,14 @@  discard block
 block discarded – undo
106 106
 		if (empty($compare)) {
107 107
 			$compare = array_keys($input);
108 108
 		}
109
-		$query = 'INSERT INTO `' .$table . '` (`'
110
-			. implode('`,`', array_keys($input)) . '`) SELECT '
109
+		$query = 'INSERT INTO `'.$table.'` (`'
110
+			. implode('`,`', array_keys($input)).'`) SELECT '
111 111
 			. str_repeat('?,', count($input) - 1).'? ' // Is there a prettier alternative?
112
-			. 'FROM `' . $table . '` WHERE ';
112
+			. 'FROM `'.$table.'` WHERE ';
113 113
 
114 114
 		$inserts = array_values($input);
115 115
 		foreach ($compare as $key) {
116
-			$query .= '`' . $key . '`';
116
+			$query .= '`'.$key.'`';
117 117
 			if (is_null($input[$key])) {
118 118
 				$query .= ' IS NULL AND ';
119 119
 			} else {
@@ -138,7 +138,7 @@  discard block
 block discarded – undo
138 138
 	/**
139 139
 	 * @throws \OCP\DB\Exception
140 140
 	 */
141
-	public function insertIgnoreConflict(string $table,array $values) : int {
141
+	public function insertIgnoreConflict(string $table, array $values) : int {
142 142
 		try {
143 143
 			$builder = $this->conn->getQueryBuilder();
144 144
 			$builder->insert($table);
Please login to merge, or discard this patch.
lib/private/DB/Migrator.php 2 patches
Indentation   +261 added lines, -261 removed lines patch added patch discarded remove patch
@@ -49,265 +49,265 @@
 block discarded – undo
49 49
 
50 50
 class Migrator {
51 51
 
52
-	/** @var \Doctrine\DBAL\Connection */
53
-	protected $connection;
54
-
55
-	/** @var ISecureRandom */
56
-	private $random;
57
-
58
-	/** @var IConfig */
59
-	protected $config;
60
-
61
-	/** @var EventDispatcherInterface  */
62
-	private $dispatcher;
63
-
64
-	/** @var bool */
65
-	private $noEmit = false;
66
-
67
-	/**
68
-	 * @param \Doctrine\DBAL\Connection $connection
69
-	 * @param ISecureRandom $random
70
-	 * @param IConfig $config
71
-	 * @param EventDispatcherInterface $dispatcher
72
-	 */
73
-	public function __construct(\Doctrine\DBAL\Connection $connection,
74
-								ISecureRandom $random,
75
-								IConfig $config,
76
-								EventDispatcherInterface $dispatcher = null) {
77
-		$this->connection = $connection;
78
-		$this->random = $random;
79
-		$this->config = $config;
80
-		$this->dispatcher = $dispatcher;
81
-	}
82
-
83
-	/**
84
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
85
-	 *
86
-	 * @throws Exception
87
-	 */
88
-	public function migrate(Schema $targetSchema) {
89
-		$this->noEmit = true;
90
-		$this->applySchema($targetSchema);
91
-	}
92
-
93
-	/**
94
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
95
-	 * @return string
96
-	 */
97
-	public function generateChangeScript(Schema $targetSchema) {
98
-		$schemaDiff = $this->getDiff($targetSchema, $this->connection);
99
-
100
-		$script = '';
101
-		$sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform());
102
-		foreach ($sqls as $sql) {
103
-			$script .= $this->convertStatementToScript($sql);
104
-		}
105
-
106
-		return $script;
107
-	}
108
-
109
-	/**
110
-	 * Create a unique name for the temporary table
111
-	 *
112
-	 * @param string $name
113
-	 * @return string
114
-	 */
115
-	protected function generateTemporaryTableName($name) {
116
-		return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
117
-	}
118
-
119
-	/**
120
-	 * Check the migration of a table on a copy so we can detect errors before messing with the real table
121
-	 *
122
-	 * @param \Doctrine\DBAL\Schema\Table $table
123
-	 * @throws \OC\DB\MigrationException
124
-	 */
125
-	protected function checkTableMigrate(Table $table) {
126
-		$name = $table->getName();
127
-		$tmpName = $this->generateTemporaryTableName($name);
128
-
129
-		$this->copyTable($name, $tmpName);
130
-
131
-		//create the migration schema for the temporary table
132
-		$tmpTable = $this->renameTableSchema($table, $tmpName);
133
-		$schemaConfig = new SchemaConfig();
134
-		$schemaConfig->setName($this->connection->getDatabase());
135
-		$schema = new Schema([$tmpTable], [], $schemaConfig);
136
-
137
-		try {
138
-			$this->applySchema($schema);
139
-			$this->dropTable($tmpName);
140
-		} catch (Exception $e) {
141
-			// pgsql needs to commit it's failed transaction before doing anything else
142
-			if ($this->connection->isTransactionActive()) {
143
-				$this->connection->commit();
144
-			}
145
-			$this->dropTable($tmpName);
146
-			throw new MigrationException($table->getName(), $e->getMessage());
147
-		}
148
-	}
149
-
150
-	/**
151
-	 * @param \Doctrine\DBAL\Schema\Table $table
152
-	 * @param string $newName
153
-	 * @return \Doctrine\DBAL\Schema\Table
154
-	 */
155
-	protected function renameTableSchema(Table $table, $newName) {
156
-		/**
157
-		 * @var \Doctrine\DBAL\Schema\Index[] $indexes
158
-		 */
159
-		$indexes = $table->getIndexes();
160
-		$newIndexes = [];
161
-		foreach ($indexes as $index) {
162
-			if ($index->isPrimary()) {
163
-				// do not rename primary key
164
-				$indexName = $index->getName();
165
-			} else {
166
-				// avoid conflicts in index names
167
-				$indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER);
168
-			}
169
-			$newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary());
170
-		}
171
-
172
-		// foreign keys are not supported so we just set it to an empty array
173
-		return new Table($newName, $table->getColumns(), $newIndexes, [], [], $table->getOptions());
174
-	}
175
-
176
-	/**
177
-	 * @throws Exception
178
-	 */
179
-	public function createSchema() {
180
-		$this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) {
181
-			/** @var string|AbstractAsset $asset */
182
-			$filterExpression = $this->getFilterExpression();
183
-			if ($asset instanceof AbstractAsset) {
184
-				return preg_match($filterExpression, $asset->getName()) !== false;
185
-			}
186
-			return preg_match($filterExpression, $asset) !== false;
187
-		});
188
-		return $this->connection->getSchemaManager()->createSchema();
189
-	}
190
-
191
-	/**
192
-	 * @param Schema $targetSchema
193
-	 * @param \Doctrine\DBAL\Connection $connection
194
-	 * @return \Doctrine\DBAL\Schema\SchemaDiff
195
-	 */
196
-	protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
197
-		// adjust varchar columns with a length higher then getVarcharMaxLength to clob
198
-		foreach ($targetSchema->getTables() as $table) {
199
-			foreach ($table->getColumns() as $column) {
200
-				if ($column->getType() instanceof StringType) {
201
-					if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) {
202
-						$column->setType(Type::getType('text'));
203
-						$column->setLength(null);
204
-					}
205
-				}
206
-			}
207
-		}
208
-
209
-		$this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) {
210
-			/** @var string|AbstractAsset $asset */
211
-			$filterExpression = $this->getFilterExpression();
212
-			if ($asset instanceof AbstractAsset) {
213
-				return preg_match($filterExpression, $asset->getName()) !== false;
214
-			}
215
-			return preg_match($filterExpression, $asset) !== false;
216
-		});
217
-		$sourceSchema = $connection->getSchemaManager()->createSchema();
218
-
219
-		// remove tables we don't know about
220
-		foreach ($sourceSchema->getTables() as $table) {
221
-			if (!$targetSchema->hasTable($table->getName())) {
222
-				$sourceSchema->dropTable($table->getName());
223
-			}
224
-		}
225
-		// remove sequences we don't know about
226
-		foreach ($sourceSchema->getSequences() as $table) {
227
-			if (!$targetSchema->hasSequence($table->getName())) {
228
-				$sourceSchema->dropSequence($table->getName());
229
-			}
230
-		}
231
-
232
-		$comparator = new Comparator();
233
-		return $comparator->compare($sourceSchema, $targetSchema);
234
-	}
235
-
236
-	/**
237
-	 * @param \Doctrine\DBAL\Schema\Schema $targetSchema
238
-	 * @param \Doctrine\DBAL\Connection $connection
239
-	 *
240
-	 * @throws Exception
241
-	 */
242
-	protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) {
243
-		if (is_null($connection)) {
244
-			$connection = $this->connection;
245
-		}
246
-
247
-		$schemaDiff = $this->getDiff($targetSchema, $connection);
248
-
249
-		if (!$connection->getDatabasePlatform() instanceof MySQLPlatform) {
250
-			$connection->beginTransaction();
251
-		}
252
-		$sqls = $schemaDiff->toSql($connection->getDatabasePlatform());
253
-		$step = 0;
254
-		foreach ($sqls as $sql) {
255
-			$this->emit($sql, $step++, count($sqls));
256
-			$connection->query($sql);
257
-		}
258
-		if (!$connection->getDatabasePlatform() instanceof MySQLPlatform) {
259
-			$connection->commit();
260
-		}
261
-	}
262
-
263
-	/**
264
-	 * @param string $sourceName
265
-	 * @param string $targetName
266
-	 */
267
-	protected function copyTable($sourceName, $targetName) {
268
-		$quotedSource = $this->connection->quoteIdentifier($sourceName);
269
-		$quotedTarget = $this->connection->quoteIdentifier($targetName);
270
-
271
-		$this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')');
272
-		$this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource);
273
-	}
274
-
275
-	/**
276
-	 * @param string $name
277
-	 */
278
-	protected function dropTable($name) {
279
-		$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name));
280
-	}
281
-
282
-	/**
283
-	 * @param $statement
284
-	 * @return string
285
-	 */
286
-	protected function convertStatementToScript($statement) {
287
-		$script = $statement . ';';
288
-		$script .= PHP_EOL;
289
-		$script .= PHP_EOL;
290
-		return $script;
291
-	}
292
-
293
-	protected function getFilterExpression() {
294
-		return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
295
-	}
296
-
297
-	protected function emit($sql, $step, $max) {
298
-		if ($this->noEmit) {
299
-			return;
300
-		}
301
-		if (is_null($this->dispatcher)) {
302
-			return;
303
-		}
304
-		$this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step + 1, $max]));
305
-	}
306
-
307
-	private function emitCheckStep($tableName, $step, $max) {
308
-		if (is_null($this->dispatcher)) {
309
-			return;
310
-		}
311
-		$this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step + 1, $max]));
312
-	}
52
+    /** @var \Doctrine\DBAL\Connection */
53
+    protected $connection;
54
+
55
+    /** @var ISecureRandom */
56
+    private $random;
57
+
58
+    /** @var IConfig */
59
+    protected $config;
60
+
61
+    /** @var EventDispatcherInterface  */
62
+    private $dispatcher;
63
+
64
+    /** @var bool */
65
+    private $noEmit = false;
66
+
67
+    /**
68
+     * @param \Doctrine\DBAL\Connection $connection
69
+     * @param ISecureRandom $random
70
+     * @param IConfig $config
71
+     * @param EventDispatcherInterface $dispatcher
72
+     */
73
+    public function __construct(\Doctrine\DBAL\Connection $connection,
74
+                                ISecureRandom $random,
75
+                                IConfig $config,
76
+                                EventDispatcherInterface $dispatcher = null) {
77
+        $this->connection = $connection;
78
+        $this->random = $random;
79
+        $this->config = $config;
80
+        $this->dispatcher = $dispatcher;
81
+    }
82
+
83
+    /**
84
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
85
+     *
86
+     * @throws Exception
87
+     */
88
+    public function migrate(Schema $targetSchema) {
89
+        $this->noEmit = true;
90
+        $this->applySchema($targetSchema);
91
+    }
92
+
93
+    /**
94
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
95
+     * @return string
96
+     */
97
+    public function generateChangeScript(Schema $targetSchema) {
98
+        $schemaDiff = $this->getDiff($targetSchema, $this->connection);
99
+
100
+        $script = '';
101
+        $sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform());
102
+        foreach ($sqls as $sql) {
103
+            $script .= $this->convertStatementToScript($sql);
104
+        }
105
+
106
+        return $script;
107
+    }
108
+
109
+    /**
110
+     * Create a unique name for the temporary table
111
+     *
112
+     * @param string $name
113
+     * @return string
114
+     */
115
+    protected function generateTemporaryTableName($name) {
116
+        return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
117
+    }
118
+
119
+    /**
120
+     * Check the migration of a table on a copy so we can detect errors before messing with the real table
121
+     *
122
+     * @param \Doctrine\DBAL\Schema\Table $table
123
+     * @throws \OC\DB\MigrationException
124
+     */
125
+    protected function checkTableMigrate(Table $table) {
126
+        $name = $table->getName();
127
+        $tmpName = $this->generateTemporaryTableName($name);
128
+
129
+        $this->copyTable($name, $tmpName);
130
+
131
+        //create the migration schema for the temporary table
132
+        $tmpTable = $this->renameTableSchema($table, $tmpName);
133
+        $schemaConfig = new SchemaConfig();
134
+        $schemaConfig->setName($this->connection->getDatabase());
135
+        $schema = new Schema([$tmpTable], [], $schemaConfig);
136
+
137
+        try {
138
+            $this->applySchema($schema);
139
+            $this->dropTable($tmpName);
140
+        } catch (Exception $e) {
141
+            // pgsql needs to commit it's failed transaction before doing anything else
142
+            if ($this->connection->isTransactionActive()) {
143
+                $this->connection->commit();
144
+            }
145
+            $this->dropTable($tmpName);
146
+            throw new MigrationException($table->getName(), $e->getMessage());
147
+        }
148
+    }
149
+
150
+    /**
151
+     * @param \Doctrine\DBAL\Schema\Table $table
152
+     * @param string $newName
153
+     * @return \Doctrine\DBAL\Schema\Table
154
+     */
155
+    protected function renameTableSchema(Table $table, $newName) {
156
+        /**
157
+         * @var \Doctrine\DBAL\Schema\Index[] $indexes
158
+         */
159
+        $indexes = $table->getIndexes();
160
+        $newIndexes = [];
161
+        foreach ($indexes as $index) {
162
+            if ($index->isPrimary()) {
163
+                // do not rename primary key
164
+                $indexName = $index->getName();
165
+            } else {
166
+                // avoid conflicts in index names
167
+                $indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER);
168
+            }
169
+            $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary());
170
+        }
171
+
172
+        // foreign keys are not supported so we just set it to an empty array
173
+        return new Table($newName, $table->getColumns(), $newIndexes, [], [], $table->getOptions());
174
+    }
175
+
176
+    /**
177
+     * @throws Exception
178
+     */
179
+    public function createSchema() {
180
+        $this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) {
181
+            /** @var string|AbstractAsset $asset */
182
+            $filterExpression = $this->getFilterExpression();
183
+            if ($asset instanceof AbstractAsset) {
184
+                return preg_match($filterExpression, $asset->getName()) !== false;
185
+            }
186
+            return preg_match($filterExpression, $asset) !== false;
187
+        });
188
+        return $this->connection->getSchemaManager()->createSchema();
189
+    }
190
+
191
+    /**
192
+     * @param Schema $targetSchema
193
+     * @param \Doctrine\DBAL\Connection $connection
194
+     * @return \Doctrine\DBAL\Schema\SchemaDiff
195
+     */
196
+    protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) {
197
+        // adjust varchar columns with a length higher then getVarcharMaxLength to clob
198
+        foreach ($targetSchema->getTables() as $table) {
199
+            foreach ($table->getColumns() as $column) {
200
+                if ($column->getType() instanceof StringType) {
201
+                    if ($column->getLength() > $connection->getDatabasePlatform()->getVarcharMaxLength()) {
202
+                        $column->setType(Type::getType('text'));
203
+                        $column->setLength(null);
204
+                    }
205
+                }
206
+            }
207
+        }
208
+
209
+        $this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) {
210
+            /** @var string|AbstractAsset $asset */
211
+            $filterExpression = $this->getFilterExpression();
212
+            if ($asset instanceof AbstractAsset) {
213
+                return preg_match($filterExpression, $asset->getName()) !== false;
214
+            }
215
+            return preg_match($filterExpression, $asset) !== false;
216
+        });
217
+        $sourceSchema = $connection->getSchemaManager()->createSchema();
218
+
219
+        // remove tables we don't know about
220
+        foreach ($sourceSchema->getTables() as $table) {
221
+            if (!$targetSchema->hasTable($table->getName())) {
222
+                $sourceSchema->dropTable($table->getName());
223
+            }
224
+        }
225
+        // remove sequences we don't know about
226
+        foreach ($sourceSchema->getSequences() as $table) {
227
+            if (!$targetSchema->hasSequence($table->getName())) {
228
+                $sourceSchema->dropSequence($table->getName());
229
+            }
230
+        }
231
+
232
+        $comparator = new Comparator();
233
+        return $comparator->compare($sourceSchema, $targetSchema);
234
+    }
235
+
236
+    /**
237
+     * @param \Doctrine\DBAL\Schema\Schema $targetSchema
238
+     * @param \Doctrine\DBAL\Connection $connection
239
+     *
240
+     * @throws Exception
241
+     */
242
+    protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) {
243
+        if (is_null($connection)) {
244
+            $connection = $this->connection;
245
+        }
246
+
247
+        $schemaDiff = $this->getDiff($targetSchema, $connection);
248
+
249
+        if (!$connection->getDatabasePlatform() instanceof MySQLPlatform) {
250
+            $connection->beginTransaction();
251
+        }
252
+        $sqls = $schemaDiff->toSql($connection->getDatabasePlatform());
253
+        $step = 0;
254
+        foreach ($sqls as $sql) {
255
+            $this->emit($sql, $step++, count($sqls));
256
+            $connection->query($sql);
257
+        }
258
+        if (!$connection->getDatabasePlatform() instanceof MySQLPlatform) {
259
+            $connection->commit();
260
+        }
261
+    }
262
+
263
+    /**
264
+     * @param string $sourceName
265
+     * @param string $targetName
266
+     */
267
+    protected function copyTable($sourceName, $targetName) {
268
+        $quotedSource = $this->connection->quoteIdentifier($sourceName);
269
+        $quotedTarget = $this->connection->quoteIdentifier($targetName);
270
+
271
+        $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')');
272
+        $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource);
273
+    }
274
+
275
+    /**
276
+     * @param string $name
277
+     */
278
+    protected function dropTable($name) {
279
+        $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name));
280
+    }
281
+
282
+    /**
283
+     * @param $statement
284
+     * @return string
285
+     */
286
+    protected function convertStatementToScript($statement) {
287
+        $script = $statement . ';';
288
+        $script .= PHP_EOL;
289
+        $script .= PHP_EOL;
290
+        return $script;
291
+    }
292
+
293
+    protected function getFilterExpression() {
294
+        return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
295
+    }
296
+
297
+    protected function emit($sql, $step, $max) {
298
+        if ($this->noEmit) {
299
+            return;
300
+        }
301
+        if (is_null($this->dispatcher)) {
302
+            return;
303
+        }
304
+        $this->dispatcher->dispatch('\OC\DB\Migrator::executeSql', new GenericEvent($sql, [$step + 1, $max]));
305
+    }
306
+
307
+    private function emitCheckStep($tableName, $step, $max) {
308
+        if (is_null($this->dispatcher)) {
309
+            return;
310
+        }
311
+        $this->dispatcher->dispatch('\OC\DB\Migrator::checkTable', new GenericEvent($tableName, [$step + 1, $max]));
312
+    }
313 313
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
 	 * @return string
114 114
 	 */
115 115
 	protected function generateTemporaryTableName($name) {
116
-		return $this->config->getSystemValue('dbtableprefix', 'oc_') . $name . '_' . $this->random->generate(13, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
116
+		return $this->config->getSystemValue('dbtableprefix', 'oc_').$name.'_'.$this->random->generate(13, ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
117 117
 	}
118 118
 
119 119
 	/**
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
 				$indexName = $index->getName();
165 165
 			} else {
166 166
 				// avoid conflicts in index names
167
-				$indexName = $this->config->getSystemValue('dbtableprefix', 'oc_') . $this->random->generate(13, ISecureRandom::CHAR_LOWER);
167
+				$indexName = $this->config->getSystemValue('dbtableprefix', 'oc_').$this->random->generate(13, ISecureRandom::CHAR_LOWER);
168 168
 			}
169 169
 			$newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary());
170 170
 		}
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
 	 * @throws Exception
178 178
 	 */
179 179
 	public function createSchema() {
180
-		$this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) {
180
+		$this->connection->getConfiguration()->setSchemaAssetsFilter(function($asset) {
181 181
 			/** @var string|AbstractAsset $asset */
182 182
 			$filterExpression = $this->getFilterExpression();
183 183
 			if ($asset instanceof AbstractAsset) {
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
 			}
207 207
 		}
208 208
 
209
-		$this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) {
209
+		$this->connection->getConfiguration()->setSchemaAssetsFilter(function($asset) {
210 210
 			/** @var string|AbstractAsset $asset */
211 211
 			$filterExpression = $this->getFilterExpression();
212 212
 			if ($asset instanceof AbstractAsset) {
@@ -268,15 +268,15 @@  discard block
 block discarded – undo
268 268
 		$quotedSource = $this->connection->quoteIdentifier($sourceName);
269 269
 		$quotedTarget = $this->connection->quoteIdentifier($targetName);
270 270
 
271
-		$this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')');
272
-		$this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource);
271
+		$this->connection->exec('CREATE TABLE '.$quotedTarget.' (LIKE '.$quotedSource.')');
272
+		$this->connection->exec('INSERT INTO '.$quotedTarget.' SELECT * FROM '.$quotedSource);
273 273
 	}
274 274
 
275 275
 	/**
276 276
 	 * @param string $name
277 277
 	 */
278 278
 	protected function dropTable($name) {
279
-		$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name));
279
+		$this->connection->exec('DROP TABLE '.$this->connection->quoteIdentifier($name));
280 280
 	}
281 281
 
282 282
 	/**
@@ -284,14 +284,14 @@  discard block
 block discarded – undo
284 284
 	 * @return string
285 285
 	 */
286 286
 	protected function convertStatementToScript($statement) {
287
-		$script = $statement . ';';
287
+		$script = $statement.';';
288 288
 		$script .= PHP_EOL;
289 289
 		$script .= PHP_EOL;
290 290
 		return $script;
291 291
 	}
292 292
 
293 293
 	protected function getFilterExpression() {
294
-		return '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
294
+		return '/^'.preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')).'/';
295 295
 	}
296 296
 
297 297
 	protected function emit($sql, $step, $max) {
Please login to merge, or discard this patch.
lib/private/DB/Exceptions/DbalException.php 1 patch
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -49,88 +49,88 @@
 block discarded – undo
49 49
  */
50 50
 class DbalException extends Exception {
51 51
 
52
-	/** @var \Doctrine\DBAL\Exception */
53
-	private $original;
52
+    /** @var \Doctrine\DBAL\Exception */
53
+    private $original;
54 54
 
55
-	/**
56
-	 * @param \Doctrine\DBAL\Exception $original
57
-	 * @param int $code
58
-	 * @param string $message
59
-	 */
60
-	private function __construct(\Doctrine\DBAL\Exception $original, int $code, string $message) {
61
-		parent::__construct(
62
-			$message,
63
-			$code,
64
-			$original
65
-		);
66
-		$this->original = $original;
67
-	}
55
+    /**
56
+     * @param \Doctrine\DBAL\Exception $original
57
+     * @param int $code
58
+     * @param string $message
59
+     */
60
+    private function __construct(\Doctrine\DBAL\Exception $original, int $code, string $message) {
61
+        parent::__construct(
62
+            $message,
63
+            $code,
64
+            $original
65
+        );
66
+        $this->original = $original;
67
+    }
68 68
 
69
-	public static function wrap(\Doctrine\DBAL\Exception $original, string $message = ''): self {
70
-		return new self(
71
-			$original,
72
-			is_int($original->getCode()) ? $original->getCode() : 0,
73
-			empty($message) ? $original->getMessage() : $message
74
-		);
75
-	}
69
+    public static function wrap(\Doctrine\DBAL\Exception $original, string $message = ''): self {
70
+        return new self(
71
+            $original,
72
+            is_int($original->getCode()) ? $original->getCode() : 0,
73
+            empty($message) ? $original->getMessage() : $message
74
+        );
75
+    }
76 76
 
77
-	public function getReason(): ?int {
78
-		/**
79
-		 * Generic errors
80
-		 */
81
-		if ($this->original instanceof ConnectionException) {
82
-			return parent::REASON_CONNECTION_LOST;
83
-		}
84
-		if ($this->original instanceof DriverException) {
85
-			return parent::REASON_DRIVER;
86
-		}
87
-		if ($this->original instanceof InvalidArgumentException) {
88
-			return parent::REASON_INVALID_ARGUMENT;
89
-		}
77
+    public function getReason(): ?int {
78
+        /**
79
+         * Generic errors
80
+         */
81
+        if ($this->original instanceof ConnectionException) {
82
+            return parent::REASON_CONNECTION_LOST;
83
+        }
84
+        if ($this->original instanceof DriverException) {
85
+            return parent::REASON_DRIVER;
86
+        }
87
+        if ($this->original instanceof InvalidArgumentException) {
88
+            return parent::REASON_INVALID_ARGUMENT;
89
+        }
90 90
 
91
-		/**
92
-		 * Constraint errors
93
-		 */
94
-		if ($this->original instanceof ForeignKeyConstraintViolationException) {
95
-			return parent::REASON_FOREIGN_KEY_VIOLATION;
96
-		}
97
-		if ($this->original instanceof NotNullConstraintViolationException) {
98
-			return parent::REASON_NOT_NULL_CONSTRAINT_VIOLATION;
99
-		}
100
-		if ($this->original instanceof UniqueConstraintViolationException) {
101
-			return parent::REASON_UNIQUE_CONSTRAINT_VIOLATION;
102
-		}
103
-		// The base exception comes last
104
-		if ($this->original instanceof ConstraintViolationException) {
105
-			return parent::REASON_CONSTRAINT_VIOLATION;
106
-		}
91
+        /**
92
+         * Constraint errors
93
+         */
94
+        if ($this->original instanceof ForeignKeyConstraintViolationException) {
95
+            return parent::REASON_FOREIGN_KEY_VIOLATION;
96
+        }
97
+        if ($this->original instanceof NotNullConstraintViolationException) {
98
+            return parent::REASON_NOT_NULL_CONSTRAINT_VIOLATION;
99
+        }
100
+        if ($this->original instanceof UniqueConstraintViolationException) {
101
+            return parent::REASON_UNIQUE_CONSTRAINT_VIOLATION;
102
+        }
103
+        // The base exception comes last
104
+        if ($this->original instanceof ConstraintViolationException) {
105
+            return parent::REASON_CONSTRAINT_VIOLATION;
106
+        }
107 107
 
108
-		/**
109
-		 * Other server errors
110
-		 */
111
-		if ($this->original instanceof DatabaseObjectExistsException) {
112
-			return parent::REASON_DATABASE_OBJECT_EXISTS;
113
-		}
114
-		if ($this->original instanceof DatabaseObjectNotFoundException) {
115
-			return parent::REASON_DATABASE_OBJECT_NOT_FOUND;
116
-		}
117
-		if ($this->original instanceof DeadlockException) {
118
-			return parent::REASON_DEADLOCK;
119
-		}
120
-		if ($this->original instanceof InvalidFieldNameException) {
121
-			return parent::REASON_INVALID_FIELD_NAME;
122
-		}
123
-		if ($this->original instanceof NonUniqueFieldNameException) {
124
-			return parent::REASON_NON_UNIQUE_FIELD_NAME;
125
-		}
126
-		if ($this->original instanceof SyntaxErrorException) {
127
-			return parent::REASON_SYNTAX_ERROR;
128
-		}
129
-		// The base server exception class comes last
130
-		if ($this->original instanceof ServerException) {
131
-			return parent::REASON_SERVER;
132
-		}
108
+        /**
109
+         * Other server errors
110
+         */
111
+        if ($this->original instanceof DatabaseObjectExistsException) {
112
+            return parent::REASON_DATABASE_OBJECT_EXISTS;
113
+        }
114
+        if ($this->original instanceof DatabaseObjectNotFoundException) {
115
+            return parent::REASON_DATABASE_OBJECT_NOT_FOUND;
116
+        }
117
+        if ($this->original instanceof DeadlockException) {
118
+            return parent::REASON_DEADLOCK;
119
+        }
120
+        if ($this->original instanceof InvalidFieldNameException) {
121
+            return parent::REASON_INVALID_FIELD_NAME;
122
+        }
123
+        if ($this->original instanceof NonUniqueFieldNameException) {
124
+            return parent::REASON_NON_UNIQUE_FIELD_NAME;
125
+        }
126
+        if ($this->original instanceof SyntaxErrorException) {
127
+            return parent::REASON_SYNTAX_ERROR;
128
+        }
129
+        // The base server exception class comes last
130
+        if ($this->original instanceof ServerException) {
131
+            return parent::REASON_SERVER;
132
+        }
133 133
 
134
-		return null;
135
-	}
134
+        return null;
135
+    }
136 136
 }
Please login to merge, or discard this patch.
lib/private/DB/ConnectionAdapter.php 2 patches
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -39,208 +39,208 @@
 block discarded – undo
39 39
  */
40 40
 class ConnectionAdapter implements IDBConnection {
41 41
 
42
-	/** @var Connection */
43
-	private $inner;
44
-
45
-	public function __construct(Connection $inner) {
46
-		$this->inner = $inner;
47
-	}
48
-
49
-	public function getQueryBuilder(): IQueryBuilder {
50
-		return $this->inner->getQueryBuilder();
51
-	}
52
-
53
-	public function prepare($sql, $limit = null, $offset = null): IPreparedStatement {
54
-		try {
55
-			return new PreparedStatement(
56
-				$this->inner->prepare($sql, $limit, $offset)
57
-			);
58
-		} catch (Exception $e) {
59
-			throw DbalException::wrap($e);
60
-		}
61
-	}
62
-
63
-	public function executeQuery(string $sql, array $params = [], $types = []): IResult {
64
-		try {
65
-			return new ResultAdapter(
66
-				$this->inner->executeQuery($sql, $params, $types)
67
-			);
68
-		} catch (Exception $e) {
69
-			throw DbalException::wrap($e);
70
-		}
71
-	}
72
-
73
-	public function executeUpdate(string $sql, array $params = [], array $types = []): int {
74
-		try {
75
-			return $this->inner->executeUpdate($sql, $params, $types);
76
-		} catch (Exception $e) {
77
-			throw DbalException::wrap($e);
78
-		}
79
-	}
80
-
81
-	public function executeStatement($sql, array $params = [], array $types = []): int {
82
-		try {
83
-			return $this->inner->executeStatement($sql, $params, $types);
84
-		} catch (Exception $e) {
85
-			throw DbalException::wrap($e);
86
-		}
87
-	}
88
-
89
-	public function lastInsertId(string $table): int {
90
-		try {
91
-			return (int)$this->inner->lastInsertId($table);
92
-		} catch (Exception $e) {
93
-			throw DbalException::wrap($e);
94
-		}
95
-	}
96
-
97
-	public function insertIfNotExist(string $table, array $input, array $compare = null) {
98
-		try {
99
-			return $this->inner->insertIfNotExist($table, $input, $compare);
100
-		} catch (Exception $e) {
101
-			throw DbalException::wrap($e);
102
-		}
103
-	}
104
-
105
-	public function insertIgnoreConflict(string $table, array $values): int {
106
-		try {
107
-			return $this->inner->insertIgnoreConflict($table, $values);
108
-		} catch (Exception $e) {
109
-			throw DbalException::wrap($e);
110
-		}
111
-	}
112
-
113
-	public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int {
114
-		try {
115
-			return $this->inner->setValues($table, $keys, $values, $updatePreconditionValues);
116
-		} catch (Exception $e) {
117
-			throw DbalException::wrap($e);
118
-		}
119
-	}
120
-
121
-	public function lockTable($tableName): void {
122
-		try {
123
-			$this->inner->lockTable($tableName);
124
-		} catch (Exception $e) {
125
-			throw DbalException::wrap($e);
126
-		}
127
-	}
128
-
129
-	public function unlockTable(): void {
130
-		try {
131
-			$this->inner->unlockTable();
132
-		} catch (Exception $e) {
133
-			throw DbalException::wrap($e);
134
-		}
135
-	}
136
-
137
-	public function beginTransaction(): void {
138
-		try {
139
-			$this->inner->beginTransaction();
140
-		} catch (Exception $e) {
141
-			throw DbalException::wrap($e);
142
-		}
143
-	}
144
-
145
-	public function inTransaction(): bool {
146
-		return $this->inner->inTransaction();
147
-	}
148
-
149
-	public function commit(): void {
150
-		try {
151
-			$this->inner->commit();
152
-		} catch (Exception $e) {
153
-			throw DbalException::wrap($e);
154
-		}
155
-	}
156
-
157
-	public function rollBack(): void {
158
-		try {
159
-			$this->inner->rollBack();
160
-		} catch (Exception $e) {
161
-			throw DbalException::wrap($e);
162
-		}
163
-	}
164
-
165
-	public function getError(): string {
166
-		return $this->inner->getError();
167
-	}
168
-
169
-	public function errorCode() {
170
-		return $this->inner->errorCode();
171
-	}
172
-
173
-	public function errorInfo() {
174
-		return $this->inner->errorInfo();
175
-	}
176
-
177
-	public function connect(): bool {
178
-		try {
179
-			return $this->inner->connect();
180
-		} catch (Exception $e) {
181
-			throw DbalException::wrap($e);
182
-		}
183
-	}
184
-
185
-	public function close(): void {
186
-		$this->inner->close();
187
-	}
188
-
189
-	public function quote($input, $type = IQueryBuilder::PARAM_STR) {
190
-		return $this->inner->quote($input, $type);
191
-	}
192
-
193
-	/**
194
-	 * @todo we are leaking a 3rdparty type here
195
-	 */
196
-	public function getDatabasePlatform(): AbstractPlatform {
197
-		return $this->inner->getDatabasePlatform();
198
-	}
199
-
200
-	public function dropTable(string $table): void {
201
-		try {
202
-			$this->inner->dropTable($table);
203
-		} catch (Exception $e) {
204
-			throw DbalException::wrap($e);
205
-		}
206
-	}
207
-
208
-	public function tableExists(string $table): bool {
209
-		try {
210
-			return $this->inner->tableExists($table);
211
-		} catch (Exception $e) {
212
-			throw DbalException::wrap($e);
213
-		}
214
-	}
215
-
216
-	public function escapeLikeParameter(string $param): string {
217
-		return $this->inner->escapeLikeParameter($param);
218
-	}
219
-
220
-	public function supports4ByteText(): bool {
221
-		return $this->inner->supports4ByteText();
222
-	}
223
-
224
-	/**
225
-	 * @todo leaks a 3rdparty type
226
-	 */
227
-	public function createSchema(): Schema {
228
-		try {
229
-			return $this->inner->createSchema();
230
-		} catch (Exception $e) {
231
-			throw DbalException::wrap($e);
232
-		}
233
-	}
234
-
235
-	public function migrateToSchema(Schema $toSchema): void {
236
-		try {
237
-			$this->inner->migrateToSchema($toSchema);
238
-		} catch (Exception $e) {
239
-			throw DbalException::wrap($e);
240
-		}
241
-	}
242
-
243
-	public function getInner(): Connection {
244
-		return $this->inner;
245
-	}
42
+    /** @var Connection */
43
+    private $inner;
44
+
45
+    public function __construct(Connection $inner) {
46
+        $this->inner = $inner;
47
+    }
48
+
49
+    public function getQueryBuilder(): IQueryBuilder {
50
+        return $this->inner->getQueryBuilder();
51
+    }
52
+
53
+    public function prepare($sql, $limit = null, $offset = null): IPreparedStatement {
54
+        try {
55
+            return new PreparedStatement(
56
+                $this->inner->prepare($sql, $limit, $offset)
57
+            );
58
+        } catch (Exception $e) {
59
+            throw DbalException::wrap($e);
60
+        }
61
+    }
62
+
63
+    public function executeQuery(string $sql, array $params = [], $types = []): IResult {
64
+        try {
65
+            return new ResultAdapter(
66
+                $this->inner->executeQuery($sql, $params, $types)
67
+            );
68
+        } catch (Exception $e) {
69
+            throw DbalException::wrap($e);
70
+        }
71
+    }
72
+
73
+    public function executeUpdate(string $sql, array $params = [], array $types = []): int {
74
+        try {
75
+            return $this->inner->executeUpdate($sql, $params, $types);
76
+        } catch (Exception $e) {
77
+            throw DbalException::wrap($e);
78
+        }
79
+    }
80
+
81
+    public function executeStatement($sql, array $params = [], array $types = []): int {
82
+        try {
83
+            return $this->inner->executeStatement($sql, $params, $types);
84
+        } catch (Exception $e) {
85
+            throw DbalException::wrap($e);
86
+        }
87
+    }
88
+
89
+    public function lastInsertId(string $table): int {
90
+        try {
91
+            return (int)$this->inner->lastInsertId($table);
92
+        } catch (Exception $e) {
93
+            throw DbalException::wrap($e);
94
+        }
95
+    }
96
+
97
+    public function insertIfNotExist(string $table, array $input, array $compare = null) {
98
+        try {
99
+            return $this->inner->insertIfNotExist($table, $input, $compare);
100
+        } catch (Exception $e) {
101
+            throw DbalException::wrap($e);
102
+        }
103
+    }
104
+
105
+    public function insertIgnoreConflict(string $table, array $values): int {
106
+        try {
107
+            return $this->inner->insertIgnoreConflict($table, $values);
108
+        } catch (Exception $e) {
109
+            throw DbalException::wrap($e);
110
+        }
111
+    }
112
+
113
+    public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int {
114
+        try {
115
+            return $this->inner->setValues($table, $keys, $values, $updatePreconditionValues);
116
+        } catch (Exception $e) {
117
+            throw DbalException::wrap($e);
118
+        }
119
+    }
120
+
121
+    public function lockTable($tableName): void {
122
+        try {
123
+            $this->inner->lockTable($tableName);
124
+        } catch (Exception $e) {
125
+            throw DbalException::wrap($e);
126
+        }
127
+    }
128
+
129
+    public function unlockTable(): void {
130
+        try {
131
+            $this->inner->unlockTable();
132
+        } catch (Exception $e) {
133
+            throw DbalException::wrap($e);
134
+        }
135
+    }
136
+
137
+    public function beginTransaction(): void {
138
+        try {
139
+            $this->inner->beginTransaction();
140
+        } catch (Exception $e) {
141
+            throw DbalException::wrap($e);
142
+        }
143
+    }
144
+
145
+    public function inTransaction(): bool {
146
+        return $this->inner->inTransaction();
147
+    }
148
+
149
+    public function commit(): void {
150
+        try {
151
+            $this->inner->commit();
152
+        } catch (Exception $e) {
153
+            throw DbalException::wrap($e);
154
+        }
155
+    }
156
+
157
+    public function rollBack(): void {
158
+        try {
159
+            $this->inner->rollBack();
160
+        } catch (Exception $e) {
161
+            throw DbalException::wrap($e);
162
+        }
163
+    }
164
+
165
+    public function getError(): string {
166
+        return $this->inner->getError();
167
+    }
168
+
169
+    public function errorCode() {
170
+        return $this->inner->errorCode();
171
+    }
172
+
173
+    public function errorInfo() {
174
+        return $this->inner->errorInfo();
175
+    }
176
+
177
+    public function connect(): bool {
178
+        try {
179
+            return $this->inner->connect();
180
+        } catch (Exception $e) {
181
+            throw DbalException::wrap($e);
182
+        }
183
+    }
184
+
185
+    public function close(): void {
186
+        $this->inner->close();
187
+    }
188
+
189
+    public function quote($input, $type = IQueryBuilder::PARAM_STR) {
190
+        return $this->inner->quote($input, $type);
191
+    }
192
+
193
+    /**
194
+     * @todo we are leaking a 3rdparty type here
195
+     */
196
+    public function getDatabasePlatform(): AbstractPlatform {
197
+        return $this->inner->getDatabasePlatform();
198
+    }
199
+
200
+    public function dropTable(string $table): void {
201
+        try {
202
+            $this->inner->dropTable($table);
203
+        } catch (Exception $e) {
204
+            throw DbalException::wrap($e);
205
+        }
206
+    }
207
+
208
+    public function tableExists(string $table): bool {
209
+        try {
210
+            return $this->inner->tableExists($table);
211
+        } catch (Exception $e) {
212
+            throw DbalException::wrap($e);
213
+        }
214
+    }
215
+
216
+    public function escapeLikeParameter(string $param): string {
217
+        return $this->inner->escapeLikeParameter($param);
218
+    }
219
+
220
+    public function supports4ByteText(): bool {
221
+        return $this->inner->supports4ByteText();
222
+    }
223
+
224
+    /**
225
+     * @todo leaks a 3rdparty type
226
+     */
227
+    public function createSchema(): Schema {
228
+        try {
229
+            return $this->inner->createSchema();
230
+        } catch (Exception $e) {
231
+            throw DbalException::wrap($e);
232
+        }
233
+    }
234
+
235
+    public function migrateToSchema(Schema $toSchema): void {
236
+        try {
237
+            $this->inner->migrateToSchema($toSchema);
238
+        } catch (Exception $e) {
239
+            throw DbalException::wrap($e);
240
+        }
241
+    }
242
+
243
+    public function getInner(): Connection {
244
+        return $this->inner;
245
+    }
246 246
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -88,7 +88,7 @@
 block discarded – undo
88 88
 
89 89
 	public function lastInsertId(string $table): int {
90 90
 		try {
91
-			return (int)$this->inner->lastInsertId($table);
91
+			return (int) $this->inner->lastInsertId($table);
92 92
 		} catch (Exception $e) {
93 93
 			throw DbalException::wrap($e);
94 94
 		}
Please login to merge, or discard this patch.