Skip to content

Commit 3bfed56

Browse files
committed
DAV custom props: catch Exception and rollback transaction in case
- before exceptions were not caught, a started transaction might not have been finished - also resolve depractions and use IQueryBuilder Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
1 parent f64b78d commit 3bfed56

File tree

1 file changed

+76
-56
lines changed

1 file changed

+76
-56
lines changed

apps/dav/lib/DAV/CustomPropertiesBackend.php

Lines changed: 76 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
*/
2525
namespace OCA\DAV\DAV;
2626

27-
use OCA\DAV\Connector\Sabre\Node;
27+
use OCP\DB\Exception;
28+
use OCP\DB\QueryBuilder\IQueryBuilder;
2829
use OCP\IDBConnection;
2930
use OCP\IUser;
3031
use Sabre\DAV\PropertyStorage\Backend\BackendInterface;
@@ -292,68 +293,56 @@ private function getUserProperties(string $path, array $requestedProperties) {
292293
}
293294

294295
/**
295-
* Update properties
296-
*
297-
* @param string $path path for which to update properties
298-
* @param array $properties array of properties to update
299-
*
300-
* @return bool
296+
* @throws Exception
301297
*/
302-
private function updateProperties(string $path, array $properties) {
303-
$deleteStatement = 'DELETE FROM `*PREFIX*properties`' .
304-
' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
305-
306-
$insertStatement = 'INSERT INTO `*PREFIX*properties`' .
307-
' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)';
308-
309-
$updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?' .
310-
' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?';
311-
298+
private function updateProperties(string $path, array $properties): bool {
312299
// TODO: use "insert or update" strategy ?
313300
$existing = $this->getUserProperties($path, []);
314-
$this->connection->beginTransaction();
315-
foreach ($properties as $propertyName => $propertyValue) {
316-
// If it was null, we need to delete the property
317-
if (is_null($propertyValue)) {
318-
if (array_key_exists($propertyName, $existing)) {
319-
$this->connection->executeUpdate($deleteStatement,
320-
[
321-
$this->user->getUID(),
322-
$this->formatPath($path),
323-
$propertyName,
324-
]
325-
);
326-
}
327-
} else {
328-
if ($propertyValue instanceOf \Sabre\DAV\Xml\Property\Complex) {
329-
$propertyValue = $propertyValue->getXml();
330-
} elseif (!is_string($propertyValue)) {
331-
$propertyValue = (string)$propertyValue;
332-
}
333-
if (!array_key_exists($propertyName, $existing)) {
334-
$this->connection->executeUpdate($insertStatement,
335-
[
336-
$this->user->getUID(),
337-
$this->formatPath($path),
338-
$propertyName,
339-
$propertyValue,
340-
]
341-
);
301+
try {
302+
$this->connection->beginTransaction();
303+
foreach ($properties as $propertyName => $propertyValue) {
304+
// common parameters for all queries
305+
$dbParameters = [
306+
'userid' => $this->user->getUID(),
307+
'propertyPath' => $this->formatPath($path),
308+
'propertyName' => $propertyName
309+
];
310+
311+
// If it was null, we need to delete the property
312+
if (is_null($propertyValue)) {
313+
if (array_key_exists($propertyName, $existing)) {
314+
$deleteQuery = $deleteQuery ?? $this->createDeleteQuery();
315+
$deleteQuery
316+
->setParameters($dbParameters)
317+
->executeStatement();
318+
}
342319
} else {
343-
$this->connection->executeUpdate($updateStatement,
344-
[
345-
$propertyValue,
346-
$this->user->getUID(),
347-
$this->formatPath($path),
348-
$propertyName,
349-
]
350-
);
320+
if ($propertyValue instanceOf \Sabre\DAV\Xml\Property\Complex) {
321+
$dbParameters['propertyValue'] = $propertyValue->getXml();
322+
} elseif (!is_string($propertyValue)) {
323+
$dbParameters['propertyValue'] = (string)$propertyValue;
324+
}
325+
326+
if (!array_key_exists($propertyName, $existing)) {
327+
$insertQuery = $insertQuery ?? $this->createInsertQuery();
328+
$insertQuery
329+
->setParameters($dbParameters)
330+
->executeStatement();
331+
} else {
332+
$updateQuery = $updateQuery ?? $this->createUpdateQuery();
333+
$updateQuery
334+
->setParameters($dbParameters)
335+
->executeStatement();
336+
}
351337
}
352338
}
353-
}
354339

355-
$this->connection->commit();
356-
unset($this->userCache[$path]);
340+
$this->connection->commit();
341+
unset($this->userCache[$path]);
342+
} catch (Exception $e) {
343+
$this->connection->rollBack();
344+
throw $e;
345+
}
357346

358347
return true;
359348
}
@@ -371,4 +360,35 @@ private function formatPath(string $path): string {
371360
return $path;
372361
}
373362
}
363+
364+
private function createDeleteQuery(): IQueryBuilder {
365+
$deleteQuery = $this->connection->getQueryBuilder();
366+
$deleteQuery->delete('properties')
367+
->where($deleteQuery->expr()->eq('userid', $deleteQuery->createParameter('userid')))
368+
->andWhere($deleteQuery->expr()->eq('propertypath', $deleteQuery->createParameter('propertyPath')))
369+
->andWhere($deleteQuery->expr()->eq('propertyname', $deleteQuery->createParameter('propertyName')));
370+
return $deleteQuery;
371+
}
372+
373+
private function createInsertQuery(): IQueryBuilder {
374+
$insertQuery = $this->connection->getQueryBuilder();
375+
$insertQuery->insert('properties')
376+
->values([
377+
'userid' => $insertQuery->createParameter('userid'),
378+
'propertypath' => $insertQuery->createParameter('propertyPath'),
379+
'propertyname' => $insertQuery->createParameter('propertyName'),
380+
'propertyvalue' => $insertQuery->createParameter('propertyValue'),
381+
]);
382+
return $insertQuery;
383+
}
384+
385+
private function createUpdateQuery(): IQueryBuilder {
386+
$updateQuery = $this->connection->getQueryBuilder();
387+
$updateQuery->update('properties')
388+
->set('propertyvalue', $updateQuery->createParameter('propertyValue'))
389+
->where($updateQuery->expr()->eq('userid', $updateQuery->createParameter('userid')))
390+
->andWhere($updateQuery->expr()->eq('propertypath', $updateQuery->createParameter('propertyPath')))
391+
->andWhere($updateQuery->expr()->eq('propertyname', $updateQuery->createParameter('propertyName')));
392+
return $updateQuery;
393+
}
374394
}

0 commit comments

Comments
 (0)