<commit_before><?php
namespace Vda\Datasource\Relational\Driver\Mysqli;

use Vda\Datasource\Relational\Driver\IConnection;
use Vda\Datasource\Relational\Driver\ISqlDialect;
use Vda\Util\Type;

class MysqlDialect implements ISqlDialect
{
    private $conn;

    public function __construct(IConnection $conn = null)
    {
        $this->conn = $conn;
    }

    public function quote($literal, $type)
    {
        if (is_null($literal)) {
            return 'null';
        }

        if ($type == Type::BOOLEAN) {
            return $literal ? '1' : '0';
        }

        if (($type & Type::NUMERIC) > 0) {
            if (!is_numeric($literal)) {
                throw new \InvalidArgumentException(
                    "The '{$literal}' literal must be numeric"
                );
            }

            return $literal;
        }

        if ($type == Type::DATE) {
            if ($literal instanceof \DateTimeInterface) {
                return $literal->format("'Y-m-d H:i:s'");
            } else {
                $timestamp = strtotime($literal);

                if ($timestamp === false) {
                    throw new \InvalidArgumentException(
                        "The '{$literal}' literal must be valid date"
                    );
                }

                return date("'Y-m-d H:i:s'", $timestamp);
            }
        }

        if ($type == Type::STRING) {
            return $this->escapeString($literal, "'");
        }

        throw new \InvalidArgumentException("The '{$type}' type is unknown");
    }

    public function quoteIdentifier($identifier)
    {
        $scope = '';
        $period = strpos($identifier, '.');
        if ($period !== false) {
            $scope = $this->escapeString(substr($identifier, 0, $period), '`') . '.';
            $identifier = substr($identifier, $period + 1);
        }

        return $scope . $this->escapeString($identifier, '`');
    }

    public function patternMatchOperator($isCaseSensitive, $isNegative)
    {
        $modifier = $isCaseSensitive ? ' BINARY ' : ' ';
        $negator = $isNegative ? ' NOT ' : ' ';

        return $negator . 'LIKE' . $modifier;
    }

    public function limitClause($limit, $offset = null)
    {
        if (!is_numeric($limit)) {
            throw new \InvalidArgumentException('Limit value must be numeric');
        }

        if (!is_null($offset) && !is_numeric($offset)) {
            throw new \InvalidArgumentException('Offset value must be numeric');
        }

        if (is_null($offset)) {
            $result = 'LIMIT ' . $limit;
        } else {
            $result = 'LIMIT ' . $offset . ', ' . $limit;
        }

        return $result;
    }

    protected function escapeString($str, $encl)
    {
        return $encl . $this->conn->escapeString($str) . $encl;
    }
}
<commit_msg>Fix MysqlDialect to correctly handle DateTimeInterface instances converted to array<commit_after><?php
namespace Vda\Datasource\Relational\Driver\Mysqli;

use Vda\Datasource\Relational\Driver\IConnection;
use Vda\Datasource\Relational\Driver\ISqlDialect;
use Vda\Util\Type;

class MysqlDialect implements ISqlDialect
{
    private $conn;

    public function __construct(IConnection $conn = null)
    {
        $this->conn = $conn;
    }

    public function quote($literal, $type)
    {
        if (is_null($literal)) {
            return 'null';
        }

        if ($type == Type::BOOLEAN) {
            return $literal ? '1' : '0';
        }

        if (($type & Type::NUMERIC) > 0) {
            if (!is_numeric($literal)) {
                throw new \InvalidArgumentException(
                    "The '{$literal}' literal must be numeric"
                );
            }

            return $literal;
        }

        if ($type == Type::DATE) {
            $timestamp = false;
            if ($literal instanceof \DateTimeInterface) {
                $timestamp = $literal->getTimestamp();
            } elseif (is_array($literal) && !empty($literal['timestamp'])) {
                $timestamp = $literal['timestamp'];
            } elseif (is_string($literal)) {
                $timestamp = strtotime($literal);
            }

            if ($timestamp === false) {
                throw new \InvalidArgumentException(
                    "The '{$literal}' literal must be valid date"
                );
            }

            return date("'Y-m-d H:i:s'", $timestamp);
        }

        if ($type == Type::STRING) {
            return $this->escapeString($literal, "'");
        }

        throw new \InvalidArgumentException("The '{$type}' type is unknown");
    }

    public function quoteIdentifier($identifier)
    {
        $scope = '';
        $period = strpos($identifier, '.');
        if ($period !== false) {
            $scope = $this->escapeString(substr($identifier, 0, $period), '`') . '.';
            $identifier = substr($identifier, $period + 1);
        }

        return $scope . $this->escapeString($identifier, '`');
    }

    public function patternMatchOperator($isCaseSensitive, $isNegative)
    {
        $modifier = $isCaseSensitive ? ' BINARY ' : ' ';
        $negator = $isNegative ? ' NOT ' : ' ';

        return $negator . 'LIKE' . $modifier;
    }

    public function limitClause($limit, $offset = null)
    {
        if (!is_numeric($limit)) {
            throw new \InvalidArgumentException('Limit value must be numeric');
        }

        if (!is_null($offset) && !is_numeric($offset)) {
            throw new \InvalidArgumentException('Offset value must be numeric');
        }

        if (is_null($offset)) {
            $result = 'LIMIT ' . $limit;
        } else {
            $result = 'LIMIT ' . $offset . ', ' . $limit;
        }

        return $result;
    }

    protected function escapeString($str, $encl)
    {
        return $encl . $this->conn->escapeString($str) . $encl;
    }
}

{'fraction_non_alphanumeric': 0.14176570458404075, 'fraction_numerical': 0.001697792869269949, 'mean_word_length': 1.8335738335738336, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, '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': '4033715', 'n_tokens_mistral': 1706, 'n_tokens_neox': 1636, 'n_words': 364}