From 41014681fa447205b1932cbd533d7b2a8965942f Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 17 Oct 2024 17:33:32 +0200 Subject: [PATCH] imp: Improve performance when checking if news are available --- locales/fr_FR/LC_MESSAGES/main.mo | Bin 58331 -> 58331 bytes locales/fr_FR/LC_MESSAGES/main.po | 6 +- src/controllers/News.php | 4 +- src/models/dao/links/NewsQueries.php | 72 +++++++++++++++++++++ tests/models/dao/links/NewsQueriesTest.php | 54 ++++++++++++++++ 5 files changed, 130 insertions(+), 6 deletions(-) diff --git a/locales/fr_FR/LC_MESSAGES/main.mo b/locales/fr_FR/LC_MESSAGES/main.mo index 5c3b48c7f78f68e994a8e7090fbf3980a3e42b00..6b60c42962b8e34dad1db2cb2fe713b0c75c9b99 100644 GIT binary patch delta 23 fcmcb8ocZ=~<_)_VI1J4d49%^K%{CuukW2;ud(#O) delta 23 fcmcb8ocZ=~<_)_VI1Ee_3@xn;EjAx&kW2;ud$I{X diff --git a/locales/fr_FR/LC_MESSAGES/main.po b/locales/fr_FR/LC_MESSAGES/main.po index 064c3efb..18432b51 100644 --- a/locales/fr_FR/LC_MESSAGES/main.po +++ b/locales/fr_FR/LC_MESSAGES/main.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: Flus\n" -"POT-Creation-Date: 2024-10-04 19:18+0200\n" -"PO-Revision-Date: 2024-10-04 19:18+0200\n" +"POT-Creation-Date: 2024-10-17 17:36+0200\n" +"PO-Revision-Date: 2024-10-17 17:36+0200\n" "Last-Translator: Marien Fressinaud \n" "Language-Team: \n" "Language: fr_FR\n" @@ -50,7 +50,7 @@ msgstr "Afficher" #: controllers/Feeds.php:107 controllers/Groups.php:90 #: controllers/Links.php:293 controllers/Links.php:465 #: controllers/Mastodon.php:211 controllers/Mastodon.php:297 -#: controllers/News.php:77 controllers/Passwords.php:89 +#: controllers/News.php:76 controllers/Passwords.php:89 #: controllers/Passwords.php:192 controllers/Registrations.php:103 #: controllers/Sessions.php:85 controllers/Support.php:70 #: controllers/collections/Filters.php:105 diff --git a/src/controllers/News.php b/src/controllers/News.php index 719f2053..0502a6f2 100644 --- a/src/controllers/News.php +++ b/src/controllers/News.php @@ -121,10 +121,8 @@ public function showAvailable(Request $request): Response ]); } - $links = models\Link::listFromFollowedCollections($user->id, max:2); - return Response::json(200, [ - 'available' => count($links) > 0, + 'available' => models\Link::anyFromFollowedCollections($user->id), ]); } } diff --git a/src/models/dao/links/NewsQueries.php b/src/models/dao/links/NewsQueries.php index 67ea113f..909760b3 100644 --- a/src/models/dao/links/NewsQueries.php +++ b/src/models/dao/links/NewsQueries.php @@ -96,6 +96,78 @@ public static function listFromFollowedCollections(string $user_id, int $max): a return self::fromDatabaseRows($results); } + /** + * Return whether there are any public links listed in followed collections + * of the given user. + */ + public static function anyFromFollowedCollections(string $user_id): bool + { + $values = [ + ':user_id' => $user_id, + ':until_hard_limit' => \Minz\Time::ago(1, 'year')->format(Database\Column::DATETIME_FORMAT), + ':until_strict' => \Minz\Time::ago(1, 'day')->format(Database\Column::DATETIME_FORMAT), + ':until_normal' => \Minz\Time::ago(1, 'week')->format(Database\Column::DATETIME_FORMAT), + ]; + + $sql = <<= :until_hard_limit + AND ( + (fc.time_filter = 'strict' AND lc.created_at >= :until_strict) OR + (fc.time_filter = 'normal' AND lc.created_at >= :until_normal) OR + (fc.time_filter = 'all' AND lc.created_at >= fc.created_at - INTERVAL '1 week') + ) + ) + SQL; + + $database = Database::get(); + $statement = $database->prepare($sql); + $statement->execute($values); + + return $statement->fetch() !== false; + } + /** * Mark the relevant links to be grouped by sources in the given collection. * diff --git a/tests/models/dao/links/NewsQueriesTest.php b/tests/models/dao/links/NewsQueriesTest.php index 1da31752..1d3eac3d 100644 --- a/tests/models/dao/links/NewsQueriesTest.php +++ b/tests/models/dao/links/NewsQueriesTest.php @@ -488,4 +488,58 @@ public function testListFromFollowedCollectionsDoesNotSelectFromFollowedIfLinkIs $this->assertSame(0, count($links)); } + + public function testAnyFromFollowedCollectionsCanReturnTrue(): void + { + $published_at = \Minz\Time::ago(1, 'day'); + $link = LinkFactory::create([ + 'user_id' => $this->other_user->id, + 'is_hidden' => false, + ]); + $collection = CollectionFactory::create([ + 'user_id' => $this->other_user->id, + 'type' => 'collection', + 'is_public' => true, + ]); + LinkToCollectionFactory::create([ + 'created_at' => $published_at, + 'collection_id' => $collection->id, + 'link_id' => $link->id, + ]); + FollowedCollectionFactory::create([ + 'user_id' => $this->user->id, + 'collection_id' => $collection->id, + ]); + + $result = models\Link::anyFromFollowedCollections($this->user->id); + + $this->assertTrue($result); + } + + public function testAnyFromFollowedCollectionsCanReturnFalse(): void + { + $published_at = \Minz\Time::ago(1, 'day'); + $link = LinkFactory::create([ + 'user_id' => $this->other_user->id, + 'is_hidden' => true, // Note the link is hidden + ]); + $collection = CollectionFactory::create([ + 'user_id' => $this->other_user->id, + 'type' => 'collection', + 'is_public' => true, + ]); + LinkToCollectionFactory::create([ + 'created_at' => $published_at, + 'collection_id' => $collection->id, + 'link_id' => $link->id, + ]); + FollowedCollectionFactory::create([ + 'user_id' => $this->user->id, + 'collection_id' => $collection->id, + ]); + + $result = models\Link::anyFromFollowedCollections($this->user->id); + + $this->assertFalse($result); + } }