setName('files:repair-tree') ->setDescription('Try and repair malformed filesystem tree structures') ->addOption('dry-run'); } public function execute(InputInterface $input, OutputInterface $output): int { $rows = $this->findBrokenTreeBits(); $fix = !$input->getOption('dry-run'); $output->writeln('Found ' . count($rows) . ' file entries with an invalid path'); if ($fix) { $this->connection->beginTransaction(); } $query = $this->connection->getQueryBuilder(); $query->update('filecache') ->set('path', $query->createParameter('path')) ->set('path_hash', $query->func()->md5($query->createParameter('path'))) ->set('storage', $query->createParameter('storage')) ->where($query->expr()->eq('fileid', $query->createParameter('fileid'))); foreach ($rows as $row) { $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); if ($fix) { $fileId = $this->getFileId((int)$row['parent_storage'], $row['parent_path'] . '/' . $row['name']); if ($fileId > 0) { $output->writeln("Cache entry has already be recreated with id $fileId, deleting instead"); $this->deleteById((int)$row['fileid']); } else { $query->setParameters([ 'fileid' => $row['fileid'], 'path' => $row['parent_path'] . '/' . $row['name'], 'storage' => $row['parent_storage'], ]); $query->execute(); } } } if ($fix) { $this->connection->commit(); } return self::SUCCESS; } private function getFileId(int $storage, string $path) { $query = $this->connection->getQueryBuilder(); $query->select('fileid') ->from('filecache') ->where($query->expr()->eq('storage', $query->createNamedParameter($storage))) ->andWhere($query->expr()->eq('path_hash', $query->createNamedParameter(md5($path)))); return $query->execute()->fetch(\PDO::FETCH_COLUMN); } private function deleteById(int $fileId): void { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId))); $query->execute(); } private function findBrokenTreeBits(): array { $query = $this->connection->getQueryBuilder(); $query->select('f.fileid', 'f.path', 'f.parent', 'f.name') ->selectAlias('p.path', 'parent_path') ->selectAlias('p.storage', 'parent_storage') ->from('filecache', 'f') ->innerJoin('f', 'filecache', 'p', $query->expr()->eq('f.parent', 'p.fileid')) ->where($query->expr()->orX( $query->expr()->andX( $query->expr()->neq('p.path_hash', $query->createNamedParameter(md5(''))), $query->expr()->neq('f.path', $query->func()->concat('p.path', $query->func()->concat($query->createNamedParameter('/'), 'f.name'))) ), $query->expr()->andX( $query->expr()->eq('p.path_hash', $query->createNamedParameter(md5(''))), $query->expr()->neq('f.path', 'f.name') ), $query->expr()->neq('f.storage', 'p.storage') )); return $query->execute()->fetchAll(); } } >/golang.org/x/net/context/pre_go19.go
blob: b105f80be4fe2bbcb225ae4343b551fc6d851b15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109