Completed
Push — master ( 8d751f...68c4fc )
by Lukas
30:11 queued 29:33
created
core/Migrations/Version13000Date20170718121200.php 1 patch
Indentation   +884 added lines, -884 removed lines patch added patch discarded remove patch
@@ -10,888 +10,888 @@
 block discarded – undo
10 10
  */
11 11
 class Version13000Date20170718121200 extends SimpleMigrationStep {
12 12
 
13
-	/**
14
-	 * @param IOutput $output
15
-	 * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
16
-	 * @param array $options
17
-	 * @since 13.0.0
18
-	 */
19
-	public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
20
-	}
21
-
22
-	/**
23
-	 * @param IOutput $output
24
-	 * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
25
-	 * @param array $options
26
-	 * @return null|Schema
27
-	 * @since 13.0.0
28
-	 */
29
-	public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
30
-		/** @var Schema $schema */
31
-		$schema = $schemaClosure();
32
-
33
-		if (!$schema->hasTable('appconfig')) {
34
-			$table = $schema->createTable('appconfig');
35
-			$table->addColumn('appid', 'string', [
36
-				'notnull' => true,
37
-				'length' => 32,
38
-				'default' => '',
39
-			]);
40
-			$table->addColumn('configkey', 'string', [
41
-				'notnull' => true,
42
-				'length' => 64,
43
-				'default' => '',
44
-			]);
45
-			$table->addColumn('configvalue', 'text', [
46
-				'notnull' => false,
47
-			]);
48
-			$table->setPrimaryKey(['appid', 'configkey']);
49
-			$table->addIndex(['configkey'], 'appconfig_config_key_index');
50
-			$table->addIndex(['appid'], 'appconfig_appid_key');
51
-		}
52
-
53
-		if (!$schema->hasTable('storages')) {
54
-			$table = $schema->createTable('storages');
55
-			$table->addColumn('id', 'string', [
56
-				'notnull' => false,
57
-				'length' => 64,
58
-			]);
59
-			$table->addColumn('numeric_id', 'integer', [
60
-				'autoincrement' => true,
61
-				'notnull' => true,
62
-				'length' => 4,
63
-			]);
64
-			$table->addColumn('available', 'integer', [
65
-				'notnull' => true,
66
-				'default' => 1,
67
-			]);
68
-			$table->addColumn('last_checked', 'integer', [
69
-				'notnull' => false,
70
-			]);
71
-			$table->setPrimaryKey(['numeric_id']);
72
-			$table->addUniqueIndex(['id'], 'storages_id_index');
73
-		}
74
-
75
-		if (!$schema->hasTable('mounts')) {
76
-			$table = $schema->createTable('mounts');
77
-			$table->addColumn('id', 'integer', [
78
-				'autoincrement' => true,
79
-				'notnull' => true,
80
-				'length' => 4,
81
-			]);
82
-			$table->addColumn('storage_id', 'integer', [
83
-				'notnull' => true,
84
-			]);
85
-			$table->addColumn('root_id', 'integer', [
86
-				'notnull' => true,
87
-			]);
88
-			$table->addColumn('user_id', 'string', [
89
-				'notnull' => true,
90
-				'length' => 64,
91
-			]);
92
-			$table->addColumn('mount_point', 'string', [
93
-				'notnull' => true,
94
-				'length' => 4000,
95
-			]);
96
-			$table->addColumn('mount_id', 'integer', [
97
-				'notnull' => false,
98
-			]);
99
-			$table->setPrimaryKey(['id']);
100
-			$table->addIndex(['user_id'], 'mounts_user_index');
101
-			$table->addIndex(['storage_id'], 'mounts_storage_index');
102
-			$table->addIndex(['root_id'], 'mounts_root_index');
103
-			$table->addIndex(['mount_id'], 'mounts_mount_id_index');
104
-			$table->addUniqueIndex(['user_id', 'root_id'], 'mounts_user_root_index');
105
-		}
106
-
107
-		if (!$schema->hasTable('mimetypes')) {
108
-			$table = $schema->createTable('mimetypes');
109
-			$table->addColumn('id', 'integer', [
110
-				'autoincrement' => true,
111
-				'notnull' => true,
112
-				'length' => 4,
113
-			]);
114
-			$table->addColumn('mimetype', 'string', [
115
-				'notnull' => true,
116
-				'length' => 255,
117
-				'default' => '',
118
-			]);
119
-			$table->setPrimaryKey(['id']);
120
-			$table->addUniqueIndex(['mimetype'], 'mimetype_id_index');
121
-		}
122
-
123
-		if (!$schema->hasTable('filecache')) {
124
-			$table = $schema->createTable('filecache');
125
-			$table->addColumn('fileid', 'integer', [
126
-				'autoincrement' => true,
127
-				'notnull' => true,
128
-				'length' => 4,
129
-			]);
130
-			$table->addColumn('storage', 'integer', [
131
-				'notnull' => true,
132
-				'length' => 4,
133
-				'default' => 0,
134
-			]);
135
-			$table->addColumn('path', 'string', [
136
-				'notnull' => false,
137
-				'length' => 4000,
138
-			]);
139
-			$table->addColumn('path_hash', 'string', [
140
-				'notnull' => true,
141
-				'length' => 32,
142
-				'default' => '',
143
-			]);
144
-			$table->addColumn('parent', 'integer', [
145
-				'notnull' => true,
146
-				'length' => 4,
147
-				'default' => 0,
148
-			]);
149
-			$table->addColumn('name', 'string', [
150
-				'notnull' => false,
151
-				'length' => 250,
152
-			]);
153
-			$table->addColumn('mimetype', 'integer', [
154
-				'notnull' => true,
155
-				'length' => 4,
156
-				'default' => 0,
157
-			]);
158
-			$table->addColumn('mimepart', 'integer', [
159
-				'notnull' => true,
160
-				'length' => 4,
161
-				'default' => 0,
162
-			]);
163
-			$table->addColumn('size', 'bigint', [
164
-				'notnull' => true,
165
-				'length' => 8,
166
-				'default' => 0,
167
-			]);
168
-			$table->addColumn('mtime', 'integer', [
169
-				'notnull' => true,
170
-				'length' => 4,
171
-				'default' => 0,
172
-			]);
173
-			$table->addColumn('storage_mtime', 'integer', [
174
-				'notnull' => true,
175
-				'length' => 4,
176
-				'default' => 0,
177
-			]);
178
-			$table->addColumn('encrypted', 'integer', [
179
-				'notnull' => true,
180
-				'length' => 4,
181
-				'default' => 0,
182
-			]);
183
-			$table->addColumn('unencrypted_size', 'bigint', [
184
-				'notnull' => true,
185
-				'length' => 8,
186
-				'default' => 0,
187
-			]);
188
-			$table->addColumn('etag', 'string', [
189
-				'notnull' => false,
190
-				'length' => 40,
191
-			]);
192
-			$table->addColumn('permissions', 'integer', [
193
-				'notnull' => false,
194
-				'length' => 4,
195
-				'default' => 0,
196
-			]);
197
-			$table->addColumn('checksum', 'string', [
198
-				'notnull' => false,
199
-				'length' => 255,
200
-			]);
201
-			$table->setPrimaryKey(['fileid']);
202
-			$table->addUniqueIndex(['storage', 'path_hash'], 'fs_storage_path_hash');
203
-			$table->addIndex(['parent', 'name'], 'fs_parent_name_hash');
204
-			$table->addIndex(['storage', 'mimetype'], 'fs_storage_mimetype');
205
-			$table->addIndex(['storage', 'mimepart'], 'fs_storage_mimepart');
206
-			$table->addIndex(['storage', 'size', 'fileid'], 'fs_storage_size');
207
-		}
208
-
209
-		if (!$schema->hasTable('group_user')) {
210
-			$table = $schema->createTable('group_user');
211
-			$table->addColumn('gid', 'string', [
212
-				'notnull' => true,
213
-				'length' => 64,
214
-				'default' => '',
215
-			]);
216
-			$table->addColumn('uid', 'string', [
217
-				'notnull' => true,
218
-				'length' => 64,
219
-				'default' => '',
220
-			]);
221
-			$table->setPrimaryKey(['gid', 'uid']);
222
-			$table->addIndex(['uid'], 'gu_uid_index');
223
-		}
224
-
225
-		if (!$schema->hasTable('group_admin')) {
226
-			$table = $schema->createTable('group_admin');
227
-			$table->addColumn('gid', 'string', [
228
-				'notnull' => true,
229
-				'length' => 64,
230
-				'default' => '',
231
-			]);
232
-			$table->addColumn('uid', 'string', [
233
-				'notnull' => true,
234
-				'length' => 64,
235
-				'default' => '',
236
-			]);
237
-			$table->setPrimaryKey(['gid', 'uid']);
238
-			$table->addIndex(['uid'], 'group_admin_uid');
239
-		}
240
-
241
-		if (!$schema->hasTable('groups')) {
242
-			$table = $schema->createTable('groups');
243
-			$table->addColumn('gid', 'string', [
244
-				'notnull' => true,
245
-				'length' => 64,
246
-				'default' => '',
247
-			]);
248
-			$table->setPrimaryKey(['gid']);
249
-		}
250
-
251
-		if (!$schema->hasTable('preferences')) {
252
-			$table = $schema->createTable('preferences');
253
-			$table->addColumn('userid', 'string', [
254
-				'notnull' => true,
255
-				'length' => 64,
256
-				'default' => '',
257
-			]);
258
-			$table->addColumn('appid', 'string', [
259
-				'notnull' => true,
260
-				'length' => 32,
261
-				'default' => '',
262
-			]);
263
-			$table->addColumn('configkey', 'string', [
264
-				'notnull' => true,
265
-				'length' => 64,
266
-				'default' => '',
267
-			]);
268
-			$table->addColumn('configvalue', 'text', [
269
-				'notnull' => false,
270
-			]);
271
-			$table->setPrimaryKey(['userid', 'appid', 'configkey']);
272
-		}
273
-
274
-		if (!$schema->hasTable('properties')) {
275
-			$table = $schema->createTable('properties');
276
-			$table->addColumn('id', 'integer', [
277
-				'autoincrement' => true,
278
-				'notnull' => true,
279
-				'length' => 4,
280
-			]);
281
-			$table->addColumn('userid', 'string', [
282
-				'notnull' => true,
283
-				'length' => 64,
284
-				'default' => '',
285
-			]);
286
-			$table->addColumn('propertypath', 'string', [
287
-				'notnull' => true,
288
-				'length' => 255,
289
-				'default' => '',
290
-			]);
291
-			$table->addColumn('propertyname', 'string', [
292
-				'notnull' => true,
293
-				'length' => 255,
294
-				'default' => '',
295
-			]);
296
-			$table->addColumn('propertyvalue', 'text', [
297
-				'notnull' => true,
298
-			]);
299
-			$table->setPrimaryKey(['id']);
300
-			$table->addIndex(['userid'], 'property_index');
301
-		}
302
-
303
-		if (!$schema->hasTable('share')) {
304
-			$table = $schema->createTable('share');
305
-			$table->addColumn('id', 'integer', [
306
-				'autoincrement' => true,
307
-				'notnull' => true,
308
-				'length' => 4,
309
-			]);
310
-			$table->addColumn('share_type', 'smallint', [
311
-				'notnull' => true,
312
-				'length' => 1,
313
-				'default' => 0,
314
-			]);
315
-			$table->addColumn('share_with', 'string', [
316
-				'notnull' => false,
317
-				'length' => 255,
318
-			]);
319
-			$table->addColumn('password', 'string', [
320
-				'notnull' => false,
321
-				'length' => 255,
322
-			]);
323
-			$table->addColumn('uid_owner', 'string', [
324
-				'notnull' => true,
325
-				'length' => 64,
326
-				'default' => '',
327
-			]);
328
-			$table->addColumn('uid_initiator', 'string', [
329
-				'notnull' => false,
330
-				'length' => 64,
331
-			]);
332
-			$table->addColumn('parent', 'integer', [
333
-				'notnull' => false,
334
-				'length' => 4,
335
-			]);
336
-			$table->addColumn('item_type', 'string', [
337
-				'notnull' => true,
338
-				'length' => 64,
339
-				'default' => '',
340
-			]);
341
-			$table->addColumn('item_source', 'string', [
342
-				'notnull' => false,
343
-				'length' => 255,
344
-			]);
345
-			$table->addColumn('item_target', 'string', [
346
-				'notnull' => false,
347
-				'length' => 255,
348
-			]);
349
-			$table->addColumn('file_source', 'integer', [
350
-				'notnull' => false,
351
-				'length' => 4,
352
-			]);
353
-			$table->addColumn('file_target', 'string', [
354
-				'notnull' => false,
355
-				'length' => 512,
356
-			]);
357
-			$table->addColumn('permissions', 'smallint', [
358
-				'notnull' => true,
359
-				'length' => 1,
360
-				'default' => 0,
361
-			]);
362
-			$table->addColumn('stime', 'bigint', [
363
-				'notnull' => true,
364
-				'length' => 8,
365
-				'default' => 0,
366
-			]);
367
-			$table->addColumn('accepted', 'smallint', [
368
-				'notnull' => true,
369
-				'length' => 1,
370
-				'default' => 0,
371
-			]);
372
-			$table->addColumn('expiration', 'datetime', [
373
-				'notnull' => false,
374
-			]);
375
-			$table->addColumn('token', 'string', [
376
-				'notnull' => false,
377
-				'length' => 32,
378
-			]);
379
-			$table->addColumn('mail_send', 'smallint', [
380
-				'notnull' => true,
381
-				'length' => 1,
382
-				'default' => 0,
383
-			]);
384
-			$table->addColumn('share_name', 'string', [
385
-				'notnull' => false,
386
-				'length' => 64,
387
-			]);
388
-			$table->setPrimaryKey(['id']);
389
-			$table->addIndex(['item_type', 'share_type'], 'item_share_type_index');
390
-			$table->addIndex(['file_source'], 'file_source_index');
391
-			$table->addIndex(['token'], 'token_index');
392
-		}
393
-
394
-		if (!$schema->hasTable('jobs')) {
395
-			$table = $schema->createTable('jobs');
396
-			$table->addColumn('id', 'integer', [
397
-				'autoincrement' => true,
398
-				'notnull' => true,
399
-				'length' => 4,
400
-			]);
401
-			$table->addColumn('class', 'string', [
402
-				'notnull' => true,
403
-				'length' => 255,
404
-				'default' => '',
405
-			]);
406
-			$table->addColumn('argument', 'string', [
407
-				'notnull' => true,
408
-				'length' => 4000,
409
-				'default' => '',
410
-			]);
411
-			$table->addColumn('last_run', 'integer', [
412
-				'notnull' => false,
413
-				'default' => 0,
414
-			]);
415
-			$table->addColumn('last_checked', 'integer', [
416
-				'notnull' => false,
417
-				'default' => 0,
418
-			]);
419
-			$table->addColumn('reserved_at', 'integer', [
420
-				'notnull' => false,
421
-				'default' => 0,
422
-			]);
423
-			$table->addColumn('execution_duration', 'integer', [
424
-				'notnull' => true,
425
-				'default' => 0,
426
-			]);
427
-			$table->setPrimaryKey(['id']);
428
-			$table->addIndex(['class'], 'job_class_index');
429
-		}
430
-
431
-		if (!$schema->hasTable('users')) {
432
-			$table = $schema->createTable('users');
433
-			$table->addColumn('uid', 'string', [
434
-				'notnull' => true,
435
-				'length' => 64,
436
-				'default' => '',
437
-			]);
438
-			$table->addColumn('displayname', 'string', [
439
-				'notnull' => false,
440
-				'length' => 64,
441
-			]);
442
-			$table->addColumn('password', 'string', [
443
-				'notnull' => true,
444
-				'length' => 255,
445
-				'default' => '',
446
-			]);
447
-			$table->setPrimaryKey(['uid']);
448
-		}
449
-
450
-		if (!$schema->hasTable('authtoken')) {
451
-			$table = $schema->createTable('authtoken');
452
-			$table->addColumn('id', 'integer', [
453
-				'autoincrement' => true,
454
-				'notnull' => true,
455
-				'length' => 4,
456
-			]);
457
-			$table->addColumn('uid', 'string', [
458
-				'notnull' => true,
459
-				'length' => 64,
460
-				'default' => '',
461
-			]);
462
-			$table->addColumn('login_name', 'string', [
463
-				'notnull' => true,
464
-				'length' => 64,
465
-				'default' => '',
466
-			]);
467
-			$table->addColumn('password', 'text', [
468
-				'notnull' => false,
469
-			]);
470
-			$table->addColumn('name', 'text', [
471
-				'notnull' => true,
472
-				'default' => '',
473
-			]);
474
-			$table->addColumn('token', 'string', [
475
-				'notnull' => true,
476
-				'length' => 200,
477
-				'default' => '',
478
-			]);
479
-			$table->addColumn('type', 'smallint', [
480
-				'notnull' => true,
481
-				'length' => 2,
482
-				'default' => 0,
483
-			]);
484
-			$table->addColumn('remember', 'smallint', [
485
-				'notnull' => true,
486
-				'length' => 1,
487
-				'default' => 0,
488
-			]);
489
-			$table->addColumn('last_activity', 'integer', [
490
-				'notnull' => true,
491
-				'length' => 4,
492
-				'default' => 0,
493
-			]);
494
-			$table->addColumn('last_check', 'integer', [
495
-				'notnull' => true,
496
-				'length' => 4,
497
-				'default' => 0,
498
-			]);
499
-			$table->addColumn('scope', 'text', [
500
-				'notnull' => false,
501
-			]);
502
-			$table->setPrimaryKey(['id']);
503
-			$table->addUniqueIndex(['token'], 'authtoken_token_index');
504
-			$table->addIndex(['last_activity'], 'authtoken_last_activity_index');
505
-		}
506
-
507
-		if (!$schema->hasTable('bruteforce_attempts')) {
508
-			$table = $schema->createTable('bruteforce_attempts');
509
-			$table->addColumn('id', 'integer', [
510
-				'autoincrement' => true,
511
-				'notnull' => true,
512
-				'length' => 4,
513
-			]);
514
-			$table->addColumn('action', 'string', [
515
-				'notnull' => true,
516
-				'length' => 64,
517
-				'default' => '',
518
-			]);
519
-			$table->addColumn('occurred', 'integer', [
520
-				'notnull' => true,
521
-				'length' => 4,
522
-				'default' => 0,
523
-			]);
524
-			$table->addColumn('ip', 'string', [
525
-				'notnull' => true,
526
-				'length' => 255,
527
-				'default' => '',
528
-			]);
529
-			$table->addColumn('subnet', 'string', [
530
-				'notnull' => true,
531
-				'length' => 255,
532
-				'default' => '',
533
-			]);
534
-			$table->addColumn('metadata', 'string', [
535
-				'notnull' => true,
536
-				'length' => 255,
537
-				'default' => '',
538
-			]);
539
-			$table->setPrimaryKey(['id']);
540
-			$table->addIndex(['ip'], 'bruteforce_attempts_ip');
541
-			$table->addIndex(['subnet'], 'bruteforce_attempts_subnet');
542
-		}
543
-
544
-		if (!$schema->hasTable('vcategory')) {
545
-			$table = $schema->createTable('vcategory');
546
-			$table->addColumn('id', 'integer', [
547
-				'autoincrement' => true,
548
-				'notnull' => true,
549
-				'length' => 4,
550
-			]);
551
-			$table->addColumn('uid', 'string', [
552
-				'notnull' => true,
553
-				'length' => 64,
554
-				'default' => '',
555
-			]);
556
-			$table->addColumn('type', 'string', [
557
-				'notnull' => true,
558
-				'length' => 64,
559
-				'default' => '',
560
-			]);
561
-			$table->addColumn('category', 'string', [
562
-				'notnull' => true,
563
-				'length' => 255,
564
-				'default' => '',
565
-			]);
566
-			$table->setPrimaryKey(['id']);
567
-			$table->addIndex(['uid'], 'uid_index');
568
-			$table->addIndex(['type'], 'type_index');
569
-			$table->addIndex(['category'], 'category_index');
570
-		}
571
-
572
-		if (!$schema->hasTable('vcategory_to_object')) {
573
-			$table = $schema->createTable('vcategory_to_object');
574
-			$table->addColumn('objid', 'integer', [
575
-				'notnull' => true,
576
-				'length' => 4,
577
-				'default' => 0,
578
-			]);
579
-			$table->addColumn('categoryid', 'integer', [
580
-				'notnull' => true,
581
-				'length' => 4,
582
-				'default' => 0,
583
-			]);
584
-			$table->addColumn('type', 'string', [
585
-				'notnull' => true,
586
-				'length' => 64,
587
-				'default' => '',
588
-			]);
589
-			$table->setPrimaryKey(['categoryid', 'objid', 'type']);
590
-			$table->addIndex(['objid', 'type'], 'vcategory_objectd_index');
591
-		}
592
-
593
-		if (!$schema->hasTable('systemtag')) {
594
-			$table = $schema->createTable('systemtag');
595
-			$table->addColumn('id', 'integer', [
596
-				'autoincrement' => true,
597
-				'notnull' => true,
598
-				'length' => 4,
599
-			]);
600
-			$table->addColumn('name', 'string', [
601
-				'notnull' => true,
602
-				'length' => 64,
603
-				'default' => '',
604
-			]);
605
-			$table->addColumn('visibility', 'smallint', [
606
-				'notnull' => true,
607
-				'length' => 1,
608
-				'default' => 1,
609
-			]);
610
-			$table->addColumn('editable', 'smallint', [
611
-				'notnull' => true,
612
-				'length' => 1,
613
-				'default' => 1,
614
-			]);
615
-			$table->setPrimaryKey(['id']);
616
-			$table->addUniqueIndex(['name', 'visibility', 'editable'], 'tag_ident');
617
-		}
618
-
619
-		if (!$schema->hasTable('systemtag_object_mapping')) {
620
-			$table = $schema->createTable('systemtag_object_mapping');
621
-			$table->addColumn('objectid', 'string', [
622
-				'notnull' => true,
623
-				'length' => 64,
624
-				'default' => '',
625
-			]);
626
-			$table->addColumn('objecttype', 'string', [
627
-				'notnull' => true,
628
-				'length' => 64,
629
-				'default' => '',
630
-			]);
631
-			$table->addColumn('systemtagid', 'integer', [
632
-				'notnull' => true,
633
-				'length' => 4,
634
-				'default' => 0,
635
-			]);
636
-			$table->addUniqueIndex(['objecttype', 'objectid', 'systemtagid'], 'mapping');
637
-		}
638
-
639
-		if (!$schema->hasTable('systemtag_group')) {
640
-			$table = $schema->createTable('systemtag_group');
641
-			$table->addColumn('systemtagid', 'integer', [
642
-				'notnull' => true,
643
-				'length' => 4,
644
-				'default' => 0,
645
-			]);
646
-			$table->addColumn('gid', 'string', [
647
-				'notnull' => true,
648
-			]);
649
-			$table->setPrimaryKey(['gid', 'systemtagid']);
650
-		}
651
-
652
-		if (!$schema->hasTable('file_locks')) {
653
-			$table = $schema->createTable('file_locks');
654
-			$table->addColumn('id', 'integer', [
655
-				'autoincrement' => true,
656
-				'notnull' => true,
657
-				'length' => 4,
658
-			]);
659
-			$table->addColumn('lock', 'integer', [
660
-				'notnull' => true,
661
-				'length' => 4,
662
-				'default' => 0,
663
-			]);
664
-			$table->addColumn('key', 'string', [
665
-				'notnull' => true,
666
-				'length' => 64,
667
-			]);
668
-			$table->addColumn('ttl', 'integer', [
669
-				'notnull' => true,
670
-				'length' => 4,
671
-				'default' => -1,
672
-			]);
673
-			$table->setPrimaryKey(['id']);
674
-			$table->addUniqueIndex(['key'], 'lock_key_index');
675
-			$table->addIndex(['ttl'], 'lock_ttl_index');
676
-		}
677
-
678
-		if (!$schema->hasTable('comments')) {
679
-			$table = $schema->createTable('comments');
680
-			$table->addColumn('id', 'integer', [
681
-				'autoincrement' => true,
682
-				'notnull' => true,
683
-				'length' => 4,
684
-			]);
685
-			$table->addColumn('parent_id', 'integer', [
686
-				'notnull' => true,
687
-				'length' => 4,
688
-				'default' => 0,
689
-			]);
690
-			$table->addColumn('topmost_parent_id', 'integer', [
691
-				'notnull' => true,
692
-				'length' => 4,
693
-				'default' => 0,
694
-			]);
695
-			$table->addColumn('children_count', 'integer', [
696
-				'notnull' => true,
697
-				'length' => 4,
698
-				'default' => 0,
699
-			]);
700
-			$table->addColumn('actor_type', 'string', [
701
-				'notnull' => true,
702
-				'length' => 64,
703
-				'default' => '',
704
-			]);
705
-			$table->addColumn('actor_id', 'string', [
706
-				'notnull' => true,
707
-				'length' => 64,
708
-				'default' => '',
709
-			]);
710
-			$table->addColumn('message', 'text', [
711
-				'notnull' => false,
712
-			]);
713
-			$table->addColumn('verb', 'string', [
714
-				'notnull' => false,
715
-				'length' => 64,
716
-			]);
717
-			$table->addColumn('creation_timestamp', 'datetime', [
718
-				'notnull' => false,
719
-			]);
720
-			$table->addColumn('latest_child_timestamp', 'datetime', [
721
-				'notnull' => false,
722
-			]);
723
-			$table->addColumn('object_type', 'string', [
724
-				'notnull' => true,
725
-				'length' => 64,
726
-				'default' => '',
727
-			]);
728
-			$table->addColumn('object_id', 'string', [
729
-				'notnull' => true,
730
-				'length' => 64,
731
-				'default' => '',
732
-			]);
733
-			$table->setPrimaryKey(['id']);
734
-			$table->addIndex(['parent_id'], 'comments_parent_id_index');
735
-			$table->addIndex(['topmost_parent_id'], 'comments_topmost_parent_id_idx');
736
-			$table->addIndex(['object_type', 'object_id', 'creation_timestamp'], 'comments_object_index');
737
-			$table->addIndex(['actor_type', 'actor_id'], 'comments_actor_index');
738
-		}
739
-
740
-		if (!$schema->hasTable('comments_read_markers')) {
741
-			$table = $schema->createTable('comments_read_markers');
742
-			$table->addColumn('user_id', 'string', [
743
-				'notnull' => true,
744
-				'length' => 64,
745
-				'default' => '',
746
-			]);
747
-			$table->addColumn('marker_datetime', 'datetime', [
748
-				'notnull' => false,
749
-			]);
750
-			$table->addColumn('object_type', 'string', [
751
-				'notnull' => true,
752
-				'length' => 64,
753
-				'default' => '',
754
-			]);
755
-			$table->addColumn('object_id', 'string', [
756
-				'notnull' => true,
757
-				'length' => 64,
758
-				'default' => '',
759
-			]);
760
-			$table->addIndex(['object_type', 'object_id'], 'comments_marker_object_index');
761
-			$table->addUniqueIndex(['user_id', 'object_type', 'object_id'], 'comments_marker_index');
762
-		}
763
-
764
-		if (!$schema->hasTable('credentials')) {
765
-			$table = $schema->createTable('credentials');
766
-			$table->addColumn('user', 'string', [
767
-				'notnull' => true,
768
-				'length' => 64,
769
-			]);
770
-			$table->addColumn('identifier', 'string', [
771
-				'notnull' => true,
772
-				'length' => 64,
773
-			]);
774
-			$table->addColumn('credentials', 'text', [
775
-				'notnull' => false,
776
-			]);
777
-			$table->setPrimaryKey(['user', 'identifier']);
778
-			$table->addIndex(['user'], 'credentials_user');
779
-		}
780
-
781
-		if (!$schema->hasTable('admin_sections')) {
782
-			$table = $schema->createTable('admin_sections');
783
-			$table->addColumn('id', 'string', [
784
-				'notnull' => true,
785
-				'length' => 64,
786
-			]);
787
-			$table->addColumn('class', 'string', [
788
-				'notnull' => true,
789
-				'length' => 255,
790
-				'default' => '',
791
-			]);
792
-			$table->addColumn('priority', 'smallint', [
793
-				'notnull' => true,
794
-				'length' => 1,
795
-				'default' => 0,
796
-			]);
797
-			$table->setPrimaryKey(['id']);
798
-			$table->addUniqueIndex(['class'], 'admin_sections_class');
799
-		}
800
-
801
-		if (!$schema->hasTable('admin_settings')) {
802
-			$table = $schema->createTable('admin_settings');
803
-			$table->addColumn('id', 'integer', [
804
-				'autoincrement' => true,
805
-				'notnull' => true,
806
-				'length' => 4,
807
-			]);
808
-			$table->addColumn('class', 'string', [
809
-				'notnull' => true,
810
-				'length' => 255,
811
-				'default' => '',
812
-			]);
813
-			$table->addColumn('section', 'string', [
814
-				'notnull' => false,
815
-				'length' => 64,
816
-			]);
817
-			$table->addColumn('priority', 'smallint', [
818
-				'notnull' => true,
819
-				'length' => 1,
820
-				'default' => 0,
821
-			]);
822
-			$table->setPrimaryKey(['id']);
823
-			$table->addUniqueIndex(['class'], 'admin_settings_class');
824
-			$table->addIndex(['section'], 'admin_settings_section');
825
-		}
826
-
827
-		if (!$schema->hasTable('personal_sections')) {
828
-			$table = $schema->createTable('personal_sections');
829
-			$table->addColumn('id', 'string', [
830
-				'notnull' => true,
831
-				'length' => 64,
832
-			]);
833
-			$table->addColumn('class', 'string', [
834
-				'notnull' => true,
835
-				'length' => 255,
836
-				'default' => '',
837
-			]);
838
-			$table->addColumn('priority', 'smallint', [
839
-				'notnull' => true,
840
-				'length' => 1,
841
-				'default' => 0,
842
-			]);
843
-			$table->setPrimaryKey(['id']);
844
-			$table->addUniqueIndex(['class'], 'personal_sections_class');
845
-		}
846
-
847
-		if (!$schema->hasTable('personal_settings')) {
848
-			$table = $schema->createTable('personal_settings');
849
-			$table->addColumn('id', 'integer', [
850
-				'autoincrement' => true,
851
-				'notnull' => true,
852
-				'length' => 4,
853
-			]);
854
-			$table->addColumn('class', 'string', [
855
-				'notnull' => true,
856
-				'length' => 255,
857
-				'default' => '',
858
-			]);
859
-			$table->addColumn('section', 'string', [
860
-				'notnull' => false,
861
-				'length' => 64,
862
-			]);
863
-			$table->addColumn('priority', 'smallint', [
864
-				'notnull' => true,
865
-				'length' => 1,
866
-				'default' => 0,
867
-			]);
868
-			$table->setPrimaryKey(['id']);
869
-			$table->addUniqueIndex(['class'], 'personal_settings_class');
870
-			$table->addIndex(['section'], 'personal_settings_section');
871
-		}
872
-
873
-		if (!$schema->hasTable('accounts')) {
874
-			$table = $schema->createTable('accounts');
875
-			$table->addColumn('uid', 'string', [
876
-				'notnull' => true,
877
-				'length' => 64,
878
-				'default' => '',
879
-			]);
880
-			$table->addColumn('data', 'text', [
881
-				'notnull' => true,
882
-				'default' => '',
883
-			]);
884
-			$table->setPrimaryKey(['uid']);
885
-		}
886
-		return $schema;
887
-	}
888
-
889
-	/**
890
-	 * @param IOutput $output
891
-	 * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
892
-	 * @param array $options
893
-	 * @since 13.0.0
894
-	 */
895
-	public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
896
-	}
13
+    /**
14
+     * @param IOutput $output
15
+     * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
16
+     * @param array $options
17
+     * @since 13.0.0
18
+     */
19
+    public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
20
+    }
21
+
22
+    /**
23
+     * @param IOutput $output
24
+     * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
25
+     * @param array $options
26
+     * @return null|Schema
27
+     * @since 13.0.0
28
+     */
29
+    public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
30
+        /** @var Schema $schema */
31
+        $schema = $schemaClosure();
32
+
33
+        if (!$schema->hasTable('appconfig')) {
34
+            $table = $schema->createTable('appconfig');
35
+            $table->addColumn('appid', 'string', [
36
+                'notnull' => true,
37
+                'length' => 32,
38
+                'default' => '',
39
+            ]);
40
+            $table->addColumn('configkey', 'string', [
41
+                'notnull' => true,
42
+                'length' => 64,
43
+                'default' => '',
44
+            ]);
45
+            $table->addColumn('configvalue', 'text', [
46
+                'notnull' => false,
47
+            ]);
48
+            $table->setPrimaryKey(['appid', 'configkey']);
49
+            $table->addIndex(['configkey'], 'appconfig_config_key_index');
50
+            $table->addIndex(['appid'], 'appconfig_appid_key');
51
+        }
52
+
53
+        if (!$schema->hasTable('storages')) {
54
+            $table = $schema->createTable('storages');
55
+            $table->addColumn('id', 'string', [
56
+                'notnull' => false,
57
+                'length' => 64,
58
+            ]);
59
+            $table->addColumn('numeric_id', 'integer', [
60
+                'autoincrement' => true,
61
+                'notnull' => true,
62
+                'length' => 4,
63
+            ]);
64
+            $table->addColumn('available', 'integer', [
65
+                'notnull' => true,
66
+                'default' => 1,
67
+            ]);
68
+            $table->addColumn('last_checked', 'integer', [
69
+                'notnull' => false,
70
+            ]);
71
+            $table->setPrimaryKey(['numeric_id']);
72
+            $table->addUniqueIndex(['id'], 'storages_id_index');
73
+        }
74
+
75
+        if (!$schema->hasTable('mounts')) {
76
+            $table = $schema->createTable('mounts');
77
+            $table->addColumn('id', 'integer', [
78
+                'autoincrement' => true,
79
+                'notnull' => true,
80
+                'length' => 4,
81
+            ]);
82
+            $table->addColumn('storage_id', 'integer', [
83
+                'notnull' => true,
84
+            ]);
85
+            $table->addColumn('root_id', 'integer', [
86
+                'notnull' => true,
87
+            ]);
88
+            $table->addColumn('user_id', 'string', [
89
+                'notnull' => true,
90
+                'length' => 64,
91
+            ]);
92
+            $table->addColumn('mount_point', 'string', [
93
+                'notnull' => true,
94
+                'length' => 4000,
95
+            ]);
96
+            $table->addColumn('mount_id', 'integer', [
97
+                'notnull' => false,
98
+            ]);
99
+            $table->setPrimaryKey(['id']);
100
+            $table->addIndex(['user_id'], 'mounts_user_index');
101
+            $table->addIndex(['storage_id'], 'mounts_storage_index');
102
+            $table->addIndex(['root_id'], 'mounts_root_index');
103
+            $table->addIndex(['mount_id'], 'mounts_mount_id_index');
104
+            $table->addUniqueIndex(['user_id', 'root_id'], 'mounts_user_root_index');
105
+        }
106
+
107
+        if (!$schema->hasTable('mimetypes')) {
108
+            $table = $schema->createTable('mimetypes');
109
+            $table->addColumn('id', 'integer', [
110
+                'autoincrement' => true,
111
+                'notnull' => true,
112
+                'length' => 4,
113
+            ]);
114
+            $table->addColumn('mimetype', 'string', [
115
+                'notnull' => true,
116
+                'length' => 255,
117
+                'default' => '',
118
+            ]);
119
+            $table->setPrimaryKey(['id']);
120
+            $table->addUniqueIndex(['mimetype'], 'mimetype_id_index');
121
+        }
122
+
123
+        if (!$schema->hasTable('filecache')) {
124
+            $table = $schema->createTable('filecache');
125
+            $table->addColumn('fileid', 'integer', [
126
+                'autoincrement' => true,
127
+                'notnull' => true,
128
+                'length' => 4,
129
+            ]);
130
+            $table->addColumn('storage', 'integer', [
131
+                'notnull' => true,
132
+                'length' => 4,
133
+                'default' => 0,
134
+            ]);
135
+            $table->addColumn('path', 'string', [
136
+                'notnull' => false,
137
+                'length' => 4000,
138
+            ]);
139
+            $table->addColumn('path_hash', 'string', [
140
+                'notnull' => true,
141
+                'length' => 32,
142
+                'default' => '',
143
+            ]);
144
+            $table->addColumn('parent', 'integer', [
145
+                'notnull' => true,
146
+                'length' => 4,
147
+                'default' => 0,
148
+            ]);
149
+            $table->addColumn('name', 'string', [
150
+                'notnull' => false,
151
+                'length' => 250,
152
+            ]);
153
+            $table->addColumn('mimetype', 'integer', [
154
+                'notnull' => true,
155
+                'length' => 4,
156
+                'default' => 0,
157
+            ]);
158
+            $table->addColumn('mimepart', 'integer', [
159
+                'notnull' => true,
160
+                'length' => 4,
161
+                'default' => 0,
162
+            ]);
163
+            $table->addColumn('size', 'bigint', [
164
+                'notnull' => true,
165
+                'length' => 8,
166
+                'default' => 0,
167
+            ]);
168
+            $table->addColumn('mtime', 'integer', [
169
+                'notnull' => true,
170
+                'length' => 4,
171
+                'default' => 0,
172
+            ]);
173
+            $table->addColumn('storage_mtime', 'integer', [
174
+                'notnull' => true,
175
+                'length' => 4,
176
+                'default' => 0,
177
+            ]);
178
+            $table->addColumn('encrypted', 'integer', [
179
+                'notnull' => true,
180
+                'length' => 4,
181
+                'default' => 0,
182
+            ]);
183
+            $table->addColumn('unencrypted_size', 'bigint', [
184
+                'notnull' => true,
185
+                'length' => 8,
186
+                'default' => 0,
187
+            ]);
188
+            $table->addColumn('etag', 'string', [
189
+                'notnull' => false,
190
+                'length' => 40,
191
+            ]);
192
+            $table->addColumn('permissions', 'integer', [
193
+                'notnull' => false,
194
+                'length' => 4,
195
+                'default' => 0,
196
+            ]);
197
+            $table->addColumn('checksum', 'string', [
198
+                'notnull' => false,
199
+                'length' => 255,
200
+            ]);
201
+            $table->setPrimaryKey(['fileid']);
202
+            $table->addUniqueIndex(['storage', 'path_hash'], 'fs_storage_path_hash');
203
+            $table->addIndex(['parent', 'name'], 'fs_parent_name_hash');
204
+            $table->addIndex(['storage', 'mimetype'], 'fs_storage_mimetype');
205
+            $table->addIndex(['storage', 'mimepart'], 'fs_storage_mimepart');
206
+            $table->addIndex(['storage', 'size', 'fileid'], 'fs_storage_size');
207
+        }
208
+
209
+        if (!$schema->hasTable('group_user')) {
210
+            $table = $schema->createTable('group_user');
211
+            $table->addColumn('gid', 'string', [
212
+                'notnull' => true,
213
+                'length' => 64,
214
+                'default' => '',
215
+            ]);
216
+            $table->addColumn('uid', 'string', [
217
+                'notnull' => true,
218
+                'length' => 64,
219
+                'default' => '',
220
+            ]);
221
+            $table->setPrimaryKey(['gid', 'uid']);
222
+            $table->addIndex(['uid'], 'gu_uid_index');
223
+        }
224
+
225
+        if (!$schema->hasTable('group_admin')) {
226
+            $table = $schema->createTable('group_admin');
227
+            $table->addColumn('gid', 'string', [
228
+                'notnull' => true,
229
+                'length' => 64,
230
+                'default' => '',
231
+            ]);
232
+            $table->addColumn('uid', 'string', [
233
+                'notnull' => true,
234
+                'length' => 64,
235
+                'default' => '',
236
+            ]);
237
+            $table->setPrimaryKey(['gid', 'uid']);
238
+            $table->addIndex(['uid'], 'group_admin_uid');
239
+        }
240
+
241
+        if (!$schema->hasTable('groups')) {
242
+            $table = $schema->createTable('groups');
243
+            $table->addColumn('gid', 'string', [
244
+                'notnull' => true,
245
+                'length' => 64,
246
+                'default' => '',
247
+            ]);
248
+            $table->setPrimaryKey(['gid']);
249
+        }
250
+
251
+        if (!$schema->hasTable('preferences')) {
252
+            $table = $schema->createTable('preferences');
253
+            $table->addColumn('userid', 'string', [
254
+                'notnull' => true,
255
+                'length' => 64,
256
+                'default' => '',
257
+            ]);
258
+            $table->addColumn('appid', 'string', [
259
+                'notnull' => true,
260
+                'length' => 32,
261
+                'default' => '',
262
+            ]);
263
+            $table->addColumn('configkey', 'string', [
264
+                'notnull' => true,
265
+                'length' => 64,
266
+                'default' => '',
267
+            ]);
268
+            $table->addColumn('configvalue', 'text', [
269
+                'notnull' => false,
270
+            ]);
271
+            $table->setPrimaryKey(['userid', 'appid', 'configkey']);
272
+        }
273
+
274
+        if (!$schema->hasTable('properties')) {
275
+            $table = $schema->createTable('properties');
276
+            $table->addColumn('id', 'integer', [
277
+                'autoincrement' => true,
278
+                'notnull' => true,
279
+                'length' => 4,
280
+            ]);
281
+            $table->addColumn('userid', 'string', [
282
+                'notnull' => true,
283
+                'length' => 64,
284
+                'default' => '',
285
+            ]);
286
+            $table->addColumn('propertypath', 'string', [
287
+                'notnull' => true,
288
+                'length' => 255,
289
+                'default' => '',
290
+            ]);
291
+            $table->addColumn('propertyname', 'string', [
292
+                'notnull' => true,
293
+                'length' => 255,
294
+                'default' => '',
295
+            ]);
296
+            $table->addColumn('propertyvalue', 'text', [
297
+                'notnull' => true,
298
+            ]);
299
+            $table->setPrimaryKey(['id']);
300
+            $table->addIndex(['userid'], 'property_index');
301
+        }
302
+
303
+        if (!$schema->hasTable('share')) {
304
+            $table = $schema->createTable('share');
305
+            $table->addColumn('id', 'integer', [
306
+                'autoincrement' => true,
307
+                'notnull' => true,
308
+                'length' => 4,
309
+            ]);
310
+            $table->addColumn('share_type', 'smallint', [
311
+                'notnull' => true,
312
+                'length' => 1,
313
+                'default' => 0,
314
+            ]);
315
+            $table->addColumn('share_with', 'string', [
316
+                'notnull' => false,
317
+                'length' => 255,
318
+            ]);
319
+            $table->addColumn('password', 'string', [
320
+                'notnull' => false,
321
+                'length' => 255,
322
+            ]);
323
+            $table->addColumn('uid_owner', 'string', [
324
+                'notnull' => true,
325
+                'length' => 64,
326
+                'default' => '',
327
+            ]);
328
+            $table->addColumn('uid_initiator', 'string', [
329
+                'notnull' => false,
330
+                'length' => 64,
331
+            ]);
332
+            $table->addColumn('parent', 'integer', [
333
+                'notnull' => false,
334
+                'length' => 4,
335
+            ]);
336
+            $table->addColumn('item_type', 'string', [
337
+                'notnull' => true,
338
+                'length' => 64,
339
+                'default' => '',
340
+            ]);
341
+            $table->addColumn('item_source', 'string', [
342
+                'notnull' => false,
343
+                'length' => 255,
344
+            ]);
345
+            $table->addColumn('item_target', 'string', [
346
+                'notnull' => false,
347
+                'length' => 255,
348
+            ]);
349
+            $table->addColumn('file_source', 'integer', [
350
+                'notnull' => false,
351
+                'length' => 4,
352
+            ]);
353
+            $table->addColumn('file_target', 'string', [
354
+                'notnull' => false,
355
+                'length' => 512,
356
+            ]);
357
+            $table->addColumn('permissions', 'smallint', [
358
+                'notnull' => true,
359
+                'length' => 1,
360
+                'default' => 0,
361
+            ]);
362
+            $table->addColumn('stime', 'bigint', [
363
+                'notnull' => true,
364
+                'length' => 8,
365
+                'default' => 0,
366
+            ]);
367
+            $table->addColumn('accepted', 'smallint', [
368
+                'notnull' => true,
369
+                'length' => 1,
370
+                'default' => 0,
371
+            ]);
372
+            $table->addColumn('expiration', 'datetime', [
373
+                'notnull' => false,
374
+            ]);
375
+            $table->addColumn('token', 'string', [
376
+                'notnull' => false,
377
+                'length' => 32,
378
+            ]);
379
+            $table->addColumn('mail_send', 'smallint', [
380
+                'notnull' => true,
381
+                'length' => 1,
382
+                'default' => 0,
383
+            ]);
384
+            $table->addColumn('share_name', 'string', [
385
+                'notnull' => false,
386
+                'length' => 64,
387
+            ]);
388
+            $table->setPrimaryKey(['id']);
389
+            $table->addIndex(['item_type', 'share_type'], 'item_share_type_index');
390
+            $table->addIndex(['file_source'], 'file_source_index');
391
+            $table->addIndex(['token'], 'token_index');
392
+        }
393
+
394
+        if (!$schema->hasTable('jobs')) {
395
+            $table = $schema->createTable('jobs');
396
+            $table->addColumn('id', 'integer', [
397
+                'autoincrement' => true,
398
+                'notnull' => true,
399
+                'length' => 4,
400
+            ]);
401
+            $table->addColumn('class', 'string', [
402
+                'notnull' => true,
403
+                'length' => 255,
404
+                'default' => '',
405
+            ]);
406
+            $table->addColumn('argument', 'string', [
407
+                'notnull' => true,
408
+                'length' => 4000,
409
+                'default' => '',
410
+            ]);
411
+            $table->addColumn('last_run', 'integer', [
412
+                'notnull' => false,
413
+                'default' => 0,
414
+            ]);
415
+            $table->addColumn('last_checked', 'integer', [
416
+                'notnull' => false,
417
+                'default' => 0,
418
+            ]);
419
+            $table->addColumn('reserved_at', 'integer', [
420
+                'notnull' => false,
421
+                'default' => 0,
422
+            ]);
423
+            $table->addColumn('execution_duration', 'integer', [
424
+                'notnull' => true,
425
+                'default' => 0,
426
+            ]);
427
+            $table->setPrimaryKey(['id']);
428
+            $table->addIndex(['class'], 'job_class_index');
429
+        }
430
+
431
+        if (!$schema->hasTable('users')) {
432
+            $table = $schema->createTable('users');
433
+            $table->addColumn('uid', 'string', [
434
+                'notnull' => true,
435
+                'length' => 64,
436
+                'default' => '',
437
+            ]);
438
+            $table->addColumn('displayname', 'string', [
439
+                'notnull' => false,
440
+                'length' => 64,
441
+            ]);
442
+            $table->addColumn('password', 'string', [
443
+                'notnull' => true,
444
+                'length' => 255,
445
+                'default' => '',
446
+            ]);
447
+            $table->setPrimaryKey(['uid']);
448
+        }
449
+
450
+        if (!$schema->hasTable('authtoken')) {
451
+            $table = $schema->createTable('authtoken');
452
+            $table->addColumn('id', 'integer', [
453
+                'autoincrement' => true,
454
+                'notnull' => true,
455
+                'length' => 4,
456
+            ]);
457
+            $table->addColumn('uid', 'string', [
458
+                'notnull' => true,
459
+                'length' => 64,
460
+                'default' => '',
461
+            ]);
462
+            $table->addColumn('login_name', 'string', [
463
+                'notnull' => true,
464
+                'length' => 64,
465
+                'default' => '',
466
+            ]);
467
+            $table->addColumn('password', 'text', [
468
+                'notnull' => false,
469
+            ]);
470
+            $table->addColumn('name', 'text', [
471
+                'notnull' => true,
472
+                'default' => '',
473
+            ]);
474
+            $table->addColumn('token', 'string', [
475
+                'notnull' => true,
476
+                'length' => 200,
477
+                'default' => '',
478
+            ]);
479
+            $table->addColumn('type', 'smallint', [
480
+                'notnull' => true,
481
+                'length' => 2,
482
+                'default' => 0,
483
+            ]);
484
+            $table->addColumn('remember', 'smallint', [
485
+                'notnull' => true,
486
+                'length' => 1,
487
+                'default' => 0,
488
+            ]);
489
+            $table->addColumn('last_activity', 'integer', [
490
+                'notnull' => true,
491
+                'length' => 4,
492
+                'default' => 0,
493
+            ]);
494
+            $table->addColumn('last_check', 'integer', [
495
+                'notnull' => true,
496
+                'length' => 4,
497
+                'default' => 0,
498
+            ]);
499
+            $table->addColumn('scope', 'text', [
500
+                'notnull' => false,
501
+            ]);
502
+            $table->setPrimaryKey(['id']);
503
+            $table->addUniqueIndex(['token'], 'authtoken_token_index');
504
+            $table->addIndex(['last_activity'], 'authtoken_last_activity_index');
505
+        }
506
+
507
+        if (!$schema->hasTable('bruteforce_attempts')) {
508
+            $table = $schema->createTable('bruteforce_attempts');
509
+            $table->addColumn('id', 'integer', [
510
+                'autoincrement' => true,
511
+                'notnull' => true,
512
+                'length' => 4,
513
+            ]);
514
+            $table->addColumn('action', 'string', [
515
+                'notnull' => true,
516
+                'length' => 64,
517
+                'default' => '',
518
+            ]);
519
+            $table->addColumn('occurred', 'integer', [
520
+                'notnull' => true,
521
+                'length' => 4,
522
+                'default' => 0,
523
+            ]);
524
+            $table->addColumn('ip', 'string', [
525
+                'notnull' => true,
526
+                'length' => 255,
527
+                'default' => '',
528
+            ]);
529
+            $table->addColumn('subnet', 'string', [
530
+                'notnull' => true,
531
+                'length' => 255,
532
+                'default' => '',
533
+            ]);
534
+            $table->addColumn('metadata', 'string', [
535
+                'notnull' => true,
536
+                'length' => 255,
537
+                'default' => '',
538
+            ]);
539
+            $table->setPrimaryKey(['id']);
540
+            $table->addIndex(['ip'], 'bruteforce_attempts_ip');
541
+            $table->addIndex(['subnet'], 'bruteforce_attempts_subnet');
542
+        }
543
+
544
+        if (!$schema->hasTable('vcategory')) {
545
+            $table = $schema->createTable('vcategory');
546
+            $table->addColumn('id', 'integer', [
547
+                'autoincrement' => true,
548
+                'notnull' => true,
549
+                'length' => 4,
550
+            ]);
551
+            $table->addColumn('uid', 'string', [
552
+                'notnull' => true,
553
+                'length' => 64,
554
+                'default' => '',
555
+            ]);
556
+            $table->addColumn('type', 'string', [
557
+                'notnull' => true,
558
+                'length' => 64,
559
+                'default' => '',
560
+            ]);
561
+            $table->addColumn('category', 'string', [
562
+                'notnull' => true,
563
+                'length' => 255,
564
+                'default' => '',
565
+            ]);
566
+            $table->setPrimaryKey(['id']);
567
+            $table->addIndex(['uid'], 'uid_index');
568
+            $table->addIndex(['type'], 'type_index');
569
+            $table->addIndex(['category'], 'category_index');
570
+        }
571
+
572
+        if (!$schema->hasTable('vcategory_to_object')) {
573
+            $table = $schema->createTable('vcategory_to_object');
574
+            $table->addColumn('objid', 'integer', [
575
+                'notnull' => true,
576
+                'length' => 4,
577
+                'default' => 0,
578
+            ]);
579
+            $table->addColumn('categoryid', 'integer', [
580
+                'notnull' => true,
581
+                'length' => 4,
582
+                'default' => 0,
583
+            ]);
584
+            $table->addColumn('type', 'string', [
585
+                'notnull' => true,
586
+                'length' => 64,
587
+                'default' => '',
588
+            ]);
589
+            $table->setPrimaryKey(['categoryid', 'objid', 'type']);
590
+            $table->addIndex(['objid', 'type'], 'vcategory_objectd_index');
591
+        }
592
+
593
+        if (!$schema->hasTable('systemtag')) {
594
+            $table = $schema->createTable('systemtag');
595
+            $table->addColumn('id', 'integer', [
596
+                'autoincrement' => true,
597
+                'notnull' => true,
598
+                'length' => 4,
599
+            ]);
600
+            $table->addColumn('name', 'string', [
601
+                'notnull' => true,
602
+                'length' => 64,
603
+                'default' => '',
604
+            ]);
605
+            $table->addColumn('visibility', 'smallint', [
606
+                'notnull' => true,
607
+                'length' => 1,
608
+                'default' => 1,
609
+            ]);
610
+            $table->addColumn('editable', 'smallint', [
611
+                'notnull' => true,
612
+                'length' => 1,
613
+                'default' => 1,
614
+            ]);
615
+            $table->setPrimaryKey(['id']);
616
+            $table->addUniqueIndex(['name', 'visibility', 'editable'], 'tag_ident');
617
+        }
618
+
619
+        if (!$schema->hasTable('systemtag_object_mapping')) {
620
+            $table = $schema->createTable('systemtag_object_mapping');
621
+            $table->addColumn('objectid', 'string', [
622
+                'notnull' => true,
623
+                'length' => 64,
624
+                'default' => '',
625
+            ]);
626
+            $table->addColumn('objecttype', 'string', [
627
+                'notnull' => true,
628
+                'length' => 64,
629
+                'default' => '',
630
+            ]);
631
+            $table->addColumn('systemtagid', 'integer', [
632
+                'notnull' => true,
633
+                'length' => 4,
634
+                'default' => 0,
635
+            ]);
636
+            $table->addUniqueIndex(['objecttype', 'objectid', 'systemtagid'], 'mapping');
637
+        }
638
+
639
+        if (!$schema->hasTable('systemtag_group')) {
640
+            $table = $schema->createTable('systemtag_group');
641
+            $table->addColumn('systemtagid', 'integer', [
642
+                'notnull' => true,
643
+                'length' => 4,
644
+                'default' => 0,
645
+            ]);
646
+            $table->addColumn('gid', 'string', [
647
+                'notnull' => true,
648
+            ]);
649
+            $table->setPrimaryKey(['gid', 'systemtagid']);
650
+        }
651
+
652
+        if (!$schema->hasTable('file_locks')) {
653
+            $table = $schema->createTable('file_locks');
654
+            $table->addColumn('id', 'integer', [
655
+                'autoincrement' => true,
656
+                'notnull' => true,
657
+                'length' => 4,
658
+            ]);
659
+            $table->addColumn('lock', 'integer', [
660
+                'notnull' => true,
661
+                'length' => 4,
662
+                'default' => 0,
663
+            ]);
664
+            $table->addColumn('key', 'string', [
665
+                'notnull' => true,
666
+                'length' => 64,
667
+            ]);
668
+            $table->addColumn('ttl', 'integer', [
669
+                'notnull' => true,
670
+                'length' => 4,
671
+                'default' => -1,
672
+            ]);
673
+            $table->setPrimaryKey(['id']);
674
+            $table->addUniqueIndex(['key'], 'lock_key_index');
675
+            $table->addIndex(['ttl'], 'lock_ttl_index');
676
+        }
677
+
678
+        if (!$schema->hasTable('comments')) {
679
+            $table = $schema->createTable('comments');
680
+            $table->addColumn('id', 'integer', [
681
+                'autoincrement' => true,
682
+                'notnull' => true,
683
+                'length' => 4,
684
+            ]);
685
+            $table->addColumn('parent_id', 'integer', [
686
+                'notnull' => true,
687
+                'length' => 4,
688
+                'default' => 0,
689
+            ]);
690
+            $table->addColumn('topmost_parent_id', 'integer', [
691
+                'notnull' => true,
692
+                'length' => 4,
693
+                'default' => 0,
694
+            ]);
695
+            $table->addColumn('children_count', 'integer', [
696
+                'notnull' => true,
697
+                'length' => 4,
698
+                'default' => 0,
699
+            ]);
700
+            $table->addColumn('actor_type', 'string', [
701
+                'notnull' => true,
702
+                'length' => 64,
703
+                'default' => '',
704
+            ]);
705
+            $table->addColumn('actor_id', 'string', [
706
+                'notnull' => true,
707
+                'length' => 64,
708
+                'default' => '',
709
+            ]);
710
+            $table->addColumn('message', 'text', [
711
+                'notnull' => false,
712
+            ]);
713
+            $table->addColumn('verb', 'string', [
714
+                'notnull' => false,
715
+                'length' => 64,
716
+            ]);
717
+            $table->addColumn('creation_timestamp', 'datetime', [
718
+                'notnull' => false,
719
+            ]);
720
+            $table->addColumn('latest_child_timestamp', 'datetime', [
721
+                'notnull' => false,
722
+            ]);
723
+            $table->addColumn('object_type', 'string', [
724
+                'notnull' => true,
725
+                'length' => 64,
726
+                'default' => '',
727
+            ]);
728
+            $table->addColumn('object_id', 'string', [
729
+                'notnull' => true,
730
+                'length' => 64,
731
+                'default' => '',
732
+            ]);
733
+            $table->setPrimaryKey(['id']);
734
+            $table->addIndex(['parent_id'], 'comments_parent_id_index');
735
+            $table->addIndex(['topmost_parent_id'], 'comments_topmost_parent_id_idx');
736
+            $table->addIndex(['object_type', 'object_id', 'creation_timestamp'], 'comments_object_index');
737
+            $table->addIndex(['actor_type', 'actor_id'], 'comments_actor_index');
738
+        }
739
+
740
+        if (!$schema->hasTable('comments_read_markers')) {
741
+            $table = $schema->createTable('comments_read_markers');
742
+            $table->addColumn('user_id', 'string', [
743
+                'notnull' => true,
744
+                'length' => 64,
745
+                'default' => '',
746
+            ]);
747
+            $table->addColumn('marker_datetime', 'datetime', [
748
+                'notnull' => false,
749
+            ]);
750
+            $table->addColumn('object_type', 'string', [
751
+                'notnull' => true,
752
+                'length' => 64,
753
+                'default' => '',
754
+            ]);
755
+            $table->addColumn('object_id', 'string', [
756
+                'notnull' => true,
757
+                'length' => 64,
758
+                'default' => '',
759
+            ]);
760
+            $table->addIndex(['object_type', 'object_id'], 'comments_marker_object_index');
761
+            $table->addUniqueIndex(['user_id', 'object_type', 'object_id'], 'comments_marker_index');
762
+        }
763
+
764
+        if (!$schema->hasTable('credentials')) {
765
+            $table = $schema->createTable('credentials');
766
+            $table->addColumn('user', 'string', [
767
+                'notnull' => true,
768
+                'length' => 64,
769
+            ]);
770
+            $table->addColumn('identifier', 'string', [
771
+                'notnull' => true,
772
+                'length' => 64,
773
+            ]);
774
+            $table->addColumn('credentials', 'text', [
775
+                'notnull' => false,
776
+            ]);
777
+            $table->setPrimaryKey(['user', 'identifier']);
778
+            $table->addIndex(['user'], 'credentials_user');
779
+        }
780
+
781
+        if (!$schema->hasTable('admin_sections')) {
782
+            $table = $schema->createTable('admin_sections');
783
+            $table->addColumn('id', 'string', [
784
+                'notnull' => true,
785
+                'length' => 64,
786
+            ]);
787
+            $table->addColumn('class', 'string', [
788
+                'notnull' => true,
789
+                'length' => 255,
790
+                'default' => '',
791
+            ]);
792
+            $table->addColumn('priority', 'smallint', [
793
+                'notnull' => true,
794
+                'length' => 1,
795
+                'default' => 0,
796
+            ]);
797
+            $table->setPrimaryKey(['id']);
798
+            $table->addUniqueIndex(['class'], 'admin_sections_class');
799
+        }
800
+
801
+        if (!$schema->hasTable('admin_settings')) {
802
+            $table = $schema->createTable('admin_settings');
803
+            $table->addColumn('id', 'integer', [
804
+                'autoincrement' => true,
805
+                'notnull' => true,
806
+                'length' => 4,
807
+            ]);
808
+            $table->addColumn('class', 'string', [
809
+                'notnull' => true,
810
+                'length' => 255,
811
+                'default' => '',
812
+            ]);
813
+            $table->addColumn('section', 'string', [
814
+                'notnull' => false,
815
+                'length' => 64,
816
+            ]);
817
+            $table->addColumn('priority', 'smallint', [
818
+                'notnull' => true,
819
+                'length' => 1,
820
+                'default' => 0,
821
+            ]);
822
+            $table->setPrimaryKey(['id']);
823
+            $table->addUniqueIndex(['class'], 'admin_settings_class');
824
+            $table->addIndex(['section'], 'admin_settings_section');
825
+        }
826
+
827
+        if (!$schema->hasTable('personal_sections')) {
828
+            $table = $schema->createTable('personal_sections');
829
+            $table->addColumn('id', 'string', [
830
+                'notnull' => true,
831
+                'length' => 64,
832
+            ]);
833
+            $table->addColumn('class', 'string', [
834
+                'notnull' => true,
835
+                'length' => 255,
836
+                'default' => '',
837
+            ]);
838
+            $table->addColumn('priority', 'smallint', [
839
+                'notnull' => true,
840
+                'length' => 1,
841
+                'default' => 0,
842
+            ]);
843
+            $table->setPrimaryKey(['id']);
844
+            $table->addUniqueIndex(['class'], 'personal_sections_class');
845
+        }
846
+
847
+        if (!$schema->hasTable('personal_settings')) {
848
+            $table = $schema->createTable('personal_settings');
849
+            $table->addColumn('id', 'integer', [
850
+                'autoincrement' => true,
851
+                'notnull' => true,
852
+                'length' => 4,
853
+            ]);
854
+            $table->addColumn('class', 'string', [
855
+                'notnull' => true,
856
+                'length' => 255,
857
+                'default' => '',
858
+            ]);
859
+            $table->addColumn('section', 'string', [
860
+                'notnull' => false,
861
+                'length' => 64,
862
+            ]);
863
+            $table->addColumn('priority', 'smallint', [
864
+                'notnull' => true,
865
+                'length' => 1,
866
+                'default' => 0,
867
+            ]);
868
+            $table->setPrimaryKey(['id']);
869
+            $table->addUniqueIndex(['class'], 'personal_settings_class');
870
+            $table->addIndex(['section'], 'personal_settings_section');
871
+        }
872
+
873
+        if (!$schema->hasTable('accounts')) {
874
+            $table = $schema->createTable('accounts');
875
+            $table->addColumn('uid', 'string', [
876
+                'notnull' => true,
877
+                'length' => 64,
878
+                'default' => '',
879
+            ]);
880
+            $table->addColumn('data', 'text', [
881
+                'notnull' => true,
882
+                'default' => '',
883
+            ]);
884
+            $table->setPrimaryKey(['uid']);
885
+        }
886
+        return $schema;
887
+    }
888
+
889
+    /**
890
+     * @param IOutput $output
891
+     * @param \Closure $schemaClosure The `\Closure` returns a `Schema`
892
+     * @param array $options
893
+     * @since 13.0.0
894
+     */
895
+    public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
896
+    }
897 897
 }
Please login to merge, or discard this patch.
core/Command/Db/ConvertType.php 2 patches
Indentation   +405 added lines, -405 removed lines patch added patch discarded remove patch
@@ -49,409 +49,409 @@
 block discarded – undo
49 49
 use Symfony\Component\Console\Question\Question;
50 50
 
51 51
 class ConvertType extends Command implements CompletionAwareInterface {
52
-	/**
53
-	 * @var \OCP\IConfig
54
-	 */
55
-	protected $config;
56
-
57
-	/**
58
-	 * @var \OC\DB\ConnectionFactory
59
-	 */
60
-	protected $connectionFactory;
61
-
62
-	/** @var array */
63
-	protected $columnTypes;
64
-
65
-	/**
66
-	 * @param \OCP\IConfig $config
67
-	 * @param \OC\DB\ConnectionFactory $connectionFactory
68
-	 */
69
-	public function __construct(IConfig $config, ConnectionFactory $connectionFactory) {
70
-		$this->config = $config;
71
-		$this->connectionFactory = $connectionFactory;
72
-		parent::__construct();
73
-	}
74
-
75
-	protected function configure() {
76
-		$this
77
-			->setName('db:convert-type')
78
-			->setDescription('Convert the Nextcloud database to the newly configured one')
79
-			->addArgument(
80
-				'type',
81
-				InputArgument::REQUIRED,
82
-				'the type of the database to convert to'
83
-			)
84
-			->addArgument(
85
-				'username',
86
-				InputArgument::REQUIRED,
87
-				'the username of the database to convert to'
88
-			)
89
-			->addArgument(
90
-				'hostname',
91
-				InputArgument::REQUIRED,
92
-				'the hostname of the database to convert to'
93
-			)
94
-			->addArgument(
95
-				'database',
96
-				InputArgument::REQUIRED,
97
-				'the name of the database to convert to'
98
-			)
99
-			->addOption(
100
-				'port',
101
-				null,
102
-				InputOption::VALUE_REQUIRED,
103
-				'the port of the database to convert to'
104
-			)
105
-			->addOption(
106
-				'password',
107
-				null,
108
-				InputOption::VALUE_REQUIRED,
109
-				'the password of the database to convert to. Will be asked when not specified. Can also be passed via stdin.'
110
-			)
111
-			->addOption(
112
-				'clear-schema',
113
-				null,
114
-				InputOption::VALUE_NONE,
115
-				'remove all tables from the destination database'
116
-			)
117
-			->addOption(
118
-				'all-apps',
119
-				null,
120
-				InputOption::VALUE_NONE,
121
-				'whether to create schema for all apps instead of only installed apps'
122
-			)
123
-			->addOption(
124
-				'chunk-size',
125
-				null,
126
-				InputOption::VALUE_REQUIRED,
127
-				'the maximum number of database rows to handle in a single query, bigger tables will be handled in chunks of this size. Lower this if the process runs out of memory during conversion.',
128
-				1000
129
-			)
130
-		;
131
-	}
132
-
133
-	protected function validateInput(InputInterface $input, OutputInterface $output) {
134
-		$type = $this->connectionFactory->normalizeType($input->getArgument('type'));
135
-		if ($type === 'sqlite3') {
136
-			throw new \InvalidArgumentException(
137
-				'Converting to SQLite (sqlite3) is currently not supported.'
138
-			);
139
-		}
140
-		if ($type === $this->config->getSystemValue('dbtype', '')) {
141
-			throw new \InvalidArgumentException(sprintf(
142
-				'Can not convert from %1$s to %1$s.',
143
-				$type
144
-			));
145
-		}
146
-		if ($type === 'oci' && $input->getOption('clear-schema')) {
147
-			// Doctrine unconditionally tries (at least in version 2.3)
148
-			// to drop sequence triggers when dropping a table, even though
149
-			// such triggers may not exist. This results in errors like
150
-			// "ORA-04080: trigger 'OC_STORAGES_AI_PK' does not exist".
151
-			throw new \InvalidArgumentException(
152
-				'The --clear-schema option is not supported when converting to Oracle (oci).'
153
-			);
154
-		}
155
-	}
156
-
157
-	protected function readPassword(InputInterface $input, OutputInterface $output) {
158
-		// Explicitly specified password
159
-		if ($input->getOption('password')) {
160
-			return;
161
-		}
162
-
163
-		// Read from stdin. stream_set_blocking is used to prevent blocking
164
-		// when nothing is passed via stdin.
165
-		stream_set_blocking(STDIN, 0);
166
-		$password = file_get_contents('php://stdin');
167
-		stream_set_blocking(STDIN, 1);
168
-		if (trim($password) !== '') {
169
-			$input->setOption('password', $password);
170
-			return;
171
-		}
172
-
173
-		// Read password by interacting
174
-		if ($input->isInteractive()) {
175
-			/** @var QuestionHelper $helper */
176
-			$helper = $this->getHelper('question');
177
-			$question = new Question('What is the database password?');
178
-			$question->setHidden(true);
179
-			$question->setHiddenFallback(false);
180
-			$password = $helper->ask($input, $output, $question);
181
-			$input->setOption('password', $password);
182
-			return;
183
-		}
184
-	}
185
-
186
-	protected function execute(InputInterface $input, OutputInterface $output) {
187
-		$this->validateInput($input, $output);
188
-		$this->readPassword($input, $output);
189
-
190
-		$fromDB = \OC::$server->getDatabaseConnection();
191
-		$toDB = $this->getToDBConnection($input, $output);
192
-
193
-		if ($input->getOption('clear-schema')) {
194
-			$this->clearSchema($toDB, $input, $output);
195
-		}
196
-
197
-		$this->createSchema($fromDB, $toDB, $input, $output);
198
-
199
-		$toTables = $this->getTables($toDB);
200
-		$fromTables = $this->getTables($fromDB);
201
-
202
-		// warn/fail if there are more tables in 'from' database
203
-		$extraFromTables = array_diff($fromTables, $toTables);
204
-		if (!empty($extraFromTables)) {
205
-			$output->writeln('<comment>The following tables will not be converted:</comment>');
206
-			$output->writeln($extraFromTables);
207
-			if (!$input->getOption('all-apps')) {
208
-				$output->writeln('<comment>Please note that tables belonging to available but currently not installed apps</comment>');
209
-				$output->writeln('<comment>can be included by specifying the --all-apps option.</comment>');
210
-			}
211
-
212
-			/** @var QuestionHelper $helper */
213
-			$helper = $this->getHelper('question');
214
-			$question = new ConfirmationQuestion('Continue with the conversion (y/n)? [n] ', false);
215
-
216
-			if (!$helper->ask($input, $output, $question)) {
217
-				return;
218
-			}
219
-		}
220
-		$intersectingTables = array_intersect($toTables, $fromTables);
221
-		$this->convertDB($fromDB, $toDB, $intersectingTables, $input, $output);
222
-	}
223
-
224
-	protected function createSchema(Connection $fromDB, Connection $toDB, InputInterface $input, OutputInterface $output) {
225
-		$output->writeln('<info>Creating schema in new database</info>');
226
-
227
-		$fromMS = new MigrationService('core', $fromDB);
228
-		$currentMigration = $fromMS->getMigration('current');
229
-		if ($currentMigration !== '0') {
230
-			$toMS = new MigrationService('core', $toDB);
231
-			$toMS->migrate($currentMigration);
232
-		}
233
-
234
-		$schemaManager = new \OC\DB\MDB2SchemaManager($toDB);
235
-		$apps = $input->getOption('all-apps') ? \OC_App::getAllApps() : \OC_App::getEnabledApps();
236
-		foreach($apps as $app) {
237
-			if (file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) {
238
-				$schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml');
239
-			} else {
240
-				// Make sure autoloading works...
241
-				\OC_App::loadApp($app);
242
-				$fromMS = new MigrationService($app, $fromDB);
243
-				$currentMigration = $fromMS->getMigration('current');
244
-				if ($currentMigration !== '0') {
245
-					$toMS = new MigrationService($app, $toDB);
246
-					$toMS->migrate($currentMigration);
247
-				}
248
-			}
249
-		}
250
-	}
251
-
252
-	protected function getToDBConnection(InputInterface $input, OutputInterface $output) {
253
-		$type = $input->getArgument('type');
254
-		$connectionParams = $this->connectionFactory->createConnectionParams();
255
-		$connectionParams = array_merge($connectionParams, [
256
-			'host' => $input->getArgument('hostname'),
257
-			'user' => $input->getArgument('username'),
258
-			'password' => $input->getOption('password'),
259
-			'dbname' => $input->getArgument('database'),
260
-		]);
261
-		if ($input->getOption('port')) {
262
-			$connectionParams['port'] = $input->getOption('port');
263
-		}
264
-		return $this->connectionFactory->getConnection($type, $connectionParams);
265
-	}
266
-
267
-	protected function clearSchema(Connection $db, InputInterface $input, OutputInterface $output) {
268
-		$toTables = $this->getTables($db);
269
-		if (!empty($toTables)) {
270
-			$output->writeln('<info>Clearing schema in new database</info>');
271
-		}
272
-		foreach($toTables as $table) {
273
-			$db->getSchemaManager()->dropTable($table);
274
-		}
275
-	}
276
-
277
-	protected function getTables(Connection $db) {
278
-		$filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
279
-		$db->getConfiguration()->
280
-			setFilterSchemaAssetsExpression($filterExpression);
281
-		return $db->getSchemaManager()->listTableNames();
282
-	}
283
-
284
-	/**
285
-	 * @param Connection $fromDB
286
-	 * @param Connection $toDB
287
-	 * @param Table $table
288
-	 * @param InputInterface $input
289
-	 * @param OutputInterface $output
290
-	 * @suppress SqlInjectionChecker
291
-	 */
292
-	protected function copyTable(Connection $fromDB, Connection $toDB, Table $table, InputInterface $input, OutputInterface $output) {
293
-		if ($table->getName() === $toDB->getPrefix() . 'migrations') {
294
-			$output->writeln('<comment>Skipping migrations table because it was already filled by running the migrations</comment>');
295
-			return;
296
-		}
297
-
298
-		$chunkSize = $input->getOption('chunk-size');
299
-
300
-		$query = $fromDB->getQueryBuilder();
301
-		$query->automaticTablePrefix(false);
302
-		$query->selectAlias($query->createFunction('COUNT(*)'), 'num_entries')
303
-			->from($table->getName());
304
-		$result = $query->execute();
305
-		$count = $result->fetchColumn();
306
-		$result->closeCursor();
307
-
308
-		$numChunks = ceil($count/$chunkSize);
309
-		if ($numChunks > 1) {
310
-			$output->writeln('chunked query, ' . $numChunks . ' chunks');
311
-		}
312
-
313
-		$progress = new ProgressBar($output, $count);
314
-		$progress->start();
315
-		$redraw = $count > $chunkSize ? 100 : ($count > 100 ? 5 : 1);
316
-		$progress->setRedrawFrequency($redraw);
317
-
318
-		$query = $fromDB->getQueryBuilder();
319
-		$query->automaticTablePrefix(false);
320
-		$query->select('*')
321
-			->from($table->getName())
322
-			->setMaxResults($chunkSize);
323
-
324
-		try {
325
-			$orderColumns = $table->getPrimaryKeyColumns();
326
-		} catch (DBALException $e) {
327
-			$orderColumns = [];
328
-			foreach ($table->getColumns() as $column) {
329
-				$orderColumns[] = $column->getName();
330
-			}
331
-		}
332
-
333
-		foreach ($orderColumns as $column) {
334
-			$query->addOrderBy($column);
335
-		}
336
-
337
-		$insertQuery = $toDB->getQueryBuilder();
338
-		$insertQuery->automaticTablePrefix(false);
339
-		$insertQuery->insert($table->getName());
340
-		$parametersCreated = false;
341
-
342
-		for ($chunk = 0; $chunk < $numChunks; $chunk++) {
343
-			$query->setFirstResult($chunk * $chunkSize);
344
-
345
-			$result = $query->execute();
346
-
347
-			while ($row = $result->fetch()) {
348
-				$progress->advance();
349
-				if (!$parametersCreated) {
350
-					foreach ($row as $key => $value) {
351
-						$insertQuery->setValue($key, $insertQuery->createParameter($key));
352
-					}
353
-					$parametersCreated = true;
354
-				}
355
-
356
-				foreach ($row as $key => $value) {
357
-					$type = $this->getColumnType($table, $key);
358
-					if ($type !== false) {
359
-						$insertQuery->setParameter($key, $value, $type);
360
-					} else {
361
-						$insertQuery->setParameter($key, $value);
362
-					}
363
-				}
364
-				$insertQuery->execute();
365
-			}
366
-			$result->closeCursor();
367
-		}
368
-		$progress->finish();
369
-	}
370
-
371
-	protected function getColumnType(Table $table, $columnName) {
372
-		$tableName = $table->getName();
373
-		if (isset($this->columnTypes[$tableName][$columnName])) {
374
-			return $this->columnTypes[$tableName][$columnName];
375
-		}
376
-
377
-		$type = $table->getColumn($columnName)->getType()->getName();
378
-
379
-		switch ($type) {
380
-			case Type::BLOB:
381
-			case Type::TEXT:
382
-				$this->columnTypes[$tableName][$columnName] = IQueryBuilder::PARAM_LOB;
383
-				break;
384
-			default:
385
-				$this->columnTypes[$tableName][$columnName] = false;
386
-		}
387
-
388
-		return $this->columnTypes[$tableName][$columnName];
389
-	}
390
-
391
-	protected function convertDB(Connection $fromDB, Connection $toDB, array $tables, InputInterface $input, OutputInterface $output) {
392
-		$this->config->setSystemValue('maintenance', true);
393
-		$schema = $fromDB->createSchema();
394
-
395
-		try {
396
-			// copy table rows
397
-			foreach($tables as $table) {
398
-				$output->writeln($table);
399
-				$this->copyTable($fromDB, $toDB, $schema->getTable($table), $input, $output);
400
-			}
401
-			if ($input->getArgument('type') === 'pgsql') {
402
-				$tools = new \OC\DB\PgSqlTools($this->config);
403
-				$tools->resynchronizeDatabaseSequences($toDB);
404
-			}
405
-			// save new database config
406
-			$this->saveDBInfo($input);
407
-		} catch(\Exception $e) {
408
-			$this->config->setSystemValue('maintenance', false);
409
-			throw $e;
410
-		}
411
-		$this->config->setSystemValue('maintenance', false);
412
-	}
413
-
414
-	protected function saveDBInfo(InputInterface $input) {
415
-		$type = $input->getArgument('type');
416
-		$username = $input->getArgument('username');
417
-		$dbHost = $input->getArgument('hostname');
418
-		$dbName = $input->getArgument('database');
419
-		$password = $input->getOption('password');
420
-		if ($input->getOption('port')) {
421
-			$dbHost .= ':'.$input->getOption('port');
422
-		}
423
-
424
-		$this->config->setSystemValues([
425
-			'dbtype'		=> $type,
426
-			'dbname'		=> $dbName,
427
-			'dbhost'		=> $dbHost,
428
-			'dbuser'		=> $username,
429
-			'dbpassword'	=> $password,
430
-		]);
431
-	}
432
-
433
-	/**
434
-	 * Return possible values for the named option
435
-	 *
436
-	 * @param string $optionName
437
-	 * @param CompletionContext $context
438
-	 * @return string[]
439
-	 */
440
-	public function completeOptionValues($optionName, CompletionContext $context) {
441
-		return [];
442
-	}
443
-
444
-	/**
445
-	 * Return possible values for the named argument
446
-	 *
447
-	 * @param string $argumentName
448
-	 * @param CompletionContext $context
449
-	 * @return string[]
450
-	 */
451
-	public function completeArgumentValues($argumentName, CompletionContext $context) {
452
-		if ($argumentName === 'type') {
453
-			return ['mysql', 'oci', 'pgsql'];
454
-		}
455
-		return [];
456
-	}
52
+    /**
53
+     * @var \OCP\IConfig
54
+     */
55
+    protected $config;
56
+
57
+    /**
58
+     * @var \OC\DB\ConnectionFactory
59
+     */
60
+    protected $connectionFactory;
61
+
62
+    /** @var array */
63
+    protected $columnTypes;
64
+
65
+    /**
66
+     * @param \OCP\IConfig $config
67
+     * @param \OC\DB\ConnectionFactory $connectionFactory
68
+     */
69
+    public function __construct(IConfig $config, ConnectionFactory $connectionFactory) {
70
+        $this->config = $config;
71
+        $this->connectionFactory = $connectionFactory;
72
+        parent::__construct();
73
+    }
74
+
75
+    protected function configure() {
76
+        $this
77
+            ->setName('db:convert-type')
78
+            ->setDescription('Convert the Nextcloud database to the newly configured one')
79
+            ->addArgument(
80
+                'type',
81
+                InputArgument::REQUIRED,
82
+                'the type of the database to convert to'
83
+            )
84
+            ->addArgument(
85
+                'username',
86
+                InputArgument::REQUIRED,
87
+                'the username of the database to convert to'
88
+            )
89
+            ->addArgument(
90
+                'hostname',
91
+                InputArgument::REQUIRED,
92
+                'the hostname of the database to convert to'
93
+            )
94
+            ->addArgument(
95
+                'database',
96
+                InputArgument::REQUIRED,
97
+                'the name of the database to convert to'
98
+            )
99
+            ->addOption(
100
+                'port',
101
+                null,
102
+                InputOption::VALUE_REQUIRED,
103
+                'the port of the database to convert to'
104
+            )
105
+            ->addOption(
106
+                'password',
107
+                null,
108
+                InputOption::VALUE_REQUIRED,
109
+                'the password of the database to convert to. Will be asked when not specified. Can also be passed via stdin.'
110
+            )
111
+            ->addOption(
112
+                'clear-schema',
113
+                null,
114
+                InputOption::VALUE_NONE,
115
+                'remove all tables from the destination database'
116
+            )
117
+            ->addOption(
118
+                'all-apps',
119
+                null,
120
+                InputOption::VALUE_NONE,
121
+                'whether to create schema for all apps instead of only installed apps'
122
+            )
123
+            ->addOption(
124
+                'chunk-size',
125
+                null,
126
+                InputOption::VALUE_REQUIRED,
127
+                'the maximum number of database rows to handle in a single query, bigger tables will be handled in chunks of this size. Lower this if the process runs out of memory during conversion.',
128
+                1000
129
+            )
130
+        ;
131
+    }
132
+
133
+    protected function validateInput(InputInterface $input, OutputInterface $output) {
134
+        $type = $this->connectionFactory->normalizeType($input->getArgument('type'));
135
+        if ($type === 'sqlite3') {
136
+            throw new \InvalidArgumentException(
137
+                'Converting to SQLite (sqlite3) is currently not supported.'
138
+            );
139
+        }
140
+        if ($type === $this->config->getSystemValue('dbtype', '')) {
141
+            throw new \InvalidArgumentException(sprintf(
142
+                'Can not convert from %1$s to %1$s.',
143
+                $type
144
+            ));
145
+        }
146
+        if ($type === 'oci' && $input->getOption('clear-schema')) {
147
+            // Doctrine unconditionally tries (at least in version 2.3)
148
+            // to drop sequence triggers when dropping a table, even though
149
+            // such triggers may not exist. This results in errors like
150
+            // "ORA-04080: trigger 'OC_STORAGES_AI_PK' does not exist".
151
+            throw new \InvalidArgumentException(
152
+                'The --clear-schema option is not supported when converting to Oracle (oci).'
153
+            );
154
+        }
155
+    }
156
+
157
+    protected function readPassword(InputInterface $input, OutputInterface $output) {
158
+        // Explicitly specified password
159
+        if ($input->getOption('password')) {
160
+            return;
161
+        }
162
+
163
+        // Read from stdin. stream_set_blocking is used to prevent blocking
164
+        // when nothing is passed via stdin.
165
+        stream_set_blocking(STDIN, 0);
166
+        $password = file_get_contents('php://stdin');
167
+        stream_set_blocking(STDIN, 1);
168
+        if (trim($password) !== '') {
169
+            $input->setOption('password', $password);
170
+            return;
171
+        }
172
+
173
+        // Read password by interacting
174
+        if ($input->isInteractive()) {
175
+            /** @var QuestionHelper $helper */
176
+            $helper = $this->getHelper('question');
177
+            $question = new Question('What is the database password?');
178
+            $question->setHidden(true);
179
+            $question->setHiddenFallback(false);
180
+            $password = $helper->ask($input, $output, $question);
181
+            $input->setOption('password', $password);
182
+            return;
183
+        }
184
+    }
185
+
186
+    protected function execute(InputInterface $input, OutputInterface $output) {
187
+        $this->validateInput($input, $output);
188
+        $this->readPassword($input, $output);
189
+
190
+        $fromDB = \OC::$server->getDatabaseConnection();
191
+        $toDB = $this->getToDBConnection($input, $output);
192
+
193
+        if ($input->getOption('clear-schema')) {
194
+            $this->clearSchema($toDB, $input, $output);
195
+        }
196
+
197
+        $this->createSchema($fromDB, $toDB, $input, $output);
198
+
199
+        $toTables = $this->getTables($toDB);
200
+        $fromTables = $this->getTables($fromDB);
201
+
202
+        // warn/fail if there are more tables in 'from' database
203
+        $extraFromTables = array_diff($fromTables, $toTables);
204
+        if (!empty($extraFromTables)) {
205
+            $output->writeln('<comment>The following tables will not be converted:</comment>');
206
+            $output->writeln($extraFromTables);
207
+            if (!$input->getOption('all-apps')) {
208
+                $output->writeln('<comment>Please note that tables belonging to available but currently not installed apps</comment>');
209
+                $output->writeln('<comment>can be included by specifying the --all-apps option.</comment>');
210
+            }
211
+
212
+            /** @var QuestionHelper $helper */
213
+            $helper = $this->getHelper('question');
214
+            $question = new ConfirmationQuestion('Continue with the conversion (y/n)? [n] ', false);
215
+
216
+            if (!$helper->ask($input, $output, $question)) {
217
+                return;
218
+            }
219
+        }
220
+        $intersectingTables = array_intersect($toTables, $fromTables);
221
+        $this->convertDB($fromDB, $toDB, $intersectingTables, $input, $output);
222
+    }
223
+
224
+    protected function createSchema(Connection $fromDB, Connection $toDB, InputInterface $input, OutputInterface $output) {
225
+        $output->writeln('<info>Creating schema in new database</info>');
226
+
227
+        $fromMS = new MigrationService('core', $fromDB);
228
+        $currentMigration = $fromMS->getMigration('current');
229
+        if ($currentMigration !== '0') {
230
+            $toMS = new MigrationService('core', $toDB);
231
+            $toMS->migrate($currentMigration);
232
+        }
233
+
234
+        $schemaManager = new \OC\DB\MDB2SchemaManager($toDB);
235
+        $apps = $input->getOption('all-apps') ? \OC_App::getAllApps() : \OC_App::getEnabledApps();
236
+        foreach($apps as $app) {
237
+            if (file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) {
238
+                $schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml');
239
+            } else {
240
+                // Make sure autoloading works...
241
+                \OC_App::loadApp($app);
242
+                $fromMS = new MigrationService($app, $fromDB);
243
+                $currentMigration = $fromMS->getMigration('current');
244
+                if ($currentMigration !== '0') {
245
+                    $toMS = new MigrationService($app, $toDB);
246
+                    $toMS->migrate($currentMigration);
247
+                }
248
+            }
249
+        }
250
+    }
251
+
252
+    protected function getToDBConnection(InputInterface $input, OutputInterface $output) {
253
+        $type = $input->getArgument('type');
254
+        $connectionParams = $this->connectionFactory->createConnectionParams();
255
+        $connectionParams = array_merge($connectionParams, [
256
+            'host' => $input->getArgument('hostname'),
257
+            'user' => $input->getArgument('username'),
258
+            'password' => $input->getOption('password'),
259
+            'dbname' => $input->getArgument('database'),
260
+        ]);
261
+        if ($input->getOption('port')) {
262
+            $connectionParams['port'] = $input->getOption('port');
263
+        }
264
+        return $this->connectionFactory->getConnection($type, $connectionParams);
265
+    }
266
+
267
+    protected function clearSchema(Connection $db, InputInterface $input, OutputInterface $output) {
268
+        $toTables = $this->getTables($db);
269
+        if (!empty($toTables)) {
270
+            $output->writeln('<info>Clearing schema in new database</info>');
271
+        }
272
+        foreach($toTables as $table) {
273
+            $db->getSchemaManager()->dropTable($table);
274
+        }
275
+    }
276
+
277
+    protected function getTables(Connection $db) {
278
+        $filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
279
+        $db->getConfiguration()->
280
+            setFilterSchemaAssetsExpression($filterExpression);
281
+        return $db->getSchemaManager()->listTableNames();
282
+    }
283
+
284
+    /**
285
+     * @param Connection $fromDB
286
+     * @param Connection $toDB
287
+     * @param Table $table
288
+     * @param InputInterface $input
289
+     * @param OutputInterface $output
290
+     * @suppress SqlInjectionChecker
291
+     */
292
+    protected function copyTable(Connection $fromDB, Connection $toDB, Table $table, InputInterface $input, OutputInterface $output) {
293
+        if ($table->getName() === $toDB->getPrefix() . 'migrations') {
294
+            $output->writeln('<comment>Skipping migrations table because it was already filled by running the migrations</comment>');
295
+            return;
296
+        }
297
+
298
+        $chunkSize = $input->getOption('chunk-size');
299
+
300
+        $query = $fromDB->getQueryBuilder();
301
+        $query->automaticTablePrefix(false);
302
+        $query->selectAlias($query->createFunction('COUNT(*)'), 'num_entries')
303
+            ->from($table->getName());
304
+        $result = $query->execute();
305
+        $count = $result->fetchColumn();
306
+        $result->closeCursor();
307
+
308
+        $numChunks = ceil($count/$chunkSize);
309
+        if ($numChunks > 1) {
310
+            $output->writeln('chunked query, ' . $numChunks . ' chunks');
311
+        }
312
+
313
+        $progress = new ProgressBar($output, $count);
314
+        $progress->start();
315
+        $redraw = $count > $chunkSize ? 100 : ($count > 100 ? 5 : 1);
316
+        $progress->setRedrawFrequency($redraw);
317
+
318
+        $query = $fromDB->getQueryBuilder();
319
+        $query->automaticTablePrefix(false);
320
+        $query->select('*')
321
+            ->from($table->getName())
322
+            ->setMaxResults($chunkSize);
323
+
324
+        try {
325
+            $orderColumns = $table->getPrimaryKeyColumns();
326
+        } catch (DBALException $e) {
327
+            $orderColumns = [];
328
+            foreach ($table->getColumns() as $column) {
329
+                $orderColumns[] = $column->getName();
330
+            }
331
+        }
332
+
333
+        foreach ($orderColumns as $column) {
334
+            $query->addOrderBy($column);
335
+        }
336
+
337
+        $insertQuery = $toDB->getQueryBuilder();
338
+        $insertQuery->automaticTablePrefix(false);
339
+        $insertQuery->insert($table->getName());
340
+        $parametersCreated = false;
341
+
342
+        for ($chunk = 0; $chunk < $numChunks; $chunk++) {
343
+            $query->setFirstResult($chunk * $chunkSize);
344
+
345
+            $result = $query->execute();
346
+
347
+            while ($row = $result->fetch()) {
348
+                $progress->advance();
349
+                if (!$parametersCreated) {
350
+                    foreach ($row as $key => $value) {
351
+                        $insertQuery->setValue($key, $insertQuery->createParameter($key));
352
+                    }
353
+                    $parametersCreated = true;
354
+                }
355
+
356
+                foreach ($row as $key => $value) {
357
+                    $type = $this->getColumnType($table, $key);
358
+                    if ($type !== false) {
359
+                        $insertQuery->setParameter($key, $value, $type);
360
+                    } else {
361
+                        $insertQuery->setParameter($key, $value);
362
+                    }
363
+                }
364
+                $insertQuery->execute();
365
+            }
366
+            $result->closeCursor();
367
+        }
368
+        $progress->finish();
369
+    }
370
+
371
+    protected function getColumnType(Table $table, $columnName) {
372
+        $tableName = $table->getName();
373
+        if (isset($this->columnTypes[$tableName][$columnName])) {
374
+            return $this->columnTypes[$tableName][$columnName];
375
+        }
376
+
377
+        $type = $table->getColumn($columnName)->getType()->getName();
378
+
379
+        switch ($type) {
380
+            case Type::BLOB:
381
+            case Type::TEXT:
382
+                $this->columnTypes[$tableName][$columnName] = IQueryBuilder::PARAM_LOB;
383
+                break;
384
+            default:
385
+                $this->columnTypes[$tableName][$columnName] = false;
386
+        }
387
+
388
+        return $this->columnTypes[$tableName][$columnName];
389
+    }
390
+
391
+    protected function convertDB(Connection $fromDB, Connection $toDB, array $tables, InputInterface $input, OutputInterface $output) {
392
+        $this->config->setSystemValue('maintenance', true);
393
+        $schema = $fromDB->createSchema();
394
+
395
+        try {
396
+            // copy table rows
397
+            foreach($tables as $table) {
398
+                $output->writeln($table);
399
+                $this->copyTable($fromDB, $toDB, $schema->getTable($table), $input, $output);
400
+            }
401
+            if ($input->getArgument('type') === 'pgsql') {
402
+                $tools = new \OC\DB\PgSqlTools($this->config);
403
+                $tools->resynchronizeDatabaseSequences($toDB);
404
+            }
405
+            // save new database config
406
+            $this->saveDBInfo($input);
407
+        } catch(\Exception $e) {
408
+            $this->config->setSystemValue('maintenance', false);
409
+            throw $e;
410
+        }
411
+        $this->config->setSystemValue('maintenance', false);
412
+    }
413
+
414
+    protected function saveDBInfo(InputInterface $input) {
415
+        $type = $input->getArgument('type');
416
+        $username = $input->getArgument('username');
417
+        $dbHost = $input->getArgument('hostname');
418
+        $dbName = $input->getArgument('database');
419
+        $password = $input->getOption('password');
420
+        if ($input->getOption('port')) {
421
+            $dbHost .= ':'.$input->getOption('port');
422
+        }
423
+
424
+        $this->config->setSystemValues([
425
+            'dbtype'		=> $type,
426
+            'dbname'		=> $dbName,
427
+            'dbhost'		=> $dbHost,
428
+            'dbuser'		=> $username,
429
+            'dbpassword'	=> $password,
430
+        ]);
431
+    }
432
+
433
+    /**
434
+     * Return possible values for the named option
435
+     *
436
+     * @param string $optionName
437
+     * @param CompletionContext $context
438
+     * @return string[]
439
+     */
440
+    public function completeOptionValues($optionName, CompletionContext $context) {
441
+        return [];
442
+    }
443
+
444
+    /**
445
+     * Return possible values for the named argument
446
+     *
447
+     * @param string $argumentName
448
+     * @param CompletionContext $context
449
+     * @return string[]
450
+     */
451
+    public function completeArgumentValues($argumentName, CompletionContext $context) {
452
+        if ($argumentName === 'type') {
453
+            return ['mysql', 'oci', 'pgsql'];
454
+        }
455
+        return [];
456
+    }
457 457
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
 
234 234
 		$schemaManager = new \OC\DB\MDB2SchemaManager($toDB);
235 235
 		$apps = $input->getOption('all-apps') ? \OC_App::getAllApps() : \OC_App::getEnabledApps();
236
-		foreach($apps as $app) {
236
+		foreach ($apps as $app) {
237 237
 			if (file_exists(\OC_App::getAppPath($app).'/appinfo/database.xml')) {
238 238
 				$schemaManager->createDbFromStructure(\OC_App::getAppPath($app).'/appinfo/database.xml');
239 239
 			} else {
@@ -269,13 +269,13 @@  discard block
 block discarded – undo
269 269
 		if (!empty($toTables)) {
270 270
 			$output->writeln('<info>Clearing schema in new database</info>');
271 271
 		}
272
-		foreach($toTables as $table) {
272
+		foreach ($toTables as $table) {
273 273
 			$db->getSchemaManager()->dropTable($table);
274 274
 		}
275 275
 	}
276 276
 
277 277
 	protected function getTables(Connection $db) {
278
-		$filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/';
278
+		$filterExpression = '/^'.preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')).'/';
279 279
 		$db->getConfiguration()->
280 280
 			setFilterSchemaAssetsExpression($filterExpression);
281 281
 		return $db->getSchemaManager()->listTableNames();
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
 	 * @suppress SqlInjectionChecker
291 291
 	 */
292 292
 	protected function copyTable(Connection $fromDB, Connection $toDB, Table $table, InputInterface $input, OutputInterface $output) {
293
-		if ($table->getName() === $toDB->getPrefix() . 'migrations') {
293
+		if ($table->getName() === $toDB->getPrefix().'migrations') {
294 294
 			$output->writeln('<comment>Skipping migrations table because it was already filled by running the migrations</comment>');
295 295
 			return;
296 296
 		}
@@ -305,9 +305,9 @@  discard block
 block discarded – undo
305 305
 		$count = $result->fetchColumn();
306 306
 		$result->closeCursor();
307 307
 
308
-		$numChunks = ceil($count/$chunkSize);
308
+		$numChunks = ceil($count / $chunkSize);
309 309
 		if ($numChunks > 1) {
310
-			$output->writeln('chunked query, ' . $numChunks . ' chunks');
310
+			$output->writeln('chunked query, '.$numChunks.' chunks');
311 311
 		}
312 312
 
313 313
 		$progress = new ProgressBar($output, $count);
@@ -394,7 +394,7 @@  discard block
 block discarded – undo
394 394
 
395 395
 		try {
396 396
 			// copy table rows
397
-			foreach($tables as $table) {
397
+			foreach ($tables as $table) {
398 398
 				$output->writeln($table);
399 399
 				$this->copyTable($fromDB, $toDB, $schema->getTable($table), $input, $output);
400 400
 			}
@@ -404,7 +404,7 @@  discard block
 block discarded – undo
404 404
 			}
405 405
 			// save new database config
406 406
 			$this->saveDBInfo($input);
407
-		} catch(\Exception $e) {
407
+		} catch (\Exception $e) {
408 408
 			$this->config->setSystemValue('maintenance', false);
409 409
 			throw $e;
410 410
 		}
Please login to merge, or discard this patch.
lib/private/Setup/PostgreSQL.php 1 patch
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -32,137 +32,137 @@
 block discarded – undo
32 32
 use OCP\IDBConnection;
33 33
 
34 34
 class PostgreSQL extends AbstractDatabase {
35
-	public $dbprettyname = 'PostgreSQL';
36
-
37
-	/**
38
-	 * @param string $username
39
-	 * @throws \OC\DatabaseSetupException
40
-	 * @suppress SqlInjectionChecker
41
-	 */
42
-	public function setupDatabase($username) {
43
-		try {
44
-			$connection = $this->connect([
45
-				'dbname' => 'postgres'
46
-			]);
47
-			//check for roles creation rights in postgresql
48
-			$builder = $connection->getQueryBuilder();
49
-			$builder->automaticTablePrefix(false);
50
-			$query = $builder
51
-				->select('rolname')
52
-				->from('pg_roles')
53
-				->where($builder->expr()->eq('rolcreaterole', new Literal('TRUE')))
54
-				->andWhere($builder->expr()->eq('rolname', $builder->createNamedParameter($this->dbUser)));
55
-
56
-			try {
57
-				$result = $query->execute();
58
-				$canCreateRoles = $result->rowCount() > 0;
59
-			} catch (DatabaseException $e) {
60
-				$canCreateRoles = false;
61
-			}
62
-
63
-			if ($canCreateRoles) {
64
-				//use the admin login data for the new database user
65
-
66
-				//add prefix to the postgresql user name to prevent collisions
67
-				$this->dbUser = 'oc_' . strtolower($username);
68
-				//create a new password so we don't need to store the admin config in the config file
69
-				$this->dbPassword = \OC::$server->getSecureRandom()->generate(30, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_DIGITS);
70
-
71
-				$this->createDBUser($connection);
72
-			}
73
-
74
-			$this->config->setValues([
75
-				'dbuser' => $this->dbUser,
76
-				'dbpassword' => $this->dbPassword,
77
-			]);
78
-
79
-			//create the database
80
-			$this->createDatabase($connection);
81
-			$query = $connection->prepare("select count(*) FROM pg_class WHERE relname=? limit 1");
82
-			$query->execute([$this->tablePrefix . "users"]);
83
-			$tablesSetup = $query->fetchColumn() > 0;
84
-
85
-			// the connection to dbname=postgres is not needed anymore
86
-			$connection->close();
87
-		} catch (\Exception $e) {
88
-			$this->logger->logException($e);
89
-			$this->logger->warning('Error trying to connect as "postgres", assuming database is setup and tables need to be created');
90
-			$tablesSetup = false;
91
-			$this->config->setValues([
92
-				'dbuser' => $this->dbUser,
93
-				'dbpassword' => $this->dbPassword,
94
-			]);
95
-		}
96
-
97
-		// connect to the ownCloud database (dbname=$this->dbname) and check if it needs to be filled
98
-		$this->dbUser = $this->config->getValue('dbuser');
99
-		$this->dbPassword = $this->config->getValue('dbpassword');
100
-		$connection = $this->connect();
101
-		try {
102
-			$connection->connect();
103
-		} catch (\Exception $e) {
104
-			$this->logger->logException($e);
105
-			throw new \OC\DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'),
106
-				$this->trans->t('You need to enter details of an existing account.'));
107
-		}
108
-	}
109
-
110
-	private function createDatabase(IDBConnection $connection) {
111
-		if (!$this->databaseExists($connection)) {
112
-			//The database does not exists... let's create it
113
-			$query = $connection->prepare("CREATE DATABASE " . addslashes($this->dbName) . " OWNER " . addslashes($this->dbUser));
114
-			try {
115
-				$query->execute();
116
-			} catch (DatabaseException $e) {
117
-				$this->logger->error('Error while trying to create database');
118
-				$this->logger->logException($e);
119
-			}
120
-		} else {
121
-			$query = $connection->prepare("REVOKE ALL PRIVILEGES ON DATABASE " . addslashes($this->dbName) . " FROM PUBLIC");
122
-			try {
123
-				$query->execute();
124
-			} catch (DatabaseException $e) {
125
-				$this->logger->error('Error while trying to restrict database permissions');
126
-				$this->logger->logException($e);
127
-			}
128
-		}
129
-	}
130
-
131
-	private function userExists(IDBConnection $connection) {
132
-		$builder = $connection->getQueryBuilder();
133
-		$builder->automaticTablePrefix(false);
134
-		$query = $builder->select('*')
135
-			->from('pg_roles')
136
-			->where($builder->expr()->eq('rolname', $builder->createNamedParameter($this->dbUser)));
137
-		$result = $query->execute();
138
-		return $result->rowCount() > 0;
139
-	}
140
-
141
-	private function databaseExists(IDBConnection $connection) {
142
-		$builder = $connection->getQueryBuilder();
143
-		$builder->automaticTablePrefix(false);
144
-		$query = $builder->select('datname')
145
-			->from('pg_database')
146
-			->where($builder->expr()->eq('datname', $builder->createNamedParameter($this->dbName)));
147
-		$result = $query->execute();
148
-		return $result->rowCount() > 0;
149
-	}
150
-
151
-	private function createDBUser(IDBConnection $connection) {
152
-		$dbUser = $this->dbUser;
153
-		try {
154
-			$i = 1;
155
-			while ($this->userExists($connection)) {
156
-				$i++;
157
-				$this->dbUser = $dbUser . $i;
158
-			};
159
-
160
-			// create the user
161
-			$query = $connection->prepare("CREATE USER " . addslashes($this->dbUser) . " CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
162
-			$query->execute();
163
-		} catch (DatabaseException $e) {
164
-			$this->logger->error('Error while trying to create database user');
165
-			$this->logger->logException($e);
166
-		}
167
-	}
35
+    public $dbprettyname = 'PostgreSQL';
36
+
37
+    /**
38
+     * @param string $username
39
+     * @throws \OC\DatabaseSetupException
40
+     * @suppress SqlInjectionChecker
41
+     */
42
+    public function setupDatabase($username) {
43
+        try {
44
+            $connection = $this->connect([
45
+                'dbname' => 'postgres'
46
+            ]);
47
+            //check for roles creation rights in postgresql
48
+            $builder = $connection->getQueryBuilder();
49
+            $builder->automaticTablePrefix(false);
50
+            $query = $builder
51
+                ->select('rolname')
52
+                ->from('pg_roles')
53
+                ->where($builder->expr()->eq('rolcreaterole', new Literal('TRUE')))
54
+                ->andWhere($builder->expr()->eq('rolname', $builder->createNamedParameter($this->dbUser)));
55
+
56
+            try {
57
+                $result = $query->execute();
58
+                $canCreateRoles = $result->rowCount() > 0;
59
+            } catch (DatabaseException $e) {
60
+                $canCreateRoles = false;
61
+            }
62
+
63
+            if ($canCreateRoles) {
64
+                //use the admin login data for the new database user
65
+
66
+                //add prefix to the postgresql user name to prevent collisions
67
+                $this->dbUser = 'oc_' . strtolower($username);
68
+                //create a new password so we don't need to store the admin config in the config file
69
+                $this->dbPassword = \OC::$server->getSecureRandom()->generate(30, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_DIGITS);
70
+
71
+                $this->createDBUser($connection);
72
+            }
73
+
74
+            $this->config->setValues([
75
+                'dbuser' => $this->dbUser,
76
+                'dbpassword' => $this->dbPassword,
77
+            ]);
78
+
79
+            //create the database
80
+            $this->createDatabase($connection);
81
+            $query = $connection->prepare("select count(*) FROM pg_class WHERE relname=? limit 1");
82
+            $query->execute([$this->tablePrefix . "users"]);
83
+            $tablesSetup = $query->fetchColumn() > 0;
84
+
85
+            // the connection to dbname=postgres is not needed anymore
86
+            $connection->close();
87
+        } catch (\Exception $e) {
88
+            $this->logger->logException($e);
89
+            $this->logger->warning('Error trying to connect as "postgres", assuming database is setup and tables need to be created');
90
+            $tablesSetup = false;
91
+            $this->config->setValues([
92
+                'dbuser' => $this->dbUser,
93
+                'dbpassword' => $this->dbPassword,
94
+            ]);
95
+        }
96
+
97
+        // connect to the ownCloud database (dbname=$this->dbname) and check if it needs to be filled
98
+        $this->dbUser = $this->config->getValue('dbuser');
99
+        $this->dbPassword = $this->config->getValue('dbpassword');
100
+        $connection = $this->connect();
101
+        try {
102
+            $connection->connect();
103
+        } catch (\Exception $e) {
104
+            $this->logger->logException($e);
105
+            throw new \OC\DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'),
106
+                $this->trans->t('You need to enter details of an existing account.'));
107
+        }
108
+    }
109
+
110
+    private function createDatabase(IDBConnection $connection) {
111
+        if (!$this->databaseExists($connection)) {
112
+            //The database does not exists... let's create it
113
+            $query = $connection->prepare("CREATE DATABASE " . addslashes($this->dbName) . " OWNER " . addslashes($this->dbUser));
114
+            try {
115
+                $query->execute();
116
+            } catch (DatabaseException $e) {
117
+                $this->logger->error('Error while trying to create database');
118
+                $this->logger->logException($e);
119
+            }
120
+        } else {
121
+            $query = $connection->prepare("REVOKE ALL PRIVILEGES ON DATABASE " . addslashes($this->dbName) . " FROM PUBLIC");
122
+            try {
123
+                $query->execute();
124
+            } catch (DatabaseException $e) {
125
+                $this->logger->error('Error while trying to restrict database permissions');
126
+                $this->logger->logException($e);
127
+            }
128
+        }
129
+    }
130
+
131
+    private function userExists(IDBConnection $connection) {
132
+        $builder = $connection->getQueryBuilder();
133
+        $builder->automaticTablePrefix(false);
134
+        $query = $builder->select('*')
135
+            ->from('pg_roles')
136
+            ->where($builder->expr()->eq('rolname', $builder->createNamedParameter($this->dbUser)));
137
+        $result = $query->execute();
138
+        return $result->rowCount() > 0;
139
+    }
140
+
141
+    private function databaseExists(IDBConnection $connection) {
142
+        $builder = $connection->getQueryBuilder();
143
+        $builder->automaticTablePrefix(false);
144
+        $query = $builder->select('datname')
145
+            ->from('pg_database')
146
+            ->where($builder->expr()->eq('datname', $builder->createNamedParameter($this->dbName)));
147
+        $result = $query->execute();
148
+        return $result->rowCount() > 0;
149
+    }
150
+
151
+    private function createDBUser(IDBConnection $connection) {
152
+        $dbUser = $this->dbUser;
153
+        try {
154
+            $i = 1;
155
+            while ($this->userExists($connection)) {
156
+                $i++;
157
+                $this->dbUser = $dbUser . $i;
158
+            };
159
+
160
+            // create the user
161
+            $query = $connection->prepare("CREATE USER " . addslashes($this->dbUser) . " CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
162
+            $query->execute();
163
+        } catch (DatabaseException $e) {
164
+            $this->logger->error('Error while trying to create database user');
165
+            $this->logger->logException($e);
166
+        }
167
+    }
168 168
 }
Please login to merge, or discard this patch.