Completed
Push — some-scrutinizing ( d3de44...c6cac2 )
by Maxence
02:32
created

CircleProviderRequestBuilder::findShareParentSql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 6
nc 1
nop 2
1
<?php
2
3
/**
4
 * Circles - Bring cloud-users closer together.
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Maxence Lange <[email protected]>
10
 * @copyright 2017
11
 * @license GNU AGPL version 3 or any later version
12
 *
13
 * This program is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License as
15
 * published by the Free Software Foundation, either version 3 of the
16
 * License, or (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU Affero General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License
24
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25
 *
26
 */
27
28
namespace OCA\Circles\Db;
29
30
31
use Doctrine\DBAL\Query\QueryBuilder;
32
use OCA\Circles\Model\Member;
33
use OCP\DB\QueryBuilder\IQueryBuilder;
34
use OCP\IDBConnection;
35
use OCP\Share;
36
37
class CircleProviderRequestBuilder {
38
39
40
	/** @var IDBConnection */
41
	protected $dbConnection;
42
43
44
	/**
45
	 * returns the SQL request to get a specific share from the fileId and circleId
46
	 *
47
	 * @param int $fileId
48
	 * @param int $circleId
49
	 *
50
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder
51
	 * @internal param $share
52
	 *
53
	 */
54
	protected function findShareParentSql($fileId, $circleId) {
55
56
		$qb = $this->getBaseSelectSql();
57
		$this->limitToShareParent($qb);
58
		$this->limitToCircle($qb, $circleId);
59
		$this->limitToFile($qb, $fileId);
60
61
		return $qb;
62
	}
63
64
65
	/**
66
	 * Limit the request to a Circle.
67
	 *
68
	 * @param $qb
69
	 * @param $circleId
70
	 */
71 View Code Duplication
	protected function limitToCircle(& $qb, $circleId) {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
72
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
73
74
		$qb->andWhere(
75
			$qb->expr()
76
			   ->eq($pf . 'share_with', $qb->createNamedParameter($circleId))
77
		);
78
	}
79
80
81
	/**
82
	 * Limit the request to the Share by its Id.
83
	 *
84
	 * @param $qb
85
	 * @param $shareId
86
	 */
87 View Code Duplication
	protected function limitToShare(& $qb, $shareId) {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88
		$expr = $qb->expr();
89
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
90
91
		$qb->andWhere(
92
			$expr->eq($pf . 'id', $qb->createNamedParameter($shareId))
93
		);
94
	}
95
96
97
	/**
98
	 * Limit the request to the top share (no children)
99
	 *
100
	 * @param $qb
101
	 */
102
	protected function limitToShareParent(& $qb) {
103
		$expr = $qb->expr();
104
105
		$qb->andWhere($expr->isNull('parent'));
106
	}
107
108
109
	/**
110
	 * limit the request to the children of a share
111
	 *
112
	 * @param $qb
113
	 * @param $userId
114
	 * @param int $parentId
115
	 */
116
	protected function limitToShareChildren(& $qb, $userId, $parentId = -1) {
117
		$expr = $qb->expr();
118
		$qb->andWhere($expr->eq('share_with', $qb->createNamedParameter($userId)));
119
120
		if ($parentId > -1) {
121
			$qb->andWhere($expr->eq('parent', $qb->createNamedParameter($parentId)));
122
		} else {
123
			$qb->andWhere($expr->isNotNull('parent'));
124
		}
125
	}
126
127
128
	/**
129
	 * limit the request to the share itself AND its children.
130
	 * perfect if you want to delete everything related to a share
131
	 *
132
	 * @param $qb
133
	 * @param $circleId
134
	 */
135
	protected function limitToShareAndChildren(& $qb, $circleId) {
136
		$expr = $qb->expr();
137
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
138
139
		$qb->andWhere(
140
			$expr->orX(
141
				$expr->eq($pf . 'parent', $qb->createNamedParameter($circleId)),
142
				$expr->eq($pf . 'id', $qb->createNamedParameter($circleId))
143
			)
144
		);
145
	}
146
147
148
	/**
149
	 * limit the request to a fileId.
150
	 *
151
	 * @param IQueryBuilder $qb
152
	 * @param $fileId
153
	 */
154 View Code Duplication
	protected function limitToFile(& $qb, $fileId) {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
156
157
		$qb->andWhere(
158
			$qb->expr()
159
			   ->eq($pf . 'file_source', $qb->createNamedParameter($fileId))
160
		);
161
	}
162
163
164
	protected function limitToPage(& $qb, $limit = -1, $offset = 0) {
165
		if ($limit !== -1) {
166
			$qb->setMaxResults($limit);
167
		}
168
169
		$qb->setFirstResult($offset);
170
	}
171
172
	/**
173
	 * limit the request to a userId
174
	 *
175
	 * @param $qb
176
	 * @param $userId
177
	 * @param bool $reShares
178
	 */
179
	protected function limitToOwner(& $qb, $userId, $reShares = false) {
180
		$expr = $qb->expr();
181
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? 's.' : '';
182
183
		if ($reShares === false) {
184
			$qb->andWhere($expr->eq($pf . 'uid_initiator', $qb->createNamedParameter($userId)));
185
		} else {
186
			$qb->andWhere(
187
				$expr->orX(
188
					$expr->eq($pf . 'uid_owner', $qb->createNamedParameter($userId)),
189
					$expr->eq($pf . 'uid_initiator', $qb->createNamedParameter($userId))
190
				)
191
			);
192
		}
193
194
	}
195
196
197
	/**
198
	 * link circle field
199
	 *
200
	 * @deprecated
201
	 *
202
	 * @param $qb
203
	 * @param $shareId
204
	 */
205
	protected function linkCircleField(& $qb, $shareId) {
206
		$expr = $qb->expr();
207
208
		$qb->from(CirclesMapper::TABLENAME, 'c')
209
		   ->andWhere(
210
			   $expr->orX(
211
				   $expr->eq('s.share_with', 'c.id'),
212
				   $expr->eq('s.parent', $qb->createNamedParameter($shareId))
213
			   )
214
		   );
215
		// ->orderBy('c.circle_name');
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
216
	}
217
218
219
	/**
220
	 * Link to members (userId) of circle
221
	 *
222
	 * @param $qb
223
	 * @param $userId
224
	 */
225
	protected function linkToMember(& $qb, $userId) {
226
		$expr = $qb->expr();
227
228
		$qb->from(MembersMapper::TABLENAME, 'm')
229
		   ->andWhere($expr->eq('s.share_with', 'm.circle_id'))
230
		   ->andWhere($expr->eq('m.user_id', $qb->createNamedParameter($userId)))
231
		   ->andWhere($expr->gte('m.level', $qb->createNamedParameter(Member::LEVEL_MEMBER)));
232
	}
233
234
235
	/**
236
	 * Link to storage/filecache
237
	 *
238
	 * @param $qb
239
	 * @param $userId
240
	 */
241
	protected function linkToFileCache(& $qb, $userId) {
242
		$expr = $qb->expr();
243
244
		$qb->leftJoin('s', 'filecache', 'f', $expr->eq('s.file_source', 'f.fileid'))
245
		   ->leftJoin('f', 'storages', 'st', $expr->eq('f.storage', 'st.numeric_id'))
246
		   ->leftJoin(
247
			   's', 'share', 's2', $expr->andX(
248
			   $expr->eq('s.id', 's2.parent'),
249
			   $expr->eq('s2.share_with', $qb->createNamedParameter($userId))
250
		   )
251
		   );
252
	}
253
254
255
	/**
256
	 * add share to the database and return the ID
257
	 *
258
	 * @param $share
259
	 *
260
	 * @return IQueryBuilder
261
	 */
262
	protected function getBaseInsertSql($share) {
263
		$qb = $this->dbConnection->getQueryBuilder();
264
		$qb->insert('share')
265
		   ->setValue('share_type', $qb->createNamedParameter(Share::SHARE_TYPE_CIRCLE))
266
		   ->setValue('item_type', $qb->createNamedParameter($share->getNodeType()))
267
		   ->setValue('item_source', $qb->createNamedParameter($share->getNodeId()))
268
		   ->setValue('file_source', $qb->createNamedParameter($share->getNodeId()))
269
		   ->setValue('file_target', $qb->createNamedParameter($share->getTarget()))
270
		   ->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()))
271
		   ->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
272
		   ->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
273
		   ->setValue('permissions', $qb->createNamedParameter($share->getPermissions()))
274
		   ->setValue('token', $qb->createNamedParameter($share->getToken()))
275
		   ->setValue('stime', $qb->createNamedParameter(time()));
276
277
		return $qb;
278
	}
279
280
281
	/**
282
	 * generate and return a base sql request.
283
	 *
284
	 * @param int $shareId
285
	 *
286
	 * @return IQueryBuilder
287
	 */
288
	protected function getBaseSelectSql($shareId = -1) {
289
290
		$qb = $this->dbConnection->getQueryBuilder();
291
		$qb->select(
292
			's.id', 's.share_type', 's.share_with', 's.uid_owner', 's.uid_initiator',
293
			's.parent', 's.item_type', 's.item_source', 's.item_target', 's.file_source',
294
			's.file_target', 's.permissions', 's.stime', 's.accepted', 's.expiration',
295
			's.token', 's.mail_send', 'c.type AS circle_type', 'c.name AS circle_name'
296
		);
297
		$this->linkToShare($qb);
298
299
		// TODO: Left-join circle and REMOVE this line
300
		$this->linkCircleField($qb, $shareId);
0 ignored issues
show
Deprecated Code introduced by
The method OCA\Circles\Db\CirclePro...lder::linkCircleField() has been deprecated.

This method has been deprecated.

Loading history...
301
302
		return $qb;
303
	}
304
305
306
	protected function getCompleteSelectSql() {
307
308
		$qb = $this->dbConnection->getQueryBuilder();
309
		$qb->select(
310
			's.*', 'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage',
311
			'f.path_hash', 'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart',
312
			'f.size', 'f.mtime', 'f.storage_mtime', 'f.encrypted', 'f.unencrypted_size',
313
			'f.etag', 'f.checksum', 's2.id AS parent_id', 's2.file_target AS parent_target',
314
			's2.permissions AS parent_perms'
315
		)
316
		   ->selectAlias('st.id', 'storage_string_id');
317
318
		$this->linkToShare($qb);
319
320
		return $qb;
321
	}
322
323
324
	private function linkToShare(& $qb) {
325
		$expr = $qb->expr();
326
327
		$qb->from('share', 's')
328
		   ->where($expr->eq('s.share_type', $qb->createNamedParameter(Share::SHARE_TYPE_CIRCLE)))
329
		   ->andWhere(
330
			   $expr->orX(
331
				   $expr->eq('s.item_type', $qb->createNamedParameter('file')),
332
				   $expr->eq('s.item_type', $qb->createNamedParameter('folder'))
333
			   )
334
		   );
335
336
	}
337
338
	/**
339
	 * generate and return a base sql request.
340
	 *
341
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder
342
	 */
343 View Code Duplication
	protected function getBaseDeleteSql() {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
344
		$qb = $this->dbConnection->getQueryBuilder();
345
		$expr = $qb->expr();
346
347
		$qb->delete('share')
348
		   ->where($expr->eq('share_type', $qb->createNamedParameter(Share::SHARE_TYPE_CIRCLE)));
349
350
		return $qb;
351
	}
352
353
354
	/**
355
	 * generate and return a base sql request.
356
	 *
357
	 * @return \OCP\DB\QueryBuilder\IQueryBuilder
358
	 */
359 View Code Duplication
	protected function getBaseUpdateSql() {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
		$qb = $this->dbConnection->getQueryBuilder();
361
		$expr = $qb->expr();
362
363
		$qb->update('share', 's')
364
		   ->where($expr->eq('share_type', $qb->createNamedParameter(Share::SHARE_TYPE_CIRCLE)));
365
366
		return $qb;
367
	}
368
}
369