<commit_before><?php

namespace Jackalope\Transport\DoctrineDBAL\Query;

use PHPCR\Query\InvalidQueryException;
use PHPCR\NodeType\NodeTypeManagerInterface;
use PHPCR\Query\QOM;

use Jackalope\NotImplementedException;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;

/**
 * Converts QOM to SQL Statements for the Doctrine DBAL database backend.
 *
 * @license http://www.apache.org/licenses/LICENSE-2.0  Apache License Version 2.0, January 2004
 */
class QOMWalker
{
    /**
     * @var NodeTypeManagerInterface
     */
    private $nodeTypeManager;

    /**
     * @var array
     */
    private $alias = array();

    /**
     * @var Doctrine\DBAL\Connection
     */
    private $conn;

    /**
     * @var AbstractPlatform
     */
    private $platform;

    private $namespaces;

    /**
     * @param \PHPCR\NodeType\NodeTypeManagerInterface $manager
     * @param Connection $conn
     * @param array $namespaces
     */
    public function __construct(NodeTypeManagerInterface $manager, Connection $conn, array $namespaces = array())
    {
        $this->conn = $conn;
        $this->nodeTypeManager = $manager;
        $this->platform = $conn->getDatabasePlatform();
        $this->namespaces = $namespaces;
    }

    /**
     * @param $selectorName
     * @return string
     */
    private function getTableAlias($selectorName)
    {
        if (strpos($selectorName, ".") === false) {
            return "n";
        }

        $selectorAlias = reset(explode(".", $selectorName));
        if (!isset($this->alias[$selectorAlias])) {
            $this->alias[$selectorAlias] = "n" . count($this->alias);
        }

        return $this->alias[$selectorAlias];
    }

    /**
     * @param \PHPCR\Query\QOM\QueryObjectModelInterface $qom
     * @return string
     */
    public function walkQOMQuery(QOM\QueryObjectModelInterface $qom)
    {
        $sql = "SELECT";
        $sql .= " " . $this->walkColumns($qom->getColumns());
        $sql .= " " . $this->walkSource($qom->getSource());
        if ($constraint = $qom->getConstraint()) {
            $sql .= " AND " . $this->walkConstraint($constraint);
        }
        if ($orderings = $qom->getOrderings()) {
            $sql .= " " . $this->walkOrderings($orderings);
        }

        return $sql;
    }

    /**
     * @param $columns
     * @return string
     */
    public function walkColumns($columns)
    {
        $sql = '';
        if ($columns) {
            foreach ($columns as $column) {
                $sql .= $this->walkColumn($column);
            }
        }

        if ('' === trim($sql)) {
            $sql = '*';
        }

        return $sql;
    }

    /*
     * @return string
     */
    public function walkColumn(QOM\ColumnInterface $column)
    {
        return '';
    }

    /**
     * @param \PHPCR\Query\QOM\SourceInterface $source
     * @return string
     * @throws \Jackalope\NotImplementedException
     */
    public function walkSource(QOM\SourceInterface $source)
    {
        if (!($source instanceof QOM\SelectorInterface)) {
            throw new NotImplementedException("Only Selector Sources are supported.");
        }

        $sql = "FROM phpcr_nodes n ".
               "WHERE n.workspace_name = ? AND n.type IN ('" . $source->getNodeTypeName() ."'";

        $subTypes = $this->nodeTypeManager->getSubtypes($source->getNodeTypeName());
        foreach ($subTypes as $subType) {
            /* @var $subType PHPCR\NodeType\NodeTypeInterface */
            $sql .= ", '" . $subType->getName() . "'";
        }
        $sql .= ')';

        return $sql;
    }

    /**
     * @param \PHPCR\Query\QOM\ConstraintInterface $constraint
     * @return string
     * @throws \PHPCR\Query\InvalidQueryException
     */
    public function walkConstraint(QOM\ConstraintInterface $constraint)
    {
        if ($constraint instanceof QOM\AndInterface) {
            return $this->walkAndConstraint($constraint);
        }
        if ($constraint instanceof QOM\OrInterface) {
            return $this->walkOrConstraint($constraint);
        }
        if ($constraint instanceof QOM\NotInterface) {
            return $this->walkNotConstraint($constraint);
        }
        if ($constraint instanceof QOM\ComparisonInterface) {
            return $this->walkComparisonConstraint($constraint);
        }
        if ($constraint instanceof QOM\DescendantNodeInterface) {
            return $this->walkDescendantNodeConstraint($constraint);
        }
        if ($constraint instanceof QOM\ChildNodeInterface) {
            return $this->walkChildNodeConstraint($constraint);
        }
        if ($constraint instanceof QOM\PropertyExistenceInterface) {
            return $this->walkPropertyExistenceConstraint($constraint);
        }
        if ($constraint instanceof QOM\SameNodeInterface) {
            return $this->walkSameNodeConstraint($constraint);
        }

        throw new InvalidQueryException("Constraint " . get_class($constraint) . " not yet supported.");
    }

    /**
     * @param \PHPCR\Query\QOM\SameNodeInterface $constraint
     * @return string
     */
    public function walkSameNodeConstraint(QOM\SameNodeInterface $constraint)
    {
        return $this->getTableAlias($constraint->getSelectorName()) . ".path = '" . $constraint->getPath() . "'";
    }

    /**
     * @param QOM\PropertyExistenceInterface $constraint
     */
    public function walkPropertyExistenceConstraint(QOM\PropertyExistenceInterface $constraint)
    {
        return $this->sqlXpathValueExists($this->getTableAlias($constraint->getSelectorName()), $constraint->getPropertyName());
    }

    /**
     * @param QOM\DescendantNodeInterface $constraint
     * @return string
     */
    public function walkDescendantNodeConstraint(QOM\DescendantNodeInterface $constraint)
    {
        return $this->getTableAlias($constraint->getSelectorName()) . ".path LIKE '" . $constraint->getAncestorPath() . "/%'";
    }

    /**<commit_msg>added ultra simple fulltext search<commit_after><?php

namespace Jackalope\Transport\DoctrineDBAL\Query;

use PHPCR\Query\InvalidQueryException;
use PHPCR\NodeType\NodeTypeManagerInterface;
use PHPCR\Query\QOM;

use Jackalope\NotImplementedException;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;

/**
 * Converts QOM to SQL Statements for the Doctrine DBAL database backend.
 *
 * @license http://www.apache.org/licenses/LICENSE-2.0  Apache License Version 2.0, January 2004
 */
class QOMWalker
{
    /**
     * @var NodeTypeManagerInterface
     */
    private $nodeTypeManager;

    /**
     * @var array
     */
    private $alias = array();

    /**
     * @var Doctrine\DBAL\Connection
     */
    private $conn;

    /**
     * @var AbstractPlatform
     */
    private $platform;

    private $namespaces;

    /**
     * @param \PHPCR\NodeType\NodeTypeManagerInterface $manager
     * @param Connection $conn
     * @param array $namespaces
     */
    public function __construct(NodeTypeManagerInterface $manager, Connection $conn, array $namespaces = array())
    {
        $this->conn = $conn;
        $this->nodeTypeManager = $manager;
        $this->platform = $conn->getDatabasePlatform();
        $this->namespaces = $namespaces;
    }

    /**
     * @param $selectorName
     * @return string
     */
    private function getTableAlias($selectorName)
    {
        if (strpos($selectorName, ".") === false) {
            return "n";
        }

        $selectorAlias = reset(explode(".", $selectorName));
        if (!isset($this->alias[$selectorAlias])) {
            $this->alias[$selectorAlias] = "n" . count($this->alias);
        }

        return $this->alias[$selectorAlias];
    }

    /**
     * @param \PHPCR\Query\QOM\QueryObjectModelInterface $qom
     * @return string
     */
    public function walkQOMQuery(QOM\QueryObjectModelInterface $qom)
    {
        $sql = "SELECT";
        $sql .= " " . $this->walkColumns($qom->getColumns());
        $sql .= " " . $this->walkSource($qom->getSource());
        if ($constraint = $qom->getConstraint()) {
            $sql .= " AND " . $this->walkConstraint($constraint);
        }
        if ($orderings = $qom->getOrderings()) {
            $sql .= " " . $this->walkOrderings($orderings);
        }

        return $sql;
    }

    /**
     * @param $columns
     * @return string
     */
    public function walkColumns($columns)
    {
        $sql = '';
        if ($columns) {
            foreach ($columns as $column) {
                $sql .= $this->walkColumn($column);
            }
        }

        if ('' === trim($sql)) {
            $sql = '*';
        }

        return $sql;
    }

    /*
     * @return string
     */
    public function walkColumn(QOM\ColumnInterface $column)
    {
        return '';
    }

    /**
     * @param \PHPCR\Query\QOM\SourceInterface $source
     * @return string
     * @throws \Jackalope\NotImplementedException
     */
    public function walkSource(QOM\SourceInterface $source)
    {
        if (!($source instanceof QOM\SelectorInterface)) {
            throw new NotImplementedException("Only Selector Sources are supported.");
        }

        $sql = "FROM phpcr_nodes n ".
               "WHERE n.workspace_name = ? AND n.type IN ('" . $source->getNodeTypeName() ."'";

        $subTypes = $this->nodeTypeManager->getSubtypes($source->getNodeTypeName());
        foreach ($subTypes as $subType) {
            /* @var $subType PHPCR\NodeType\NodeTypeInterface */
            $sql .= ", '" . $subType->getName() . "'";
        }
        $sql .= ')';

        return $sql;
    }

    /**
     * @param \PHPCR\Query\QOM\ConstraintInterface $constraint
     * @return string
     * @throws \PHPCR\Query\InvalidQueryException
     */
    public function walkConstraint(QOM\ConstraintInterface $constraint)
    {
        if ($constraint instanceof QOM\AndInterface) {
            return $this->walkAndConstraint($constraint);
        }
        if ($constraint instanceof QOM\OrInterface) {
            return $this->walkOrConstraint($constraint);
        }
        if ($constraint instanceof QOM\NotInterface) {
            return $this->walkNotConstraint($constraint);
        }
        if ($constraint instanceof QOM\ComparisonInterface) {
            return $this->walkComparisonConstraint($constraint);
        }
        if ($constraint instanceof QOM\DescendantNodeInterface) {
            return $this->walkDescendantNodeConstraint($constraint);
        }
        if ($constraint instanceof QOM\ChildNodeInterface) {
            return $this->walkChildNodeConstraint($constraint);
        }
        if ($constraint instanceof QOM\PropertyExistenceInterface) {
            return $this->walkPropertyExistenceConstraint($constraint);
        }
        if ($constraint instanceof QOM\SameNodeInterface) {
            return $this->walkSameNodeConstraint($constraint);
        }
        if ($constraint instanceof QOM\FullTextSearchInterface) {
            return $this->walkFullTextSearchConstraint($constraint);
        }

        throw new InvalidQueryException("Constraint " . get_class($constraint) . " not yet supported.");
    }

    /**
     * @param \PHPCR\Query\QOM\SameNodeInterface $constraint
     * @return string
     */
    public function walkSameNodeConstraint(QOM\SameNodeInterface $constraint)
    {
        return $this->getTableAlias($constraint->getSelectorName()) . ".path = '" . $constraint->getPath() . "'";
    }

    /**
     * @param \PHPCR\Query\QOM\FullTextSearchInterface $constraint
     * @return string
     */
    public function walkFullTextSearchConstraint(QOM\FullTextSearchInterface $constraint)
    {
        return $this->sqlXpathExtractValue($this->getTableAlias($constraint->getSelectorName()), $constraint->getPropertyName()).' LIKE '. $this->conn->quote('%'.$constraint->getFullTextSearchExpression().'%');
    }

    /**
     * @param QOM\PropertyExistenceInterface $constraint
     */
    public function walkPropertyExistenceConstraint(QOM\PropertyExistenceInterface $constraint)
    {
        return $this->sqlXpathValueExists($this->getTableAlias($constraint->getSelectorName()), $constraint->getPropertyName());
    }

    /**
     * @param QOM\DescendantNodeInterface $constraint
     * @return string
     */
    public function walkDescendantNodeConstraint(QOM\DescendantNodeInterface $constraint)
    {
        return $this->getTableAlias($constraint->getSelectorName()) . ".path LIKE '" . $constraint->getAncestorPath() . "/%'";
    }

    /**
{'fraction_non_alphanumeric': 0.13406730694151636, 'fraction_numerical': 0.0012493167798859998, 'mean_word_length': 2.4672441797509475, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4820462', 'n_tokens_mistral': 3592, 'n_tokens_neox': 3511, 'n_words': 652}