- Added a 'select' attribute, WIP on ArrayCollection and ArrayOf also
This commit is contained in:
parent
b394b9348f
commit
f938e18572
@ -10,7 +10,7 @@ use Ulmus\Entity\JsonUnserializable;
|
|||||||
class ArrayOf implements \Ulmus\Entity\EntityValueModifier
|
class ArrayOf implements \Ulmus\Entity\EntityValueModifier
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected string $type,
|
public readonly string $type,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function push(mixed $value, ReflectedProperty $property): mixed
|
public function push(mixed $value, ReflectedProperty $property): mixed
|
||||||
|
|||||||
10
src/Attribute/Property/Field/Select.php
Normal file
10
src/Attribute/Property/Field/Select.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Ulmus\Attribute\Property\Field;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY)]
|
||||||
|
class Select {
|
||||||
|
public function __construct(
|
||||||
|
public string $sql,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@ -10,21 +10,13 @@ use Ulmus\Ulmus,
|
|||||||
|
|
||||||
class EntityField implements WhereRawParameter
|
class EntityField implements WhereRawParameter
|
||||||
{
|
{
|
||||||
public string $name;
|
public function __construct(
|
||||||
|
public string $name,
|
||||||
public string $entityClass;
|
public string $entityClass,
|
||||||
|
public ? string $alias,
|
||||||
public ? string $alias;
|
protected EntityResolver $entityResolver,
|
||||||
|
protected bool $select = false
|
||||||
protected EntityResolver $entityResolver;
|
) {}
|
||||||
|
|
||||||
public function __construct(string $entityClass, string $name, ? string $alias, EntityResolver $resolver)
|
|
||||||
{
|
|
||||||
$this->entityClass = $entityClass;
|
|
||||||
$this->name = $name;
|
|
||||||
$this->alias = $alias;
|
|
||||||
$this->entityResolver = $resolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function name($useAlias = true) : string
|
public function name($useAlias = true) : string
|
||||||
{
|
{
|
||||||
@ -32,7 +24,17 @@ class EntityField implements WhereRawParameter
|
|||||||
|
|
||||||
$name = $this->entityResolver->databaseAdapter()->adapter()->escapeIdentifier($name, AdapterInterface::IDENTIFIER_FIELD);
|
$name = $this->entityResolver->databaseAdapter()->adapter()->escapeIdentifier($name, AdapterInterface::IDENTIFIER_FIELD);
|
||||||
|
|
||||||
return $useAlias && $this->alias ? "{$this->alias}.$name" : $name;
|
$fullname = $useAlias && $this->alias ? "{$this->alias}.$name" : $name;
|
||||||
|
|
||||||
|
if ($this->select) {
|
||||||
|
$select = $this->entityResolver->searchFieldAnnotation($this->name, [Field\Select::class]);
|
||||||
|
|
||||||
|
if ($select) {
|
||||||
|
return "(" . str_replace(['%NAME%'], [$fullname], $select->sql) . ") AS code";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fullname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isScalarType($type) : bool
|
public static function isScalarType($type) : bool
|
||||||
|
|||||||
@ -9,7 +9,12 @@ class ArrayCollection extends EntityCollection implements JsonUnserializable
|
|||||||
|
|
||||||
public function jsonUnserialize(array $json): void
|
public function jsonUnserialize(array $json): void
|
||||||
{
|
{
|
||||||
$this->fromarray($json);
|
$this->fromArray($json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize(): mixed
|
||||||
|
{
|
||||||
|
return $this->getArrayCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fromArray(array $datasets, ? string /*stringable*/ $entityClass = null) : self
|
public function fromArray(array $datasets, ? string /*stringable*/ $entityClass = null) : self
|
||||||
|
|||||||
@ -309,21 +309,21 @@ trait EntityTrait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Ignore]
|
#[Ignore]
|
||||||
public static function field($name, null|string|false $alias = Repository::DEFAULT_ALIAS) : EntityField
|
public static function field($name, null|string|false $alias = Repository::DEFAULT_ALIAS, bool $select = false) : EntityField
|
||||||
{
|
{
|
||||||
$default = ( $alias === false ? '' : static::repository()::DEFAULT_ALIAS ); # bw compatibility, to be deprecated
|
$default = ( $alias === false ? '' : static::repository()::DEFAULT_ALIAS ); # bw compatibility, to be deprecated
|
||||||
|
|
||||||
$alias = $alias ? Ulmus::repository(static::class)->adapter->adapter()->escapeIdentifier($alias, Adapter\AdapterInterface::IDENTIFIER_FIELD) : $default;
|
$alias = $alias ? Ulmus::repository(static::class)->adapter->adapter()->escapeIdentifier($alias, Adapter\AdapterInterface::IDENTIFIER_FIELD) : $default;
|
||||||
|
|
||||||
return new EntityField(static::class, $name, $alias, Ulmus::resolveEntity(static::class));
|
return new EntityField(
|
||||||
|
entityClass: static::class, name: $name, alias: $alias, entityResolver: Ulmus::resolveEntity(static::class), select: $select
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Ignore]
|
#[Ignore]
|
||||||
public static function fields(array $fields, null|string|false $alias = Repository::DEFAULT_ALIAS, string $separator = ', ') : string
|
public static function fields(array $fields, null|string|false $alias = Repository::DEFAULT_ALIAS, string $separator = ', ', bool $select = false) : string
|
||||||
{
|
{
|
||||||
return implode($separator, array_map(function($item) use ($alias){
|
return implode($separator, array_map(fn($e) => static::field($e, $alias, $select), $fields));
|
||||||
return static::field($item, $alias);
|
|
||||||
}, $fields));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Ignore]
|
#[Ignore]
|
||||||
|
|||||||
@ -59,7 +59,7 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
public function loadOne() : ? object
|
public function loadOne() : ? object
|
||||||
{
|
{
|
||||||
return $this->limit(1)->selectSqlQuery()->collectionFromQuery()[0] ?? null;
|
return $this->limit(1)->loadAll()[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function loadOneFromField($field, $value) : ? object
|
public function loadOneFromField($field, $value) : ? object
|
||||||
@ -77,6 +77,7 @@ class Repository implements RepositoryInterface
|
|||||||
return $this->selectSqlQuery()->collectionFromQuery();
|
return $this->selectSqlQuery()->collectionFromQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\Deprecated(message: "loadFromField is now to be used instead of this method")]
|
||||||
public function loadAllFromField($field, $value, $operator= Query\Where::OPERATOR_EQUAL) : EntityCollection
|
public function loadAllFromField($field, $value, $operator= Query\Where::OPERATOR_EQUAL) : EntityCollection
|
||||||
{
|
{
|
||||||
return $this->loadFromField($field, $value, $operator);
|
return $this->loadFromField($field, $value, $operator);
|
||||||
@ -84,7 +85,7 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
public function loadFromField($field, $value, $operator= Query\Where::OPERATOR_EQUAL) : EntityCollection
|
public function loadFromField($field, $value, $operator= Query\Where::OPERATOR_EQUAL) : EntityCollection
|
||||||
{
|
{
|
||||||
return $this->selectSqlQuery()->where($field, $value, $operator)->collectionFromQuery();
|
return $this->where($field, $value, $operator)->loadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function count() : int
|
public function count() : int
|
||||||
@ -245,8 +246,6 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
$diff = $fieldsAndValue ?? $this->generateWritableDataset($entity);
|
$diff = $fieldsAndValue ?? $this->generateWritableDataset($entity);
|
||||||
|
|
||||||
# dump($diff);
|
|
||||||
|
|
||||||
if ( [] !== $diff ) {
|
if ( [] !== $diff ) {
|
||||||
if ($primaryKeyDefinition) {
|
if ($primaryKeyDefinition) {
|
||||||
$pkField = key($primaryKeyDefinition);
|
$pkField = key($primaryKeyDefinition);
|
||||||
@ -263,7 +262,6 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
$entity->entityFillFromDataset($dataset, true);
|
$entity->entityFillFromDataset($dataset, true);
|
||||||
|
|
||||||
# $fieldsAndValue ??= &$dataset;
|
|
||||||
$this->eventExecute(Event\Query\Update::class, $this, $entity, $dataset, $replace);
|
$this->eventExecute(Event\Query\Update::class, $this, $entity, $dataset, $replace);
|
||||||
|
|
||||||
return $update ? (bool) $update->rowCount : false;
|
return $update ? (bool) $update->rowCount : false;
|
||||||
@ -400,6 +398,7 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
foreach ($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) {
|
foreach ($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) {
|
||||||
if (null === $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Relation\Ignore::class ])) {
|
if (null === $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Relation\Ignore::class ])) {
|
||||||
|
# @TODO add handling of the new #[Select] attribute here !
|
||||||
$this->select(sprintf("%s.$key as {$prependField}{$field->name}", $this->escapeIdentifier($alias)));
|
$this->select(sprintf("%s.$key as {$prependField}{$field->name}", $this->escapeIdentifier($alias)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,7 +455,7 @@ class Repository implements RepositoryInterface
|
|||||||
|
|
||||||
if ( $canSelect ) {
|
if ( $canSelect ) {
|
||||||
$select = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true);
|
$select = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true);
|
||||||
$this->select($this->entityClass::fields(array_map(fn($f) => $f['object']->name ?? $f['name'], $select)));
|
$this->select($this->entityClass::fields(array_map(fn($f) => $f['object']->name ?? $f['name'], $select), select: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
$fields = (array) $fields;
|
$fields = (array) $fields;
|
||||||
@ -488,6 +487,8 @@ class Repository implements RepositoryInterface
|
|||||||
$name = $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Field::class ])->name ?? $field->name;
|
$name = $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Field::class ])->name ?? $field->name;
|
||||||
|
|
||||||
if ($canSelect) {
|
if ($canSelect) {
|
||||||
|
# @TODO add handling of the new #[Select] attribute here !
|
||||||
|
|
||||||
$this->select("$escAlias.$fieldName as $alias\${$name}");
|
$this->select("$escAlias.$fieldName as $alias\${$name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -563,7 +564,11 @@ class Repository implements RepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( null === $this->queryBuilder->getFragment(Query\Select::class) ) {
|
if ( null === $this->queryBuilder->getFragment(Query\Select::class) ) {
|
||||||
$this->select($this->escapeIdentifier($this->alias) . ".*");
|
# @TODO add handling of the new #[Select] attribute here !
|
||||||
|
$select = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true);
|
||||||
|
$this->select($this->entityClass::fields(array_map(fn($f) => $f['object']->name ?? $f['name'], $select), alias: $this->alias, select: true));
|
||||||
|
|
||||||
|
# $this->select($this->escapeIdentifier($this->alias) . ".*");
|
||||||
}
|
}
|
||||||
|
|
||||||
# Apply FILTER annotation to this too !
|
# Apply FILTER annotation to this too !
|
||||||
|
|||||||
@ -222,7 +222,7 @@ trait QueryBuildingTrait
|
|||||||
{
|
{
|
||||||
if ( null === $this->queryBuilder->getFragment(Query\Select::class) ) {
|
if ( null === $this->queryBuilder->getFragment(Query\Select::class) ) {
|
||||||
$fields = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true);
|
$fields = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true);
|
||||||
$this->select($this->entityClass::fields(array_map(fn($f) => $f->object->name ?? $f->name, $fields)));
|
$this->select($this->entityClass::fields(fields: array_map(fn($f) => $f->object->name ?? $f->name, $fields), select: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( null === $this->queryBuilder->getFragment(Query\From::class) ) {
|
if ( null === $this->queryBuilder->getFragment(Query\From::class) ) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user