<commit_before><?php namespace TyrionCMS\SimpleOrm;


use TyrionCMS\SimpleOrm\Exceptions\DatabaseItemNotFoundException;
use TyrionCMS\SimpleOrm\Exceptions\DatabaseModelException;
use TyrionCMS\SimpleOrm\Exceptions\DatabaseUpdateModelException;
use TyrionCMS\SimpleOrm\Item\ClearPdoItem;
use TyrionCMS\SimpleOrm\Item\DbTableRowItem;

final class DbStatement
{
    private $connection;
    private $query;
    private $arguments = null;
    private $rowItemInstance;
    private $create_dynamic_properties = false;

    public function __construct(\PDO $connection)
    {
        $this->connection = $connection;
        $this->rowItemInstance = new ClearPdoItem();
    }

    /**
     * @param DbTableRowItem $rowItemInstance
     * @return $this
     */
    public function setRowItemInstance(DbTableRowItem $rowItemInstance)
    {
        $this->rowItemInstance = $rowItemInstance;
        return $this;
    }

    public function findResult(): DbTableRowIterator
    {
        $stmt = $this->execute()->getStatement();
        $rowList = new DbTableRowList();
        while ($result = $stmt->fetchObject()) {
            if (!$this->getRowItemInstance() instanceof ClearPdoItem) {
                $rowList->addItem($this->generateTableRowItem($result, $this->getRowItemInstance()));
            } else {
                $clearDbItem = new ClearPdoItem();
                $clearDbItem->setData($result);
                $rowList->addItem($clearDbItem);
            }
        }
        $rowListIterator = new DbTableRowIterator($rowList);
        return $rowListIterator;
    }

    public function execute(): PDOExecuteResult
    {
        $stmt = $this->connection->prepare($this->query);
        $result = $stmt->execute($this->arguments);
        $dbResult = new PDOExecuteResult($stmt, $result);
        return $dbResult;
    }

    private function getRowItemInstance(): DbTableRowItem
    {
        try {
            $instance = (new \ReflectionClass($this->rowItemInstance))->newInstance();
        } catch (\Exception $e) {
            throw new DatabaseModelException("Unable to create model from class: {$this->rowItemInstance}");
        }
        if (!$instance instanceof DbTableRowItem) {
            throw new DatabaseModelException("Create instance has to implement DbTableRowItem");
        }
        return $instance;
    }

    private function generateTableRowItem($result, DbTableRowItem $rowItem): DbTableRowItem
    {
        $obj = new \ReflectionObject($rowItem);
        $new_object = $obj->newInstance();

        foreach ($obj->getProperties() as $property) {
            $property->setAccessible(true);
            $property_name = $property->getName();
            if (isset($result->$property_name)) {
                $property->setValue($new_object, $result->$property_name);
            }
        }

        if($this->isCreateDynamicProperties()){
            $previousRowInstance = $this->getRowItemInstance();
            $this->setRowItemInstance(new ClearPdoItem());
            $tableFields = $this->setQuery("DESCRIBE product")->findResult()->getTableList()->getItems();
            /** @var ClearPdoItem $field */
            foreach($tableFields as $field){
                $field = $field->getData('Field');
                try {
                    $obj->getProperty($field);
                } catch (\ReflectionException $e) {
                    $new_object->$field = (isset($result->$field)) ? $result->$field : null;
                }
            }
            $this->setRowItemInstance($previousRowInstance);
        }

        return $new_object;
    }

    public function findOne(): ? DbTableRowItem
    {
        $stmt = $this->execute()->getStatement();
        $row = $stmt->fetchObject();
        $row = ($row) ? $this->generateTableRowItem($row, $this->getRowItemInstance()) : null;
        if (is_null($row)) {
            throw new DatabaseItemNotFoundException("Unable to find item");<commit_msg>Save selected fields to temp variable for query in loop<commit_after><?php namespace TyrionCMS\SimpleOrm;


use TyrionCMS\SimpleOrm\Exceptions\DatabaseItemNotFoundException;
use TyrionCMS\SimpleOrm\Exceptions\DatabaseModelException;
use TyrionCMS\SimpleOrm\Exceptions\DatabaseUpdateModelException;
use TyrionCMS\SimpleOrm\Item\ClearPdoItem;
use TyrionCMS\SimpleOrm\Item\DbTableRowItem;

final class DbStatement
{
    private $connection;
    private $query;
    private $arguments = null;
    private $rowItemInstance;
    private $create_dynamic_properties = false;
    private $tableFields = array();

    public function __construct(\PDO $connection)
    {
        $this->connection = $connection;
        $this->rowItemInstance = new ClearPdoItem();
    }

    /**
     * @param DbTableRowItem $rowItemInstance
     * @return $this
     */
    public function setRowItemInstance(DbTableRowItem $rowItemInstance)
    {
        $this->rowItemInstance = $rowItemInstance;
        return $this;
    }

    public function findResult(): DbTableRowIterator
    {
        $stmt = $this->execute()->getStatement();
        $rowList = new DbTableRowList();
        while ($result = $stmt->fetchObject()) {
            if (!$this->getRowItemInstance() instanceof ClearPdoItem) {
                $rowList->addItem($this->generateTableRowItem($result, $this->getRowItemInstance()));
            } else {
                $clearDbItem = new ClearPdoItem();
                $clearDbItem->setData($result);
                $rowList->addItem($clearDbItem);
            }
        }
        $rowListIterator = new DbTableRowIterator($rowList);
        return $rowListIterator;
    }

    public function execute(): PDOExecuteResult
    {
        $stmt = $this->connection->prepare($this->query);
        $result = $stmt->execute($this->arguments);
        $dbResult = new PDOExecuteResult($stmt, $result);
        return $dbResult;
    }

    private function getRowItemInstance(): DbTableRowItem
    {
        try {
            $instance = (new \ReflectionClass($this->rowItemInstance))->newInstance();
        } catch (\Exception $e) {
            throw new DatabaseModelException("Unable to create model from class: {$this->rowItemInstance}");
        }
        if (!$instance instanceof DbTableRowItem) {
            throw new DatabaseModelException("Create instance has to implement DbTableRowItem");
        }
        return $instance;
    }

    private function generateTableRowItem($result, DbTableRowItem $rowItem): DbTableRowItem
    {
        $obj = new \ReflectionObject($rowItem);
        $new_object = $obj->newInstance();

        foreach ($obj->getProperties() as $property) {
            $property->setAccessible(true);
            $property_name = $property->getName();
            if (isset($result->$property_name)) {
                $property->setValue($new_object, $result->$property_name);
            }
        }

        if($this->isCreateDynamicProperties()){
            if(!array_key_exists($obj->getName(), $this->tableFields)) {
                $previousRowInstance = $this->getRowItemInstance();
                $this->setRowItemInstance(new ClearPdoItem());
                $tableFields = $this->setQuery("DESCRIBE product")->findResult()->getTableList()->getItems();
                $this->tableFields[$obj->getName()] = $tableFields;
            }else{
                $tableFields = $this->tableFields[$obj->getName()];
            }
            /** @var ClearPdoItem $field */
            foreach($tableFields as $field){
                $field = $field->getData('Field');
                try {
                    $obj->getProperty($field);
                } catch (\ReflectionException $e) {
                    $new_object->$field = (isset($result->$field)) ? $result->$field : null;
                }
            }
            if(isset($previousRowInstance)) {
                $this->setRowItemInstance($previousRowInstance);
            }
        }

        return $new_object;
    }

    public function findOne(): ? DbTableRowItem
    {
        $stmt = $this->execute()->getStatement();
        $row = $stmt->fetchObject();
        $row = ($row) ? $this->generateTableRowItem($row, $this->getRowItemInstance()) : null;
        if (is_null($row)) {
            throw new DatabaseItemNotFoundException("Unable to find item");
{'fraction_non_alphanumeric': 0.12782859894077997, 'fraction_numerical': 0.0, 'mean_word_length': 2.485318791946309, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 99, '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': '918208', 'n_tokens_mistral': 2274, 'n_tokens_neox': 2190, 'n_words': 415}