Skip to content

Commit

Permalink
Wrap-up changes for updated subfolders
Browse files Browse the repository at this point in the history
When a subfolder is updated, the changes were not saved.
Changed folders are now tracked and changes metadata update are done for the all the changed folders instead of the top one.

Signed-off-by: Louis Chemineau <louis@chmn.me>
  • Loading branch information
artonge committed Mar 20, 2023
1 parent 47f2d4a commit 8992567
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 7 deletions.
9 changes: 7 additions & 2 deletions lib/Controller/LockingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,14 @@ public function unlockFolder(int $id, ?string $shareToken = null): DataResponse
throw new OCSForbiddenException($this->l10n->t('You are not allowed to remove the lock'));
}

$this->fileService->finalizeChanges($nodes[0]);
$touchFoldersIds = $this->metaDataStorage->getTouchedFolders($token);
foreach ($touchFoldersIds as $folderId) {
$this->fileService->finalizeChanges($userFolder->getById($folderId)[0]);

$this->metaDataStorage->saveIntermediateFile($ownerId, $id);
$this->metaDataStorage->saveIntermediateFile($ownerId, $folderId);
}

$this->metaDataStorage->clearTouchedFolders($token);

try {
$this->lockManager->unlockFile($id, $token);
Expand Down
4 changes: 2 additions & 2 deletions lib/Controller/MetaDataController.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public function updateMetaData(int $id, string $metaData): DataResponse {
}

try {
$this->metaDataStorage->updateMetaDataIntoIntermediateFile($this->userId, $id, $metaData);
$this->metaDataStorage->updateMetaDataIntoIntermediateFile($this->userId, $id, $metaData, $e2eToken);
} catch (MissingMetaDataException $e) {
throw new OCSNotFoundException($this->l10n->t('Metadata-file does not exist'));
} catch (NotFoundException $e) {
Expand Down Expand Up @@ -201,7 +201,7 @@ public function addMetadataFileDrop(int $id, string $fileDrop, ?string $shareTok
$decodedMetadata['filedrop'] = array_merge($decodedMetadata['filedrop'] ?? [], $decodedFileDrop);
$encodedMetadata = json_encode($decodedMetadata);

$this->metaDataStorage->updateMetaDataIntoIntermediateFile($ownerId, $id, $encodedMetadata);
$this->metaDataStorage->updateMetaDataIntoIntermediateFile($ownerId, $id, $encodedMetadata, $e2eToken);
} catch (MissingMetaDataException $e) {
throw new OCSNotFoundException($this->l10n->t('Metadata-file does not exist'));
} catch (NotFoundException $e) {
Expand Down
2 changes: 1 addition & 1 deletion lib/FileService.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function revertChanges(Folder $folder): bool {
}

/**
* @return bool Whether this operation changed any files
* @return bool Move and delete temporary files suffixed by .e2e-to-save and .e2e-to-delete
*/
public function finalizeChanges(Folder $folder): bool {
$intermediateFiles = $this->getIntermediateFiles($folder);
Expand Down
20 changes: 19 additions & 1 deletion lib/IMetaDataStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function setMetaDataIntoIntermediateFile(string $userId, int $id, string
* @throws NotFoundException
* @throws MissingMetaDataException
*/
public function updateMetaDataIntoIntermediateFile(string $userId, int $id, string $fileKey): void;
public function updateMetaDataIntoIntermediateFile(string $userId, int $id, string $fileKey, string $token = null): void;

/**
* Moves intermediate metadata file to final file
Expand All @@ -84,4 +84,22 @@ public function deleteIntermediateFile(string $userId, int $id): void;
* @throws NotFoundException
*/
public function deleteMetaData(string $userId, int $id): void;

/**
* Return the list of folders marked as touched.
*
* @return int[]
*
* @throws NotPermittedException
* @throws NotFoundException
*/
public function getTouchedFolders(string $token): array;

/**
* Clear the list of touched folder for a token.
*
* @throws NotPermittedException
* @throws NotFoundException
*/
public function clearTouchedFolders(?string $token): void;
}
33 changes: 32 additions & 1 deletion lib/MetaDataStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public function setMetaDataIntoIntermediateFile(string $userId, int $id, string
/**
* @inheritDoc
*/
public function updateMetaDataIntoIntermediateFile(string $userId, int $id, string $fileKey): void {
public function updateMetaDataIntoIntermediateFile(string $userId, int $id, string $fileKey, string $token = null): void {
// ToDo check signature for race condition
$this->verifyFolderStructure();
$this->verifyOwner($userId, $id);
Expand Down Expand Up @@ -136,6 +136,18 @@ public function updateMetaDataIntoIntermediateFile(string $userId, int $id, stri

$intermediateMetaDataFile
->putContent($fileKey);

// To ease the wrap-up process during unlocking,
// we keep track of every folder for which metadata was updated.
// For that we create a file named /tokens/$token/$folderId.
if ($token !== null) {
try {
$tokenFolder = $this->appData->getFolder("/tokens/$token");
} catch (NotFoundException $ex) {
$tokenFolder = $this->appData->newFolder("/tokens/$token");
}
$tokenFolder->newFile("$id", '');
}
}

/**
Expand Down Expand Up @@ -308,4 +320,23 @@ protected function getLegacyOwnerPath(string $userId, int $id):string {

return $ownerNodes[0]->getPath();
}

/**
* @inheritDoc
*/
public function getTouchedFolders(string $token): array {
return array_map(
fn (ISimpleFile $file) => (int)$file->getName(),
$this->appData->getFolder("/tokens")->getFolder($token)->getDirectoryListing()
);
}

/**
* @inheritDoc
*/
public function clearTouchedFolders(?string $token): void {
if ($token !== null) {
$this->appData->getFolder("/tokens/$token")->delete();
}
}
}
2 changes: 2 additions & 0 deletions lib/RollbackService.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ public function rollbackOlderThan(int $olderThanTimestamp, ?int $limit = null):
continue;
}

$this->metaDataStorage->clearTouchedFolders($lock->getToken());

$this->lockMapper->delete($lock);
}
}
Expand Down

0 comments on commit 8992567

Please sign in to comment.