- Added Events to repository and entitytrait objects. Some more work to be done on this.

- Diverses bug fixes linked to join and relations
- Field date and datetime are now outputed using given locale.
This commit is contained in:
Dave Mc Nicoll committed 2020-05-20 15:34:50 -04:00
1 parent 1839726dc0
commit 4d221859fc
15 files changed
+421 -99

No files matched your search

+96 -12
View File
@@ -6,6 +6,8 @@ use Ulmus\Common\EntityResolver;
class Repository
{
use EventTrait;
const DEFAULT_ALIAS = "this";
public ? ConnectionAdapter $adapter;
@@ -17,7 +19,9 @@ class Repository
public string $alias;
public string $entityClass;
public array $events = [];
public function __construct(string $entity, string $alias = self::DEFAULT_ALIAS, ConnectionAdapter $adapter = null) {
$this->entityClass = $entity;
$this->alias = $alias;
@@ -36,9 +40,9 @@ class Repository
return $this->where($field, $value)->loadOne();
}
public function loadFromPk($value, $primaryKey = "id") : ? object
public function loadFromPk($value, /* ? stringable */ $primaryKey = null) : ? object
{
return $this->loadOneFromField($primaryKey, $value);
return $primaryKey ? $this->loadOneFromField($primaryKey, $value) : $this->wherePrimaryKey($value)->loadOne();
}
public function loadAll() : EntityCollection
@@ -53,6 +57,10 @@ class Repository
public function count() : int
{
if ( null !== $select = $this->queryBuilder->getFragment(Query\Select::class) ) {
$this->queryBuilder->removeFragment($select);
}
$this->select("COUNT(*)")->selectSqlQuery();
$this->finalizeQuery();
@@ -79,8 +87,39 @@ class Repository
return (bool) $this->wherePrimaryKey($value)->deleteOne()->rowCount();
}
public function destroy(object $entity) : bool
{
if ( ! $this->matchEntity($entity) ) {
throw new \Exception("Your entity class `" . get_class($entity) . "` cannot match entity type of repository `{$this->entityClass}`");
}
$primaryKeyDefinition = Ulmus::resolveEntity($this->entityClass)->getPrimaryKeyField();
if ( $primaryKeyDefinition === null ) {
throw new \Exception(sprintf("No primary key found for entity %s", $this->entityClass));
}
else {
$pkField = key($primaryKeyDefinition);
return $this->deleteFromPk($entity->$pkField);
}
return false;
}
public function destroyAll(EntityCollection $collection) : void
{
foreach($collection as $entity) {
$this->destroy($entity);
}
}
public function save(object $entity) : bool
{
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();
@@ -124,7 +163,7 @@ class Repository
public function generateDatasetDiff(object $entity) : array
{
return array_diff_assoc( array_change_key_case($entity->toArray()), array_change_key_case($entity->entityGetDataset(true)) );
return array_diff_assoc( array_change_key_case($entity->toArray()), array_change_key_case($entity->entityGetDataset(false, true)) );
}
public function yieldAll() : \Generator
@@ -294,9 +333,9 @@ class Repository
return $this;
}
public function orNotHaving($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
public function orNotHaving($field, $value) : self
{
$this->queryBuilder->having($field, $value, $operator, Query\Having::CONDITION_OR, true);
$this->queryBuilder->having($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Having::CONDITION_OR, true);
return $this;
}
@@ -322,9 +361,9 @@ class Repository
return $this;
}
public function orNotIn($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
public function orNotIn($field, $value) : self
{
return $this->orNot($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR);
return $this->orNot($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR, true);
}
public function like($field, $value) : self
@@ -436,11 +475,14 @@ class Repository
return $this;
}
/* @TODO */
public function commit() : self
{
return $this;
}
/* @TODO */
public function rollback() : self
{
return $this;
@@ -457,6 +499,33 @@ class Repository
return $this->where($primaryKeyField[$pkField]->name ?? $pkField, $value);
}
public function withJoin(/*string|array*/ $fields) : self
{
$resolvedEntity = Ulmus::resolveEntity($this->entityClass);
$this->select("{$this->alias}.*");
foreach((array) $fields as $item) {
if ( null !== $join = $resolvedEntity->searchFieldAnnotation($item, new Annotation\Property\Join) ) {
$alias = $join->alias ?? $item;
$entity = $join->entity ?? $resolvedEntity->properties[$item]['type'];
foreach($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME) as $key => $field) {
$this->select("$alias.$key as {$alias}\${$field['name']}");
}
$key = is_string($join->key) ? $this->entityClass::field($join->key) : $join->key;
$foreignKey = is_string($join->foreignKey) ? $entity::field($join->foreignKey, $alias) : $join->foreignKey;
$this->join($join->type, $entity::resolveEntity()->tableName(), $key, $foreignKey, $alias);
}
else {
throw new \Exception("You referenced field `$item` which do not exist or do not contain a valid @Join annotation.");
}
}
return $this;
}
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest) : self
{
$searchRequest->count = $searchRequest->filter( clone $this )
@@ -473,12 +542,12 @@ class Repository
->offset($searchRequest->offset())
->limit($searchRequest->limit());
}
public function collectionFromQuery(? string $entityClass = null) : EntityCollection
{
$class = $entityClass ?: $this->entityClass;
$entityCollection = new EntityCollection();
$entityCollection = $this->instanciateEntityCollection();
$this->selectSqlQuery();
@@ -487,9 +556,20 @@ class Repository
foreach(Ulmus::iterateQueryBuilder($this->queryBuilder, $this->adapter) as $entityData) {
$entityCollection->append( ( new $class() )->entityFillFromDataset($entityData) );
}
$this->eventExecute(Event\RepositoryCollectionFromQueryInterface::class, $entityCollection);
return $entityCollection;
}
public function arrayFromQuery() : array
{
$this->selectSqlQuery();
$this->finalizeQuery();
return Ulmus::datasetQueryBuilder($this->queryBuilder, $this->adapter);
}
public function runQuery() : ? \PDOStatement
{
@@ -556,9 +636,9 @@ class Repository
}
public function table()
public function instanciateEntityCollection() : EntityCollection
{
return "REFLECT TABLE";
return new EntityCollection();
}
public function escapeTable(string $identifier) : string
@@ -576,5 +656,9 @@ class Repository
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_SCHEMA);
}
protected function matchEntity(object $entity) {
return get_class($entity) === $this->entityClass;
}
protected function finalizeQuery() : void {}
}