<commit_before><?php

namespace iriscrm\SimplePOData;

use POData\Providers\Metadata\ResourceProperty;
use POData\Providers\Metadata\ResourceSet;
use POData\UriProcessor\QueryProcessor\Expression\Parser\IExpressionProvider;
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\KeyDescriptor;
use POData\Providers\Query\IQueryProvider;
use POData\Providers\Expression\MySQLExpressionProvider;
use POData\Providers\Query\QueryType;
use POData\Providers\Query\QueryResult;

abstract class BaseQueryProvider implements IQueryProvider
{
    /**
    * @var Connection
    */
    protected $db;

    public function __construct($db){
        $this->db = $db;
    }

    abstract protected function queryAll($sql, $parameters = null);

    abstract protected function queryScalar($sql, $parameters = null);

    /* Stubbed Implementaiton Here */
    public function getQueryProvider()
    {
        return new QueryProvider();
    }

    public function handlesOrderedPaging()
    {
        return true;
    }

    public function getExpressionProvider()
    {
        return new MySQLExpressionProvider();
    }

    protected function getEntityName($entityClassName)
    {
        preg_match_all('/\\\([a-zA-Z]+)/', $entityClassName, $matches);
        if (!empty($matches[1])) {
            return $matches[1][count($matches[1]) - 1];
        }
        return $entityClassName;
    }

    protected function getTableName($entityName)
    {
        $tableName = $entityName;
        preg_match_all('/[A-Z][a-z]+/', $entityName, $matches);
        if (!empty($matches[0])) {
            $tableName = implode('_', $matches[0]);
        }
        return strtolower($tableName);
    }

    public function getResourceSet(
        QueryType $queryType,
        ResourceSet $resourceSet,
        $filterInfo = null,
        $orderBy = null,
        $top = null,
        $skip = null
    ) {
        $result = new QueryResult();

        $entityClassName = $resourceSet->getResourceType()->getInstanceType()->name;
        $entityName = $this->getEntityName($entityClassName);
        $tableName = $this->getTableName($entityName);

        $option = null;
        if ($queryType == QueryType::ENTITIES_WITH_COUNT()){
            //tell mysql we want to know the count prior to the LIMIT 
            //$option = 'SQL_CALC_FOUND_ROWS';
        }

        $where = $filterInfo ? ' WHERE ' . $filterInfo->getExpressionAsString(): '';
        $sqlCount = 'SELECT COUNT(*) FROM ' . $tableName . $where;
        if ($queryType == QueryType::ENTITIES() || $queryType == QueryType::ENTITIES_WITH_COUNT()) {
            $sql = 'SELECT ' . $option . ' * FROM ' . $tableName . $where 
                    . ' LIMIT ' . $top . ' OFFSET ' . $skip;
            $data = $this->queryAll($sql);
            
            if ($queryType == QueryType::ENTITIES_WITH_COUNT()){
                //get those found rows
                //$result->count = $this->queryScalar('SELECT FOUND_ROWS()');
                $result->count = $this->queryScalar($sqlCount);
            }<commit_msg>Base variant of ORDER BY support<commit_after><?php

namespace iriscrm\SimplePOData;

use POData\Providers\Metadata\ResourceProperty;
use POData\Providers\Metadata\ResourceSet;
use POData\UriProcessor\QueryProcessor\Expression\Parser\IExpressionProvider;
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\KeyDescriptor;
use POData\Providers\Query\IQueryProvider;
use POData\Providers\Expression\MySQLExpressionProvider;
use POData\Providers\Query\QueryType;
use POData\Providers\Query\QueryResult;

abstract class BaseQueryProvider implements IQueryProvider
{
    /**
    * @var Connection
    */
    protected $db;

    public function __construct($db){
        $this->db = $db;
    }

    abstract protected function queryAll($sql, $parameters = null);

    abstract protected function queryScalar($sql, $parameters = null);

    /* Stubbed Implementaiton Here */
    public function getQueryProvider()
    {
        return new QueryProvider();
    }

    public function handlesOrderedPaging()
    {
        return true;
    }

    public function getExpressionProvider()
    {
        return new MySQLExpressionProvider();
    }

    protected function getEntityName($entityClassName)
    {
        preg_match_all('/\\\([a-zA-Z]+)/', $entityClassName, $matches);
        if (!empty($matches[1])) {
            return $matches[1][count($matches[1]) - 1];
        }
        return $entityClassName;
    }

    protected function getTableName($entityName)
    {
        $tableName = $entityName;
        preg_match_all('/[A-Z][a-z]+/', $entityName, $matches);
        if (!empty($matches[0])) {
            $tableName = implode('_', $matches[0]);
        }
        return strtolower($tableName);
    }

    protected function getOrderByExpressionAsString($orderBy)
    {
        $result = '';
        foreach ($orderBy->getOrderByInfo()->getOrderByPathSegments() as $order) {
            foreach ($order->getSubPathSegments() as $subOrder) {
                $result .= $result ? ', ' : '';
                $result .= $subOrder->getName();
                $result .= $order->isAscending() ? ' ASC' : ' DESC';
            }
        }
        return $result;
    }

    public function getResourceSet(
        QueryType $queryType,
        ResourceSet $resourceSet,
        $filterInfo = null,
        $orderBy = null,
        $top = null,
        $skip = null
    ) {
        $result = new QueryResult();

        $entityClassName = $resourceSet->getResourceType()->getInstanceType()->name;
        $entityName = $this->getEntityName($entityClassName);
        $tableName = $this->getTableName($entityName);

        $option = null;
        if ($queryType == QueryType::ENTITIES_WITH_COUNT()){
            //tell mysql we want to know the count prior to the LIMIT 
            //$option = 'SQL_CALC_FOUND_ROWS';
        }

        $where = $filterInfo ? ' WHERE ' . $filterInfo->getExpressionAsString() : '';

        $order = $orderBy ? ' ORDER BY ' . $this->getOrderByExpressionAsString($orderBy) : '';

        $sqlCount = 'SELECT COUNT(*) FROM ' . $tableName . $where;
        if ($queryType == QueryType::ENTITIES() || $queryType == QueryType::ENTITIES_WITH_COUNT()) {
            $sql = 'SELECT ' . $option . ' * FROM ' . $tableName . $where . $order
                    . ' LIMIT ' . $top . ' OFFSET ' . $skip;
            $data = $this->queryAll($sql);
            
            if ($queryType == QueryType::ENTITIES_WITH_COUNT()){
                //get those found rows
                //$result->count = $this->queryScalar('SELECT FOUND_ROWS()');
                $result->count = $this->queryScalar($sqlCount);
            }
{'fraction_non_alphanumeric': 0.13330347813106433, 'fraction_numerical': 0.0017913121361397223, 'mean_word_length': 2.50418410041841, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 33, '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': '4472204', 'n_tokens_mistral': 1914, 'n_tokens_neox': 1867, 'n_words': 383}