<commit_before><commit_msg>Create a MatchAgainst parser which allows us to use full text search in doctrine queries<commit_after><?php

namespace SumoCoders\FrameworkCoreBundle\Extensions\Doctrine;

use Doctrine\ORM\Query\AST\InputParameter;
use Doctrine\ORM\Query\AST\Literal;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;

/**
 * "MATCH_AGAINST" "(" {StateFieldPathExpression ","}* InParameter {Literal}? ")"
 */
class MatchAgainst extends FunctionNode
{
    /** @var array */
    private $columns = [];

    /** @var string|InputParameter */
    private $needle;

    /** @var Literal */
    private $mode;

    public function parse(Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        while ($parser->getLexer()->isNextToken(Lexer::T_IDENTIFIER)) {
            $this->columns[] = $parser->StateFieldPathExpression();
            $parser->match(Lexer::T_COMMA);
        };

        $this->needle = $parser->InParameter();

        while ($parser->getLexer()->isNextToken(Lexer::T_STRING)) {
            $this->mode = $parser->Literal();
        }

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }

    public function getSql(SqlWalker $sqlWalker)
    {
        $haystack = null;
        $first = true;
        foreach ($this->columns as $column) {
            if (!$first) {
                $haystack .= ', ';
            }

            $first = false;

            $haystack .= $column->dispatch($sqlWalker);
        }

        $query = "MATCH(" . $haystack . ") AGAINST (" . $this->needle->dispatch($sqlWalker);

        if ($this->mode) {
            $query .= " " . $this->mode->value . " )";
        } else {
            $query .= " )";
        }

        return $query;
    }
}
{'fraction_non_alphanumeric': 0.1572192513368984, 'fraction_numerical': 0.0, 'mean_word_length': 2.4267399267399266, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 24, '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': '5326972', 'n_tokens_mistral': 609, 'n_tokens_neox': 570, 'n_words': 99}