Chapter6: CountFollowerProjector

This commit is contained in:
Carlos Buenosvinos
2021-08-13 13:23:20 +02:00
parent 3dbcd8ac5c
commit 5a184bc4c1
5 changed files with 83 additions and 15 deletions

View File

@@ -1,6 +1,5 @@
doctrine_migrations:
migrations:
dir_name: '%kernel.project_dir%/migrations'
# namespace is arbitrary but should be different from App\Migrations
# as migrations classes should NOT be autoloaded
namespace: DoctrineMigrations
dir_name: '%kernel.project_dir%/migrations'
# namespace is arbitrary but should be different from App\Migrations
# as migrations classes should NOT be autoloaded
namespace: DoctrineMigrations

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Command;
use Cheeper\Application\Command\Author\SignUp;
use Cheeper\Application\Command\Cheep\PostCheep;
use Cheeper\Chapter6\Application\Projector\Author\CountFollowerProjector;
use Cheeper\Chapter6\Application\Projector\Author\CountFollowers;
use Doctrine\DBAL\Driver\Connection;
use Predis\ClientInterface;
use Ramsey\Uuid\Uuid;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
//snippet project-counter-followers-command
final class ProjectCounterFollowersCommand extends Command implements ContainerAwareInterface
{
use ContainerAwareTrait;
protected static $defaultName = 'app:projector:counter-followers';
public function __construct(
string $name = null,
public ClientInterface $redis,
public Connection $database
)
{
parent::__construct($name);
}
protected function configure(): void
{
$this
->setDescription('Project counter followers')
->addArgument('authorId', InputArgument::REQUIRED, 'Author Id')
;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$authorId = $input->getArgument("authorId");
(new CountFollowerProjector(
$this->redis,
$this->database,
))(
CountFollowers::ofAuthor($authorId)
);
return 0;
}
}
//end-snippet

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Cheeper\Chapter6\Application\Projector\Author;
use Cheeper\Chapter6\Application\Projector\CountFollowers;
use Cheeper\DomainModel\Author\AuthorId;
use Doctrine\DBAL\Driver\Connection as Database;
use Predis\ClientInterface as Redis;
@@ -21,18 +20,22 @@ final class CountFollowerProjector
$authorId = AuthorId::fromString($query->authorId());
$stmt = $this->database->prepare(
"SELECT a.id as id, a.username as username, COUNT(*) as followers ".
"FROM authors a, follow_relationships fr ".
"WHERE a.id = fr.followed_id ".
"AND a.id = :authorId ".
"GROUP BY a.id, a.username"
"SELECT a.author_id_id_as_string as id, a.user_name_user_name as username, COUNT(*) as followers ".
"FROM authors a, follows f ".
"WHERE a.author_id_id_as_string = f.to_author_id_id_as_string ".
"AND a.author_id_id_as_string = :authorId ".
"GROUP BY id, username"
);
$stmt->bindValue('authorId', $authorId->toString());
$stmt->execute();
$result = $stmt->fetchAssociative();
$result['followers'] = (int) $result['followers'];
$this->redis->set(
'key',
$stmt->fetchAllAssociative(),
'author_followers_counter_projection:'.$authorId->toString(),
json_encode($result)
);
}
}

View File

@@ -2,9 +2,9 @@
declare(strict_types=1);
namespace Cheeper\Chapter6\Application\Projector;
namespace Cheeper\Chapter6\Application\Projector\Author;
//snippet count-followers
//snippet projector-count-followers
final class CountFollowers
{
private string $authorId;

View File

@@ -74,5 +74,13 @@ final class DoctrineOrmFollows implements Follows
{
$this->em->persist($follow);
}
public function ofFromAuthorIdAndToAuthorId(AuthorId $fromAuthorId, AuthorId $toAuthorId): ?Follow
{
return $this->findOneBy([
'fromAuthorId' => $fromAuthorId->toString(),
'toAuthorId' => $toAuthorId->toString()
]);
}
}
//end-snippet