Completed
Pull Request — master (#551)
by Maxence
01:59
created

Version0019Date20200603080001::postSchemaChange()   D

Complexity

Conditions 10
Paths 512

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 39
rs 4.1777
c 0
b 0
f 0
cc 10
nc 512
nop 3

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2019
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
declare(strict_types=1);
28
29
namespace OCA\Circles\Migration;
30
31
use Closure;
32
use Doctrine\DBAL\Schema\SchemaException;
33
use Doctrine\DBAL\Types\Type;
34
use OCP\DB\ISchemaWrapper;
35
use OCP\IDBConnection;
36
use OCP\Migration\IOutput;
37
use OCP\Migration\SimpleMigrationStep;
38
39
/**
40
 * Auto-generated migration step: Please modify to your needs!
41
 */
42
class Version0019Date20200603080001 extends SimpleMigrationStep {
43
44
45
	/** @var IDBConnection */
46
	private $connection;
47
48
49
	/**
50
	 * @param IDBConnection $connection
51
	 */
52
	public function __construct(IDBConnection $connection) {
53
		$this->connection = $connection;
54
	}
55
56
57
	/**
58
	 * @param IOutput $output
59
	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
60
	 * @param array $options
61
	 *
62
	 * @return null|ISchemaWrapper
63
	 * @throws SchemaException
64
	 */
65
	public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
66
		/** @var ISchemaWrapper $schema */
67
		$schema = $schemaClosure();
68
69
		if (!$schema->hasTable('circle_circles')) {
70
			$table = $schema->createTable('circle_circles');
71
			$table->addColumn(
72
				'id', 'integer', [
73
						'autoincrement' => true,
74
						'notnull'       => true,
75
						'length'        => 4,
76
						'unsigned'      => true,
77
					]
78
			);
79
			$table->addColumn(
80
				'unique_id', 'string', [
81
							   'notnull' => true,
82
							   'length'  => 15,
83
						   ]
84
			);
85
			$table->addColumn(
86
				'long_id', 'string', [
87
							 'notnull' => true,
88
							 'length'  => 64,
89
						 ]
90
			);
91
			$table->addColumn(
92
				'name', 'string', [
93
						  'notnull' => true,
94
						  'length'  => 127,
95
					  ]
96
			);
97
			$table->addColumn(
98
				'alt_name', 'string', [
99
							  'notnull' => false,
100
							  'length'  => 127,
101
							  'default' => ''
102
						  ]
103
			);
104
			$table->addColumn(
105
				'description', 'text', [
106
								 'notnull' => false
107
							 ]
108
			);
109
			$table->addColumn(
110
				'settings', 'text', [
111
							  'notnull' => false
112
						  ]
113
			);
114
			$table->addColumn(
115
				'type', 'smallint', [
116
						  'notnull' => true,
117
						  'length'  => 2,
118
					  ]
119
			);
120
			$table->addColumn(
121
				'creation', 'datetime', [
122
							  'notnull' => false,
123
						  ]
124
			);
125
			$table->addColumn(
126
				'contact_addressbook', 'integer', [
127
										 'notnull'  => false,
128
										 'unsigned' => true,
129
										 'length'   => 7,
130
									 ]
131
			);
132
			$table->addColumn(
133
				'contact_groupname', 'string', [
134
									   'notnull' => false,
135
									   'length'  => 127,
136
								   ]
137
			);
138
			$table->setPrimaryKey(['id']);
139
			$table->addUniqueIndex(['unique_id']);
140
			$table->addUniqueIndex(['long_id']);
141
			$table->addIndex(['type']);
142
		}
143
144
//
145
//		if (!$schema->hasTable('circle_clouds')) {
146
//			$table = $schema->createTable('circle_clouds');
147
//			$table->addColumn(
148
//				'cloud_id', 'string', [
149
//							  'notnull' => true,
150
//							  'length'  => 64,
151
//						  ]
152
//			);
153
//			$table->addColumn(
154
//				'address', 'string', [
155
//							 'notnull' => true,
156
//							 'length'  => 255,
157
//						 ]
158
//			);
159
//			$table->addColumn(
160
//				'status', 'smallint', [
161
//							'notnull' => true,
162
//							'length'  => 1,
163
//						]
164
//			);
165
//			$table->addColumn(
166
//				'note', 'text', [
167
//						  'notnull' => false
168
//					  ]
169
//			);
170
//			$table->addColumn(
171
//				'created', 'datetime', [
172
//							 'notnull' => false,
173
//						 ]
174
//			);
175
//			$table->setPrimaryKey(['cloud_id']);
176
//		}
177
178
179 View Code Duplication
		if (!$schema->hasTable('circle_groups')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
180
			$table = $schema->createTable('circle_groups');
181
			$table->addColumn(
182
				'circle_id', 'string', [
183
							   'notnull' => true,
184
							   'length'  => 15,
185
						   ]
186
			);
187
			$table->addColumn(
188
				'group_id', 'string', [
189
							  'notnull' => true,
190
							  'length'  => 64,
191
						  ]
192
			);
193
			$table->addColumn(
194
				'level', 'smallint', [
195
						   'notnull' => true,
196
						   'length'  => 1,
197
					   ]
198
			);
199
			$table->addColumn(
200
				'note', 'text', [
201
						  'notnull' => false
202
					  ]
203
			);
204
			$table->addColumn(
205
				'joined', 'datetime', [
206
							'notnull' => false,
207
						]
208
			);
209
			$table->setPrimaryKey(['circle_id', 'group_id']);
210
		}
211
212
213
		if (!$schema->hasTable('circle_gsevents')) {
214
			$table = $schema->createTable('circle_gsevents');
215
			$table->addColumn(
216
				'token', 'string', [
217
						   'notnull' => false,
218
						   'length'  => 63,
219
					   ]
220
			);
221
			$table->addColumn(
222
				'event', 'text', [
223
						   'notnull' => false
224
					   ]
225
			);
226
			$table->addColumn(
227
				'instance', 'string', [
228
							  'length'  => 255,
229
							  'notnull' => false
230
						  ]
231
			);
232
			$table->addColumn(
233
				'severity', 'integer', [
234
							  'length'  => 3,
235
							  'notnull' => false
236
						  ]
237
			);
238
			$table->addColumn(
239
				'status', 'integer', [
240
							'length'  => 3,
241
							'notnull' => false
242
						]
243
			);
244
			$table->addColumn(
245
				'creation', 'bigint', [
246
							  'length'  => 14,
247
							  'notnull' => false
248
						  ]
249
			);
250
			$table->addUniqueIndex(['token', 'instance']);
251
		}
252
253
254
		if (!$schema->hasTable('circle_gsshares')) {
255
			$table = $schema->createTable('circle_gsshares');
256
			$table->addColumn(
257
				'id', 'integer', [
258
						'notnull'       => false,
259
						'length'        => 11,
260
						'autoincrement' => true,
261
						'unsigned'      => true
262
					]
263
			);
264
			$table->addColumn(
265
				'circle_id', 'string', [
266
							   'length'  => 15,
267
							   'notnull' => false
268
						   ]
269
			);
270
			$table->addColumn(
271
				'owner', 'string', [
272
						   'length'  => 15,
273
						   'notnull' => false
274
					   ]
275
			);
276
			$table->addColumn(
277
				'instance', 'string', [
278
							  'length'  => 255,
279
							  'notnull' => false
280
						  ]
281
			);
282
			$table->addColumn(
283
				'token', 'string', [
284
						   'notnull' => false,
285
						   'length'  => 63
286
					   ]
287
			);
288
			$table->addColumn(
289
				'parent', 'integer', [
290
							'notnull' => false,
291
							'length'  => 11,
292
						]
293
			);
294
			$table->addColumn(
295
				'mountpoint', 'text', [
296
								'notnull' => false
297
							]
298
			);
299
			$table->addColumn(
300
				'mountpoint_hash', 'string', [
301
									 'length'  => 64,
302
									 'notnull' => false
303
								 ]
304
			);
305
			$table->setPrimaryKey(['id']);
306
			$table->addUniqueIndex(['circle_id', 'mountpoint_hash']);
307
		}
308
309
310 View Code Duplication
		if (!$schema->hasTable('circle_gsshares_mp')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
311
			$table = $schema->createTable('circle_gsshares_mp');
312
			$table->addColumn(
313
				'share_id', 'integer', [
314
							  'length'  => 11,
315
							  'notnull' => false
316
						  ]
317
			);
318
			$table->addColumn(
319
				'user_id', 'string', [
320
							 'length'  => 127,
321
							 'notnull' => false
322
						 ]
323
			);
324
			$table->addColumn(
325
				'mountpoint', 'text', [
326
								'notnull' => false
327
							]
328
			);
329
			$table->addColumn(
330
				'mountpoint_hash', 'string', [
331
									 'length'  => 64,
332
									 'notnull' => false
333
								 ]
334
			);
335
			$table->setPrimaryKey(['share_id', 'user_id']);
336
			$table->addUniqueIndex(['share_id', 'mountpoint_hash']);
337
		}
338
339
340
		if (!$schema->hasTable('circle_links')) {
341
			$table = $schema->createTable('circle_links');
342
			$table->addColumn(
343
				'id', 'smallint', [
344
						'autoincrement' => true,
345
						'notnull'       => true,
346
						'length'        => 3,
347
						'unsigned'      => true,
348
					]
349
			);
350
			$table->addColumn(
351
				'status', 'smallint', [
352
							'notnull' => true,
353
							'length'  => 1,
354
						]
355
			);
356
			$table->addColumn(
357
				'circle_id', 'string', [
358
							   'notnull' => true,
359
							   'length'  => 64,
360
						   ]
361
			);
362
			$table->addColumn(
363
				'unique_id', 'string', [
364
							   'notnull' => false,
365
							   'length'  => 64,
366
						   ]
367
			);
368
			$table->addColumn(
369
				'address', 'string', [
370
							 'notnull' => true,
371
							 'length'  => 128,
372
						 ]
373
			);
374
			$table->addColumn(
375
				'token', 'string', [
376
						   'notnull' => true,
377
						   'length'  => 64,
378
					   ]
379
			);
380
			$table->addColumn(
381
				'key', 'string', [
382
						 'notnull' => true,
383
						 'length'  => 64,
384
					 ]
385
			);
386
			$table->addColumn(
387
				'creation', 'datetime', [
388
							  'notnull' => false,
389
						  ]
390
			);
391
			$table->setPrimaryKey(['id']);
392
		}
393
394
395
		if (!$schema->hasTable('circle_members')) {
396
			$table = $schema->createTable('circle_members');
397
			$table->addColumn(
398
				'circle_id', 'string', [
399
							   'notnull' => true,
400
							   'length'  => 15,
401
						   ]
402
			);
403
			$table->addColumn(
404
				'member_id', 'string', [
405
							   'notnull' => false,
406
							   'length'  => 15,
407
						   ]
408
			);
409
			$table->addColumn(
410
				'contact_id', 'string', [
411
								'notnull' => false,
412
								'length'  => 127,
413
							]
414
			);
415
			$table->addColumn(
416
				'user_type', 'smallint', [
417
							   'notnull' => true,
418
							   'length'  => 1,
419
							   'default' => 1,
420
						   ]
421
			);
422
			$table->addColumn(
423
				'user_id', 'string', [
424
							 'notnull' => true,
425
							 'length'  => 127,
426
						 ]
427
			);
428
			$table->addColumn(
429
				'cached_name', 'string', [
430
								 'notnull' => false,
431
								 'length'  => 255,
432
								 'default' => ''
433
							 ]
434
			);
435
			$table->addColumn(
436
				'cached_update', 'datetime', [
437
								   'notnull' => false,
438
							   ]
439
			);
440
			$table->addColumn(
441
				'instance', 'string', [
442
							  'default' => '',
443
							  'length'  => 255
444
						  ]
445
			);
446
			$table->addColumn(
447
				'level', 'smallint', [
448
						   'notnull' => true,
449
						   'length'  => 1,
450
					   ]
451
			);
452
			$table->addColumn(
453
				'status', 'string', [
454
							'notnull' => false,
455
							'length'  => 15,
456
						]
457
			);
458
			$table->addColumn(
459
				'note', 'text', [
460
						  'notnull' => false
461
					  ]
462
			);
463
			$table->addColumn(
464
				'joined', 'datetime', [
465
							'notnull' => false,
466
						]
467
			);
468
			$table->addColumn(
469
				'contact_meta', 'text', [
470
								  'notnull' => false
471
							  ]
472
			);
473
			$table->addColumn(
474
				'contact_checked', 'integer', [
475
									 'notnull' => false,
476
									 'length'  => 1,
477
								 ]
478
			);
479
480
			$table->setPrimaryKey(['circle_id', 'user_id', 'user_type', 'contact_id', 'instance']);
481
		}
482
483
484
		if (!$schema->hasTable('circle_shares')) {
485
			$table = $schema->createTable('circle_shares');
486
			$table->addColumn(
487
				'id', 'integer', [
488
						'autoincrement' => true,
489
						'notnull'       => true,
490
						'length'        => 4,
491
						'unsigned'      => true,
492
					]
493
			);
494
			$table->addColumn(
495
				'unique_id', 'string', [
496
							   'notnull' => false,
497
							   'length'  => 32,
498
						   ]
499
			);
500
			$table->addColumn(
501
				'circle_id', 'string', [
502
							   'notnull' => true,
503
							   'length'  => 15,
504
						   ]
505
			);
506
			$table->addColumn(
507
				'source', 'string', [
508
							'notnull' => true,
509
							'length'  => 15,
510
						]
511
			);
512
			$table->addColumn(
513
				'type', 'string', [
514
						  'notnull' => true,
515
						  'length'  => 15,
516
					  ]
517
			);
518
			$table->addColumn(
519
				'author', 'string', [
520
							'notnull' => true,
521
							'length'  => 127,
522
						]
523
			);
524
			$table->addColumn(
525
				'cloud_id', 'string', [
526
							  'notnull' => false,
527
							  'length'  => 254,
528
							  'default' => 'null',
529
						  ]
530
			);
531
			$table->addColumn(
532
				'headers', 'text', [
533
							 'notnull' => false
534
						 ]
535
			);
536
			$table->addColumn(
537
				'payload', 'text', [
538
							 'notnull' => true
539
						 ]
540
			);
541
			$table->addColumn(
542
				'creation', 'datetime', [
543
							  'notnull' => false,
544
						  ]
545
			);
546
			$table->setPrimaryKey(['id']);
547
		}
548
549
550
		if (!$schema->hasTable('circle_tokens')) {
551
			$table = $schema->createTable('circle_tokens');
552
			$table->addColumn(
553
				'circle_id', 'string', [
554
							   'notnull' => true,
555
							   'length'  => 15,
556
						   ]
557
			);
558
			$table->addColumn(
559
				'member_id', 'string', [
560
							   'notnull' => false,
561
							   'length'  => 15,
562
						   ]
563
			);
564
			$table->addColumn(
565
				'user_id', 'string', [
566
							 'notnull' => true,
567
							 'length'  => 255,
568
						 ]
569
			);
570
			$table->addColumn(
571
				'share_id', 'bigint', [
572
							  'notnull' => true,
573
							  'length'  => 14,
574
						  ]
575
			);
576
			$table->addColumn(
577
				'token', 'string', [
578
						   'notnull' => true,
579
						   'length'  => 31,
580
					   ]
581
			);
582
			$table->addColumn(
583
				'password', 'string', [
584
							  'notnull' => true,
585
							  'length'  => 127,
586
						  ]
587
			);
588
			$table->addColumn(
589
				'accepted', 'integer', [
590
							  'notnull' => false,
591
							  'length'  => 1,
592
						  ]
593
			);
594
			$table->setPrimaryKey(['circle_id', 'user_id', 'share_id']);
595
		}
596
597
598
		return $schema;
599
	}
600
601
602
	/**
603
	 * @param IOutput $output
604
	 * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
605
	 * @param array $options
606
	 */
607
	public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
608
609
		/** @var ISchemaWrapper $schema */
610
		$schema = $schemaClosure();
611
612
		if ($schema->hasTable('circles_tokens')) {
613
			$this->copyTable('circles_tokens', 'circle_tokens');
614
		}
615
		if ($schema->hasTable('circles_circles')) {
616
			$this->copyTableCircles('circles_circles', 'circle_circles');
617
		}
618
//		if ($schema->hasTable('circles_clouds')) {
619
//			$this->copyTable('circles_clouds', 'circle_clouds');
620
//		}
621
		if ($schema->hasTable('circles_groups')) {
622
			$this->copyTable('circles_groups', 'circle_groups');
623
		}
624
		if ($schema->hasTable('circles_gsevents')) {
625
			$this->copyTable('circles_gsevents', 'circle_gsevents');
626
		}
627
		if ($schema->hasTable('circles_gsshares')) {
628
			$this->copyTable('circles_gsshares', 'circle_gsshares');
629
		}
630
		if ($schema->hasTable('circles_gsshares_mp')) {
631
			$this->copyTable('circles_gsshares_mp', 'circle_gsshares_mp');
632
		}
633
		if ($schema->hasTable('circles_links')) {
634
			$this->copyTable('circles_links', 'circle_links');
635
		}
636
		if ($schema->hasTable('circles_members')) {
637
			$this->copyTable('circles_members', 'circle_members', ['instance' => '', 'contact_id' => '']);
638
		}
639
		if ($schema->hasTable('circles_shares')) {
640
			$this->copyTable('circles_shares', 'circle_shares');
641
		}
642
643
		$this->updateMemberId();
644
		$this->updateTokens();
645
	}
646
647
648
	/**
649
	 * @param $orig
650
	 * @param $dest
651
	 * @param array $default
652
	 */
653
	protected function copyTable($orig, $dest, array $default = []) {
654
		$qb = $this->connection->getQueryBuilder();
655
656
		$qb->select('*')
657
		   ->from($orig);
658
659
		$result = $qb->execute();
660
		while ($row = $result->fetch()) {
661
			$copy = $this->connection->getQueryBuilder();
662
			$copy->insert($dest);
663
			$ak = array_keys($row);
664
			foreach ($ak as $k) {
665
				if ($row[$k] !== null) {
666
					$copy->setValue($k, $copy->createNamedParameter($row[$k]));
667
				} elseif (array_key_exists($k, $default)) {
668
					$copy->setValue($k, $copy->createNamedParameter($default[$k]));
669
				}
670
			}
671
672
			$ak = array_keys($default);
673
			foreach ($ak as $k) {
674
				if (!array_key_exists($k, $row)) {
675
					$copy->setValue($k, $copy->createNamedParameter($default[$k]));
676
				}
677
			}
678
679
			$copy->execute();
680
		}
681
	}
682
683
684
	/**
685
	 * @param $orig
686
	 * @param $dest
687
	 */
688
	protected function copyTableCircles($orig, $dest) {
689
		$qb = $this->connection->getQueryBuilder();
690
691
		$qb->select('*')
692
		   ->from($orig);
693
694
		$result = $qb->execute();
695
		while ($row = $result->fetch()) {
696
			$copy = $this->connection->getQueryBuilder();
697
			$copy->insert($dest);
698
			$ak = array_keys($row);
699
			foreach ($ak as $k) {
700
				$v = $row[$k];
701
				if ($k === 'unique_id') {
702
					$copy->setValue('unique_id', $copy->createNamedParameter(substr($v, 0, 14)));
703
					$copy->setValue('long_id', $copy->createNamedParameter($v));
704
				} else if ($v !== null) {
705
					$copy->setValue($k, $copy->createNamedParameter($v));
706
				}
707
			}
708
709
			$copy->execute();
710
		}
711
	}
712
713
714
	/**
715
	 *
716
	 */
717
	private function updateMemberId() {
718
		$qb = $this->connection->getQueryBuilder();
719
		$expr = $qb->expr();
720
721
		$orX = $expr->orX();
722
		$orX->add($expr->eq('member_id', $qb->createNamedParameter('')));
723
		$orX->add($expr->isNull('member_id'));
724
725
		$qb->select('circle_id', 'user_id', 'user_type', 'instance')
726
		   ->from('circle_members')
727
		   ->where($orX);
728
729
		$result = $qb->execute();
730
		while ($row = $result->fetch()) {
731
			$uniqueId = substr(bin2hex(openssl_random_pseudo_bytes(24)), 0, 15);
732
733
			$update = $this->connection->getQueryBuilder();
734
			$expru = $update->expr();
735
			$update->update('circle_members')
736
				   ->set('member_id', $update->createNamedParameter($uniqueId))
737
				   ->where($expru->eq('circle_id', $update->createNamedParameter($row['circle_id'])))
738
				   ->andWhere($expru->eq('user_id', $update->createNamedParameter($row['user_id'])))
739
				   ->andWhere($expru->eq('user_type', $update->createNamedParameter($row['user_type'])))
740
				   ->andWhere($expru->eq('instance', $update->createNamedParameter($row['instance'])));
741
742
			$update->execute();
743
		}
744
	}
745
746
747
	/**
748
	 *
749
	 */
750
	private function updateTokens() {
751
		$qb = $this->connection->getQueryBuilder();
752
		$expr = $qb->expr();
753
		$orX = $expr->orX();
754
		$orX->add($expr->eq('member_id', $qb->createNamedParameter('')));
755
		$orX->add($expr->isNull('member_id'));
756
		$qb->select('user_id', 'circle_id')
757
		   ->from('circle_tokens')
758
		   ->where($orX);
759
760
		$result = $qb->execute();
761
		while ($row = $result->fetch()) {
762
			$qbm = $this->connection->getQueryBuilder();
763
			$exprm = $qbm->expr();
764
765
			$qbm->select('member_id')
766
				->from('circle_members')
767
				->where($exprm->eq('circle_id', $qbm->createNamedParameter($row['circle_id'])))
768
				->andWhere($exprm->eq('user_id', $qbm->createNamedParameter($row['user_id'])))
769
				->andWhere($exprm->neq('user_type', $qbm->createNamedParameter('1')));
770
771
			$resultm = $qbm->execute();
772
			$member = $resultm->fetch();
773
774
			$update = $this->connection->getQueryBuilder();
775
			$expru = $update->expr();
776
			$update->update('circle_tokens')
777
				   ->set('member_id', $update->createNamedParameter($member['member_id']))
778
				   ->where($expru->eq('circle_id', $update->createNamedParameter($row['circle_id'])))
779
				   ->andWhere($expru->eq('user_id', $update->createNamedParameter($row['user_id'])));
780
781
			$update->execute();
782
		}
783
	}
784
785
786
}
787