- A lot of bugfixes, mainly with escaping (still working on it to get 100% coverage)

This commit is contained in:
mcndave committed 2021-03-15 13:42:52 +00:00
1 parent e3d0e45a4e
commit 3905047111
8 files changed
+91 -126

No files matched your search

+21 -61
View File
@@ -2,7 +2,7 @@
namespace Ulmus;
use Ulmus\Annotation\Property\{ 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
@@ -175,64 +175,6 @@ class Repository
}
}
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();
@@ -347,7 +289,10 @@ class Repository
public function set(array $dataset) : self
{
$this->queryBuilder->set($dataset);
$keys = array_keys($dataset);
$escapedFields = array_combine($keys, array_map([ $this, 'escapeField' ], $keys));
$this->queryBuilder->set($dataset, $escapedFields);
return $this;
}
@@ -732,7 +677,7 @@ class Repository
public function createSqlQuery() : self
{
if ( null === $this->queryBuilder->getFragment(Query\Create::class) ) {
$this->queryBuilder->create($this->entityResolver->fieldList(), $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) ) {
@@ -778,6 +723,21 @@ class Repository
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);