Issues (40)

lib/Migration/Version010300Date20210906093000.php (1 issue)

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

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

365
		if (!/** @scrutinizer ignore-deprecated */ $table->hasPrimaryKey()) {

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...
366
			$table->setPrimaryKey($columns);
367
		}
368
	}
369
}
370