Completed
Push — master ( 1ef465...189e1f )
by
unknown
25:57
created
apps/files/lib/Command/RepairTree.php 2 patches
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -16,113 +16,113 @@
 block discarded – undo
16 16
 use Symfony\Component\Console\Output\OutputInterface;
17 17
 
18 18
 class RepairTree extends Command {
19
-	public const CHUNK_SIZE = 200;
20
-
21
-	public function __construct(
22
-		protected IDBConnection $connection,
23
-	) {
24
-		parent::__construct();
25
-	}
26
-
27
-	protected function configure(): void {
28
-		$this
29
-			->setName('files:repair-tree')
30
-			->setDescription('Try and repair malformed filesystem tree structures (may be necessary to run multiple times for nested malformations)')
31
-			->addOption('dry-run')
32
-			->addOption('storage-id', 's', InputOption::VALUE_OPTIONAL, 'If set, only repair files within the given storage numeric ID', null)
33
-			->addOption('path', 'p', InputOption::VALUE_OPTIONAL, 'If set, only repair files within the given path', null);
34
-	}
35
-
36
-	public function execute(InputInterface $input, OutputInterface $output): int {
37
-		$rows = $this->findBrokenTreeBits(
38
-			$input->getOption('storage-id'),
39
-			$input->getOption('path'),
40
-		);
41
-		$fix = !$input->getOption('dry-run');
42
-
43
-		$output->writeln('Found ' . count($rows) . ' file entries with an invalid path');
44
-
45
-		if ($fix) {
46
-			$this->connection->beginTransaction();
47
-		}
48
-
49
-		$query = $this->connection->getQueryBuilder();
50
-		$query->update('filecache')
51
-			->set('path', $query->createParameter('path'))
52
-			->set('path_hash', $query->func()->md5($query->createParameter('path')))
53
-			->set('storage', $query->createParameter('storage'))
54
-			->where($query->expr()->eq('fileid', $query->createParameter('fileid')));
55
-
56
-		foreach ($rows as $row) {
57
-			$output->writeln("Path of file {$row['fileid']} is {$row['path']} but should be {$row['parent_path']}/{$row['name']} based on its parent", OutputInterface::VERBOSITY_VERBOSE);
58
-
59
-			if ($fix) {
60
-				$fileId = $this->getFileId((int)$row['parent_storage'], $row['parent_path'] . '/' . $row['name']);
61
-				if ($fileId > 0) {
62
-					$output->writeln("Cache entry has already be recreated with id $fileId, deleting instead");
63
-					$this->deleteById((int)$row['fileid']);
64
-				} else {
65
-					$query->setParameters([
66
-						'fileid' => $row['fileid'],
67
-						'path' => $row['parent_path'] . '/' . $row['name'],
68
-						'storage' => $row['parent_storage'],
69
-					]);
70
-					$query->executeStatement();
71
-				}
72
-			}
73
-		}
74
-
75
-		if ($fix) {
76
-			$this->connection->commit();
77
-		}
78
-
79
-		return self::SUCCESS;
80
-	}
81
-
82
-	private function getFileId(int $storage, string $path) {
83
-		$query = $this->connection->getQueryBuilder();
84
-		$query->select('fileid')
85
-			->from('filecache')
86
-			->where($query->expr()->eq('storage', $query->createNamedParameter($storage)))
87
-			->andWhere($query->expr()->eq('path_hash', $query->createNamedParameter(md5($path))));
88
-		return $query->executeQuery()->fetchOne();
89
-	}
90
-
91
-	private function deleteById(int $fileId): void {
92
-		$query = $this->connection->getQueryBuilder();
93
-		$query->delete('filecache')
94
-			->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId)));
95
-		$query->executeStatement();
96
-	}
97
-
98
-	private function findBrokenTreeBits(?string $storageId, ?string $path): array {
99
-		$query = $this->connection->getQueryBuilder();
100
-
101
-		$query->select('f.fileid', 'f.path', 'f.parent', 'f.name')
102
-			->selectAlias('p.path', 'parent_path')
103
-			->selectAlias('p.storage', 'parent_storage')
104
-			->from('filecache', 'f')
105
-			->innerJoin('f', 'filecache', 'p', $query->expr()->eq('f.parent', 'p.fileid'))
106
-			->where($query->expr()->orX(
107
-				$query->expr()->andX(
108
-					$query->expr()->neq('p.path_hash', $query->createNamedParameter(md5(''))),
109
-					$query->expr()->neq('f.path', $query->func()->concat('p.path', $query->func()->concat($query->createNamedParameter('/'), 'f.name')))
110
-				),
111
-				$query->expr()->andX(
112
-					$query->expr()->eq('p.path_hash', $query->createNamedParameter(md5(''))),
113
-					$query->expr()->neq('f.path', 'f.name')
114
-				),
115
-				$query->expr()->neq('f.storage', 'p.storage')
116
-			));
117
-
118
-		if ($storageId !== null) {
119
-			$query->andWhere($query->expr()->eq('f.storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
120
-		}
121
-
122
-		if ($path !== null) {
123
-			$query->andWhere($query->expr()->like('f.path', $query->createNamedParameter($path . '%')));
124
-		}
125
-
126
-		return $query->executeQuery()->fetchAllAssociative();
127
-	}
19
+    public const CHUNK_SIZE = 200;
20
+
21
+    public function __construct(
22
+        protected IDBConnection $connection,
23
+    ) {
24
+        parent::__construct();
25
+    }
26
+
27
+    protected function configure(): void {
28
+        $this
29
+            ->setName('files:repair-tree')
30
+            ->setDescription('Try and repair malformed filesystem tree structures (may be necessary to run multiple times for nested malformations)')
31
+            ->addOption('dry-run')
32
+            ->addOption('storage-id', 's', InputOption::VALUE_OPTIONAL, 'If set, only repair files within the given storage numeric ID', null)
33
+            ->addOption('path', 'p', InputOption::VALUE_OPTIONAL, 'If set, only repair files within the given path', null);
34
+    }
35
+
36
+    public function execute(InputInterface $input, OutputInterface $output): int {
37
+        $rows = $this->findBrokenTreeBits(
38
+            $input->getOption('storage-id'),
39
+            $input->getOption('path'),
40
+        );
41
+        $fix = !$input->getOption('dry-run');
42
+
43
+        $output->writeln('Found ' . count($rows) . ' file entries with an invalid path');
44
+
45
+        if ($fix) {
46
+            $this->connection->beginTransaction();
47
+        }
48
+
49
+        $query = $this->connection->getQueryBuilder();
50
+        $query->update('filecache')
51
+            ->set('path', $query->createParameter('path'))
52
+            ->set('path_hash', $query->func()->md5($query->createParameter('path')))
53
+            ->set('storage', $query->createParameter('storage'))
54
+            ->where($query->expr()->eq('fileid', $query->createParameter('fileid')));
55
+
56
+        foreach ($rows as $row) {
57
+            $output->writeln("Path of file {$row['fileid']} is {$row['path']} but should be {$row['parent_path']}/{$row['name']} based on its parent", OutputInterface::VERBOSITY_VERBOSE);
58
+
59
+            if ($fix) {
60
+                $fileId = $this->getFileId((int)$row['parent_storage'], $row['parent_path'] . '/' . $row['name']);
61
+                if ($fileId > 0) {
62
+                    $output->writeln("Cache entry has already be recreated with id $fileId, deleting instead");
63
+                    $this->deleteById((int)$row['fileid']);
64
+                } else {
65
+                    $query->setParameters([
66
+                        'fileid' => $row['fileid'],
67
+                        'path' => $row['parent_path'] . '/' . $row['name'],
68
+                        'storage' => $row['parent_storage'],
69
+                    ]);
70
+                    $query->executeStatement();
71
+                }
72
+            }
73
+        }
74
+
75
+        if ($fix) {
76
+            $this->connection->commit();
77
+        }
78
+
79
+        return self::SUCCESS;
80
+    }
81
+
82
+    private function getFileId(int $storage, string $path) {
83
+        $query = $this->connection->getQueryBuilder();
84
+        $query->select('fileid')
85
+            ->from('filecache')
86
+            ->where($query->expr()->eq('storage', $query->createNamedParameter($storage)))
87
+            ->andWhere($query->expr()->eq('path_hash', $query->createNamedParameter(md5($path))));
88
+        return $query->executeQuery()->fetchOne();
89
+    }
90
+
91
+    private function deleteById(int $fileId): void {
92
+        $query = $this->connection->getQueryBuilder();
93
+        $query->delete('filecache')
94
+            ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId)));
95
+        $query->executeStatement();
96
+    }
97
+
98
+    private function findBrokenTreeBits(?string $storageId, ?string $path): array {
99
+        $query = $this->connection->getQueryBuilder();
100
+
101
+        $query->select('f.fileid', 'f.path', 'f.parent', 'f.name')
102
+            ->selectAlias('p.path', 'parent_path')
103
+            ->selectAlias('p.storage', 'parent_storage')
104
+            ->from('filecache', 'f')
105
+            ->innerJoin('f', 'filecache', 'p', $query->expr()->eq('f.parent', 'p.fileid'))
106
+            ->where($query->expr()->orX(
107
+                $query->expr()->andX(
108
+                    $query->expr()->neq('p.path_hash', $query->createNamedParameter(md5(''))),
109
+                    $query->expr()->neq('f.path', $query->func()->concat('p.path', $query->func()->concat($query->createNamedParameter('/'), 'f.name')))
110
+                ),
111
+                $query->expr()->andX(
112
+                    $query->expr()->eq('p.path_hash', $query->createNamedParameter(md5(''))),
113
+                    $query->expr()->neq('f.path', 'f.name')
114
+                ),
115
+                $query->expr()->neq('f.storage', 'p.storage')
116
+            ));
117
+
118
+        if ($storageId !== null) {
119
+            $query->andWhere($query->expr()->eq('f.storage', $query->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
120
+        }
121
+
122
+        if ($path !== null) {
123
+            $query->andWhere($query->expr()->like('f.path', $query->createNamedParameter($path . '%')));
124
+        }
125
+
126
+        return $query->executeQuery()->fetchAllAssociative();
127
+    }
128 128
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
 		);
41 41
 		$fix = !$input->getOption('dry-run');
42 42
 
43
-		$output->writeln('Found ' . count($rows) . ' file entries with an invalid path');
43
+		$output->writeln('Found '.count($rows).' file entries with an invalid path');
44 44
 
45 45
 		if ($fix) {
46 46
 			$this->connection->beginTransaction();
@@ -57,14 +57,14 @@  discard block
 block discarded – undo
57 57
 			$output->writeln("Path of file {$row['fileid']} is {$row['path']} but should be {$row['parent_path']}/{$row['name']} based on its parent", OutputInterface::VERBOSITY_VERBOSE);
58 58
 
59 59
 			if ($fix) {
60
-				$fileId = $this->getFileId((int)$row['parent_storage'], $row['parent_path'] . '/' . $row['name']);
60
+				$fileId = $this->getFileId((int) $row['parent_storage'], $row['parent_path'].'/'.$row['name']);
61 61
 				if ($fileId > 0) {
62 62
 					$output->writeln("Cache entry has already be recreated with id $fileId, deleting instead");
63
-					$this->deleteById((int)$row['fileid']);
63
+					$this->deleteById((int) $row['fileid']);
64 64
 				} else {
65 65
 					$query->setParameters([
66 66
 						'fileid' => $row['fileid'],
67
-						'path' => $row['parent_path'] . '/' . $row['name'],
67
+						'path' => $row['parent_path'].'/'.$row['name'],
68 68
 						'storage' => $row['parent_storage'],
69 69
 					]);
70 70
 					$query->executeStatement();
@@ -120,7 +120,7 @@  discard block
 block discarded – undo
120 120
 		}
121 121
 
122 122
 		if ($path !== null) {
123
-			$query->andWhere($query->expr()->like('f.path', $query->createNamedParameter($path . '%')));
123
+			$query->andWhere($query->expr()->like('f.path', $query->createNamedParameter($path.'%')));
124 124
 		}
125 125
 
126 126
 		return $query->executeQuery()->fetchAllAssociative();
Please login to merge, or discard this patch.