From 9ba9006014a509bf62f53af54c43830c02486592 Mon Sep 17 00:00:00 2001 From: Alexei Sorokin Date: Tue, 7 Jul 2020 22:41:03 +0300 Subject: [PATCH] [CORE] Avoid materialisation in the TaggedProfileNoticeStream query This is analogous to c862589dcfafac57213f72dfdad5d56c896946b0 --- lib/notices/taggedprofilenoticestream.php | 104 ++++++++++------------ lib/notices/tagnoticestream.php | 4 +- 2 files changed, 50 insertions(+), 58 deletions(-) diff --git a/lib/notices/taggedprofilenoticestream.php b/lib/notices/taggedprofilenoticestream.php index f6fb476ff1..4941cc5ac5 100644 --- a/lib/notices/taggedprofilenoticestream.php +++ b/lib/notices/taggedprofilenoticestream.php @@ -1,53 +1,52 @@ . + /** - * StatusNet - the distributed open-source microblogging tool - * Copyright (C) 2011, StatusNet, Inc. - * * Stream of notices by a profile with a given tag - * - * PHP version 5 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ -if (!defined('GNUSOCIAL')) { exit(1); } +defined('GNUSOCIAL') || die(); /** * Stream of notices with a given profile and tag * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ class TaggedProfileNoticeStream extends ScopingNoticeStream { - function __construct($profile, $tag, Profile $scoped=null) + public function __construct($profile, $tag, Profile $scoped = null) { - parent::__construct(new CachingNoticeStream(new RawTaggedProfileNoticeStream($profile, $tag), - 'profile:notice_ids_tagged:'.$profile->id.':'.Cache::keyize($tag)), - $scoped); + parent::__construct( + new CachingNoticeStream( + new RawTaggedProfileNoticeStream($profile, $tag), + 'profile:notice_ids_tagged:' . $profile->id . ':' . Cache::keyize($tag) + ), + $scoped + ); } } @@ -55,11 +54,10 @@ class TaggedProfileNoticeStream extends ScopingNoticeStream * Raw stream of notices with a given profile and tag * * @category Stream - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ class RawTaggedProfileNoticeStream extends NoticeStream @@ -67,46 +65,40 @@ class RawTaggedProfileNoticeStream extends NoticeStream protected $profile; protected $tag; - function __construct($profile, $tag) + public function __construct($profile, $tag) { $this->profile = $profile; $this->tag = $tag; } - function getNoticeIds($offset, $limit, $since_id, $max_id) + public function getNoticeIds($offset, $limit, $since_id, $max_id) { - // XXX It would be nice to do this without a join - // (necessary to do it efficiently on accounts with long history) + $nt = new Notice_tag(); - $notice = new Notice(); + $nt->tag = $this->tag; - $query = - "select id from notice join notice_tag on id=notice_id where tag='". - $notice->escape($this->tag) . - "' and profile_id=" . intval($this->profile->id); + $nt->selectAdd(); + $nt->selectAdd('notice_id'); - $since = Notice::whereSinceId($since_id, 'id', 'notice.created'); - if ($since) { - $query .= " and ($since)"; - } + $nt->joinAdd(['notice_id', 'notice:id']); - $max = Notice::whereMaxId($max_id, 'id', 'notice.created'); - if ($max) { - $query .= " and ($max)"; - } + $nt->whereAdd(sprintf('notice.profile_id = %d', $this->profile->id)); - $query .= ' order by notice.created DESC, id DESC'; + Notice::addWhereSinceId($nt, $since_id, 'notice_id', 'notice_tag.created'); + Notice::addWhereMaxId($nt, $max_id, 'notice_id', 'notice_tag.created'); + + $nt->orderBy('notice_tag.created DESC, notice_id DESC'); if (!is_null($offset)) { - $query .= " LIMIT " . intval($limit) . " OFFSET " . intval($offset); + $nt->limit($offset, $limit); } - $notice->query($query); + $ids = []; - $ids = array(); - - while ($notice->fetch()) { - $ids[] = $notice->id; + if ($nt->find()) { + while ($nt->fetch()) { + $ids[] = $nt->notice_id; + } } return $ids; diff --git a/lib/notices/tagnoticestream.php b/lib/notices/tagnoticestream.php index 26857f6d21..9f4213b38c 100644 --- a/lib/notices/tagnoticestream.php +++ b/lib/notices/tagnoticestream.php @@ -78,8 +78,8 @@ class RawTagNoticeStream extends NoticeStream $nt->selectAdd(); $nt->selectAdd('notice_id'); - Notice::addWhereSinceId($nt, $since_id, 'notice_id'); - Notice::addWhereMaxId($nt, $max_id, 'notice_id'); + Notice::addWhereSinceId($nt, $since_id, 'notice_id', 'notice_tag.created'); + Notice::addWhereMaxId($nt, $max_id, 'notice_id', 'notice_tag.created'); if (!empty($this->selectVerbs)) { $nt->joinAdd(array('notice_id', 'notice:id'));