diff --git a/composer.json b/composer.json index 29725c5..2dadbf8 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "authors": [ { "name": "Dave Mc Nicoll", - "email": "mcndave@gmail.com" + "email": "info@mcnd.ca" } ], "require": { diff --git a/src/Adapter/SQLite.php b/src/Adapter/SQLite.php index 497508e..743e2e0 100644 --- a/src/Adapter/SQLite.php +++ b/src/Adapter/SQLite.php @@ -193,5 +193,8 @@ class SQLite implements AdapterInterface { return (int) in_array($string, explode(',', $string_list)); }, 2); + $pdo->sqliteCreateFunction('day', fn($date) => ( new \DateTime($date) )->format('d'), 1); + $pdo->sqliteCreateFunction('month', fn($date) => ( new \DateTime($date) )->format('m'), 1); + $pdo->sqliteCreateFunction('year', fn($date) => ( new \DateTime($date) )->format('Y'), 1); } } \ No newline at end of file diff --git a/src/Common/EntityField.php b/src/Common/EntityField.php index c9bb1b5..4e84344 100644 --- a/src/Common/EntityField.php +++ b/src/Common/EntityField.php @@ -56,7 +56,7 @@ class EntityField implements WhereRawParameter $definition = new FieldDefinition($adapter, $field); return implode(" ", [ - $definition->getSqlName(), + $adapter->escapeIdentifier($definition->getSqlName(), AdapterInterface::IDENTIFIER_FIELD), $definition->getSqlType(), $definition->getSqlParams(), ]); diff --git a/src/EntityCollection.php b/src/EntityCollection.php index 0a6179e..100c275 100644 --- a/src/EntityCollection.php +++ b/src/EntityCollection.php @@ -49,6 +49,11 @@ class EntityCollection extends \ArrayObject { return $this->filtersCollection($callback, true, false)->toArray(); } + public function filtersCount(Callable $callback) : array + { + return $this->filtersCollection($callback, true, false)->count(); + } + public function filtersOne(Callable $callback) : ? object { foreach($this->filters($callback, true) as $item) { @@ -209,7 +214,7 @@ class EntityCollection extends \ArrayObject { return $list; } - public function unique(/*stringable|callable */ $field, bool $strict = false) : self + public function unique(\Stringable|callable $field, bool $strict = false) : self { $list = []; $obj = new static(); @@ -390,14 +395,16 @@ class EntityCollection extends \ArrayObject { return $this; } - public function sort(callable $callback, $function = "uasort") : self + public function sort(null|callable $callback = null, $function = "uasort") : self { + $callback ??= fn($e1, $e2) => $e1 <=> $e2; + call_user_func_array([ $this, $function ], [ $callback ]); return $this; } - public function rsort(callable $callback, $function = "uasort") : self + public function rsort(null|callable $callback = null, $function = "uasort") : self { return $this->sort(...func_get_args())->reverse(); } diff --git a/src/Repository.php b/src/Repository.php index dab53fc..0ad31a5 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -22,16 +22,18 @@ class Repository public ? ConnectionAdapter $adapter; - protected Query\QueryBuilderInterface $queryBuilder; - - protected EntityResolver $entityResolver; - public string $alias; public string $entityClass; public array $events = []; + protected Query\QueryBuilderInterface $queryBuilder; + + protected EntityResolver $entityResolver; + + protected array $joined = []; + public function __construct(string $entity, string $alias = self::DEFAULT_ALIAS, ConnectionAdapter $adapter = null) { $this->entityClass = $entity; $this->alias = $alias; @@ -592,6 +594,13 @@ class Repository # @TODO Apply FILTER annotation to this too ! foreach(array_filter((array) $fields) as $item) { + if ( isset($this->joined[$item]) ) { + continue; + } + else { + $this->joined[$item] = true; + } + $annotation = $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Join::class, Join::class ]) ?: $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Relation::class, Relation::class ]);