Skip to content

Commit

Permalink
Code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrian Miu committed Feb 24, 2020
1 parent e550593 commit ea08185
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 56 deletions.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: Sirius ORM | Fast yet flexibile ORM built with DX in mind
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/siriusphp/orm.svg?style=flat-square)](https://scrutinizer-ci.com/g/siriusphp/orm/code-structure)
[![Quality Score](https://img.shields.io/scrutinizer/g/siriusphp/orm.svg?style=flat-square)](https://scrutinizer-ci.com/g/siriusphp/orm)

Sirius ORM is a fast yet flexible data mapper solution developed with DX in mind.
Sirius ORM is a [fast](https://github.com/adrianmiu/forked-php-orm-benchmark) yet flexible data mapper solution developed with DX in mind.

### Installation

Expand Down
28 changes: 15 additions & 13 deletions src/Entity/GenericEntityHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,40 @@

namespace Sirius\Orm\Entity;

use Sirius\Orm\CastingManager;
use Sirius\Orm\Helpers\Arr;
use Sirius\Orm\Mapper;
use Sirius\Orm\Orm;

class GenericEntityHydrator implements HydratorInterface
{
/**
* @var Orm
* @var $castingManager
*/
protected $orm;
protected $castingManager;

/**
* @var Mapper
*/
protected $mapper;

public function __construct(Orm $orm, Mapper $mapper)
public function setMapper(Mapper $mapper)
{
$this->orm = $orm;
$this->mapper = $mapper;
}

public function hydrate($attributes = [])
public function setCastingManager(CastingManager $castingManager)
{
$attributes = $this->orm
->getCastingManager()
->castArray($attributes, $this->mapper->getCasts());
$this->castingManager = $castingManager;
}

public function hydrate(array $attributes = [])
{
$attributes = $this->castingManager
->castArray($attributes, $this->mapper->getCasts());
$attributes = Arr::renameKeys($attributes, $this->mapper->getColumnAttributeMap());
$class = $this->mapper->getEntityClass() ?? GenericEntity::class;

return new $class($attributes, $this->orm->getCastingManager());
return new $class($attributes, $this->castingManager);
}

public function extract(EntityInterface $entity)
Expand All @@ -42,9 +45,8 @@ public function extract(EntityInterface $entity)
$entity->getArrayCopy(),
array_flip($this->mapper->getColumnAttributeMap())
);
$data = $this->orm
->getCastingManager()
->castArrayForDb($data, $this->mapper->getCasts());
$data = $this->castingManager
->castArrayForDb($data, $this->mapper->getCasts());

return Arr::only($data, $this->mapper->getColumns());
}
Expand Down
2 changes: 1 addition & 1 deletion src/Entity/HydratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

interface HydratorInterface
{
public function hydrate($attributes = []);
public function hydrate(array $attributes = []);

public function extract(EntityInterface $entity);
}
36 changes: 26 additions & 10 deletions src/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,6 @@ class Mapper
*/
protected $orm;

/**
* @var Query
*/
private $queryPrototype;

public static function make(Orm $orm, MapperConfig $mapperConfig)
{
$mapper = new static($orm, $mapperConfig->entityHydrator);
Expand Down Expand Up @@ -153,19 +148,24 @@ public static function make(Orm $orm, MapperConfig $mapperConfig)
public function __construct(Orm $orm, HydratorInterface $entityHydrator = null, QueryBuilder $queryBuilder = null)
{
$this->orm = $orm;

if (! $entityHydrator) {
$entityHydrator = new GenericEntityHydrator($orm, $this);
$entityHydrator = new GenericEntityHydrator();
$entityHydrator->setMapper($this);
$entityHydrator->setCastingManager($orm->getCastingManager());
}
$this->entityHydrator = $entityHydrator;

if (! $queryBuilder) {
$this->queryBuilder = QueryBuilder::getInstance();
$queryBuilder = QueryBuilder::getInstance();
}
$this->entityHydrator = $entityHydrator;
$this->tableReference = QueryHelper::reference($this->table, $this->tableAlias);
$this->queryBuilder = $queryBuilder;
}

public function __call(string $method, array $params)
{
switch ($method) {
case 'where':
case 'where':
case 'columns':
case 'orderBy':
Expand Down Expand Up @@ -277,6 +277,10 @@ public function getTableAlias($returnTableIfNull = false)

public function getTableReference()
{
if (!$this->tableReference) {
$this->tableReference = QueryHelper::reference($this->table, $this->tableAlias);
}

return $this->tableReference;
}

Expand Down Expand Up @@ -432,6 +436,17 @@ public function getEntityAttribute(EntityInterface $entity, $attribute)
return $entity->get($attribute);
}

public function addRelation($name, $relation)
{
if (is_array($relation) || $relation instanceof Relation) {
$this->relations[$name] = $relation;
return;
}
throw new \InvalidArgumentException(
sprintf('The relation has to be an Relation instance or an array of configuration options')
);
}

public function hasRelation($name): bool
{
return isset($this->relations[$name]);
Expand Down Expand Up @@ -490,10 +505,11 @@ public function save(EntityInterface $entity, $withRelations = true)
try {
$action->run();
$this->getWriteConnection()->commit();

$this->orm->getConnectionLocator()->lockToWrite(false);
return true;
} catch (\Exception $e) {
$this->getWriteConnection()->rollBack();
$this->orm->getConnectionLocator()->lockToWrite(false);
throw $e;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/MapperLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

interface MapperLocator
{
public function has($mapperName): bool;
public function has($name): bool;

public function get($mapperName): Mapper;
public function get($name): Mapper;
}
62 changes: 33 additions & 29 deletions src/Orm.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@
use Sirius\Orm\Entity\EntityInterface;
use Sirius\Orm\Helpers\Str;
use Sirius\Orm\Relation\Relation;
use Sirius\Orm\Relation\RelationBuilder;
use Sirius\Orm\Relation\RelationConfig;

class Orm implements MapperLocator
{
/**
* @var array
*/
protected $mappers = [];

/**
* @var array
*/
protected $lazyMappers = [];

/**
Expand All @@ -26,21 +33,31 @@ class Orm implements MapperLocator
*/
protected $castingManager;

public function __construct(ConnectionLocator $connectionLocator, CastingManager $castingManager = null)
{
/**
* @var RelationBuilder
*/
protected $relationBuilder;

public function __construct(
ConnectionLocator $connectionLocator,
CastingManager $castingManager = null
){
$this->connectionLocator = $connectionLocator;

if (! $castingManager) {
$castingManager = new CastingManager();
}
$this->castingManager = $castingManager;

$this->relationBuilder = new RelationBuilder($this);
}

public function register($mapperName, $mapperOrConfigOrFactory): self
public function register($name, $mapperOrConfigOrFactory): self
{
if ($mapperOrConfigOrFactory instanceof MapperConfig || is_callable($mapperOrConfigOrFactory)) {
$this->lazyMappers[$mapperName] = $mapperOrConfigOrFactory;
$this->lazyMappers[$name] = $mapperOrConfigOrFactory;
} elseif ($mapperOrConfigOrFactory instanceof Mapper) {
$this->mappers[$mapperName] = $mapperOrConfigOrFactory;
$this->mappers[$name] = $mapperOrConfigOrFactory;
$mapperOrConfigOrFactory->registerCasts($this->castingManager);
} else {
throw new InvalidArgumentException('$mapperOrConfigOrFactory must be a Mapper instance,
Expand All @@ -50,24 +67,24 @@ public function register($mapperName, $mapperOrConfigOrFactory): self
return $this;
}

public function has($mapperName): bool
public function has($name): bool
{
return isset($this->mappers[$mapperName]) || isset($this->lazyMappers[$mapperName]);
return isset($this->mappers[$name]) || isset($this->lazyMappers[$name]);
}

public function get($mapperName): Mapper
public function get($name): Mapper
{
if (isset($this->lazyMappers[$mapperName])) {
$this->mappers[$mapperName] = $this->buildMapper($this->lazyMappers[$mapperName]);
$this->mappers[$mapperName]->registerCasts($this->castingManager);
unset($this->lazyMappers[$mapperName]);
if (isset($this->lazyMappers[$name])) {
$this->mappers[$name] = $this->buildMapper($this->lazyMappers[$name]);
$this->mappers[$name]->registerCasts($this->castingManager);
unset($this->lazyMappers[$name]);
}

if (! isset($this->mappers[$mapperName]) || ! $this->mappers[$mapperName]) {
throw new InvalidArgumentException(sprintf('Mapper named %s is not registered', $mapperName));
if ( ! isset($this->mappers[$name]) || ! $this->mappers[$name]) {
throw new InvalidArgumentException(sprintf('Mapper named %s is not registered', $name));
}

return $this->mappers[$mapperName];
return $this->mappers[$name];
}

public function save($mapperName, EntityInterface $entity, ...$params)
Expand All @@ -92,20 +109,7 @@ public function select($mapperName): Query

public function createRelation(Mapper $nativeMapper, $name, $options): Relation
{
$foreignMapper = $options[RelationConfig::FOREIGN_MAPPER];
if ($this->has($foreignMapper)) {
if (! $foreignMapper instanceof Mapper) {
$foreignMapper = $this->get($foreignMapper);
}
}
$type = $options[RelationConfig::TYPE];
$relationClass = __NAMESPACE__ . '\\Relation\\' . Str::className($type);

if (! class_exists($relationClass)) {
throw new InvalidArgumentException("{$relationClass} does not exist");
}

return new $relationClass($name, $nativeMapper, $foreignMapper, $options);
return $this->relationBuilder->newRelation($nativeMapper, $name, $options);
}

private function buildMapper($mapperConfigOrFactory): Mapper
Expand Down
38 changes: 38 additions & 0 deletions src/Relation/RelationBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Sirius\Orm\Relation;

use Sirius\Orm\Helpers\Str;
use Sirius\Orm\Mapper;
use Sirius\Orm\Orm;

class RelationBuilder {

/**
* @var Orm
*/
protected $orm;

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

public function newRelation(Mapper $nativeMapper, $name, $options): Relation
{
$foreignMapper = $options[RelationConfig::FOREIGN_MAPPER];
if ($this->orm->has($foreignMapper)) {
if (! $foreignMapper instanceof Mapper) {
$foreignMapper = $this->orm->get($foreignMapper);
}
}
$type = $options[RelationConfig::TYPE];
$relationClass = __NAMESPACE__ . '\\' . Str::className($type);

if (! class_exists($relationClass)) {
throw new \InvalidArgumentException("{$relationClass} does not exist");
}

return new $relationClass($name, $nativeMapper, $foreignMapper, $options);
}
}

0 comments on commit ea08185

Please sign in to comment.