This commit is contained in:
Dave Mc Nicoll committed 2021-11-24 16:36:13 +00:00
commit f14347f01d
9 files changed
+245 -131

No files matched your search

+105 -39
View File
@@ -2,7 +2,7 @@
namespace Ulmus;
use Ulmus\Annotation\Property\{ Field, Filter, FilterJoin, Where, Having, Relation, Join, WithJoin, Relation\Ignore as RelationIgnore };
use Ulmus\Annotation\Property\{Field, Where, Having, Relation, Filter, Join, FilterJoin, WithJoin, Relation\Ignore as RelationIgnore};
use Ulmus\Common\EntityResolver;
class Repository
@@ -148,7 +148,7 @@ class Repository
# $dataset = array_filter($dataset, fn($item, $field) => ! ($this->entityResolver->searchFieldAnnotation($field, new Field, false)->readonly ?? false), \ARRAY_FILTER_USE_BOTH);
$statement = $this->insertSqlQuery($fieldsAndValue ?? $dataset, $replace)->runInsertQuery();
if ( ( 0 !== $statement->lastInsertId ) &&
( null !== $primaryKeyDefinition )) {
@@ -183,23 +183,82 @@ class Repository
return false;
}
public function saveAll(EntityCollection $collection) : int
{
$changed = 0;
foreach ($collection as $entity) {
$this->save($entity) && $changed++;
}
return $changed;
}
public function loadCollectionRelation(EntityCollection $collection, /*array|string*/ $fields) : void
{
foreach ((array)$fields as $name) {
if (null !== ($relation = $this->entityResolver->searchFieldAnnotation($name, new Annotation\Property\Relation()))) {
$relationType = strtolower(str_replace(['-', '_', ' '], '', $relation->type));
$order = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\OrderBy());
$where = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\Where());
$baseEntity = $relation->entity ?? $relation->bridge ?? $this->entityResolver->properties[$name]['type'];
$baseEntityResolver = $baseEntity::resolveEntity();
$property = ($baseEntityResolver->field($relation->foreignKey, 01, false) ?: $baseEntityResolver->field($relation->foreignKey, 02))['name'];
$entityProperty = ($this->entityResolver->field($relation->key, 01, false) ?: $this->entityResolver->field($relation->key, 02))['name'];
$repository = $baseEntity::repository();
foreach ($where as $condition) {
$repository->where($condition->field, is_callable($condition->value) ? call_user_func_array($condition->value, [$this]) : $condition->value, $condition->operator, $condition->condition);
}
foreach ($order as $item) {
$repository->orderBy($item->field, $item->order);
}
$field = $relation->key;
$values = [];
$key = is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey);
foreach ($collection as $item) {
$values[] = is_callable($field) ? $field($item) : $item->$entityProperty;
}
$repository->where($key, $values);
switch ($relationType) {
case 'onetoone':
$results = call_user_func([$repository, "loadOne"]);
$item->$name = $results ?: new $baseEntity();
break;
case 'onetomany':
$results = call_user_func([$repository, $relation->function]);
foreach ($collection as $item) {
$item->$name = $baseEntity::entityCollection();
$item->$name->mergeWith($results->filtersCollection(fn($e) => $e->$property === $item->$entityProperty));
}
break;
}
}
}
}
public function replace(/*object|array*/ $entity, ? array $fieldsAndValue = null) : bool
{
return $this->save($entity, $fieldsAndValue, true);
}
public function saveAll(EntityCollection $collection) : int
{
$changed = 0;
foreach($collection as $entity) {
$this->save($entity) && $changed++;
}
return $changed;
}
public function replaceAll(EntityCollection $collection) : void
public function replaceAll(/*EntityCollection|array*/ $collection) : void
{
foreach($collection as $entity) {
$this->replace($entity);
@@ -262,6 +321,13 @@ class Repository
}
}
public function removeQueryFragment(/*? Query\Fragment|string*/ $fragment) : self
{
$fragment && $this->queryBuilder->removeFragment($fragment);
return $this;
}
public function selectEntity(string $entity, string $alias, string $prependField = "") : self
{
$prependField and ($prependField .= "$");
@@ -479,6 +545,7 @@ class Repository
$this->select("{$this->alias}.*");
}
# @TODO Apply FILTER annotation to this too !
foreach(array_filter((array) $fields) as $item) {
$annotation = $this->entityResolver->searchFieldAnnotation($item, new Join) ?:
$this->entityResolver->searchFieldAnnotation($item, new Relation);
@@ -611,6 +678,30 @@ class Repository
return $this;
}
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
{
if ($count) {
$searchRequest->count = $searchRequest->filter($this->serverRequestCountRepository())
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
->groups($searchRequest->groups())
->count();
}
return $searchRequest->filter($this)
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
->orders($searchRequest->orders())
->groups($searchRequest->groups())
->offset($searchRequest->offset())
->limit($searchRequest->limit());
}
protected function serverRequestCountRepository() : Repository
{
return new Repository\ServerRequestCountRepository($this->entityClass, $this->alias, $this->adapter);
}
public function collectionFromQuery(? string $entityClass = null) : EntityCollection
{
$class = $entityClass ?: $this->entityClass;
@@ -831,29 +922,4 @@ class Repository
}
protected function finalizeQuery() : void {}
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
{
if ($count) {
# @TODO Must be placed inside an event instead of directly there !
$searchRequest->count = $searchRequest->filter($this->serverRequestCountRepository())
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
->groups($searchRequest->groups())
->count();
}
return $searchRequest->filter($this)
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
->orders($searchRequest->orders())
->groups($searchRequest->groups())
->offset($searchRequest->offset())
->limit($searchRequest->limit());
}
protected function serverRequestCountRepository() : Repository
{
return new Repository\ServerRequestCountRepository($this->entityClass, $this->alias, $this->adapter);
}
}