- A lot of bugfixes and fitting to accomodate ldap adapter

This commit is contained in:
Dave Mc Nicoll committed 2022-04-13 03:31:48 +00:00
1 parent f14347f01d
commit 16d76470da
15 files changed
+350 -216

No files matched your search

+131 -109
View File
@@ -7,7 +7,7 @@ use Ulmus\Common\EntityResolver;
class Repository
{
use EventTrait, Repository\ConditionTrait;
use EventTrait, Repository\ConditionTrait, Repository\EscapeTrait;
const DEFAULT_ALIAS = "this";
@@ -30,7 +30,7 @@ class Repository
$this->adapter = $adapter ?? $this->entityResolver->databaseAdapter();
$this->queryBuilder = new QueryBuilder();
}
public function __clone()
{
#$this->queryBuilder = clone $this->queryBuilder;
@@ -74,7 +74,7 @@ class Repository
$this->select( "DISTINCT COUNT(*) OVER ()" );
}
else {
$this->select(Common\Sql::function("COUNT", "*"));
$this->select(Common\Sql::function("COUNT", '*'));
}
$this->selectSqlQuery();
@@ -144,13 +144,13 @@ class Repository
$primaryKeyDefinition = Ulmus::resolveEntity($this->entityClass)->getPrimaryKeyField();
if ( ! $entity->isLoaded() ) {
if ( $replace || ! $entity->isLoaded() ) {
# $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 )) {
if ( ( 0 !== $statement->lastInsertId ) &&
( null !== $primaryKeyDefinition )) {
$pkField = key($primaryKeyDefinition);
$dataset[$pkField] = $statement->lastInsertId;
@@ -192,65 +192,64 @@ class Repository
}
return $changed;
}
public function loadCollectionRelation(EntityCollection $collection, /*array|string*/ $fields) : void
public function insertAll(/* EntityCollection | array */ $collection, int $size = 1000) : int
{
foreach ((array)$fields as $name) {
if (null !== ($relation = $this->entityResolver->searchFieldAnnotation($name, new Annotation\Property\Relation()))) {
$relationType = strtolower(str_replace(['-', '_', ' '], '', $relation->type));
if ( empty($collection) ) {
return 0;
}
elseif ( is_array($collection) ) {
$collection = $this->entityClass::entityCollection($collection);
}
$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;
}
foreach($collection as $entity) {
if ( ! $this->matchEntity($entity) ) {
throw new \Exception("Your entity class `" . get_class($entity) . "` cannot match entity type of repository `{$this->entityClass}`");
}
}
$dataset = $entity->toArray();
$primaryKeyDefinition = Ulmus::resolveEntity($this->entityClass)->getPrimaryKeyField();
if ( $replace || ! $entity->isLoaded() ) {
# $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 )) {
$pkField = key($primaryKeyDefinition);
$dataset[$pkField] = $statement->lastInsertId;
}
$entity->entityFillFromDataset($dataset, true);
return (bool) $statement->lastInsertId;
}
else {
if ( $primaryKeyDefinition === null ) {
throw new \Exception(sprintf("No primary key found for entity %s", $this->entityClass));
}
$diff = $fieldsAndValue ?? $this->generateWritableDataset($entity);
if ( [] !== $diff ) {
$pkField = key($primaryKeyDefinition);
$pkFieldName = $primaryKeyDefinition[$pkField]->name ?? $pkField;
$this->where($pkFieldName, $dataset[$pkFieldName]);
$update = $this->updateSqlQuery($diff)->runUpdateQuery();
$entity->entityFillFromDataset($dataset, true);
return $update ? (bool) $update->rowCount() : false;
}
}
}
public function replace(/*object|array*/ $entity, ? array $fieldsAndValue = null) : bool
@@ -258,11 +257,15 @@ class Repository
return $this->save($entity, $fieldsAndValue, true);
}
public function replaceAll(/*EntityCollection|array*/ $collection) : void
public function replaceAll(/*EntityCollection|array*/ $collection) : int
{
$changed = 0;
foreach($collection as $entity) {
$this->replace($entity);
$this->replace($entity) && $changed++;
}
return $changed;
}
public function truncate(? string $table = null, ? string $alias = null, ? string $schema = null) : self
@@ -323,7 +326,9 @@ class Repository
public function removeQueryFragment(/*? Query\Fragment|string*/ $fragment) : self
{
$fragment && $this->queryBuilder->removeFragment($fragment);
foreach((array) $fragment as $item) {
$this->queryBuilder->removeFragment($item);
}
return $this;
}
@@ -407,7 +412,7 @@ class Repository
return $this;
}
public function delete() : self
public function delete(...$args) : self
{
$this->queryBuilder->delete($this->alias);
@@ -489,10 +494,10 @@ class Repository
public function randomizeOrder() : self
{
$this->queryBuilder->orderBy(Common\Sql::function('RAND', Sql::identifier('CURDATE()+0')));
return $this;
}
public function orders(array $orderList) : self
{
foreach($orderList as $field => $direction) {
@@ -678,6 +683,64 @@ class Repository
return $this;
}
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 filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
{
if ($count) {
@@ -859,7 +922,7 @@ class Repository
return $result;
}
public function instanciateEntityCollection(...$arguments) : EntityCollection
{
return $this->entityClass::entityCollection(...$arguments);
@@ -870,48 +933,7 @@ class Repository
return new $this->entityClass();
}
public function escapeField(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_FIELD);
}
public function escapeFieldList(array $fieldList) : array
{
foreach($fieldList as &$list) {
$list['name'] = $this->escapeField($list['name']);
$fieldTag = array_filter($list['tags'] ?? [], fn($item) => $item['object'] instanceof Field)[0]['object'] ?? null;
if ( $fieldTag && isset($fieldTag->name) ) {
$fieldTag->name = $this->escapeField($fieldTag->name);
}
}
return $fieldList;
}
public function escapeTable(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_TABLE);
}
public function escapeDatabase(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_DATABASE);
}
public function escapedDatabase() : ? string
{
$name = $this->entityResolver->tableAnnotation()->database ?? $this->adapter->adapter()->database ?? null;
return $name ? static::escapeDatabase($name) : null;
}
public function escapeSchema(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_SCHEMA);
}
public function hasFilters() : bool
{
return isset($this->queryBuilder->where);