feat(db): add remote convertors

This commit is contained in:
Ondrej Vlach 2024-08-02 14:14:06 +02:00
parent 857507abe5
commit 3e3cc96d77
No known key found for this signature in database
GPG Key ID: 7F141CDACEDEE2DE
3 changed files with 260 additions and 0 deletions

View File

@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
namespace App\Service\Persist;
use App\Entity\Remote\Brilo\Comments\Comment;
use App\Repository\Comments\CommentsRepository;
use App\Repository\Post\PostRepository;
use Psr\Log\LoggerInterface;
class RemoteCommentConvertor
{
public function __construct(
protected readonly PostRepository $postRepository,
protected readonly CommentsRepository $commentsRepository,
protected readonly LoggerInterface $logger,
) {
}
/**
* Converts remote entities into database entities
* @param Comment[] $remoteComments
* @return \Generator<\App\Entity\Database\Comments\Comment>
*/
public function convert(iterable $remoteComments): \Generator
{
foreach ($remoteComments as $remoteComment) {
$comment = $this->commentsRepository->find($remoteComment->id);
if ($comment === null) {
$this->logger->info("Creating new comment for ID: {$remoteComment->id}");
yield $this->createComment($remoteComment);
} else {
$this->logger->info("Updating post for ID: {$remoteComment->id}");
$this->updateComment($remoteComment, $comment);
yield $comment;
}
}
}
/**
* Create new comment entity from remote comment
* @param Comment $remoteComment
* @return \App\Entity\Database\Comments\Comment
*/
protected function createComment(Comment $remoteComment): \App\Entity\Database\Comments\Comment
{
$post = $this->postRepository->find($remoteComment->postId) ?? throw new \LogicException("Post not found for ID: {$remoteComment->postId}");
return new \App\Entity\Database\Comments\Comment(
$remoteComment->id,
$post,
$remoteComment->name,
$remoteComment->email,
$remoteComment->body
);
}
/**
* Update existing comment entity with remote comment data
* @param Comment $remoteComment
* @param \App\Entity\Database\Comments\Comment $comment
* @return void
*/
protected function updateComment(Comment $remoteComment, \App\Entity\Database\Comments\Comment $comment): void
{
$post = $this->postRepository->find($remoteComment->postId) ?? throw new \LogicException("Post not found for ID: {$remoteComment->postId}");
$comment->post = $post;
$comment->name = $remoteComment->name;
$comment->email = $remoteComment->email;
$comment->body = $remoteComment->body;
}
}

View File

@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
namespace App\Service\Persist;
use App\Entity\Remote\Brilo\Posts\Post;
use App\Repository\Post\PostRepository;
use App\Repository\Users\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Psr\Log\LoggerInterface;
class RemotePostsConvertor
{
public function __construct(
protected readonly PostRepository $postRepository,
protected readonly UserRepository $userRepository,
protected readonly LoggerInterface $logger,
) {
}
/**
* Convert remote posts into database posts.
* @param Post[] $remotePosts
* @return \Generator<\App\Entity\Database\Posts\Post>
*/
public function convert(iterable $remotePosts): \Generator
{
foreach ($remotePosts as $remotePost) {
$post = $this->postRepository->find($remotePost->id);
if ($post === null) {
$this->logger->info("Creating new post for ID: {$remotePost->id}");
yield $this->createPost($remotePost);
} else {
$this->logger->info("Updating post for ID: {$remotePost->id}");
$this->updatePost($remotePost, $post);
yield $post;
}
}
}
/**
* Create a new post from the remote data.
* @param Post $remotePost
* @return \App\Entity\Database\Posts\Post
*/
protected function createPost(Post $remotePost): \App\Entity\Database\Posts\Post
{
$user = $this->userRepository->find($remotePost->userId) ?? throw new \LogicException("User not found for ID: {$remotePost->userId}");
return new \App\Entity\Database\Posts\Post(
$remotePost->id,
$user,
$remotePost->title,
$remotePost->body,
new ArrayCollection(),
);
}
/**
* Update an existing post with the remote data.
* @param Post $remotePost
* @param \App\Entity\Database\Posts\Post $post
* @return void
*/
protected function updatePost(Post $remotePost, \App\Entity\Database\Posts\Post $post): void
{
$user = $this->userRepository->find($remotePost->userId) ?? throw new \LogicException("User not found for ID: {$remotePost->userId}");
$post->user = $user;
$post->title = $remotePost->title;
$post->body = $remotePost->body;
}
}

View File

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace App\Service\Persist;
use App\Entity\Database\Users\Address;
use App\Entity\Database\Users\Company;
use App\Entity\Remote\Brilo\Users\User;
use App\Repository\Users\CompanyRepository;
use App\Repository\Users\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Psr\Log\LoggerInterface;
class RemoteUsersConvertor
{
public function __construct(
protected readonly UserRepository $userRepository,
protected readonly CompanyRepository $companyRepository,
protected readonly LoggerInterface $logger,
) {
}
/**
* Converts remote users to database users
* @param User[] $remoteUsers
* @return \Generator<\App\Entity\Database\Users\User>
*/
public function convert(iterable $remoteUsers): \Generator
{
$ids = array_map(function ($remoteUser) {
return $remoteUser->id;
}, (array) $remoteUsers);
$existentIds = $this->userRepository->findByIds($ids);
foreach ($remoteUsers as $remoteUser) {
if (isset($existentIds[$remoteUser->id])) {
$localUser = $existentIds[$remoteUser->id];
$this->updateUser($remoteUser, $localUser);
$this->logger->debug("Updating user with ID: {$remoteUser->id}");
yield $localUser;
} else {
$this->logger->debug("Creating new user with ID: {$remoteUser->id}");
yield $this->createUser($remoteUser);
}
}
}
/**
* Update user from the given remote user
* @param User $remoteUser
* @param \App\Entity\Database\Users\User $user
* @return void
*/
protected function updateUser(User $remoteUser, \App\Entity\Database\Users\User $user): void
{
$user->name = $remoteUser->name;
$user->username = $remoteUser->username;
$user->email = $remoteUser->email;
$user->phone = $remoteUser->phone;
$user->website = $remoteUser->website;
$user->address->city = $remoteUser->address->city;
$user->address->street = $remoteUser->address->street;
$user->address->suite = $remoteUser->address->suite;
$user->address->zipcode = $remoteUser->address->zipcode;
$user->address->lat = (float) $remoteUser->address->geo->lat;
$user->address->lng = (float) $remoteUser->address->geo->lng;
if ($user->company->name !== $remoteUser->company->name) {
$user->company = $this->companyRepository->findByName($remoteUser->company->name) ?? new Company(
null,
new ArrayCollection(),
$remoteUser->company->name,
$remoteUser->company->catchPhrase,
$remoteUser->company->bs,
);
} else {
$user->company->catchPhrase = $remoteUser->company->catchPhrase;
$user->company->bs = $remoteUser->company->bs;
}
}
/**
* Creates a new user from the given remote user
* @param User $remoteUser
* @return \App\Entity\Database\Users\User
*/
protected function createUser(User $remoteUser): \App\Entity\Database\Users\User
{
return new \App\Entity\Database\Users\User(
$remoteUser->id,
$remoteUser->name,
$remoteUser->username,
$remoteUser->email,
$remoteUser->phone,
$remoteUser->website,
new Address(
null,
null,
$remoteUser->address->street,
$remoteUser->address->suite,
$remoteUser->address->city,
$remoteUser->address->zipcode,
(float) $remoteUser->address->geo->lat,
(float) $remoteUser->address->geo->lng,
),
$this->companyRepository->findByName($remoteUser->company->name) ?? new Company(
null,
new ArrayCollection(),
$remoteUser->company->name,
$remoteUser->company->catchPhrase,
$remoteUser->company->bs,
)
);
}
}