Completed
Pull Request — master (#6034)
by Joas
15:24
created
lib/private/Repair/NC13/RepairInvalidPaths.php 3 patches
Doc Comments   +3 added lines patch added patch discarded remove patch
@@ -82,6 +82,9 @@
 block discarded – undo
82 82
 		return $rows;
83 83
 	}
84 84
 
85
+	/**
86
+	 * @param string $path
87
+	 */
85 88
 	private function getId($storage, $path) {
86 89
 		if (!$this->getIdQuery) {
87 90
 			$builder = $this->connection->getQueryBuilder();
Please login to merge, or discard this patch.
Indentation   +153 added lines, -153 removed lines patch added patch discarded remove patch
@@ -29,157 +29,157 @@
 block discarded – undo
29 29
 use OCP\Migration\IRepairStep;
30 30
 
31 31
 class RepairInvalidPaths implements IRepairStep {
32
-	const MAX_ROWS = 200;
33
-
34
-	/** @var IDBConnection */
35
-	private $connection;
36
-	/** @var IConfig */
37
-	private $config;
38
-
39
-	private $getIdQuery;
40
-	private $updateQuery;
41
-	private $reparentQuery;
42
-	private $deleteQuery;
43
-
44
-	public function __construct(IDBConnection $connection, IConfig $config) {
45
-		$this->connection = $connection;
46
-		$this->config = $config;
47
-	}
48
-
49
-
50
-	public function getName() {
51
-		return 'Repair invalid paths in file cache';
52
-	}
53
-
54
-	/**
55
-	 * @return array[]
56
-	 * @suppress SqlInjectionChecker
57
-	 */
58
-	private function getInvalidEntries() {
59
-		$builder = $this->connection->getQueryBuilder();
60
-
61
-		$computedPath = $builder->func()->concat(
62
-			'p.path',
63
-			$builder->func()->concat($builder->createNamedParameter('/'), 'f.name')
64
-		);
65
-
66
-		//select f.path, f.parent,p.path from oc_filecache f inner join oc_filecache p on f.parent=p.fileid and p.path!='' where f.path != p.path || '/' || f.name;
67
-		$builder->select('f.fileid', 'f.path', 'f.name', 'f.parent', 'f.storage')
68
-			->selectAlias('p.path', 'parent_path')
69
-			->selectAlias('p.storage', 'parent_storage')
70
-			->from('filecache', 'f')
71
-			->innerJoin('f', 'filecache', 'p', $builder->expr()->andX(
72
-				$builder->expr()->eq('f.parent', 'p.fileid'),
73
-				$builder->expr()->nonEmptyString('p.name')
74
-			))
75
-			->where($builder->expr()->neq('f.path', $computedPath))
76
-			->setMaxResults(self::MAX_ROWS);
77
-
78
-		$result = $builder->execute();
79
-		$rows = $result->fetchAll();
80
-		$result->closeCursor();
81
-
82
-		return $rows;
83
-	}
84
-
85
-	private function getId($storage, $path) {
86
-		if (!$this->getIdQuery) {
87
-			$builder = $this->connection->getQueryBuilder();
88
-
89
-			$this->getIdQuery = $builder->select('fileid')
90
-				->from('filecache')
91
-				->where($builder->expr()->eq('storage', $builder->createParameter('storage')))
92
-				->andWhere($builder->expr()->eq('path', $builder->createParameter('path')));
93
-		}
94
-
95
-		$this->getIdQuery->setParameter('storage', $storage, IQueryBuilder::PARAM_INT);
96
-		$this->getIdQuery->setParameter('path', $path);
97
-
98
-		return $this->getIdQuery->execute()->fetchColumn();
99
-	}
100
-
101
-	/**
102
-	 * @param string $fileid
103
-	 * @param string $newPath
104
-	 * @param string $newStorage
105
-	 * @suppress SqlInjectionChecker
106
-	 */
107
-	private function update($fileid, $newPath, $newStorage) {
108
-		if (!$this->updateQuery) {
109
-			$builder = $this->connection->getQueryBuilder();
110
-
111
-			$this->updateQuery = $builder->update('filecache')
112
-				->set('path', $builder->createParameter('newpath'))
113
-				->set('path_hash', $builder->func()->md5($builder->createParameter('newpath')))
114
-				->set('storage', $builder->createParameter('newstorage'))
115
-				->where($builder->expr()->eq('fileid', $builder->createParameter('fileid')));
116
-		}
117
-
118
-		$this->updateQuery->setParameter('newpath', $newPath);
119
-		$this->updateQuery->setParameter('newstorage', $newStorage);
120
-		$this->updateQuery->setParameter('fileid', $fileid, IQueryBuilder::PARAM_INT);
121
-
122
-		$this->updateQuery->execute();
123
-	}
124
-
125
-	private function reparent($from, $to) {
126
-		if (!$this->reparentQuery) {
127
-			$builder = $this->connection->getQueryBuilder();
128
-
129
-			$this->reparentQuery = $builder->update('filecache')
130
-				->set('parent', $builder->createParameter('to'))
131
-				->where($builder->expr()->eq('fileid', $builder->createParameter('from')));
132
-		}
133
-
134
-		$this->reparentQuery->setParameter('from', $from);
135
-		$this->reparentQuery->setParameter('to', $to);
136
-
137
-		$this->reparentQuery->execute();
138
-	}
139
-
140
-	private function delete($fileid) {
141
-		if (!$this->deleteQuery) {
142
-			$builder = $this->connection->getQueryBuilder();
143
-
144
-			$this->deleteQuery = $builder->delete('filecache')
145
-				->where($builder->expr()->eq('fileid', $builder->createParameter('fileid')));
146
-		}
147
-
148
-		$this->deleteQuery->setParameter('fileid', $fileid, IQueryBuilder::PARAM_INT);
149
-
150
-		$this->deleteQuery->execute();
151
-	}
152
-
153
-	private function repair() {
154
-		$this->connection->beginTransaction();
155
-		$entries = $this->getInvalidEntries();
156
-		$count = 0;
157
-		foreach ($entries as $entry) {
158
-			$count++;
159
-			$calculatedPath = $entry['parent_path'] . '/' . $entry['name'];
160
-			if ($newId = $this->getId($entry['parent_storage'], $calculatedPath)) {
161
-				// a new entry with the correct path has already been created, reuse that one and delete the incorrect entry
162
-				$this->reparent($entry['fileid'], $newId);
163
-				$this->delete($entry['fileid']);
164
-			} else {
165
-				$this->update($entry['fileid'], $calculatedPath, $entry['parent_storage']);
166
-			}
167
-		}
168
-		$this->connection->commit();
169
-		return $count;
170
-	}
171
-
172
-	public function run(IOutput $output) {
173
-		$versionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0');
174
-		// was added to 12.0.0.30 and 13.0.0.1
175
-		if (version_compare($versionFromBeforeUpdate, '12.0.0.30', '<') || version_compare($versionFromBeforeUpdate, '13.0.0.0', '==')) {
176
-			$totalCount = 0;
177
-			do {
178
-				$count = $this->repair();
179
-				$totalCount += $count;
180
-			} while ($count === self::MAX_ROWS);
181
-
182
-			$output->info('Repaired ' . $totalCount . ' paths');
183
-		}
184
-	}
32
+    const MAX_ROWS = 200;
33
+
34
+    /** @var IDBConnection */
35
+    private $connection;
36
+    /** @var IConfig */
37
+    private $config;
38
+
39
+    private $getIdQuery;
40
+    private $updateQuery;
41
+    private $reparentQuery;
42
+    private $deleteQuery;
43
+
44
+    public function __construct(IDBConnection $connection, IConfig $config) {
45
+        $this->connection = $connection;
46
+        $this->config = $config;
47
+    }
48
+
49
+
50
+    public function getName() {
51
+        return 'Repair invalid paths in file cache';
52
+    }
53
+
54
+    /**
55
+     * @return array[]
56
+     * @suppress SqlInjectionChecker
57
+     */
58
+    private function getInvalidEntries() {
59
+        $builder = $this->connection->getQueryBuilder();
60
+
61
+        $computedPath = $builder->func()->concat(
62
+            'p.path',
63
+            $builder->func()->concat($builder->createNamedParameter('/'), 'f.name')
64
+        );
65
+
66
+        //select f.path, f.parent,p.path from oc_filecache f inner join oc_filecache p on f.parent=p.fileid and p.path!='' where f.path != p.path || '/' || f.name;
67
+        $builder->select('f.fileid', 'f.path', 'f.name', 'f.parent', 'f.storage')
68
+            ->selectAlias('p.path', 'parent_path')
69
+            ->selectAlias('p.storage', 'parent_storage')
70
+            ->from('filecache', 'f')
71
+            ->innerJoin('f', 'filecache', 'p', $builder->expr()->andX(
72
+                $builder->expr()->eq('f.parent', 'p.fileid'),
73
+                $builder->expr()->nonEmptyString('p.name')
74
+            ))
75
+            ->where($builder->expr()->neq('f.path', $computedPath))
76
+            ->setMaxResults(self::MAX_ROWS);
77
+
78
+        $result = $builder->execute();
79
+        $rows = $result->fetchAll();
80
+        $result->closeCursor();
81
+
82
+        return $rows;
83
+    }
84
+
85
+    private function getId($storage, $path) {
86
+        if (!$this->getIdQuery) {
87
+            $builder = $this->connection->getQueryBuilder();
88
+
89
+            $this->getIdQuery = $builder->select('fileid')
90
+                ->from('filecache')
91
+                ->where($builder->expr()->eq('storage', $builder->createParameter('storage')))
92
+                ->andWhere($builder->expr()->eq('path', $builder->createParameter('path')));
93
+        }
94
+
95
+        $this->getIdQuery->setParameter('storage', $storage, IQueryBuilder::PARAM_INT);
96
+        $this->getIdQuery->setParameter('path', $path);
97
+
98
+        return $this->getIdQuery->execute()->fetchColumn();
99
+    }
100
+
101
+    /**
102
+     * @param string $fileid
103
+     * @param string $newPath
104
+     * @param string $newStorage
105
+     * @suppress SqlInjectionChecker
106
+     */
107
+    private function update($fileid, $newPath, $newStorage) {
108
+        if (!$this->updateQuery) {
109
+            $builder = $this->connection->getQueryBuilder();
110
+
111
+            $this->updateQuery = $builder->update('filecache')
112
+                ->set('path', $builder->createParameter('newpath'))
113
+                ->set('path_hash', $builder->func()->md5($builder->createParameter('newpath')))
114
+                ->set('storage', $builder->createParameter('newstorage'))
115
+                ->where($builder->expr()->eq('fileid', $builder->createParameter('fileid')));
116
+        }
117
+
118
+        $this->updateQuery->setParameter('newpath', $newPath);
119
+        $this->updateQuery->setParameter('newstorage', $newStorage);
120
+        $this->updateQuery->setParameter('fileid', $fileid, IQueryBuilder::PARAM_INT);
121
+
122
+        $this->updateQuery->execute();
123
+    }
124
+
125
+    private function reparent($from, $to) {
126
+        if (!$this->reparentQuery) {
127
+            $builder = $this->connection->getQueryBuilder();
128
+
129
+            $this->reparentQuery = $builder->update('filecache')
130
+                ->set('parent', $builder->createParameter('to'))
131
+                ->where($builder->expr()->eq('fileid', $builder->createParameter('from')));
132
+        }
133
+
134
+        $this->reparentQuery->setParameter('from', $from);
135
+        $this->reparentQuery->setParameter('to', $to);
136
+
137
+        $this->reparentQuery->execute();
138
+    }
139
+
140
+    private function delete($fileid) {
141
+        if (!$this->deleteQuery) {
142
+            $builder = $this->connection->getQueryBuilder();
143
+
144
+            $this->deleteQuery = $builder->delete('filecache')
145
+                ->where($builder->expr()->eq('fileid', $builder->createParameter('fileid')));
146
+        }
147
+
148
+        $this->deleteQuery->setParameter('fileid', $fileid, IQueryBuilder::PARAM_INT);
149
+
150
+        $this->deleteQuery->execute();
151
+    }
152
+
153
+    private function repair() {
154
+        $this->connection->beginTransaction();
155
+        $entries = $this->getInvalidEntries();
156
+        $count = 0;
157
+        foreach ($entries as $entry) {
158
+            $count++;
159
+            $calculatedPath = $entry['parent_path'] . '/' . $entry['name'];
160
+            if ($newId = $this->getId($entry['parent_storage'], $calculatedPath)) {
161
+                // a new entry with the correct path has already been created, reuse that one and delete the incorrect entry
162
+                $this->reparent($entry['fileid'], $newId);
163
+                $this->delete($entry['fileid']);
164
+            } else {
165
+                $this->update($entry['fileid'], $calculatedPath, $entry['parent_storage']);
166
+            }
167
+        }
168
+        $this->connection->commit();
169
+        return $count;
170
+    }
171
+
172
+    public function run(IOutput $output) {
173
+        $versionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0');
174
+        // was added to 12.0.0.30 and 13.0.0.1
175
+        if (version_compare($versionFromBeforeUpdate, '12.0.0.30', '<') || version_compare($versionFromBeforeUpdate, '13.0.0.0', '==')) {
176
+            $totalCount = 0;
177
+            do {
178
+                $count = $this->repair();
179
+                $totalCount += $count;
180
+            } while ($count === self::MAX_ROWS);
181
+
182
+            $output->info('Repaired ' . $totalCount . ' paths');
183
+        }
184
+    }
185 185
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
 		$count = 0;
157 157
 		foreach ($entries as $entry) {
158 158
 			$count++;
159
-			$calculatedPath = $entry['parent_path'] . '/' . $entry['name'];
159
+			$calculatedPath = $entry['parent_path'].'/'.$entry['name'];
160 160
 			if ($newId = $this->getId($entry['parent_storage'], $calculatedPath)) {
161 161
 				// a new entry with the correct path has already been created, reuse that one and delete the incorrect entry
162 162
 				$this->reparent($entry['fileid'], $newId);
@@ -179,7 +179,7 @@  discard block
 block discarded – undo
179 179
 				$totalCount += $count;
180 180
 			} while ($count === self::MAX_ROWS);
181 181
 
182
-			$output->info('Repaired ' . $totalCount . ' paths');
182
+			$output->info('Repaired '.$totalCount.' paths');
183 183
 		}
184 184
 	}
185 185
 }
Please login to merge, or discard this patch.