<commit_before><?php
/**
 * @copyright: DotKernel
 * @library: dotkernel/dot-ems
 * @author: n3vrax
 * Date: 11/17/2016
 * Time: 10:48 PM
 */

namespace Dot\Ems\Mapper;

use Dot\Ems\Mapper\Relation\RelationInterface;
use Dot\Ems\ObjectPropertyTrait;
use Dot\Ems\Paginator\Adapter\RelationalDbSelect;

/**
 * Class AggregateDbMapper
 * @package Dot\Ems\Mapper
 */
class RelationalDbMapper extends AbstractDbMapper implements RelationalMapperInterface
{
    use ObjectPropertyTrait;

    /** @var  string */
    protected $paginatorAdapterName = RelationalDbSelect::class;

    /** @var RelationInterface[] */
    protected $relations = [];

    /** @var bool  */
    protected $deleteCascade = false;

    /**
     * @param $where
     * @return null|object
     */
    public function fetch($where)
    {
        $entity = parent::fetch($where);
        if($entity) {
            $this->buildEntity($entity);
        }

        return $entity;
    }

    /**
     * @param array $where
     * @param array $filters
     * @param bool $paginated
     * @return array|null|\Zend\Paginator\Paginator
     */
    public function fetchAll($where = [], $filters = [], $paginated = false)
    {
        $entities = parent::fetchAll($where, $filters, $paginated);
        if($entities && !$paginated) {
            foreach ($entities as $entity) {
                $this->buildEntity($entity);
            }
        }

        return $entities;
    }

    /**
     * @param $entity
     * @return int
     */
    public function create($entity)
    {
        $affectedRows = parent::create($entity);
        if($affectedRows) {
            $affectedRows += $this->saveSubEntities($entity, $this->lastInsertValue());
        }

        return $affectedRows;
    }

    /**
     * @param $entity
     * @return int
     */
    public function update($entity)
    {
        $affectedRows = parent::update($entity);
        $affectedRows += $this->saveSubEntities($entity, $this->getProperty($entity, $this->getIdentifierName()));
        return $affectedRows;
    }

    /**
     * @param $where
     * @return int
     */
    public function delete($where)
    {
        $affectedRows = parent::delete($where);
        if(is_object($where) && is_a($where, get_class($this->getPrototype()))) {
            if($this->deleteCascade && $affectedRows) {
                $affectedRows += $this->deleteSubEntities($where, true);
            }
        }

        return $affectedRows;
    }

    /**
     * @param $entity
     * @param $id
     * @return int
     */
    public function saveSubEntities($entity, $id)
    {
        $affectedRows = 0;
        foreach (array_keys($this->relations) as $property) {
            $relation = $this->relations[$property];

            $subEntity = $this->getProperty($entity, $property);
            if(!empty($subEntity)) {
                $affectedRows += $relation->saveRef($subEntity, $id);
            }
        }
        return $affectedRows;
    }

    /**
     * @param $entity
     * @param bool $bulk
     * @return int|mixed
     */
    public function deleteSubEntities($entity, $bulk = true)
    {
        $affectedRows = 0;
        $id = $this->getProperty($entity, $this->getIdentifierName());

        foreach (array_keys($this->relations) as $property) {
            $relation = $this->relations[$property];

            if($bulk) {
                $affectedRows += $relation->deleteRef($id);
            }
            else {
                $subEntity = $this->getProperty($entity, $property);
                if(!empty($subEntity)) {
                    $affectedRows += $relation->deleteRef($subEntity, $id);
                }
            }
        }
        return $affectedRows;<commit_msg>if relation property is null, assume we have to clear any linked entities, depending on the relation type<commit_after><?php
/**
 * @copyright: DotKernel
 * @library: dotkernel/dot-ems
 * @author: n3vrax
 * Date: 11/17/2016
 * Time: 10:48 PM
 */

namespace Dot\Ems\Mapper;

use Dot\Ems\Mapper\Relation\RelationInterface;
use Dot\Ems\ObjectPropertyTrait;
use Dot\Ems\Paginator\Adapter\RelationalDbSelect;

/**
 * Class AggregateDbMapper
 * @package Dot\Ems\Mapper
 */
class RelationalDbMapper extends AbstractDbMapper implements RelationalMapperInterface
{
    use ObjectPropertyTrait;

    /** @var  string */
    protected $paginatorAdapterName = RelationalDbSelect::class;

    /** @var RelationInterface[] */
    protected $relations = [];

    /** @var bool  */
    protected $deleteCascade = false;

    /**
     * @param $where
     * @return null|object
     */
    public function fetch($where)
    {
        $entity = parent::fetch($where);
        if($entity) {
            $this->buildEntity($entity);
        }

        return $entity;
    }

    /**
     * @param array $where
     * @param array $filters
     * @param bool $paginated
     * @return array|null|\Zend\Paginator\Paginator
     */
    public function fetchAll($where = [], $filters = [], $paginated = false)
    {
        $entities = parent::fetchAll($where, $filters, $paginated);
        if($entities && !$paginated) {
            foreach ($entities as $entity) {
                $this->buildEntity($entity);
            }
        }

        return $entities;
    }

    /**
     * @param $entity
     * @return int
     */
    public function create($entity)
    {
        $affectedRows = parent::create($entity);
        if($affectedRows) {
            $affectedRows += $this->saveSubEntities($entity, $this->lastInsertValue());
        }

        return $affectedRows;
    }

    /**
     * @param $entity
     * @return int
     */
    public function update($entity)
    {
        $affectedRows = parent::update($entity);
        $affectedRows += $this->saveSubEntities($entity, $this->getProperty($entity, $this->getIdentifierName()));
        return $affectedRows;
    }

    /**
     * @param $where
     * @return int
     */
    public function delete($where)
    {
        $affectedRows = parent::delete($where);
        if(is_object($where) && is_a($where, get_class($this->getPrototype()))) {
            if($this->deleteCascade && $affectedRows) {
                $affectedRows += $this->deleteSubEntities($where, true);
            }
        }

        return $affectedRows;
    }

    /**
     * @param $entity
     * @param $id
     * @return int
     */
    public function saveSubEntities($entity, $id)
    {
        $affectedRows = 0;
        foreach (array_keys($this->relations) as $property) {
            $relation = $this->relations[$property];

            $subEntity = $this->getProperty($entity, $property);
            if($subEntity !== null) {
                $affectedRows += $relation->saveRef($subEntity, $id);
            }
            else {
                //just make sure we clear any trace
                $affectedRows += $relation->deleteRef($id);
            }
        }
        return $affectedRows;
    }

    /**
     * @param $entity
     * @param bool $bulk
     * @return int|mixed
     */
    public function deleteSubEntities($entity, $bulk = true)
    {
        $affectedRows = 0;
        $id = $this->getProperty($entity, $this->getIdentifierName());

        foreach (array_keys($this->relations) as $property) {
            $relation = $this->relations[$property];

            if($bulk) {
                $affectedRows += $relation->deleteRef($id);
            }
            else {
                $subEntity = $this->getProperty($entity, $property);
                if(!empty($subEntity)) {
                    $affectedRows += $relation->deleteRef($subEntity, $id);
                }
            }
        }
        return $affectedRows;
{'fraction_non_alphanumeric': 0.14293125810635537, 'fraction_numerical': 0.0038910505836575876, 'mean_word_length': 2.064785373608903, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 46, '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': '4900404', 'n_tokens_mistral': 2317, 'n_tokens_neox': 2177, 'n_words': 429}