Passed
Pull Request — master (#1078)
by Pauli
02:53
created

BaseMapper   F

Complexity

Total Complexity 92

Size/Duplication

Total Lines 555
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 220
c 4
b 0
f 0
dl 0
loc 555
rs 2
wmc 92

32 Methods

Rating   Name   Duplication   Size   Complexity  
A findById() 0 12 2
A createEntity() 0 2 1
A __construct() 0 5 1
A find() 0 3 1
A findAll() 0 7 1
A latestUpdateTime() 0 6 2
A exists() 0 4 1
A prepareSubstringSearchPattern() 0 14 3
B advFormatSqlCondition() 0 16 11
A findAllStarred() 0 8 2
A selectEntities() 0 2 1
A findAllIds() 0 12 2
A selectUserEntities() 0 8 2
B formatSortingClause() 0 17 8
A questionMarks() 0 6 2
A formatTimestampConditions() 0 25 5
C advFormatSqlOperator() 0 18 16
A formatNameConditions() 0 18 4
A insertOrUpdate() 0 8 2
A findAllByName() 0 18 2
A deleteByCond() 0 3 1
A latestInsertTime() 0 6 2
A findAllUsers() 0 5 1
A findAllAdvanced() 0 18 3
A insert() 0 16 4
A count() 0 5 1
A findAllRated() 0 8 2
A deleteById() 0 6 2
A deleteAll() 0 3 1
A updateOrInsert() 0 13 3
A setStarredDate() 0 10 2
A update() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like BaseMapper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BaseMapper, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
/**
4
 * ownCloud - Music app
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Pauli Järvinen <[email protected]>
10
 * @copyright Pauli Järvinen 2016 - 2023
11
 */
12
13
namespace OCA\Music\Db;
14
15
use OCP\AppFramework\Db\DoesNotExistException;
16
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
17
use OCP\IDBConnection;
18
19
use OCA\Music\AppFramework\Db\CompatibleMapper;
20
use OCA\Music\AppFramework\Db\UniqueConstraintViolationException;
21
use OCA\Music\Utility\Util;
22
23
/**
24
 * Common base class for data access classes of the Music app
25
 * @phpstan-template EntityType of Entity
26
 * @phpstan-method EntityType findEntity(string $sql, array $params)
27
 * @phpstan-method EntityType[] findEntities(string $sql, array $params, ?int $limit=null, ?int $offset=null)
28
 */
29
abstract class BaseMapper extends CompatibleMapper {
0 ignored issues
show
Deprecated Code introduced by
The class OCA\Music\AppFramework\Db\OldNextcloudMapper has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

29
abstract class BaseMapper extends /** @scrutinizer ignore-deprecated */ CompatibleMapper {
Loading history...
30
	const SQL_DATE_FORMAT = 'Y-m-d H:i:s.v';
31
32
	protected $nameColumn;
33
	/** @phpstan-var class-string<EntityType> $entityClass */
34
	protected $entityClass;
35
36
	/**
37
	 * @phpstan-param class-string<EntityType> $entityClass
38
	 */
39
	public function __construct(IDBConnection $db, string $tableName, string $entityClass, string $nameColumn) {
40
		parent::__construct($db, $tableName, $entityClass);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...udMapper::__construct() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

40
		/** @scrutinizer ignore-deprecated */ parent::__construct($db, $tableName, $entityClass);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
41
		$this->nameColumn = $nameColumn;
42
		// eclipse the base class property to help phpstan
43
		$this->entityClass = $entityClass;
44
	}
45
46
	/**
47
	 * Create an empty object of the entity class bound to this mapper
48
	 * @phpstan-return EntityType
49
	 */
50
	public function createEntity() : Entity {
51
		return new $this->entityClass();
52
	}
53
54
	/**
55
	 * Find a single entity by id and user_id
56
	 * @throws DoesNotExistException if the entity does not exist
57
	 * @throws MultipleObjectsReturnedException if more than one entity exists
58
	 * @phpstan-return EntityType
59
	 */
60
	public function find(int $id, string $userId) : Entity {
61
		$sql = $this->selectUserEntities("`{$this->getTableName()}`.`id` = ?");
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

61
		$sql = $this->selectUserEntities("`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`id` = ?");

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
62
		return $this->findEntity($sql, [$userId, $id]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->findEntity...l, array($userId, $id)) returns the type OCP\AppFramework\Db\Entity which includes types incompatible with the type-hinted return OCA\Music\Db\Entity.
Loading history...
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...oudMapper::findEntity() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

62
		return /** @scrutinizer ignore-deprecated */ $this->findEntity($sql, [$userId, $id]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
63
	}
64
65
	/**
66
	 * Find all entities matching the given IDs. Specifying the owning user is optional.
67
	 * @param integer[] $ids  IDs of the entities to be found
68
	 * @param string|null $userId
69
	 * @return Entity[]
70
	 * @phpstan-return EntityType[]
71
	 */
72
	public function findById(array $ids, string $userId=null) : array {
73
		$count = \count($ids);
74
		$condition = "`{$this->getTableName()}`.`id` IN ". $this->questionMarks($count);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

74
		$condition = "`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`id` IN ". $this->questionMarks($count);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
75
76
		if (empty($userId)) {
77
			$sql = $this->selectEntities($condition);
78
		} else {
79
			$sql = $this->selectUserEntities($condition);
80
			$ids = \array_merge([$userId], $ids);
81
		}
82
83
		return $this->findEntities($sql, $ids);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::findEntities() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

83
		return /** @scrutinizer ignore-deprecated */ $this->findEntities($sql, $ids);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
84
	}
85
86
	/**
87
	 * Find all user's entities
88
	 * @param string|null $createdMin Optional minimum `created` timestamp.
89
	 * @param string|null $createdMax Optional maximum `created` timestamp.
90
	 * @param string|null $updatedMin Optional minimum `updated` timestamp.
91
	 * @param string|null $updatedMax Optional maximum `updated` timestamp.
92
	 * @return Entity[]
93
	 * @phpstan-return EntityType[]
94
	 */
95
	public function findAll(string $userId, int $sortBy=SortBy::None, int $limit=null, int $offset=null,
96
							?string $createdMin=null, ?string $createdMax=null, ?string $updatedMin=null, ?string $updatedMax=null) : array {
97
		$sorting = $this->formatSortingClause($sortBy);
98
		[$condition, $params] = $this->formatTimestampConditions($createdMin, $createdMax, $updatedMin, $updatedMax);
99
		$sql = $this->selectUserEntities($condition, $sorting);
100
		\array_unshift($params, $userId);
101
		return $this->findEntities($sql, $params, $limit, $offset);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::findEntities() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

101
		return /** @scrutinizer ignore-deprecated */ $this->findEntities($sql, $params, $limit, $offset);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
102
	}
103
104
	/**
105
	 * Find all user's entities matching the given name
106
	 * @param string|null $createdMin Optional minimum `created` timestamp.
107
	 * @param string|null $createdMax Optional maximum `created` timestamp.
108
	 * @param string|null $updatedMin Optional minimum `updated` timestamp.
109
	 * @param string|null $updatedMax Optional maximum `updated` timestamp.
110
	 * @return Entity[]
111
	 * @phpstan-return EntityType[]
112
	 */
113
	public function findAllByName(
114
		?string $name, string $userId, int $matchMode=MatchMode::Exact, int $limit=null, int $offset=null,
115
		?string $createdMin=null, ?string $createdMax=null, ?string $updatedMin=null, ?string $updatedMax=null) : array {
116
117
		$params = [$userId];
118
119
		[$condition, $nameParams] = $this->formatNameConditions($name, $matchMode);
120
		$params = \array_merge($params, $nameParams);
121
122
		[$timestampConds, $timestampParams] = $this->formatTimestampConditions($createdMin, $createdMax, $updatedMin, $updatedMax);
123
		if (!empty($timestampConds)) {
124
			$condition .= ' AND ' . $timestampConds;
125
			$params = \array_merge($params, $timestampParams);
126
		}
127
128
		$sql = $this->selectUserEntities($condition, $this->formatSortingClause(SortBy::Name));
129
130
		return $this->findEntities($sql, $params, $limit, $offset);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::findEntities() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

130
		return /** @scrutinizer ignore-deprecated */ $this->findEntities($sql, $params, $limit, $offset);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
131
	}
132
133
	/**
134
	 * Find all user's starred entities. It is safe to call this also on entity types
135
	 * not supporting starring in which case an empty array will be returned.
136
	 * @return Entity[]
137
	 * @phpstan-return EntityType[]
138
	 */
139
	public function findAllStarred(string $userId, int $limit=null, int $offset=null) : array {
140
		if (\property_exists($this->entityClass, 'starred')) {
141
			$sql = $this->selectUserEntities(
142
				"`{$this->getTableName()}`.`starred` IS NOT NULL",
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

142
				"`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`starred` IS NOT NULL",

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
143
				$this->formatSortingClause(SortBy::Name));
144
			return $this->findEntities($sql, [$userId], $limit, $offset);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::findEntities() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

144
			return /** @scrutinizer ignore-deprecated */ $this->findEntities($sql, [$userId], $limit, $offset);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
145
		} else {
146
			return [];
147
		}
148
	}
149
150
	/**
151
	 * Find all entities with user-given rating 1-5
152
	 * @return Entity[]
153
	 * @phpstan-return EntityType[]
154
	 */
155
	public function findAllRated(string $userId, int $limit=null, int $offset=null) : array {
156
		if (\property_exists($this->entityClass, 'rating')) {
157
			$sql = $this->selectUserEntities(
158
				"`{$this->getTableName()}`.`rating` > 0",
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

158
				"`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`rating` > 0",

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
159
				$this->formatSortingClause(SortBy::Rating));
160
			return $this->findEntities($sql, [$userId], $limit, $offset);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::findEntities() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

160
			return /** @scrutinizer ignore-deprecated */ $this->findEntities($sql, [$userId], $limit, $offset);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
161
		} else {
162
			return [];
163
		}
164
	}
165
166
	/**
167
	 * Find all entities matching multiple criteria, as needed for the Ampache API method `advanced_search`
168
	 * @param string $conjunction Operator to use between the rules, either 'and' or 'or'
169
	 * @param array $rules Array of arrays: [['rule' => string, 'operator' => string, 'input' => string], ...]
170
	 * 				Here, 'rule' has dozens of possible values depending on the business layer in question
171
	 * 				(see https://ampache.org/api/api-advanced-search#available-search-rules, alias names not supported here),
172
	 * 				'operator' is one of 
173
	 * 				['contain', 'notcontain', 'start', 'end', 'is', 'isnot', '>=', '<=', '=', '!=', '>', '<', 'true', 'false', 'equal', 'ne', 'limit'],
174
	 * 				'input' is the right side value of the 'operator' (disregarded for the operators 'true' and 'false')
175
	 * @return Entity[]
176
	 * @phpstan-return EntityType[]
177
	 */
178
	public function findAllAdvanced(string $conjunction, array $rules, string $userId, ?int $limit=null, ?int $offset=null) : array {
179
		$sqlConditions = [];
180
		$sqlParams = [$userId];
181
182
		foreach ($rules as $rule) {
183
			list('op' => $sqlOp, 'param' => $param) = $this->advFormatSqlOperator($rule['operator'], $rule['input'], $userId);
184
			$cond = $this->advFormatSqlCondition($rule['rule'], $sqlOp);
185
			$sqlConditions[] = $cond;
186
			// On some conditions, the parameter may need to be repeated several times
187
			$paramCount = \substr_count($cond, '?');
188
			for ($i = 0; $i < $paramCount; ++$i) {
189
				$sqlParams[] = $param;
190
			}
191
		}
192
		$sqlConditions = \implode(" $conjunction ", $sqlConditions);
193
194
		$sql = $this->selectUserEntities($sqlConditions, $this->formatSortingClause(SortBy::Name));
195
		return $this->findEntities($sql, $sqlParams, $limit, $offset);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::findEntities() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

195
		return /** @scrutinizer ignore-deprecated */ $this->findEntities($sql, $sqlParams, $limit, $offset);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
196
	}
197
198
	/**
199
	 * Optionally, limit to given IDs which may be used to check the validity of those IDs.
200
	 * @return int[]
201
	 */
202
	public function findAllIds(string $userId, ?array $ids = null) : array {
203
		$sql = "SELECT `id` FROM `{$this->getTableName()}` WHERE `user_id` = ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

203
		$sql = "SELECT `id` FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` WHERE `user_id` = ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
204
		$params = [$userId];
205
206
		if ($ids !== null) {
207
			$sql .= ' AND `id` IN ' . $this->questionMarks(\count($ids));
208
			$params = \array_merge($params, $ids);
209
		}
210
211
		$result = $this->execute($sql, $params);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

211
		$result = /** @scrutinizer ignore-deprecated */ $this->execute($sql, $params);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
212
213
		return \array_map('intval', $result->fetchAll(\PDO::FETCH_COLUMN));
214
	}
215
216
	/**
217
	 * Find IDs of all users owning any entities of this mapper
218
	 * @return string[]
219
	 */
220
	public function findAllUsers() : array {
221
		$sql = "SELECT DISTINCT(`user_id`) FROM `{$this->getTableName()}`";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

221
		$sql = "SELECT DISTINCT(`user_id`) FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
222
		$result = $this->execute($sql);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

222
		$result = /** @scrutinizer ignore-deprecated */ $this->execute($sql);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
223
224
		return $result->fetchAll(\PDO::FETCH_COLUMN);
225
	}
226
227
	/**
228
	 * Delete all entities with given IDs without specifying the user
229
	 * @param integer[] $ids  IDs of the entities to be deleted
230
	 */
231
	public function deleteById(array $ids) : void {
232
		$count = \count($ids);
233
		if ($count === 0) {
234
			return;
235
		}
236
		$this->deleteByCond('`id` IN ' . $this->questionMarks($count), $ids);
237
	}
238
239
	/**
240
	 * Delete all entities matching the given SQL condition
241
	 * @param string $condition SQL 'WHERE' condition (without the keyword 'WHERE')
242
	 * @param array $params SQL parameters for the condition
243
	 */
244
	protected function deleteByCond(string $condition, array $params) : void {
245
		$sql = "DELETE FROM `{$this->getTableName()}` WHERE ". $condition;
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

245
		$sql = "DELETE FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` WHERE ". $condition;

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
246
		$this->execute($sql, $params);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

246
		/** @scrutinizer ignore-deprecated */ $this->execute($sql, $params);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
247
	}
248
249
	/**
250
	 * Delete all entities of the given user
251
	 */
252
	public function deleteAll(string $userId) : void {
253
		$sql = "DELETE FROM `{$this->getTableName()}` WHERE `user_id` = ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

253
		$sql = "DELETE FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` WHERE `user_id` = ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
254
		$this->execute($sql, [$userId]);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

254
		/** @scrutinizer ignore-deprecated */ $this->execute($sql, [$userId]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
255
	}
256
257
	/**
258
	 * Tests if entity with given ID and user ID exists in the database
259
	 */
260
	public function exists(int $id, string $userId) : bool {
261
		$sql = "SELECT 1 FROM `{$this->getTableName()}` WHERE `id` = ? AND `user_id` = ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

261
		$sql = "SELECT 1 FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` WHERE `id` = ? AND `user_id` = ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
262
		$result = $this->execute($sql, [$id, $userId]);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

262
		$result = /** @scrutinizer ignore-deprecated */ $this->execute($sql, [$id, $userId]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
263
		return $result->rowCount() > 0;
264
	}
265
266
	/**
267
	 * Count all entities of a user
268
	 */
269
	public function count(string $userId) : int {
270
		$sql = "SELECT COUNT(*) AS count FROM `{$this->getTableName()}` WHERE `user_id` = ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

270
		$sql = "SELECT COUNT(*) AS count FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` WHERE `user_id` = ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
271
		$result = $this->execute($sql, [$userId]);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

271
		$result = /** @scrutinizer ignore-deprecated */ $this->execute($sql, [$userId]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
272
		$row = $result->fetch();
273
		return \intval($row['count']);
274
	}
275
276
	/**
277
	 * {@inheritDoc}
278
	 * @see CompatibleMapper::insert()
279
	 * @phpstan-param EntityType $entity
280
	 * @phpstan-return EntityType
281
	 */
282
	public function insert(\OCP\AppFramework\Db\Entity $entity) : \OCP\AppFramework\Db\Entity {
283
		$now = new \DateTime();
284
		$nowStr = $now->format(self::SQL_DATE_FORMAT);
285
		$entity->setCreated($nowStr);
286
		$entity->setUpdated($nowStr);
287
288
		try {
289
			return parent::insert($entity); // @phpstan-ignore-line: no way to tell phpstan that the parent uses the template type
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...xtcloudMapper::insert() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

289
			return /** @scrutinizer ignore-deprecated */ parent::insert($entity); // @phpstan-ignore-line: no way to tell phpstan that the parent uses the template type

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
290
		} catch (\Doctrine\DBAL\Exception\UniqueConstraintViolationException $e) {
291
			throw new UniqueConstraintViolationException($e->getMessage(), $e->getCode(), $e);
292
		} catch (\OCP\DB\Exception $e) {
293
			// Nextcloud 21+
294
			if ($e->getReason() == \OCP\DB\Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
295
				throw new UniqueConstraintViolationException($e->getMessage(), $e->getCode(), $e);
296
			} else {
297
				throw $e;
298
			}
299
		}
300
	}
301
302
	/**
303
	 * {@inheritDoc}
304
	 * @see CompatibleMapper::update()
305
	 * @phpstan-param EntityType $entity
306
	 * @phpstan-return EntityType
307
	 */
308
	public function update(\OCP\AppFramework\Db\Entity $entity) : \OCP\AppFramework\Db\Entity {
309
		$now = new \DateTime();
310
		$entity->setUpdated($now->format(self::SQL_DATE_FORMAT));
311
		return parent::update($entity); // @phpstan-ignore-line: no way to tell phpstan that the parent uses the template type
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...xtcloudMapper::update() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

311
		return /** @scrutinizer ignore-deprecated */ parent::update($entity); // @phpstan-ignore-line: no way to tell phpstan that the parent uses the template type

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
312
	}
313
314
	/**
315
	 * Insert an entity, or if an entity with the same identity already exists,
316
	 * update the existing entity.
317
	 * Note: The functions insertOrUpate and updateOrInsert get the exactly same thing done. The only difference is
318
	 * that the former is optimized for cases where the entity doens't exist and the latter for cases where it does exist.
319
	 * @return Entity The inserted or updated entity, containing also the id field
320
	 * @phpstan-param EntityType $entity
321
	 * @phpstan-return EntityType
322
	 */
323
	public function insertOrUpdate(Entity $entity) : Entity {
324
		try {
325
			return $this->insert($entity);
326
		} catch (UniqueConstraintViolationException $ex) {
327
			$existingEntity = $this->findUniqueEntity($entity);
328
			$entity->setId($existingEntity->getId());
329
			$entity->setCreated($existingEntity->getCreated());
330
			return $this->update($entity);
331
		}
332
	}
333
334
	/**
335
	 * Update an entity whose unique constraint fields match the given entity. If such entity is not found,
336
	 * a new entity is inserted.
337
	 * Note: The functions insertOrUpate and updateOrInsert get the exactly same thing done. The only difference is
338
	 * that the former is optimized for cases where the entity doens't exist and the latter for cases where it does exist.
339
	 * @return Entity The inserted or updated entity, containing also the id field
340
	 * @phpstan-param EntityType $entity
341
	 * @phpstan-return EntityType
342
	 */
343
	public function updateOrInsert(Entity $entity) : Entity {
344
		try {
345
			$existingEntity = $this->findUniqueEntity($entity);
346
			$entity->setId($existingEntity->getId());
347
			return $this->update($entity);
348
		} catch (DoesNotExistException $ex) {
349
			try {
350
				return $this->insert($entity);
351
			} catch (UniqueConstraintViolationException $ex) {
352
				// the conflicting entry didn't exist an eyeblink ago but now it does
353
				// => this is essentially a concurrent update and it is anyway non-deterministic, which
354
				//    update happens last; cancel this update
355
				return $this->findUniqueEntity($entity);
356
			}
357
		}
358
	}
359
360
	/**
361
	 * Set the "starred" column of the given entities
362
	 * @param \DateTime|null $date
363
	 * @param integer[] $ids
364
	 * @param string $userId
365
	 * @return int number of modified entities
366
	 */
367
	public function setStarredDate(?\DateTime $date, array $ids, string $userId) : int {
368
		$count = \count($ids);
369
		if (!empty($date)) {
370
			$date = $date->format(self::SQL_DATE_FORMAT);
371
		}
372
373
		$sql = "UPDATE `{$this->getTableName()}` SET `starred` = ?
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

373
		$sql = "UPDATE `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` SET `starred` = ?

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
374
				WHERE `id` IN {$this->questionMarks($count)} AND `user_id` = ?";
375
		$params = \array_merge([$date], $ids, [$userId]);
376
		return $this->execute($sql, $params)->rowCount();
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

376
		return /** @scrutinizer ignore-deprecated */ $this->execute($sql, $params)->rowCount();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
377
	}
378
379
	public function latestInsertTime(string $userId) : ?\DateTime {
380
		$sql = "SELECT MAX(`{$this->getTableName()}`.`created`) FROM `{$this->getTableName()}` WHERE `user_id` = ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

380
		$sql = "SELECT MAX(`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`created`) FROM `{$this->getTableName()}` WHERE `user_id` = ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
381
		$result = $this->execute($sql, [$userId]);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

381
		$result = /** @scrutinizer ignore-deprecated */ $this->execute($sql, [$userId]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
382
		$createdTime = $result->fetch(\PDO::FETCH_COLUMN);
383
384
		return ($createdTime === null) ? null : new \DateTime($createdTime);
385
	}
386
387
	public function latestUpdateTime(string $userId) : ?\DateTime {
388
		$sql = "SELECT MAX(`{$this->getTableName()}`.`updated`) FROM `{$this->getTableName()}` WHERE `user_id` = ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

388
		$sql = "SELECT MAX(`{$this->getTableName()}`.`updated`) FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` WHERE `user_id` = ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
389
		$result = $this->execute($sql, [$userId]);
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...tcloudMapper::execute() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

389
		$result = /** @scrutinizer ignore-deprecated */ $this->execute($sql, [$userId]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
390
		$createdTime = $result->fetch(\PDO::FETCH_COLUMN);
391
392
		return ($createdTime === null) ? null : new \DateTime($createdTime);
393
	}
394
395
	/**
396
	 * helper creating a string like '(?,?,?)' with the specified number of elements
397
	 */
398
	protected function questionMarks(int $count) : string {
399
		$questionMarks = [];
400
		for ($i = 0; $i < $count; $i++) {
401
			$questionMarks[] = '?';
402
		}
403
		return '(' . \implode(',', $questionMarks) . ')';
404
	}
405
406
	/**
407
	 * Build a SQL SELECT statement which selects all entities of the given user,
408
	 * and optionally applies other conditions, too.
409
	 * This is built upon `selectEntities` which may be overridden by the derived class.
410
	 * @param string|null $condition Optional extra condition. This will get automatically
411
	 *                               prefixed with ' AND ', so don't include that.
412
	 * @param string|null $extension Any extension (e.g. ORDER BY, LIMIT) to be added after
413
	 *                               the conditions in the SQL statement
414
	 */
415
	protected function selectUserEntities(string $condition=null, string $extension=null) : string {
416
		$allConditions = "`{$this->getTableName()}`.`user_id` = ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

416
		$allConditions = "`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`user_id` = ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
417
418
		if (!empty($condition)) {
419
			$allConditions .= " AND ($condition)";
420
		}
421
422
		return $this->selectEntities($allConditions, $extension);
423
	}
424
425
	/**
426
	 * Build a SQL SELECT statement which selects all entities matching the given condition.
427
	 * The derived class may override this if necessary.
428
	 * @param string $condition This will get automatically prefixed with ' WHERE '
429
	 * @param string|null $extension Any extension (e.g. ORDER BY, LIMIT) to be added after
430
	 *                               the conditions in the SQL statement
431
	 */
432
	protected function selectEntities(string $condition, string $extension=null) : string {
433
		return "SELECT * FROM `{$this->getTableName()}` WHERE $condition $extension ";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

433
		return "SELECT * FROM `{/** @scrutinizer ignore-deprecated */ $this->getTableName()}` WHERE $condition $extension ";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
434
	}
435
436
	/**
437
	 * @return array with two values: The SQL condition as string and the SQL parameters as string[]
438
	 */
439
	protected function formatNameConditions(?string $name, int $matchMode) : array {
440
		$params = [];
441
		$nameCol = "`{$this->getTableName()}`.`{$this->nameColumn}`";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

441
		$nameCol = "`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`{$this->nameColumn}`";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
442
		if ($name === null) {
443
			$condition = "$nameCol IS NULL";
444
		} else {
445
			if ($matchMode === MatchMode::Exact) {
446
				$condition = "LOWER($nameCol) = LOWER(?)";
447
			} else {
448
				$condition = "LOWER($nameCol) LIKE LOWER(?)";
449
			}
450
			if ($matchMode === MatchMode::Substring) {
451
				$params[] = self::prepareSubstringSearchPattern($name);
452
			} else {
453
				$params[] = $name;
454
			}
455
		}
456
		return [$condition, $params];
457
	}
458
459
	/**
460
	 * @return array with two values: The SQL condition as string and the SQL parameters as string[]
461
	 */
462
	protected function formatTimestampConditions(?string $createdMin, ?string $createdMax, ?string $updatedMin, ?string $updatedMax) : array {
463
		$conditions = [];
464
		$params = [];
465
466
		if (!empty($createdMin)) {
467
			$conditions[] = "`{$this->getTableName()}`.`created` >= ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

467
			$conditions[] = "`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`created` >= ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
468
			$params[] = $createdMin;
469
		}
470
471
		if (!empty($createdMax)) {
472
			$conditions[] = "`{$this->getTableName()}`.`created` <= ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

472
			$conditions[] = "`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`created` <= ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
473
			$params[] = $createdMax;
474
		}
475
476
		if (!empty($updatedMin)) {
477
			$conditions[] = "`{$this->getTableName()}`.`updated` >= ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

477
			$conditions[] = "`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`updated` >= ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
478
			$params[] = $updatedMin;
479
		}
480
481
		if (!empty($updatedMax)) {
482
			$conditions[] = "`{$this->getTableName()}`.`updated` <= ?";
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

482
			$conditions[] = "`{/** @scrutinizer ignore-deprecated */ $this->getTableName()}`.`updated` <= ?";

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
483
			$params[] = $updatedMax;
484
		}
485
486
		return [\implode(' AND ', $conditions), $params];
487
	}
488
489
	/**
490
	 * Convert given sorting condition to an SQL clause. Derived class may overide this if necessary.
491
	 * @param int $sortBy One of the constants defined in the class SortBy
492
	 */
493
	protected function formatSortingClause(int $sortBy, bool $invertSort = false) : ?string {
494
		$table = $this->getTableName();
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

494
		$table = /** @scrutinizer ignore-deprecated */ $this->getTableName();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
495
		if ($sortBy == SortBy::Name) {
496
			$dir = $invertSort ? 'DESC' : 'ASC';
497
			return "ORDER BY LOWER(`$table`.`{$this->nameColumn}`) $dir";
498
		} elseif ($sortBy == SortBy::Newest) {
499
			$dir = $invertSort ? 'ASC' : 'DESC';
500
			return "ORDER BY `$table`.`id` $dir"; // abuse the fact that IDs are ever-incrementing values
501
		} elseif ($sortBy == SortBy::Rating) {
502
			if (\property_exists($this->entityClass, 'rating')) {
503
				$dir = $invertSort ? 'ASC' : 'DESC';
504
				return "ORDER BY `$table`.`rating` $dir";
505
			} else {
506
				return null;
507
			}
508
		} else {
509
			return null;
510
		}
511
	}
512
513
	protected static function prepareSubstringSearchPattern(string $input) : string {
514
		// possibly multiparted query enclosed in quotation marks is handled as a single substring,
515
		// while the default interpretation of multipart string is that each of the parts can be found
516
		// separately as substring in the given order
517
		if (Util::startsWith($input, '"') && Util::endsWith($input, '"')) {
518
			// remove the quotation
519
			$pattern = \substr($input, 1, -1);
520
		} else {
521
			// split to parts by whitespace
522
			$parts = \preg_split('/\s+/', $input, -1, PREG_SPLIT_NO_EMPTY);
523
			// glue the parts back together with a wildcard charater
524
			$pattern = \implode('%', $parts);
525
		}
526
		return "%$pattern%";
527
	}
528
529
	/**
530
	 * Format SQL operator and parameter matching the given advanced search operator.
531
	 * @return array like ['op' => string, 'param' => string]
532
	 */
533
	protected function advFormatSqlOperator(string $ruleOperator, string $ruleInput, string $userId) {
534
		switch ($ruleOperator) {
535
			case 'contain':		return ['op' => 'LIKE',						'param' => "%$ruleInput%"];
536
			case 'notcontain':	return ['op' => 'NOT LIKE',					'param' => "%$ruleInput%"];
537
			case 'start':		return ['op' => 'LIKE',						'param' => "$ruleInput%"];
538
			case 'end':			return ['op' => 'LIKE',						'param' => "%$ruleInput"];
539
			case 'is':			return ['op' => '=',						'param' => "$ruleInput"];
540
			case 'isnot':		return ['op' => '!=',						'param' => "$ruleInput"];
541
			case 'sounds':		return ['op' => 'SOUNDS LIKE',				'param' => $ruleInput]; // MySQL-specific syntax
542
			case 'notsounds':	return ['op' => 'NOT SOUNDS LIKE',			'param' => $ruleInput]; // MySQL-specific syntax
543
			case 'regexp':		return ['op' => 'REGEXP',					'param' => $ruleInput]; // MySQL-specific syntax
544
			case 'notregexp':	return ['op' => 'NOT REGEXP',				'param' => $ruleInput]; // MySQL-specific syntax
545
			case 'true':		return ['op' => 'IS NOT NULL',				'param' => null];
546
			case 'false':		return ['op' => 'IS NULL',					'param' => null];
547
			case 'equal':		return ['op' => '',							'param' => $ruleInput];
548
			case 'ne':			return ['op' => 'NOT',						'param' => $ruleInput];
549
			case 'limit':		return ['op' => (string)(int)$ruleInput,	'param' => $userId];	// this is a bit hacky, userId needs to be passed as an SQL param while simple sanitation suffices for the limit
550
			default:			return ['op' => $ruleOperator,				'param' => $ruleInput]; // all numerical operators fall here
551
		}
552
	}
553
554
	/**
555
	 * Format SQL condition matching the given advanced search rule and SQL operator.
556
	 * Derived classes should override this to provide support for table-specific rules.
557
	 */
558
	protected function advFormatSqlCondition(string $rule, string $sqlOp) : string {
559
		$table = $this->getTableName();
0 ignored issues
show
Deprecated Code introduced by
The function OCA\Music\AppFramework\D...dMapper::getTableName() has been deprecated: 14.0.0 Move over to QBMapper ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

559
		$table = /** @scrutinizer ignore-deprecated */ $this->getTableName();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
560
		$nameCol = $this->nameColumn;
561
562
		switch ($rule) {
563
			case 'title':			return "LOWER(`$table`.`$nameCol`) $sqlOp LOWER(?)";
564
			case 'my_flagged':		return "`$table`.`starred` $sqlOp";
565
			case 'favorite':		return "(LOWER(`$table`.`$nameCol`) $sqlOp LOWER(?) AND `$table`.`starred` IS NOT NULL)"; // title search among flagged
566
			case 'myrating':		// fall throuhg, we provide no access to other people's data
567
			case 'rating':			return "`$table`.`rating` $sqlOp ?";
568
			case 'added':			return "`$table`.`created` $sqlOp ?";
569
			case 'updated':			return "`$table`.`updated` $sqlOp ?";
570
			case 'mbid':			return "`$table`.`mbid` $sqlOp ?";
571
			case 'recent_added':	return "`$table`.`id` IN (SELECT * FROM (SELECT `id` FROM `$table` WHERE `user_id` = ? ORDER BY `created` DESC LIMIT $sqlOp) mysqlhack)";
572
			case 'recent_updated':	return "`$table`.`id` IN (SELECT * FROM (SELECT `id` FROM `$table` WHERE `user_id` = ? ORDER BY `updated` DESC LIMIT $sqlOp) mysqlhack)";
573
			default:				throw new \DomainException("Rule '$rule' not supported on this entity type");
574
		}
575
	}
576
577
	/**
578
	 * Find an entity which has the same identity as the supplied entity.
579
	 * How the identity of the entity is defined, depends on the derived concrete class.
580
	 * @phpstan-param EntityType $entity
581
	 * @phpstan-return EntityType
582
	 */
583
	abstract protected function findUniqueEntity(Entity $entity) : Entity;
584
}
585