<commit_before><?php

namespace Codeages\Biz\Framework\Dao;

use Doctrine\DBAL\Query\QueryBuilder;

class DynamicQueryBuilder extends QueryBuilder
{
    protected $conditions;

    public function __construct(Connection $connection, $conditions)
    {
        parent::__construct($connection);
        $this->conditions = $conditions;
    }

    public function where($where)
    {
        if (!$this->isWhereInConditions($where)) {
            return $this;
        }

        return parent::where($where);
    }

    public function andWhere($where)
    {
        if (!$this->isWhereInConditions($where)) {
            return $this;
        }

        if ($this->isInCondition($where)) {
            return $this->addWhereIn($where);
        }

        if ($this->isLikeCondtion($where)) {
            return $this->andWhereLike($where);
        }

        return parent::andWhere($where);
    }

    public function andStaticWhere($where)
    {
        return parent::andWhere($where);
    }

    private function addWhereIn($where)
    {
        $conditionName = $this->getConditionName($where);
        if (empty($this->conditions[$conditionName]) or !is_array($this->conditions[$conditionName])) {
            return $this;
        }

        $marks = array();
        foreach (array_values($this->conditions[$conditionName]) as $index => $value) {
            $marks[] = ":{$conditionName}_{$index}";
            $this->conditions["{$conditionName}_{$index}"] = $value;
        }

        $where = str_replace(":{$conditionName}", implode(',', $marks), $where);

        return parent::andWhere($where);
    }

    private function andWhereLike($where)
    {
        $conditionName = $this->getConditionName($where);
        if (empty($this->conditions[$conditionName]) || !is_string($this->conditions[$conditionName])) {
            return $this;
        }

        //PRE_LIKE
        if (preg_match('/\s+PRE_LIKE\s+/', $where)) {
            $where = preg_replace('/PRE_LIKE/', "LIKE", $where);
            $this->conditions[$conditionName] = "%{$this->conditions[$conditionName]}";
        } else if (preg_match('/\s+SUF_LIKE\s+/', $where)) {
            $where = preg_replace('/SUF_LIKE/', "LIKE", $where);
            $this->conditions[$conditionName] = "{$this->conditions[$conditionName]}%";
        } else {
            $this->conditions[$conditionName] = "%{$this->conditions[$conditionName]}%";
        }

        return parent::andWhere($where);
    }

    public function execute()
    {
        foreach ($this->conditions as $field => $value) {
            $this->setParameter(":{$field}", $value);
        }

        return parent::execute();
    }

    private function isLikeCondtion($where)
    {
        return preg_match('/\s+(PRE_|SUF_)?LIKE\s+/', $where);
    }

    private function isInCondition($where)
    {
        $matched = preg_match('/\s+(IN)\s+/', $where, $matches);<commit_msg>使用一次正则表达式匹配<commit_after><?php

namespace Codeages\Biz\Framework\Dao;

use Doctrine\DBAL\Query\QueryBuilder;

class DynamicQueryBuilder extends QueryBuilder
{
    protected $conditions;

    public function __construct(Connection $connection, $conditions)
    {
        parent::__construct($connection);
        $this->conditions = $conditions;
    }

    public function where($where)
    {
        if (!$this->isWhereInConditions($where)) {
            return $this;
        }

        return parent::where($where);
    }

    public function andWhere($where)
    {
        if (!$this->isWhereInConditions($where)) {
            return $this;
        }

        if ($this->isInCondition($where)) {
            return $this->addWhereIn($where);
        }

        $likeMatchs = $this->getLikeCondtion($where);
        if ($likeMatchs && in_array($likeMatchs[1], $likeMatchs)) {
            return $this->andWhereLike($where, $likeMatchs[1]);
        }

        return parent::andWhere($where);
    }

    public function andStaticWhere($where)
    {
        return parent::andWhere($where);
    }

    private function addWhereIn($where)
    {
        $conditionName = $this->getConditionName($where);
        if (empty($this->conditions[$conditionName]) or !is_array($this->conditions[$conditionName])) {
            return $this;
        }

        $marks = array();
        foreach (array_values($this->conditions[$conditionName]) as $index => $value) {
            $marks[] = ":{$conditionName}_{$index}";
            $this->conditions["{$conditionName}_{$index}"] = $value;
        }

        $where = str_replace(":{$conditionName}", implode(',', $marks), $where);

        return parent::andWhere($where);
    }

    private function andWhereLike($where, $like)
    {
        $conditionName = $this->getConditionName($where);
        if (empty($this->conditions[$conditionName]) || !is_string($this->conditions[$conditionName])) {
            return $this;
        }

        //PRE_LIKE
        if ($like == 'PRE_LIKE') {
            $where = preg_replace('/PRE_LIKE/', "LIKE", $where);
            $this->conditions[$conditionName] = "%{$this->conditions[$conditionName]}";
        } else if ($like == 'SUF_LIKE') {
            $where = preg_replace('/SUF_LIKE/', "LIKE", $where);
            $this->conditions[$conditionName] = "{$this->conditions[$conditionName]}%";
        } else {
            $this->conditions[$conditionName] = "%{$this->conditions[$conditionName]}%";
        }

        return parent::andWhere($where);
    }

    public function execute()
    {
        foreach ($this->conditions as $field => $value) {
            $this->setParameter(":{$field}", $value);
        }

        return parent::execute();
    }

    private function getLikeCondtion($where)
    {
        preg_match('/\s+((PRE_|SUF_)?LIKE)\s+/', $where, $matches);

        return $matches;
    }

    private function isInCondition($where)
    {
        $matched = preg_match('/\s+(IN)\s+/', $where, $matches);
{'fraction_non_alphanumeric': 0.16694800810263336, 'fraction_numerical': 0.00033760972316002703, 'mean_word_length': 2.552158273381295, 'pattern_counts': {'":': 6, '<': 5, '<?xml version=': 0, '>': 53, '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': '6251799', 'n_tokens_mistral': 1734, 'n_tokens_neox': 1693, 'n_words': 285}