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