- Work done on Ulmus which were added within the Bottin de suppléance app
This commit is contained in:
1 parent
7fb591e1f5
commit
9ad2e94d12
9 files changed
+219
-127
No files matched your search
+103
-54
@@ -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, Join, WithJoin, Relation\Ignore as RelationIgnore};
|
||||
use Ulmus\Common\EntityResolver;
|
||||
|
||||
class Repository
|
||||
@@ -63,7 +63,7 @@ class Repository
|
||||
|
||||
public function count() : int
|
||||
{
|
||||
$this->removeQueryFragment(Query\Select::class);
|
||||
$this->removeQueryFragment($this->queryBuilder->getFragment(Query\Select::class));
|
||||
|
||||
if ( $this->queryBuilder->getFragment(Query\GroupBy::class) ) {
|
||||
$this->select( "DISTINCT COUNT(*) OVER ()" );
|
||||
@@ -79,12 +79,12 @@ class Repository
|
||||
return Ulmus::runSelectQuery($this->queryBuilder, $this->adapter)->fetchColumn(0);
|
||||
}
|
||||
|
||||
public function deleteOne()
|
||||
protected function deleteOne()
|
||||
{
|
||||
return $this->limit(1)->deleteSqlQuery()->runQuery();
|
||||
}
|
||||
|
||||
public function deleteAll()
|
||||
protected function deleteAll()
|
||||
{
|
||||
return $this->deleteSqlQuery()->runQuery();
|
||||
}
|
||||
@@ -125,8 +125,12 @@ class Repository
|
||||
}
|
||||
}
|
||||
|
||||
public function save(object $entity, ? array $fieldsAndValue = null) : bool
|
||||
public function save(/*object|array*/ $entity) : bool
|
||||
{
|
||||
if ( is_array($entity) ) {
|
||||
$entity = ( new $this->entityClass() )->fromArray($entity);
|
||||
}
|
||||
|
||||
if ( ! $this->matchEntity($entity) ) {
|
||||
throw new \Exception("Your entity class `" . get_class($entity) . "` cannot match entity type of repository `{$this->entityClass}`");
|
||||
}
|
||||
@@ -136,7 +140,7 @@ class Repository
|
||||
$primaryKeyDefinition = Ulmus::resolveEntity($this->entityClass)->getPrimaryKeyField();
|
||||
|
||||
if ( ! $entity->isLoaded() ) {
|
||||
$statement = $this->insertSqlQuery($fieldsAndValue ?? $dataset)->runQuery();
|
||||
$statement = $this->insertSqlQuery($dataset)->runQuery();
|
||||
|
||||
if ( ( 0 !== $statement->lastInsertId ) &&
|
||||
( null !== $primaryKeyDefinition )) {
|
||||
@@ -152,9 +156,7 @@ class Repository
|
||||
throw new \Exception(sprintf("No primary key found for entity %s", $this->entityClass));
|
||||
}
|
||||
|
||||
$diff = $fieldsAndValue ?? $this->generateDatasetDiff($entity);
|
||||
|
||||
if ( [] !== $diff ) {
|
||||
if ( [] !== $diff = $this->generateDatasetDiff($entity) ) {
|
||||
$pkField = key($primaryKeyDefinition);
|
||||
$pkFieldName = $primaryKeyDefinition[$pkField]->name ?? $pkField;
|
||||
$this->where($pkFieldName, $dataset[$pkFieldName]);
|
||||
@@ -170,13 +172,71 @@ class Repository
|
||||
return false;
|
||||
}
|
||||
|
||||
public function saveAll(EntityCollection $collection) : void
|
||||
public function saveAll(/*EntityCollection|array*/ $collection) : void
|
||||
{
|
||||
foreach($collection as $entity) {
|
||||
$this->save($entity);
|
||||
}
|
||||
}
|
||||
|
||||
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 truncate(? string $table = null, ? string $alias = null, ? string $schema = null) : self
|
||||
{
|
||||
$schema = $schema ?: $this->entityResolver->schemaName();
|
||||
@@ -213,6 +273,13 @@ class Repository
|
||||
}
|
||||
}
|
||||
|
||||
public function removeQueryFragment(? Query\Fragment $fragment) : self
|
||||
{
|
||||
$fragment && $this->queryBuilder->removeFragment($fragment);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function selectEntity(string $entity, string $alias, string $prependField = "") : self
|
||||
{
|
||||
$prependField and ($prependField .= "$");
|
||||
@@ -430,6 +497,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);
|
||||
@@ -461,10 +529,6 @@ class Repository
|
||||
$this->having(is_object($condition->field) ? $condition->field : $entity::field($condition->field), $condition->value, $condition->operator);
|
||||
}
|
||||
|
||||
foreach($this->entityResolver->searchFieldAnnotationList($item, new Filter() ) as $filter) {
|
||||
call_user_func_array([ $this->entityClass, $filter->method ], [ $this, $item ]);
|
||||
}
|
||||
|
||||
$this->close();
|
||||
|
||||
$key = is_string($annotation->key) ? $this->entityClass::field($annotation->key) : $annotation->key;
|
||||
@@ -486,10 +550,6 @@ class Repository
|
||||
$join->where(is_object($field) ? $field : $entity::field($field, $alias), $condition->value, $condition->operator);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($this->entityResolver->searchFieldAnnotationList($item, new FilterJoin() ) as $filter) {
|
||||
call_user_func_array([ $this->entityClass, $filter->method ], [ $join, $item ]);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
@@ -562,6 +622,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;
|
||||
@@ -655,7 +739,7 @@ class Repository
|
||||
public function createSqlQuery() : self
|
||||
{
|
||||
if ( null === $this->queryBuilder->getFragment(Query\Create::class) ) {
|
||||
$this->queryBuilder->create($this->escapeFieldList($this->entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true)), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
|
||||
$this->queryBuilder->create($this->escapeFieldList($this->entityResolver->fieldList()), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
|
||||
}
|
||||
|
||||
if ( null === $this->queryBuilder->getFragment(Query\Engine::class) ) {
|
||||
@@ -667,16 +751,6 @@ class Repository
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function alterSqlQuery(array $fields) : self
|
||||
{
|
||||
if ( null === $this->queryBuilder->getFragment(Query\Alter::class) ) {
|
||||
$this->queryBuilder->create($this->escapeFieldList($this->entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true)), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function fromRow($row) : self
|
||||
{
|
||||
|
||||
@@ -758,29 +832,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);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user