From 60d9384e5ec7e8d6f7ffa1c3ecc180ffaac710a3 Mon Sep 17 00:00:00 2001
From: Joas Schilling <coding@schilljs.com>
Date: Wed, 11 Mar 2020 12:12:07 +0100
Subject: [PATCH] Optionally write the reference id into the database

Signed-off-by: Joas Schilling <coding@schilljs.com>
---
 lib/private/Comments/Manager.php | 83 +++++++++++++++++++++++---------
 1 file changed, 61 insertions(+), 22 deletions(-)

diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php
index aad7cad0200..d04f3f965b3 100644
--- a/lib/private/Comments/Manager.php
+++ b/lib/private/Comments/Manager.php
@@ -29,6 +29,7 @@
 namespace OC\Comments;
 
 use Doctrine\DBAL\Exception\DriverException;
+use Doctrine\DBAL\Exception\InvalidFieldNameException;
 use OCP\Comments\CommentsEvent;
 use OCP\Comments\IComment;
 use OCP\Comments\ICommentsEventHandler;
@@ -745,23 +746,46 @@ class Manager implements ICommentsManager {
 	 * @param IComment $comment
 	 * @return bool
 	 */
-	protected function insert(IComment &$comment) {
+	protected function insert(IComment $comment): bool {
+
+		try {
+			$result = $this->insertQuery($comment, true);
+		} catch (InvalidFieldNameException $e) {
+			// The reference id field was only added in Nextcloud 19.
+			// In order to not cause too long waiting times on the update,
+			// it was decided to only add it lazy, as it is also not a critical
+			// feature, but only helps to have a better experience while commenting.
+			// So in case the reference_id field is missing,
+			// we simply save the comment without that field.
+			$result = $this->insertQuery($comment, false);
+		}
+
+		return $result;
+	}
+
+	protected function insertQuery(IComment $comment, bool $tryWritingReferenceId): bool {
 		$qb = $this->dbConn->getQueryBuilder();
-		$affectedRows = $qb
-			->insert('comments')
-			->values([
-				'parent_id' => $qb->createNamedParameter($comment->getParentId()),
-				'topmost_parent_id' => $qb->createNamedParameter($comment->getTopmostParentId()),
-				'children_count' => $qb->createNamedParameter($comment->getChildrenCount()),
-				'actor_type' => $qb->createNamedParameter($comment->getActorType()),
-				'actor_id' => $qb->createNamedParameter($comment->getActorId()),
-				'message' => $qb->createNamedParameter($comment->getMessage()),
-				'verb' => $qb->createNamedParameter($comment->getVerb()),
-				'creation_timestamp' => $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'),
-				'latest_child_timestamp' => $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'),
-				'object_type' => $qb->createNamedParameter($comment->getObjectType()),
-				'object_id' => $qb->createNamedParameter($comment->getObjectId()),
-			])
+
+		$values = [
+			'parent_id' => $qb->createNamedParameter($comment->getParentId()),
+			'topmost_parent_id' => $qb->createNamedParameter($comment->getTopmostParentId()),
+			'children_count' => $qb->createNamedParameter($comment->getChildrenCount()),
+			'actor_type' => $qb->createNamedParameter($comment->getActorType()),
+			'actor_id' => $qb->createNamedParameter($comment->getActorId()),
+			'message' => $qb->createNamedParameter($comment->getMessage()),
+			'verb' => $qb->createNamedParameter($comment->getVerb()),
+			'creation_timestamp' => $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'),
+			'latest_child_timestamp' => $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'),
+			'object_type' => $qb->createNamedParameter($comment->getObjectType()),
+			'object_id' => $qb->createNamedParameter($comment->getObjectId()),
+		];
+
+		if ($tryWritingReferenceId) {
+			$values['reference_id'] = $qb->createNamedParameter($comment->getReferenceId());
+		}
+
+		$affectedRows = $qb->insert('comments')
+			->values($values)
 			->execute();
 
 		if ($affectedRows > 0) {
@@ -786,8 +810,21 @@ class Manager implements ICommentsManager {
 		$this->sendEvent(CommentsEvent::EVENT_PRE_UPDATE, $this->get($comment->getId()));
 		$this->uncache($comment->getId());
 
+		try {
+			$result = $this->updateQuery($comment, true);
+		} catch (InvalidFieldNameException $e) {
+			// See function insert() for explanation
+			$result = $this->updateQuery($comment, false);
+		}
+
+		$this->sendEvent(CommentsEvent::EVENT_UPDATE, $comment);
+
+		return $result;
+	}
+
+	protected function updateQuery(IComment $comment, bool $tryWritingReferenceId): bool {
 		$qb = $this->dbConn->getQueryBuilder();
-		$affectedRows = $qb
+		$qb
 			->update('comments')
 			->set('parent_id', $qb->createNamedParameter($comment->getParentId()))
 			->set('topmost_parent_id', $qb->createNamedParameter($comment->getTopmostParentId()))
@@ -799,17 +836,19 @@ class Manager implements ICommentsManager {
 			->set('creation_timestamp', $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'))
 			->set('latest_child_timestamp', $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'))
 			->set('object_type', $qb->createNamedParameter($comment->getObjectType()))
-			->set('object_id', $qb->createNamedParameter($comment->getObjectId()))
-			->where($qb->expr()->eq('id', $qb->createParameter('id')))
-			->setParameter('id', $comment->getId())
+			->set('object_id', $qb->createNamedParameter($comment->getObjectId()));
+
+		if ($tryWritingReferenceId) {
+			$qb->set('reference_id', $qb->createNamedParameter($comment->getReferenceId()));
+		}
+
+		$affectedRows = $qb->where($qb->expr()->eq('id', $qb->createNamedParameter($comment->getId())))
 			->execute();
 
 		if ($affectedRows === 0) {
 			throw new NotFoundException('Comment to update does ceased to exist');
 		}
 
-		$this->sendEvent(CommentsEvent::EVENT_UPDATE, $comment);
-
 		return $affectedRows > 0;
 	}
 
-- 
GitLab