Skip to content

Commit

Permalink
sync token
Browse files Browse the repository at this point in the history
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
  • Loading branch information
ArtificialOwl committed Oct 22, 2023
1 parent 2837291 commit 754a1f7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 35 deletions.
19 changes: 8 additions & 11 deletions lib/private/FilesMetadata/FilesMetadataManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use OC\FilesMetadata\Service\MetadataRequestService;
use OCP\BackgroundJob\IJobList;
use OCP\DB\Exception;
use OCP\DB\Exception as DBException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\Node\NodeCreatedEvent;
Expand Down Expand Up @@ -107,23 +108,19 @@ public function saveMetadata(IFilesMetadata $filesMetadata): void {
}

try {
// if update request changed no rows, means that new entry is needed, or sync_token not valid anymore
$updated = $this->metadataRequestService->updateMetadata($filesMetadata);
if ($updated === 0) {
if ($filesMetadata->getSyncToken() === '') {
$this->metadataRequestService->store($filesMetadata);
} else {
$this->metadataRequestService->updateMetadata($filesMetadata);
}
} catch (\OCP\DB\Exception $e) {
// if duplicate, only means a desync during update. cancel update process.
if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
$this->logger->warning(
'issue while saveMetadata', ['exception' => $e, 'metadata' => $filesMetadata]
);
}
} catch (DBException $e) {
// most of the logged exception are the result of race condition
// between 2 simultaneous process trying to create/update metadata
$this->logger->warning('issue while saveMetadata', ['exception' => $e, 'metadata' => $filesMetadata]);

return;
}

// $this->removeDeprecatedMetadata($filesMetadata);
foreach ($filesMetadata->getIndexes() as $index) {
try {
$this->indexRequestService->updateIndex($filesMetadata, $index);
Expand Down
2 changes: 1 addition & 1 deletion lib/private/FilesMetadata/Model/FilesMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function import(array $data): IFilesMetadata {
*/
public function importFromDatabase(array $data, string $prefix = ''): IFilesMetadata {
try {
$this->syncToken = $data[$prefix . 'sync_token'];
return $this->import(
json_decode($data[$prefix . 'json'] ?? '[]',
true,
Expand Down Expand Up @@ -346,7 +347,6 @@ public function getValueWrapper(string $key): MetadataValueWrapper {
return $this->metadata[$key];
}


public function jsonSerialize(): array {
$data = [];
foreach ($this->metadata as $metaKey => $metaValueWrapper) {
Expand Down
53 changes: 33 additions & 20 deletions lib/private/FilesMetadata/Service/MetadataRequestService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace OC\FilesMetadata\Service;

use JsonException;
use OC\FilesMetadata\Model\FilesMetadata;
use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
Expand Down Expand Up @@ -34,7 +33,7 @@ public function store(IFilesMetadata $filesMetadata): void {
$qb->insert(self::TABLE_METADATA)
->setValue('file_id', $qb->createNamedParameter($filesMetadata->getFileId(), IQueryBuilder::PARAM_INT))
->setValue('json', $qb->createNamedParameter(json_encode($filesMetadata->jsonSerialize())))
->setValue('sync_token', $qb->createNamedParameter($filesMetadata->getSyncToken()))
->setValue('sync_token', $qb->createNamedParameter($this->generateSyncToken()))
->setValue('last_update', $qb->createFunction('NOW()'));
$qb->executeStatement();
}
Expand All @@ -48,13 +47,17 @@ public function store(IFilesMetadata $filesMetadata): void {
public function getMetadataFromFileId(int $fileId): IFilesMetadata {
try {
$qb = $this->dbConnection->getQueryBuilder();
$qb->select('json')->from(self::TABLE_METADATA);
$qb->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
$qb->select('json', 'sync_token')->from(self::TABLE_METADATA);
$qb->where(
$qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))
);
$result = $qb->executeQuery();
$data = $result->fetch();
$result->closeCursor();
} catch (Exception $e) {
$this->logger->warning('exception while getMetadataFromDatabase()', ['exception' => $e, 'fileId' => $fileId]);
$this->logger->warning(
'exception while getMetadataFromDatabase()', ['exception' => $e, 'fileId' => $fileId]
);
throw new FilesMetadataNotFoundException();
}

Expand All @@ -68,7 +71,6 @@ public function getMetadataFromFileId(int $fileId): IFilesMetadata {
return $metadata;
}


/**
* @param int $fileId
*
Expand All @@ -82,32 +84,43 @@ public function dropMetadata(int $fileId): void {
$qb->executeStatement();
}

private function removeDeprecatedMetadata(IFilesMetadata $filesMetadata): void {
// TODO delete aussi les index generate a partir d'une string[]

$qb = $this->dbConnection->getQueryBuilder();
$qb->delete(self::TABLE_METADATA_INDEX)
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($filesMetadata->getFileId(), IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->notIn('file_id', $filesMetadata->getIndexes(), IQueryBuilder::PARAM_STR_ARRAY));
$qb->executeStatement();
}


/**
* @param IFilesMetadata $filesMetadata
*
* @return bool
* @throws Exception
*/
public function updateMetadata(IFilesMetadata $filesMetadata): int {
// TODO check sync_token on update
$qb = $this->dbConnection->getQueryBuilder();
$expr = $qb->expr();

$qb->update(self::TABLE_METADATA)
->set('json', $qb->createNamedParameter(json_encode($filesMetadata->jsonSerialize())))
->set('sync_token', $qb->createNamedParameter('abc'))
->set('sync_token', $qb->createNamedParameter($this->generateSyncToken()))
->set('last_update', $qb->createFunction('NOW()'))
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($filesMetadata->getFileId(), IQueryBuilder::PARAM_INT)));
->where(
$expr->andX(
$expr->eq('file_id', $qb->createNamedParameter($filesMetadata->getFileId(), IQueryBuilder::PARAM_INT)),
$expr->eq('sync_token', $qb->createNamedParameter($filesMetadata->getSyncToken()))
)
);

return $qb->executeStatement();
}


private function generateSyncToken(): string {
$chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';

$str = '';
$max = strlen($chars);
for ($i = 0; $i < 7; $i++) {
try {
$str .= $chars[random_int(0, $max - 2)];
} catch (Exception $e) {
}
}

return $str;
}
}
6 changes: 3 additions & 3 deletions lib/public/FilesMetadata/Model/IFilesMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public function getArray(string $key): array;
public function getStringList(string $key): array;
public function getIntList(string $key): array;
public function getType(string $key): string;
public function set(string $key, string $value): self;
public function setInt(string $key, int $value): self;
public function setFloat(string $key, float $value): self;
public function set(string $key, string $value, bool $index = false): self;
public function setInt(string $key, int $value, bool $index = false): self;
public function setFloat(string $key, float $value, bool $index = false): self;
public function setBool(string $key, bool $value): self;
public function setArray(string $key, array $value): self;
public function setStringList(string $key, array $value): self;
Expand Down

0 comments on commit 754a1f7

Please sign in to comment.