Chapter6: CountFollowerProjector
This commit is contained in:
@@ -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
|
||||
|
||||
58
src/App/Command/ProjectCounterFollowersCommand.php
Normal file
58
src/App/Command/ProjectCounterFollowersCommand.php
Normal 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
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user