Skip to content

Commit 575de52

Browse files
committed
Use two queries to mark parent as outdated
Signed-off-by: Ari Selseng <ari@selseng.net>
1 parent 1b27e95 commit 575de52

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

apps/files_external/lib/Command/Notify.php

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException;
3131
use OCA\Files_External\Lib\StorageConfig;
3232
use OCA\Files_External\Service\GlobalStoragesService;
33+
use OCP\DB\QueryBuilder\IQueryBuilder;
3334
use OCP\Files\Notify\IChange;
3435
use OCP\Files\Notify\INotifyHandler;
3536
use OCP\Files\Notify\IRenameChange;
@@ -48,8 +49,6 @@ class Notify extends Base {
4849
private $globalService;
4950
/** @var IDBConnection */
5051
private $connection;
51-
/** @var \OCP\DB\QueryBuilder\IQueryBuilder */
52-
private $updateQuery;
5352
/** @var ILogger */
5453
private $logger;
5554

@@ -58,7 +57,6 @@ function __construct(GlobalStoragesService $globalService, IDBConnection $connec
5857
$this->globalService = $globalService;
5958
$this->connection = $connection;
6059
$this->logger = $logger;
61-
$this->updateQuery = $this->getUpdateQuery($this->connection);
6260
}
6361

6462
protected function configure() {
@@ -162,13 +160,22 @@ private function markParentAsOutdated($mountId, $path, OutputInterface $output)
162160
}
163161

164162
try {
165-
$this->updateQuery->execute([$parent, $mountId]);
163+
$storageIds = $this->getStorageIds($mountId);
166164
} catch (DriverException $ex) {
167-
$this->logger->logException($ex, ['app' => 'files_external', 'message' => 'Error while trying to mark folder as outdated', 'level' => ILogger::WARN]);
165+
$this->logger->logException($ex, ['message' => 'Error while trying to find correct storage ids.', 'level' => ILogger::WARN]);
168166
$this->connection = $this->reconnectToDatabase($this->connection, $output);
169167
$output->writeln('<info>Needed to reconnect to the database</info>');
170-
$this->updateQuery = $this->getUpdateQuery($this->connection);
171-
$this->updateQuery->execute([$parent, $mountId]);
168+
$storageIds = $this->getStorageIds($mountId);
169+
}
170+
if (count($storageIds) === 0) {
171+
throw new StorageNotAvailableException('No storages found by mount ID ' . $mountId);
172+
}
173+
$storageIds = array_map('intval', $storageIds);
174+
175+
$result = $this->updateParent($storageIds, $parent);
176+
if ($result === 0) {
177+
//TODO: Find existing parent further up the tree in the database and register that folder instead.
178+
$this->logger->info('Failed updating parent for "' . $path . '" while trying to register change. It may not exist in the filecache.');
172179
}
173180
}
174181

@@ -199,15 +206,33 @@ private function logUpdate(IChange $change, OutputInterface $output) {
199206
}
200207

201208
/**
202-
* @return \Doctrine\DBAL\Statement
209+
* @param int $mountId
210+
* @return array
211+
*/
212+
private function getStorageIds($mountId) {
213+
$qb = $this->connection->getQueryBuilder();
214+
return $qb
215+
->select('storage_id')
216+
->from('mounts')
217+
->where($qb->expr()->eq('mount_id', $qb->createNamedParameter($mountId, IQueryBuilder::PARAM_INT)))
218+
->execute()
219+
->fetchAll(\PDO::FETCH_COLUMN);
220+
}
221+
222+
/**
223+
* @param array $storageIds
224+
* @param string $parent
225+
* @return int
203226
*/
204-
private function getUpdateQuery(IDBConnection $connection) {
205-
// the query builder doesn't really like subqueries with parameters
206-
return $connection->prepare(
207-
'UPDATE *PREFIX*filecache SET size = -1
208-
WHERE `path` = ?
209-
AND `storage` IN (SELECT storage_id FROM *PREFIX*mounts WHERE mount_id = ?)'
210-
);
227+
private function updateParent($storageIds, $parent) {
228+
$pathHash = md5(trim(\OC_Util::normalizeUnicode($parent), '/'));
229+
$qb = $this->connection->getQueryBuilder();
230+
return $qb
231+
->update('filecache')
232+
->set('size', $qb->createNamedParameter(-1, IQueryBuilder::PARAM_INT))
233+
->where($qb->expr()->in('storage', $qb->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY, ':storage_ids')))
234+
->andWhere($qb->expr()->eq('path_hash', $qb->createNamedParameter($pathHash, IQueryBuilder::PARAM_STR)))
235+
->execute();
211236
}
212237

213238
/**
@@ -217,14 +242,14 @@ private function reconnectToDatabase(IDBConnection $connection, OutputInterface
217242
try {
218243
$connection->close();
219244
} catch (\Exception $ex) {
220-
$this->logger->logException($ex, ['app' => 'files_external', 'message' => 'Error while disconnecting from DB', 'level' => ILogger::WARN]);
245+
$this->logger->logException($ex, ['message' => 'Error while disconnecting from DB', 'level' => ILogger::WARN]);
221246
$output->writeln("<info>Error while disconnecting from database: {$ex->getMessage()}</info>");
222247
}
223248
while (!$connection->isConnected()) {
224249
try {
225250
$connection->connect();
226251
} catch (\Exception $ex) {
227-
$this->logger->logException($ex, ['app' => 'files_external', 'message' => 'Error while re-connecting to database', 'level' => ILogger::WARN]);
252+
$this->logger->logException($ex, ['message' => 'Error while re-connecting to database', 'level' => ILogger::WARN]);
228253
$output->writeln("<info>Error while re-connecting to database: {$ex->getMessage()}</info>");
229254
sleep(60);
230255
}

0 commit comments

Comments
 (0)