From ead09b10856543ab99280fd0a0ef58a522687721 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 17:28:37 -0100 Subject: [PATCH] count followers/following/posts on cache update Signed-off-by: Maxence Lange --- lib/Db/CoreRequestBuilder.php | 23 ++++++++++++++++++ lib/Db/FollowsRequest.php | 40 ++++++++++++++++++++++++++++++++ lib/Db/FollowsRequestBuilder.php | 16 +++++++++++++ lib/Db/NotesRequest.php | 17 ++++++++++++++ lib/Db/NotesRequestBuilder.php | 16 +++++++++++++ lib/Service/ActorService.php | 28 ++++++++++++++++------ 6 files changed, 133 insertions(+), 7 deletions(-) diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index f6622803..130dedd7 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -195,6 +195,18 @@ class CoreRequestBuilder { } + /** + * Limit the request to the FollowId + * + * @param IQueryBuilder $qb + * @param bool $accepted + */ + protected function limitToAccepted(IQueryBuilder &$qb, bool $accepted) { + $this->limitToDBField($qb, 'accepted', ($accepted) ? '1' : '0'); + + } + + /** * Limit the request to the ServiceId * @@ -272,6 +284,17 @@ class CoreRequestBuilder { } + /** + * Limit the request to the url + * + * @param IQueryBuilder $qb + * @param string $actorId + */ + protected function limitToAttributedTo(IQueryBuilder &$qb, string $actorId) { + $this->limitToDBField($qb, 'attributed_to', $actorId, false); + } + + /** * Limit the request to the status * diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index b4197b17..5b024414 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -31,6 +31,7 @@ declare(strict_types=1); namespace OCA\Social\Db; +use daita\MySmallPhpTools\Traits\TArrayTools; use OCA\Social\Exceptions\FollowDoesNotExistException; use OCA\Social\Model\ActivityPub\Follow; @@ -43,6 +44,9 @@ use OCA\Social\Model\ActivityPub\Follow; class FollowsRequest extends FollowsRequestBuilder { + use TArrayTools; + + /** * Insert a new Note in the database. * @@ -96,6 +100,42 @@ class FollowsRequest extends FollowsRequestBuilder { } + /** + * @param string $actorId + * + * @return int + */ + public function countFollowers(string $actorId): int { + $qb = $this->countFollowsSelectSql(); + $this->limitToObjectId($qb, $actorId); + $this->limitToAccepted($qb, true); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + + /** + * @param string $actorId + * + * @return int + */ + public function countFollowing(string $actorId): int { + $qb = $this->countFollowsSelectSql(); + $this->limitToActorId($qb, $actorId); + $this->limitToAccepted($qb, true); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + /** * @param string $followId * diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php index 1947dd4c..7a6882c4 100644 --- a/lib/Db/FollowsRequestBuilder.php +++ b/lib/Db/FollowsRequestBuilder.php @@ -92,6 +92,22 @@ class FollowsRequestBuilder extends CoreRequestBuilder { } + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function countFollowsSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') + ->from(self::TABLE_SERVER_FOLLOWS, 'f'); + + $this->defaultSelectAlias = 'f'; + + return $qb; + } + + /** * Base of the Sql Delete request * diff --git a/lib/Db/NotesRequest.php b/lib/Db/NotesRequest.php index e2c7d9c8..f4bf6842 100644 --- a/lib/Db/NotesRequest.php +++ b/lib/Db/NotesRequest.php @@ -137,6 +137,23 @@ class NotesRequest extends NotesRequestBuilder { } + /** + * @param string $actorId + * + * @return int + */ + public function countNotesFromActorId(string $actorId): int { + $qb = $this->countNotesSelectSql(); + $this->limitToAttributedTo($qb, $actorId); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + /** * @param string $actorId * @param int $since diff --git a/lib/Db/NotesRequestBuilder.php b/lib/Db/NotesRequestBuilder.php index 90ff24e1..e6f2cb18 100644 --- a/lib/Db/NotesRequestBuilder.php +++ b/lib/Db/NotesRequestBuilder.php @@ -92,6 +92,22 @@ class NotesRequestBuilder extends CoreRequestBuilder { } + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function countNotesSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') + ->from(self::TABLE_SERVER_NOTES, 'sn'); + + $this->defaultSelectAlias = 'sn'; + + return $qb; + } + + /** * Base of the Sql Delete request * diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index dea05590..aeb14860 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -34,9 +34,10 @@ use daita\MySmallPhpTools\Traits\TArrayTools; use Exception; use OC\User\NoUserException; use OCA\Social\Db\ActorsRequest; +use OCA\Social\Db\FollowsRequest; +use OCA\Social\Db\NotesRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; -use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; @@ -56,6 +57,12 @@ class ActorService { /** @var ActorsRequest */ private $actorsRequest; + /** @var FollowsRequest */ + private $followsRequest; + + /** @var NotesRequest */ + private $notesRequest; + /** @var PersonService */ private $personService; @@ -70,15 +77,19 @@ class ActorService { * ActorService constructor. * * @param ActorsRequest $actorsRequest + * @param FollowsRequest $followsRequest + * @param NotesRequest $notesRequest * @param PersonService $personService * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( - ActorsRequest $actorsRequest, PersonService $personService, ConfigService $configService, - MiscService $miscService + ActorsRequest $actorsRequest, FollowsRequest $followsRequest, NotesRequest $notesRequest, + PersonService $personService, ConfigService $configService, MiscService $miscService ) { $this->actorsRequest = $actorsRequest; + $this->followsRequest = $followsRequest; + $this->notesRequest = $notesRequest; $this->personService = $personService; $this->configService = $configService; $this->miscService = $miscService; @@ -212,10 +223,13 @@ class ActorService { */ public function cacheLocalActorByUsername(string $username, bool $refresh = false) { try { - $actor = $this->getActor($username); - $actor->addDetailInt('followers', 10); - $actor->addDetailInt('following', 10); - $actor->addDetailInt('post', 100); + $actor = $this->getActor($username);; + $count = [ + 'followers', $this->followsRequest->countFollowers($actor->getId()), + 'following', $this->followsRequest->countFollowing($actor->getId()), + 'post', $this->notesRequest->countNotesFromActorId($actor->getId()) + ]; + $actor->addDetailArray('count', $count); $this->personService->cacheLocalActor($actor, $refresh); } catch (ActorDoesNotExistException $e) {