Passed
Push — feature/1061-random-view ( afd67b...1c2ae7 )
by Pauli
03:33
created

TrackMapper::findAllByCriteria()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
c 1
b 0
f 0
nc 8
nop 8
dl 0
loc 21
rs 9.8333

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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 Morris Jobke <[email protected]>
10
 * @author Pauli Järvinen <[email protected]>
11
 * @copyright Morris Jobke 2013, 2014
12
 * @copyright Pauli Järvinen 2016 - 2023
13
 */
14
15
namespace OCA\Music\Db;
16
17
use OCP\IDBConnection;
18
19
/**
20
 * @phpstan-extends BaseMapper<Track>
21
 */
22
class TrackMapper extends BaseMapper {
23
	public function __construct(IDBConnection $db) {
24
		parent::__construct($db, 'music_tracks', Track::class, 'title');
25
	}
26
27
	/**
28
	 * Override the base implementation to include data from multiple tables
29
	 *
30
	 * {@inheritdoc}
31
	 * @see BaseMapper::selectEntities()
32
	 */
33
	protected function selectEntities(string $condition, string $extension=null) : string {
34
		return "SELECT `*PREFIX*music_tracks`.*, `file`.`name` AS `filename`, `file`.`size`, `file`.`mtime` AS `file_mod_time`,
35
						`album`.`name` AS `album_name`, `artist`.`name` AS `artist_name`, `genre`.`name` AS `genre_name`
36
				FROM `*PREFIX*music_tracks`
37
				INNER JOIN `*PREFIX*filecache` `file`
38
				ON `*PREFIX*music_tracks`.`file_id` = `file`.`fileid`
39
				INNER JOIN `*PREFIX*music_albums` `album`
40
				ON `*PREFIX*music_tracks`.`album_id` = `album`.`id`
41
				INNER JOIN `*PREFIX*music_artists` `artist`
42
				ON `*PREFIX*music_tracks`.`artist_id` = `artist`.`id`
43
				LEFT JOIN `*PREFIX*music_genres` `genre`
44
				ON `*PREFIX*music_tracks`.`genre_id` = `genre`.`id`
45
				WHERE $condition $extension";
46
	}
47
48
	/**
49
	 * Overridden from the base implementation to add support for sorting by artist, play_count, and last_played.
50
	 *
51
	 * {@inheritdoc}
52
	 * @see BaseMapper::formatSortingClause()
53
	 */
54
	protected function formatSortingClause(int $sortBy, bool $invertSort = false) : ?string {
55
		$dir = $invertSort ? 'DESC' : 'ASC';
56
		switch ($sortBy) {
57
			case SortBy::Parent:
58
				// Note: the alternative form "LOWER(`artist_name`) wouldn't work on PostgreSQL, see https://github.com/owncloud/music/issues/1046 for a similar case
59
				return "ORDER BY LOWER(`artist`.`name`) $dir, LOWER(`title`) $dir";
60
			case SortBy::PlayCount:
61
				return "ORDER BY LOWER(`play_count`) $dir";
62
			case SortBy::LastPlayed:
63
				return "ORDER BY LOWER(`last_played`) $dir";
64
			default:
65
				return parent::formatSortingClause($sortBy, $invertSort);
66
		}
67
	}
68
69
	/**
70
	 * Returns all tracks of the given artist (both album and track artists are considered)
71
	 * @return Track[]
72
	 */
73
	public function findAllByArtist(int $artistId, string $userId, ?int $limit=null, ?int $offset=null) : array {
74
		$sql = $this->selectUserEntities(
75
				'`artist_id` = ? OR `album_id` IN (SELECT `id` from `*PREFIX*music_albums` WHERE `album_artist_id` = ?) ',
76
				'ORDER BY LOWER(`title`)');
77
		$params = [$userId, $artistId, $artistId];
78
		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

78
		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...
79
	}
80
81
	/**
82
	 * @return Track[]
83
	 */
84
	public function findAllByAlbum(int $albumId, string $userId, ?int $artistId=null, ?int $limit=null, ?int $offset=null) : array {
85
		$condition = '`album_id` = ?';
86
		$params = [$userId, $albumId];
87
88
		if ($artistId !== null) {
89
			$condition .= ' AND `artist_id` = ? ';
90
			$params[] = $artistId;
91
		}
92
93
		$sql = $this->selectUserEntities($condition,
94
				'ORDER BY `*PREFIX*music_tracks`.`disk`, `number`, LOWER(`title`)');
95
		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

95
		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...
96
	}
97
98
	/**
99
	 * @return Track[]
100
	 */
101
	public function findAllByFolder(int $folderId, string $userId, ?int $limit=null, ?int $offset=null) : array {
102
		$sql = $this->selectUserEntities('`file`.`parent` = ?', 'ORDER BY LOWER(`title`)');
103
		$params = [$userId, $folderId];
104
		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

104
		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...
105
	}
106
107
	/**
108
	 * @return Track[]
109
	 */
110
	public function findAllByGenre(int $genreId, string $userId, ?int $limit=null, ?int $offset=null) : array {
111
		$sql = $this->selectUserEntities('`genre_id` = ?', 'ORDER BY LOWER(`title`)');
112
		$params = [$userId, $genreId];
113
		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

113
		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...
114
	}
115
116
	/**
117
	 * @param string $userId
118
	 * @return int[]
119
	 */
120
	public function findAllFileIds(string $userId) : array {
121
		$sql = 'SELECT `file_id` FROM `*PREFIX*music_tracks` WHERE `user_id` = ?';
122
		$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

122
		$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...
123
124
		return \array_map(function ($i) {
125
			return (int)$i['file_id'];
126
		}, $result->fetchAll());
127
	}
128
129
	/**
130
	 * Find a track of user matching a file ID
131
	 * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
132
	 */
133
	public function findByFileId(int $fileId, string $userId) : Track {
134
		$sql = $this->selectUserEntities('`file_id` = ?');
135
		$params = [$userId, $fileId];
136
		return $this->findEntity($sql, $params);
0 ignored issues
show
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

136
		return /** @scrutinizer ignore-deprecated */ $this->findEntity($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...
Bug Best Practice introduced by
The expression return $this->findEntity($sql, $params) returns the type OCP\AppFramework\Db\Entity which includes types incompatible with the type-hinted return OCA\Music\Db\Track.
Loading history...
137
	}
138
139
	/**
140
	 * Find tracks of user with multiple file IDs
141
	 * @param integer[] $fileIds
142
	 * @param string[] $userIds
143
	 * @return Track[]
144
	 */
145
	public function findByFileIds(array $fileIds, array $userIds) : array {
146
		$sql = $this->selectEntities(
147
				'`*PREFIX*music_tracks`.`user_id` IN ' . $this->questionMarks(\count($userIds)) .
148
				' AND `file_id` IN '. $this->questionMarks(\count($fileIds)));
149
		$params = \array_merge($userIds, $fileIds);
150
		return $this->findEntities($sql, $params);
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

150
		return /** @scrutinizer ignore-deprecated */ $this->findEntities($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...
151
	}
152
153
	/**
154
	 * Finds tracks of all users matching one or multiple file IDs
155
	 * @param integer[] $fileIds
156
	 * @return Track[]
157
	 */
158
	public function findAllByFileIds(array $fileIds) : array {
159
		$sql = $this->selectEntities('`file_id` IN '.
160
				$this->questionMarks(\count($fileIds)));
161
		return $this->findEntities($sql, $fileIds);
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

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

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...
162
	}
163
164
	public function countByArtist(int $artistId) : int {
165
		$sql = 'SELECT COUNT(*) AS `count` FROM `*PREFIX*music_tracks` WHERE `artist_id` = ?';
166
		$result = $this->execute($sql, [$artistId]);
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

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

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...
167
		$row = $result->fetch();
168
		return (int)$row['count'];
169
	}
170
171
	public function countByAlbum(int $albumId) : int {
172
		$sql = 'SELECT COUNT(*) AS `count` FROM `*PREFIX*music_tracks` WHERE `album_id` = ?';
173
		$result = $this->execute($sql, [$albumId]);
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

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

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...
174
		$row = $result->fetch();
175
		return (int)$row['count'];
176
	}
177
178
	/**
179
	 * @return integer Duration in seconds
180
	 */
181
	public function totalDurationOfAlbum(int $albumId) : int {
182
		$sql = 'SELECT SUM(`length`) AS `duration` FROM `*PREFIX*music_tracks` WHERE `album_id` = ?';
183
		$result = $this->execute($sql, [$albumId]);
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

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

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...
184
		$row = $result->fetch();
185
		return (int)$row['duration'];
186
	}
187
188
	/**
189
	 * Get durations of the given tracks.
190
	 * @param integer[] $trackIds
191
	 * @return array {int => int} where keys are track IDs and values are corresponding durations
192
	 */
193
	public function getDurations(array $trackIds) : array {
194
		$result = [];
195
196
		if (!empty($trackIds)) {
197
			$sql = 'SELECT `id`, `length` FROM `*PREFIX*music_tracks` WHERE `id` IN ' .
198
						$this->questionMarks(\count($trackIds));
199
			$rows = $this->execute($sql, $trackIds)->fetchAll();
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

199
			$rows = /** @scrutinizer ignore-deprecated */ $this->execute($sql, $trackIds)->fetchAll();

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...
200
			foreach ($rows as $row) {
201
				$result[$row['id']] = (int)$row['length'];
202
			}
203
		}
204
		return $result;
205
	}
206
207
	/**
208
	 * @return Track[]
209
	 */
210
	public function findAllByNameRecursive(string $name, string $userId, ?int $limit=null, ?int $offset=null) {
211
		$condition = '( LOWER(`artist`.`name`) LIKE LOWER(?) OR
212
						LOWER(`album`.`name`) LIKE LOWER(?) OR
213
						LOWER(`title`) LIKE LOWER(?) )';
214
		$sql = $this->selectUserEntities($condition, 'ORDER BY LOWER(`title`)');
215
		$name = BaseMapper::prepareSubstringSearchPattern($name);
216
		$params = [$userId, $name, $name, $name];
217
		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

217
		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...
218
	}
219
220
	/**
221
	 * Returns all tracks specified by name and/or artist name
222
	 * @param string|null $name the name of the track
223
	 * @param string|null $artistName the name of the artist
224
	 * @param string $userId the name of the user
225
	 * @return Track[] Tracks matching the criteria
226
	 */
227
	public function findAllByNameAndArtistName(?string $name, ?string $artistName, string $userId) : array {
228
		$sqlConditions = [];
229
		$params = [$userId];
230
231
		if (!empty($name)) {
232
			$sqlConditions[] = '`title` = ?';
233
			$params[] = $name;
234
		}
235
236
		if (!empty($artistName)) {
237
			$sqlConditions[] = '`artist`.`name` = ?';
238
			$params[] = $artistName;
239
		}
240
241
		// at least one condition has to be given, otherwise return an empty set
242
		if (\count($sqlConditions) > 0) {
243
			$sql = $this->selectUserEntities(\implode(' AND ', $sqlConditions));
244
			return $this->findEntities($sql, $params);
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

244
			return /** @scrutinizer ignore-deprecated */ $this->findEntities($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...
245
		} else {
246
			return [];
247
		}
248
	}
249
250
	/**
251
	 * Returns all tracks specified by various criteria, all of which are optional
252
	 * @param int[]|null $genres Array of genre IDs
253
	 * @param int|null $fromYear Earliest release year to include
254
	 * @param int|null $toYear Latest release year to include
255
	 * @param int $sortBy Sorting rule as defined in the class SortBy
256
	 * @param string $userId the name of the user
257
	 * @return Track[] Tracks matching the criteria
258
	 */
259
	public function findAllByCriteria(array $genres, ?int $fromYear, ?int $toYear, int $sortBy, bool $invertSort, string $userId, ?int $limit=null, ?int $offset=null) : array {
260
		$sqlConditions = [];
261
		$params = [$userId];
262
263
		if (!empty($genres)) {
264
			$sqlConditions[] = '`genre_id` IN ' . $this->questionMarks(\count($genres));
265
			$params = \array_merge($params, $genres);
266
		}
267
268
		if (!empty($fromYear)) {
269
			$sqlConditions[] = '`year` >= ?';
270
			$params[] = $fromYear;
271
		}
272
273
		if (!empty($toYear)) {
274
			$sqlConditions[] = '`year` <= ?';
275
			$params[] = $toYear;
276
		}
277
278
		$sql = $this->selectUserEntities(\implode(' AND ', $sqlConditions), self::formatSortingClause($sortBy, $invertSort));
0 ignored issues
show
Bug Best Practice introduced by
The method OCA\Music\Db\TrackMapper::formatSortingClause() is not static, but was called statically. ( Ignorable by Annotation )

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

278
		$sql = $this->selectUserEntities(\implode(' AND ', $sqlConditions), self::/** @scrutinizer ignore-call */ formatSortingClause($sortBy, $invertSort));
Loading history...
279
		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

279
		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...
280
	}
281
282
	/**
283
	 * Find most frequently played tracks
284
	 * @return Track[]
285
	 */
286
	public function findFrequentPlay(string $userId, ?int $limit=null, ?int $offset=null) : array {
287
		$sql = $this->selectUserEntities('`play_count` > 0', 'ORDER BY `play_count` DESC, LOWER(`title`)');
288
		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

288
		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...
289
	}
290
291
	/**
292
	 * Find most recently played tracks
293
	 * @return Track[]
294
	 */
295
	public function findRecentPlay(string $userId, ?int $limit=null, ?int $offset=null) : array {
296
		$sql = $this->selectUserEntities('`last_played` IS NOT NULL', 'ORDER BY `last_played` DESC');
297
		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

297
		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...
298
	}
299
300
	/**
301
	 * Find least recently played tracks
302
	 * @return Track[]
303
	 */
304
	public function findNotRecentPlay(string $userId, ?int $limit=null, ?int $offset=null) : array {
305
		$sql = $this->selectUserEntities(null, 'ORDER BY `last_played` ASC');
306
		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

306
		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...
307
	}
308
309
	/**
310
	 * Finds all track IDs of the user along with the parent folder ID of each track
311
	 * @return array where keys are folder IDs and values are arrays of track IDs
312
	 */
313
	public function findTrackAndFolderIds(string $userId) : array {
314
		$sql = 'SELECT `track`.`id` AS id, `file`.`name` AS `filename`, `file`.`parent` AS parent
315
				FROM `*PREFIX*music_tracks` `track`
316
				JOIN `*PREFIX*filecache` `file`
317
				ON `track`.`file_id` = `file`.`fileid`
318
				WHERE `track`.`user_id` = ?';
319
320
		$rows = $this->execute($sql, [$userId])->fetchAll();
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

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

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...
321
322
		// Sort the results according the file names. This can't be made using ORDERBY in the
323
		// SQL query because then we couldn't use the "natural order" comparison algorithm
324
		\usort($rows, function ($a, $b) {
325
			return \strnatcasecmp($a['filename'], $b['filename']);
326
		});
327
328
		// group the files to parent folder "buckets"
329
		$result = [];
330
		foreach ($rows as $row) {
331
			$result[(int)$row['parent']][] = (int)$row['id'];
332
		}
333
334
		return $result;
335
	}
336
337
	/**
338
	 * Find names and parents of the file system nodes with given IDs within the given storage
339
	 * @param int[] $nodeIds
340
	 * @param string $storageId
341
	 * @return array where keys are the node IDs and values are associative arrays
342
	 *         like { 'name' => string, 'parent' => int };
343
	 */
344
	public function findNodeNamesAndParents(array $nodeIds, string $storageId) : array {
345
		$result = [];
346
347
		if (!empty($nodeIds)) {
348
			$sql = 'SELECT `fileid`, `name`, `parent` '.
349
					'FROM `*PREFIX*filecache` `filecache` '.
350
					'JOIN `*PREFIX*storages` `storages` '.
351
					'ON `filecache`.`storage` = `storages`.`numeric_id` '.
352
					'WHERE `storages`.`id` = ? '.
353
					'AND `filecache`.`fileid` IN '. $this->questionMarks(\count($nodeIds));
354
355
			$rows = $this->execute($sql, \array_merge([$storageId], $nodeIds))->fetchAll();
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

355
			$rows = /** @scrutinizer ignore-deprecated */ $this->execute($sql, \array_merge([$storageId], $nodeIds))->fetchAll();

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...
356
357
			foreach ($rows as $row) {
358
				$result[$row['fileid']] = [
359
					'name' => $row['name'],
360
					'parent' => (int)$row['parent']
361
				];
362
			}
363
		}
364
365
		return $result;
366
	}
367
368
	/**
369
	 * Returns all genre IDs associated with the given artist
370
	 * @return int[]
371
	 */
372
	public function getGenresByArtistId(int $artistId, string $userId) : array {
373
		$sql = 'SELECT DISTINCT(`genre_id`) FROM `*PREFIX*music_tracks` WHERE
374
				`genre_id` IS NOT NULL AND `user_id` = ? AND `artist_id` = ?';
375
		$rows = $this->execute($sql, [$userId, $artistId]);
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

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

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...
376
		return $rows->fetchAll(\PDO::FETCH_COLUMN);
377
	}
378
379
	/**
380
	 * Returns all tracks IDs of the user, organized by the genre_id.
381
	 * @return array where keys are genre IDs and values are arrays of track IDs
382
	 */
383
	public function mapGenreIdsToTrackIds(string $userId) : array {
384
		$sql = 'SELECT `id`, `genre_id` FROM `*PREFIX*music_tracks`
385
				WHERE `genre_id` IS NOT NULL and `user_id` = ?';
386
		$rows = $this->execute($sql, [$userId])->fetchAll();
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

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

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...
387
388
		$result = [];
389
		foreach ($rows as $row) {
390
			$result[(int)$row['genre_id']][] = (int)$row['id'];
391
		}
392
393
		return $result;
394
	}
395
396
	/**
397
	 * Returns file IDs of the tracks which do not have genre scanned. This is not the same
398
	 * thing as unknown genre, which means that the genre has been scanned but was not found
399
	 * from the track metadata.
400
	 * @return int[]
401
	 */
402
	public function findFilesWithoutScannedGenre(string $userId) : array {
403
		$sql = 'SELECT `track`.`file_id` FROM `*PREFIX*music_tracks` `track`
404
				INNER JOIN `*PREFIX*filecache` `file`
405
				ON `track`.`file_id` = `file`.`fileid`
406
				WHERE `genre_id` IS NULL and `user_id` = ?';
407
		$rows = $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

407
		$rows = /** @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...
408
		return $rows->fetchAll(\PDO::FETCH_COLUMN);
409
	}
410
411
	/**
412
	 * Update "last played" timestamp and increment the total play count of the track.
413
	 * The DB row is updated *without* updating the `updated` column.
414
	 * @return bool true if the track was found and updated, false otherwise
415
	 */
416
	public function recordTrackPlayed(int $trackId, string $userId, \DateTime $timeOfPlay) : bool {
417
		$sql = 'UPDATE `*PREFIX*music_tracks`
418
				SET `last_played` = ?, `play_count` = `play_count` + 1
419
				WHERE `user_id` = ? AND `id` = ?';
420
		$params = [$timeOfPlay->format(BaseMapper::SQL_DATE_FORMAT), $userId, $trackId];
421
		$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

421
		$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...
422
		return ($result->rowCount() > 0);
423
	}
424
425
	/**
426
	 * @see \OCA\Music\Db\BaseMapper::findUniqueEntity()
427
	 * @param Track $track
428
	 * @return Track
429
	 */
430
	protected function findUniqueEntity(Entity $track) : Entity {
431
		return $this->findByFileId($track->getFileId(), $track->getUserId());
0 ignored issues
show
Bug introduced by
The method getFileId() does not exist on OCA\Music\Db\Entity. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

431
		return $this->findByFileId($track->/** @scrutinizer ignore-call */ getFileId(), $track->getUserId());
Loading history...
Bug introduced by
It seems like $track->getFileId() can also be of type null; however, parameter $fileId of OCA\Music\Db\TrackMapper::findByFileId() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

431
		return $this->findByFileId(/** @scrutinizer ignore-type */ $track->getFileId(), $track->getUserId());
Loading history...
432
	}
433
}
434