Passed
Push — master ( e16209...96692d )
by Pauli
01:58
created

migrateMusicTracks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 24
c 0
b 0
f 0
dl 0
loc 27
rs 9.536
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace OCA\Music\Migration;
6
7
use Closure;
8
use OCP\DB\ISchemaWrapper;
9
use OCP\Migration\SimpleMigrationStep;
10
use OCP\Migration\IOutput;
11
12
/**
13
 * Migrate the DB schema to Music v1.3.0 level from any previous version starting from v0.4.0
14
 */
15
class Version010300Date20210906093000 extends SimpleMigrationStep {
16
17
	/**
18
	 * @param IOutput $output
19
	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
20
	 * @param array $options
21
	 */
22
	public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
23
	}
24
25
	/**
26
	 * @param IOutput $output
27
	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
28
	 * @param array $options
29
	 * @return null|ISchemaWrapper
30
	 */
31
	public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
32
		/** @var ISchemaWrapper $schema */
33
		$schema = $schemaClosure();
34
35
		$this->migrateMusicArtists($schema);
36
		$this->migrateMusicAlbums($schema);
37
		$this->migrateMusicTracks($schema);
38
		$this->migrateMusicPlaylists($schema);
39
		$this->migrateMusicGenres($schema);
40
		$this->migrateMusicRadioStations($schema);
41
		$this->migrateMusicAmpacheSessions($schema);
42
		$this->migrateAmpacheUsers($schema);
43
		$this->migrateMusicCache($schema);
44
		$this->migrateMusicBookmarks($schema);
45
		$this->migratePodcastChannels($schema);
46
		$this->migratePodcastEpisodes($schema);
47
48
		return $schema;
49
	}
50
51
	/**
52
	 * @param IOutput $output
53
	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
54
	 * @param array $options
55
	 */
56
	public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
57
	}
58
59
	private function migrateMusicArtists(ISchemaWrapper $schema) {
60
		$table = $this->getOrCreateTable($schema, 'music_artists');
61
		$this->setColumns($table, [
62
			[ 'id',				'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
63
			[ 'user_id',		'string',	['notnull' => true, 'length' => 64] ],
64
			[ 'name',			'string',	['notnull' => false, 'length' => 256] ],
65
			[ 'cover_file_id',	'bigint',	['notnull' => false,'length' => 10] ],
66
			[ 'mbid',			'string',	['notnull' => false, 'length' => 36] ],
67
			[ 'hash',			'string',	['notnull' => true, 'length' => 32] ],
68
			[ 'starred',		'datetime',	['notnull' => false] ],
69
			[ 'created',		'datetime',	['notnull' => false] ],
70
			[ 'updated',		'datetime',	['notnull' => false] ]
71
		]);
72
		$this->dropObsoleteColumn($table, 'image');
73
74
		$this->setPrimaryKey($table, ['id']);
75
		$this->setUniqueIndex($table, 'user_id_hash_idx', ['user_id', 'hash']);
76
	}
77
78
	private function migrateMusicAlbums(ISchemaWrapper $schema) {
79
		$table = $this->getOrCreateTable($schema, 'music_albums');
80
		$this->setColumns($table, [
81
			[ 'id',					'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
82
			[ 'user_id',			'string',	['notnull' => true, 'length' => 64] ],
83
			[ 'name',				'string',	['notnull' => false, 'length' => 256] ],
84
			[ 'cover_file_id',		'bigint',	['notnull' => false, 'length' => 10] ],
85
			[ 'mbid',				'string',	['notnull' => false, 'length' => 36] ],
86
			[ 'disk',				'integer',	['notnull' => false, 'unsigned' => true] ],
87
			[ 'mbid_group',			'string',	['notnull' => false, 'length' => 36] ],
88
			[ 'album_artist_id',	'integer',	['notnull' => false] ],
89
			[ 'hash',				'string',	['notnull' => true, 'length' => 32] ],
90
			[ 'starred',			'datetime',	['notnull' => false] ],
91
			[ 'created',			'datetime',	['notnull' => false] ],
92
			[ 'updated',			'datetime',	['notnull' => false] ]
93
		]);
94
		$this->dropObsoleteColumn($table, 'year');
95
96
		$this->setPrimaryKey($table, ['id']);
97
		$this->setIndex($table, 'ma_cover_file_id_idx', ['cover_file_id']);
98
		$this->setIndex($table, 'ma_album_artist_id_idx', ['album_artist_id']);
99
		$this->setUniqueIndex($table, 'ma_user_id_hash_idx', ['user_id', 'hash']);
100
	}
101
102
	private function migrateMusicTracks(ISchemaWrapper $schema) {
103
		$table = $this->getOrCreateTable($schema, 'music_tracks');
104
		$this->setColumns($table, [
105
			[ 'id',			'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true, ] ],
106
			[ 'user_id',	'string',	['notnull' => true, 'length' => 64, ] ],
107
			[ 'title',		'string',	['notnull' => true, 'length' => 256, ] ],
108
			[ 'number',		'integer',	['notnull' => false, 'unsigned' => true] ],
109
			[ 'disk',		'integer',	['notnull' => false, 'unsigned' => true] ],
110
			[ 'year',		'integer',	['notnull' => false, 'unsigned' => true] ],
111
			[ 'artist_id',	'integer',	['notnull' => false] ],
112
			[ 'album_id',	'integer',	['notnull' => false] ],
113
			[ 'length',		'integer',	['notnull' => false, 'unsigned' => true] ],
114
			[ 'file_id',	'bigint',	['notnull' => true, 'length' => 10] ],
115
			[ 'bitrate',	'integer',	['notnull' => false, 'unsigned' => true] ],
116
			[ 'mimetype',	'string',	['notnull' => true, 'length' => 256] ],
117
			[ 'mbid',		'string',	['notnull' => false, 'length' => 36] ],
118
			[ 'starred',	'datetime',	['notnull' => false] ],
119
			[ 'genre_id',	'integer',	['notnull' => false, 'unsigned' => true, ] ],
120
			[ 'created',	'datetime', ['notnull' => false] ],
121
			[ 'updated',	'datetime', ['notnull' => false] ]
122
		]);
123
124
		$this->setPrimaryKey($table, ['id']);
125
		$this->setIndex($table, 'music_tracks_artist_id_idx', ['artist_id']);
126
		$this->setIndex($table, 'music_tracks_album_id_idx', ['album_id']);
127
		$this->setIndex($table, 'music_tracks_user_id_idx', ['user_id']);
128
		$this->setUniqueIndex($table, 'music_tracks_file_user_id_idx', ['file_id', 'user_id']);
129
	}
130
131
	private function migrateMusicPlaylists(ISchemaWrapper $schema) {
132
		$table = $this->getOrCreateTable($schema, 'music_playlists');
133
		$this->setColumns($table, [
134
			[ 'id',			'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
135
			[ 'user_id',	'string',	['notnull' => true, 'length' => 64] ],
136
			[ 'name',		'string',	['notnull' => false, 'length' => 256] ],
137
			[ 'track_ids',	'text',		['notnull' => false] ],
138
			[ 'created',	'datetime',	['notnull' => false] ],
139
			[ 'updated',	'datetime',	['notnull' => false] ],
140
			[ 'comment',	'string',	['notnull' => false, 'length' => 256] ]
141
		]);
142
143
		$this->setPrimaryKey($table, ['id']);
144
	}
145
146
	private function migrateMusicGenres(ISchemaWrapper $schema) {
147
		$table = $this->getOrCreateTable($schema, 'music_genres');
148
		$this->setColumns($table, [
149
			[ 'id',			'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
150
			[ 'user_id',	'string',	['notnull' => true, 'length' => 64] ],
151
			[ 'name',		'string',	['notnull' => false, 'length' => 64] ],
152
			[ 'lower_name',	'string',	['notnull' => false, 'length' => 64] ],
153
			[ 'created',	'datetime',	['notnull' => false] ],
154
			[ 'updated',	'datetime',	['notnull' => false] ]
155
		]);
156
157
		$this->setPrimaryKey($table, ['id']);
158
		$this->setUniqueIndex($table, 'mg_lower_name_user_id_idx', ['lower_name', 'user_id']);
159
	}
160
161
	private function migrateMusicRadioStations(ISchemaWrapper $schema) {
162
		$table = $this->getOrCreateTable($schema, 'music_radio_stations');
163
		$this->setColumns($table, [
164
			[ 'id', 		'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
165
			[ 'user_id',	'string',	['notnull' => true, 'length' => 64] ],
166
			[ 'name',		'string',	['notnull' => false, 'length' => 256] ],
167
			[ 'stream_url',	'string',	['notnull' => true, 'length' => 2048] ],
168
			[ 'home_url',	'string',	['notnull' => false, 'length' => 2048] ],
169
			[ 'created',	'datetime',	['notnull' => false] ],
170
			[ 'updated',	'datetime',	['notnull' => false] ]
171
		]);
172
173
		$this->setPrimaryKey($table, ['id']);
174
	}
175
176
	private function migrateMusicAmpacheSessions(ISchemaWrapper $schema) {
177
		$table = $this->getOrCreateTable($schema, 'music_ampache_sessions');
178
		$this->setColumns($table, [
179
			[ 'id',			'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
180
			[ 'user_id',	'string',	['notnull' => true, 'length' => 64] ],
181
			[ 'token',		'string',	['notnull' => true, 'length' => 64] ],
182
			[ 'expiry',		'integer',	['notnull' => true,'unsigned' => true] ]
183
		]);
184
185
		$this->setPrimaryKey($table, ['id']);
186
		$this->setUniqueIndex($table, 'music_ampache_sessions_index', ['token']);
187
	}
188
189
	private function migrateAmpacheUsers(ISchemaWrapper $schema) {
190
		$table = $this->getOrCreateTable($schema, 'music_ampache_users');
191
		$this->setColumns($table, [
192
			[ 'id',				'integer',	['autoincrement' => true, 'notnull' => true, 'length' => 4] ],
193
			[ 'user_id',		'string',	['notnull' => true, 'length' => 64] ],
194
			[ 'description',	'string',	['notnull' => false, 'length' => 64] ],
195
			[ 'hash',			'string',	['notnull' => true, 'length' => 64] ]
196
		]);
197
198
		$this->setPrimaryKey($table, ['id']);
199
		$this->setUniqueIndex($table, 'music_ampache_users_index', ['hash', 'user_id']);
200
	}
201
202
	private function migrateMusicCache(ISchemaWrapper $schema) {
203
		$table = $this->getOrCreateTable($schema, 'music_cache');
204
		$this->setColumns($table, [
205
			[ 'id',			'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
206
			[ 'key',		'string',	['notnull' => true, 'length' => 64] ],
207
			[ 'user_id',	'string',	['notnull' => true, 'length' => 64] ],
208
			[ 'data',		'text',		['notnull' => false] ],
209
		]);
210
211
		$this->setPrimaryKey($table, ['id']);
212
		$this->setUniqueIndex($table, 'music_cache_index', ['user_id', 'key']);
213
	}
214
215
	private function migrateMusicBookmarks(ISchemaWrapper $schema) {
216
		$table = $this->getOrCreateTable($schema, 'music_bookmarks');
217
		$this->setColumns($table, [
218
			[ 'id',			'integer',		['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
219
			[ 'user_id',	'string',		['notnull' => true, 'length' => 64] ],
220
			[ 'type',		'integer',		['notnull' => true] ],
221
			[ 'entry_id',	'integer',		['notnull' => true] ],
222
			[ 'position',	'integer',		['notnull' => true] ],
223
			[ 'comment',	'string',		['notnull' => false, 'length' => 256] ],
224
			[ 'created',	'datetime',		['notnull' => false] ],
225
			[ 'updated',	'datetime',		['notnull' => false] ]
226
		]);
227
228
		$this->setPrimaryKey($table, ['id']);
229
		$this->setUniqueIndex($table, 'music_bookmarks_index', ['user_id', 'type', 'entry_id']);
230
231
		$this->dropObsoleteIndex($table, 'music_bookmarks_user_track');
232
		$this->dropObsoleteColumn($table, 'track_id');
233
	}
234
235
	private function migratePodcastChannels(ISchemaWrapper $schema) {
236
		$table = $this->getOrCreateTable($schema, 'music_podcast_channels');
237
		$this->setColumns($table, [
238
			[ 'id',					'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
239
			[ 'user_id',			'string',	['notnull' => true, 'length' => 64] ],
240
			[ 'rss_url',			'string',	['notnull' => true, 'length' => 2048] ],
241
			[ 'rss_hash',			'string',	['notnull' => true, 'length' => 64] ],
242
			[ 'content_hash',		'string',	['notnull' => true, 'length' => 64] ],
243
			[ 'update_checked',		'datetime',	['notnull' => true] ],
244
			[ 'published',			'datetime',	['notnull' => false] ],
245
			[ 'last_build_date',	'datetime',	['notnull' => false] ],
246
			[ 'title',				'string',	['notnull' => false, 'length' => 256] ],
247
			[ 'link_url',			'string',	['notnull' => false, 'length' => 2048] ],
248
			[ 'language',			'string',	['notnull' => false, 'length' => 32] ],
249
			[ 'copyright',			'string',	['notnull' => false, 'length' => 256] ],
250
			[ 'author',				'string',	['notnull' => false, 'length' => 256] ],
251
			[ 'description',		'text',		['notnull' => false] ],
252
			[ 'image_url',			'string',	['notnull' => false, 'length' => 2048] ],
253
			[ 'category',			'string',	['notnull' => false, 'length' => 256] ],
254
			[ 'starred',			'datetime',	['notnull' => false] ],
255
			[ 'created',			'datetime',	['notnull' => false] ],
256
			[ 'updated',			'datetime',	['notnull' => false] ]
257
		]);
258
259
		$this->setPrimaryKey($table, ['id']);
260
		$this->setUniqueIndex($table, 'music_podcast_channels_index', ['rss_hash', 'user_id']);
261
	}
262
263
	private function migratePodcastEpisodes(ISchemaWrapper $schema) {
264
		$table = $this->getOrCreateTable($schema, 'music_podcast_episodes');
265
		$this->setColumns($table, [
266
			[ 'id',				'integer',	['autoincrement' => true, 'notnull' => true, 'unsigned' => true] ],
267
			[ 'user_id',		'string',	['notnull' => true, 'length' => 64] ],
268
			[ 'channel_id',		'integer',	['notnull' => true, 'unsigned' => true] ],
269
			[ 'stream_url',		'string',	['notnull' => false, 'length' => 2048] ],
270
			[ 'mimetype',		'string',	['notnull' => false, 'length' => 256] ],
271
			[ 'size',			'integer',	['notnull' => false] ],
272
			[ 'duration',		'integer',	['notnull' => false] ],
273
			[ 'guid',			'string',	['notnull' => true, 'length' => 2048] ],
274
			[ 'guid_hash',		'string',	['notnull' => true, 'length' => 64] ],
275
			[ 'title',			'string',	['notnull' => false, 'length' => 256] ],
276
			[ 'episode',		'integer',	['notnull' => false] ],
277
			[ 'season',			'integer',	['notnull' => false] ],
278
			[ 'link_url',		'string',	['notnull' => false, 'length' => 2048] ],
279
			[ 'published',		'datetime',	['notnull' => false] ],
280
			[ 'keywords',		'string',	['notnull' => false, 'length' => 256] ],
281
			[ 'copyright',		'string',	['notnull' => false, 'length' => 256] ],
282
			[ 'author',			'string',	['notnull' => false, 'length' => 256] ],
283
			[ 'description',	'text',		['notnull' => false] ],
284
			[ 'starred',		'datetime',	['notnull' => false] ],
285
			[ 'created',		'datetime',	['notnull' => false] ],
286
			[ 'updated',		'datetime',	['notnull' => false] ]
287
		]);
288
289
		$this->setPrimaryKey($table, ['id']);
290
		$this->setUniqueIndex($table, 'music_podcast_episodes_index', ['guid_hash', 'channel_id', 'user_id']);
291
	}
292
293
	private function getOrCreateTable(ISchemaWrapper $schema, string $name) {
294
		if (!$schema->hasTable($name)) {
295
			return $schema->createTable($name);
296
		} else {
297
			return $schema->getTable($name);
298
		}
299
	}
300
301
	private function setColumn($table, string $name, string $type, array $args) {
302
		if (!$table->hasColumn($name)) {
303
			$table->addColumn($name, $type, $args);
304
		}
305
	}
306
307
	private function setColumns($table, array $nameTypeArgsPerCol) {
308
		foreach ($nameTypeArgsPerCol as $nameTypeArgs) {
309
			list($name, $type, $args) = $nameTypeArgs;
310
			$this->setColumn($table, $name, $type, $args);
311
		}
312
	}
313
314
	private function dropObsoleteColumn($table, string $name) {
315
		if ($table->hasColumn($name)) {
316
			$table->dropColumn($name);
317
		}
318
	}
319
320
	private function dropObsoleteIndex($table, string $name) {
321
		if ($table->hasIndex($name)) {
322
			$table->dropIndex($name);
323
		}
324
	}
325
326
	private function setIndex($table, string $name, array $columns) {
327
		if (!$table->hasIndex($name)) {
328
			$table->addIndex($columns, $name);
329
		}
330
	}
331
332
	private function setUniqueIndex($table, string $name, array $columns) {
333
		if (!$table->hasIndex($name)) {
334
			$table->addUniqueIndex($columns, $name);
335
		}
336
	}
337
338
	private function setPrimaryKey($table, array $columns) {
339
		if (!$table->hasPrimaryKey()) {
340
			$table->setPrimaryKey($columns);
341
		}
342
	}
343
}
344