Browse Source

Fix MariaDB for updates (#8254)

fix https://github.com/FreshRSS/FreshRSS/issues/8252
regression from https://github.com/FreshRSS/FreshRSS/pull/6957
The current code works with MySQL 8+ (as well as PostgreSQL and SQLite), but not with MariaDB, because MariaDB does not support CTE (Common Table Expression) fully (which I was not aware of)...
Alexandre Alapetite 4 tháng trước cách đây
mục cha
commit
b3cfc387b8
2 tập tin đã thay đổi với 45 bổ sung10 xóa
  1. 3 10
      app/Models/FeedDAO.php
  2. 42 0
      app/Models/FeedDAOPGSQL.php

+ 3 - 10
app/Models/FeedDAO.php

@@ -497,16 +497,9 @@ SQL;
 				GROUP BY id_feed
 			)
 			UPDATE `_feed`
-			SET `cache_nbEntries` = COALESCE((
-					SELECT c.total_entries
-					FROM entry_counts AS c
-					WHERE c.id_feed = `_feed`.id
-				), 0),
-				`cache_nbUnreads` = COALESCE((
-					SELECT c.unread_entries
-					FROM entry_counts AS c
-					WHERE c.id_feed = `_feed`.id
-				), 0)
+			LEFT JOIN entry_counts ON entry_counts.id_feed = `_feed`.id
+			SET `cache_nbEntries` = COALESCE(entry_counts.total_entries, 0),
+				`cache_nbUnreads` = COALESCE(entry_counts.unread_entries, 0)
 			WHERE $whereFeedIds
 			SQL;
 		$stm = $this->pdo->prepare($sql);

+ 42 - 0
app/Models/FeedDAOPGSQL.php

@@ -10,4 +10,46 @@ SELECT setval('`_feed_id_seq`', COALESCE(MAX(id), 0) + 1, false) FROM `_feed`
 SQL;
 		return $this->pdo->exec($sql) !== false;
 	}
+
+	#[\Override]
+	public function updateCachedValues(int ...$feedIds): int|false {
+		if (empty($feedIds)) {
+			$whereFeedIds = 'true';
+			$whereEntryIdFeeds = 'true';
+		} else {
+			$whereFeedIds = 'id IN (' . str_repeat('?,', count($feedIds) - 1) . '?)';
+			$whereEntryIdFeeds = 'id_feed IN (' . str_repeat('?,', count($feedIds) - 1) . '?)';
+		}
+		$sql = <<<SQL
+			WITH entry_counts AS (
+				SELECT
+					id_feed,
+					COUNT(*) AS total_entries,
+					SUM(CASE WHEN is_read = 0 THEN 1 ELSE 0 END) AS unread_entries
+				FROM `_entry`
+				WHERE $whereEntryIdFeeds
+				GROUP BY id_feed
+			)
+			UPDATE `_feed`
+			SET `cache_nbEntries` = COALESCE((
+					SELECT c.total_entries
+					FROM entry_counts AS c
+					WHERE c.id_feed = `_feed`.id
+				), 0),
+				`cache_nbUnreads` = COALESCE((
+					SELECT c.unread_entries
+					FROM entry_counts AS c
+					WHERE c.id_feed = `_feed`.id
+				), 0)
+			WHERE $whereFeedIds
+			SQL;
+		$stm = $this->pdo->prepare($sql);
+		if ($stm !== false && $stm->execute(array_merge($feedIds, $feedIds))) {
+			return $stm->rowCount();
+		} else {
+			$info = $stm === false ? $this->pdo->errorInfo() : $stm->errorInfo();
+			Minz_Log::error('SQL error ' . __METHOD__ . json_encode($info));
+			return false;
+		}
+	}
 }