<commit_before><?php
namespace FOD\OrmDenormalizer;


use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
use Doctrine\ORM\Query\Expr\Composite;
use Doctrine\ORM\Query\Expr\From;
use Doctrine\ORM\Query\Expr\GroupBy;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Query\Expr\OrderBy;
use Doctrine\ORM\Query\Expr\Orx;
use Doctrine\ORM\Query\Expr\Select;
use Doctrine\ORM\QueryBuilder;
use Doctrine\DBAL\Query\QueryBuilder as DBALQueryBuilder;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\Expression\CompositeExpression;
use FOD\OrmDenormalizer\DnTableGroup;

/**
 * Class ORMQueryBuilderDenormalizer
 * @package FOD\OrmDenormalizer
 */
class ORMQueryBuilderDenormalizer
{
    protected $entityClassTableMapping = [];

    protected $entityClassMapping = [];

    protected $entityAliases = [];

    protected $aliasesReplacedMap = [];

    /** @var  DnTableGroup */
    protected $dnTableGroup;

    /** @var  QueryBuilder */
    protected $queryBuilder;

    /**
     * DenormalizedQueryBuilder constructor.
     *
     * @param QueryBuilder $queryBuilder
     * @param DnTableGroup $dnTableGroup
     * @param ClassMetadataFactory $classMetadataFactory
     */
    public function __construct(QueryBuilder $queryBuilder, DnTableGroup $dnTableGroup, ClassMetadataFactory $classMetadataFactory)
    {
        $this->queryBuilder = $queryBuilder;
        $this->dnTableGroup = $dnTableGroup;

        foreach ($queryBuilder->getRootEntities() as $entityIndex => $rootEntity) {
            $this->entityClassMapping[$rootEntity] = $classMetadataFactory->getMetadataFor($rootEntity)->getName();
            $this->entityClassTableMapping[$this->entityClassMapping[$rootEntity]] = $dnTableGroup->getTableName();
            $this->entityAliases[$queryBuilder->getRootAliases()[$entityIndex]] = $this->entityClassMapping[$rootEntity];
        }

        $this->extractAliases();
    }

    /**
     * @param Connection $connection
     *
     * @return DBALQueryBuilder
     */
    public function translate(Connection $connection)
    {
        $target = $connection->createQueryBuilder();
        foreach ($this->queryBuilder->getDQLParts() as $name => $dqlPart) {
            if (!$dqlPart) {
                continue;
            }
            $method = 'translate' . ucfirst($name);
            if (method_exists($this, $method)) {
                $dbalPart = is_array($dqlPart)
                    ? array_map([$this, $method], $dqlPart)
                    : $this->{$method}($dqlPart);
                $target->add($name, $dbalPart);
            }
        }

        $dbalParams = $this->translateParameters($this->queryBuilder->getParameters());
        $target->setParameters($dbalParams['params'], $dbalParams['paramTypes']);
        $target->setFirstResult($this->queryBuilder->getFirstResult());
        $target->setMaxResults($this->queryBuilder->getMaxResults());

        return $target;
    }

    /**
     * @return $this
     * @throws \Exception
     */
    protected function extractAliases()
    {
        /** @var Join[] $joins */
        foreach ($this->queryBuilder->getDQLPart('join') as $joins) {
            /** @var Join $join */
            foreach ($joins as $join) {
                list($joinAlias, $joinProperty) = explode('.', $join->getJoin());

                if (isset($this->entityAliases[$joinAlias], $this->dnTableGroup->getStructureSchema()[$this->entityAliases[$joinAlias]], $this->dnTableGroup->getStructureSchema()[$this->entityAliases[$joinAlias]][$joinProperty])) {
                    $this->entityAliases[$join->getAlias()] = $this->dnTableGroup->getStructureSchema()[$this->entityAliases[$joinAlias]][$joinProperty];
                } else {
                    throw new \Exception($this->entityAliases[$joinAlias] . ' not in schema table ' . $this->dnTableGroup->getTableName());
                }
            }
        }

        $entityAliases = array_flip($this->entityAliases);

        foreach ($this->dnTableGroup->getColumns() as $dnColumn) {
            $this->aliasesReplacedMap[$entityAliases[$dnColumn->getTargetEntityClass()] . '.' . $dnColumn->getTargetPropertyName()] = $dnColumn->getName();
        }

        return $this;
    }

    /**
     * @param Select $dqlPart
     *
     * @return string
     */
    protected function translateSelect(Select $dqlPart)
    {
        return (string)new Select(array_map([$this, 'stripAlias'], $dqlPart->getParts()));
    }

    /**
     * @param From $dqlPart
     *
     * @return array
     */
    protected function translateFrom(From $dqlPart)
    {
        return [
            'table' => $this->entityClassTableMapping[$this->entityAliases[$dqlPart->getAlias()]],
            'alias' => null,
        ];
    }

    /**<commit_msg>fix extract aliases<commit_after><?php
namespace FOD\OrmDenormalizer;


use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
use Doctrine\ORM\Query\Expr\Composite;
use Doctrine\ORM\Query\Expr\From;
use Doctrine\ORM\Query\Expr\GroupBy;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Query\Expr\OrderBy;
use Doctrine\ORM\Query\Expr\Orx;
use Doctrine\ORM\Query\Expr\Select;
use Doctrine\ORM\QueryBuilder;
use Doctrine\DBAL\Query\QueryBuilder as DBALQueryBuilder;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\Expression\CompositeExpression;

/**
 * Class ORMQueryBuilderDenormalizer
 * @package FOD\OrmDenormalizer
 */
class ORMQueryBuilderDenormalizer
{
    protected $entityClassTableMapping = [];

    protected $entityClassMapping = [];

    protected $entityAliases = [];

    protected $aliasesReplacedMap = [];

    /** @var  DnTableGroup */
    protected $dnTableGroup;

    /** @var  QueryBuilder */
    protected $queryBuilder;

    /**
     * DenormalizedQueryBuilder constructor.
     *
     * @param QueryBuilder $queryBuilder
     * @param DnTableGroup $dnTableGroup
     * @param ClassMetadataFactory $classMetadataFactory
     */
    public function __construct(QueryBuilder $queryBuilder, DnTableGroup $dnTableGroup, ClassMetadataFactory $classMetadataFactory)
    {
        $this->queryBuilder = $queryBuilder;
        $this->dnTableGroup = $dnTableGroup;

        foreach ($queryBuilder->getRootEntities() as $entityIndex => $rootEntity) {
            $this->entityClassMapping[$rootEntity] = $classMetadataFactory->getMetadataFor($rootEntity)->getName();
            $this->entityClassTableMapping[$this->entityClassMapping[$rootEntity]] = $dnTableGroup->getTableName();
            $this->entityAliases[$queryBuilder->getRootAliases()[$entityIndex]] = $this->entityClassMapping[$rootEntity];
        }

        $this->extractAliases();
    }

    /**
     * @param Connection $connection
     *
     * @return DBALQueryBuilder
     */
    public function translate(Connection $connection)
    {
        $target = $connection->createQueryBuilder();
        foreach ($this->queryBuilder->getDQLParts() as $name => $dqlPart) {
            if (!$dqlPart) {
                continue;
            }
            $method = 'translate' . ucfirst($name);
            if (method_exists($this, $method)) {
                $dbalPart = is_array($dqlPart)
                    ? array_map([$this, $method], $dqlPart)
                    : $this->{$method}($dqlPart);
                $target->add($name, $dbalPart);
            }
        }

        $dbalParams = $this->translateParameters($this->queryBuilder->getParameters());
        $target->setParameters($dbalParams['params'], $dbalParams['paramTypes']);
        $target->setFirstResult($this->queryBuilder->getFirstResult());
        $target->setMaxResults($this->queryBuilder->getMaxResults());

        return $target;
    }

    /**
     * @return $this
     * @throws \Exception
     */
    protected function extractAliases()
    {
        /** @var Join[] $joins */
        foreach ($this->queryBuilder->getDQLPart('join') as $joins) {
            /** @var Join $join */
            foreach ($joins as $join) {

                $splitJoin = explode('.', $join->getJoin());

                if (count($splitJoin) === 2) {
                    list($joinAlias, $joinProperty) = $splitJoin;
                    if (isset($this->entityAliases[$joinAlias], $this->dnTableGroup->getStructureSchema()[$this->entityAliases[$joinAlias]], $this->dnTableGroup->getStructureSchema()[$this->entityAliases[$joinAlias]][$joinProperty])) {
                        $this->entityAliases[$join->getAlias()] = $this->dnTableGroup->getStructureSchema()[$this->entityAliases[$joinAlias]][$joinProperty];
                    } else {
                        throw new \Exception($this->entityAliases[$joinAlias] . ' not in schema table ' . $this->dnTableGroup->getTableName());
                    }
                } elseif (count($splitJoin) === 1) {
                    $this->entityAliases[$join->getAlias()] = $join->getJoin();
                }
            }
        }

        foreach (array_flip($this->entityAliases) as $className => $entityAlias) {
            foreach ($this->dnTableGroup->getColumns() as $dnColumn) {
                if ($dnColumn->getTargetEntityClass() === $className) {
                    $this->aliasesReplacedMap[$entityAlias . '.' . $dnColumn->getTargetPropertyName()] = $dnColumn->getName();
                }
            }
        }

        return $this;
    }

    /**
     * @param Select $dqlPart
     *
     * @return string
     */
    protected function translateSelect(Select $dqlPart)
    {
        return (string)new Select(array_map([$this, 'stripAlias'], $dqlPart->getParts()));
    }

    /**
     * @param From $dqlPart
     *
     * @return array
     */
    protected function translateFrom(From $dqlPart)
    {
        return [
            'table' => $this->entityClassTableMapping[$this->entityAliases[$dqlPart->getAlias()]],
            'alias' => null,
        ];
    }

    /**
{'fraction_non_alphanumeric': 0.14373242265970268, 'fraction_numerical': 0.0002008838891120932, 'mean_word_length': 2.7111442415206857, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 129, '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': '7539698', 'n_tokens_mistral': 2844, 'n_tokens_neox': 2776, 'n_words': 436}