<commit_before><?php

namespace PerFi\PerFiBundle\Repository;

use Doctrine\ORM\EntityRepository;
use PerFi\Domain\Account\AccountId;
use PerFi\Domain\Account\AccountRepository;
use PerFi\Domain\MoneyFactory;
use PerFi\Domain\Transaction\Transaction;
use PerFi\Domain\Transaction\TransactionDate;
use PerFi\Domain\Transaction\TransactionId;
use PerFi\Domain\Transaction\TransactionRecordDate;
use PerFi\Domain\Transaction\TransactionRepository as TransactionRepositoryInterface;
use PerFi\Domain\Transaction\TransactionType;
use PerFi\PerFiBundle\Entity\Transaction as DtoTransaction;

/**
 * TransactionRepository
 */
class TransactionRepository extends EntityRepository
    implements TransactionRepositoryInterface
{

    /**
     * @var AccountRepository
     */
    private $accountRepository;

    public function setAccountRepository(AccountRepository $accountRepository)
    {
        $this->accountRepository = $accountRepository;
    }

    /**
     * {@inheritdoc}
     */
    public function add(Transaction $transaction)
    {
        $entity = new DtoTransaction();
        $entity->setTransactionId((string) $transaction->id());
        $entity->setType((string) $transaction->type());
        $entity->setSourceAccount((string) $transaction->sourceAccount()->id());
        $entity->setDestinationAccount((string) $transaction->destinationAccount()->id());
        $entity->setDate($transaction->date());
        $entity->setRecordDate($transaction->recordDate());
        $entity->setDescription($transaction->description());

        $amount = $transaction->amount();
        $entity->setAmount($amount->getAmount());
        $entity->setCurrency((string) $amount->getCurrency());

        $em = $this->getEntityManager();
        $em->persist($entity);
        $em->flush();
    }

    /**
     * {@inheritdoc}
     */
    public function getAll() : array
    {
        $queryBuilder = $this->createQueryBuilder('t');

        $dtos = $queryBuilder
            ->select('t')
            ->getQuery()
            ->getResult();

        return $this->dtosToEntities($dtos);
    }

    private function dtosToEntities($dtos)
    {
        $transactions = [];

        foreach ($dtos as $dto) {
            $transactions[] = $this->dtoToEntity($dto);
        }

        return $transactions;
    }

    private function dtoToEntity($dto)
    {
        $sourceAccountId = AccountId::fromString($dto->getSourceAccount());
        $destinationAccountId = AccountId::fromString($dto->getDestinationAccount());

        $transaction = Transaction::withId(
            TransactionId::fromString($dto->getTransactionId()),
            TransactionType::fromString($dto->getType()),
            $this->accountRepository->get($sourceAccountId),
            $this->accountRepository->get($destinationAccountId),
            MoneyFactory::centsInCurrency($dto->getAmount(), $dto->getCurrency()),
            TransactionDate::fromString($dto->getDate()->format('Y-m-d')),
            TransactionRecordDate::fromString($dto->getRecordDate()->format('Y-m-d H:i:s')),
            $dto->getDescription()
        );

        return $transaction;
    }
}<commit_msg>Use query builder to get transactions<commit_after><?php

namespace PerFi\PerFiBundle\Repository;

use Doctrine\ORM\EntityRepository;
use PerFi\Domain\Transaction\Transaction;
use PerFi\Domain\Transaction\TransactionRepository as TransactionRepositoryInterface;
use PerFi\PerFiBundle\Entity\Transaction as DtoTransaction;
use PerFi\PerFiBundle\Factory\TransactionFactory;

/**
 * TransactionRepository
 */
class TransactionRepository extends EntityRepository
    implements TransactionRepositoryInterface
{

    /**
     * @var AccountRepository
     */
    private $accountRepository;

    public function setAccountRepository(AccountRepository $accountRepository)
    {
        $this->accountRepository = $accountRepository;
    }

    /**
     * {@inheritdoc}
     */
    public function add(Transaction $transaction)
    {
        $entity = new DtoTransaction();
        $entity->setTransactionId((string) $transaction->id());
        $entity->setType((string) $transaction->type());
        $entity->setSourceAccount((string) $transaction->sourceAccount()->id());
        $entity->setDestinationAccount((string) $transaction->destinationAccount()->id());
        $entity->setDate($transaction->date());
        $entity->setRecordDate($transaction->recordDate());
        $entity->setDescription($transaction->description());

        $amount = $transaction->amount();
        $entity->setAmount($amount->getAmount());
        $entity->setCurrency((string) $amount->getCurrency());

        $em = $this->getEntityManager();
        $em->persist($entity);
        $em->flush();
    }

    /**
     * {@inheritdoc}
     */
    public function getAll() : array
    {
        $qb = $this->getEntityManager()->getConnection()->createQueryBuilder();

        $statement = $qb->select(
            't.transaction_id', 't.type', 't.amount', 't.currency',
            't.date', 't.record_date', 't.description',
            'sa.account_id AS source_account_id',
            'sa.title AS source_account_title',
            'sa.type AS source_account_type',
            'da.account_id AS destination_account_id',
            'da.title AS destination_account_title',
            'da.type AS destination_account_type'
        )
        ->from('transaction', 't')
        ->innerJoin('t', 'account', 'sa', 't.source_account = sa.account_id')
        ->innerJoin('t', 'account', 'da', 't.destination_account = da.account_id')
        ->execute();

        return $this->mapToEntities($statement);
    }

    private function mapToEntities($statement) : array
    {
        $transactions = [];

        while ($row = $statement->fetch()) {
            $transactions[] = $this->mapToEntity($row);
        }

        return $transactions;
    }

    private function mapToEntity(array $row) : Transaction
    {
        return TransactionFactory::fromArray($row);
    }
}
{'fraction_non_alphanumeric': 0.14421000166140555, 'fraction_numerical': 0.0, 'mean_word_length': 3.1431520991052992, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7247250', 'n_tokens_mistral': 1596, 'n_tokens_neox': 1582, 'n_words': 256}