- Added the HAVING and TRUNCATE keyword
- Fixed GroupBy which was not implemented yet - Added a new SQL raw() function - From statement now accepts subqueries
This commit is contained in:
1 parent
538af38769
commit
139504f8dd
17 files changed
+566
-251
No files matched your search
+68
-199
@@ -6,7 +6,7 @@ use Ulmus\Common\EntityResolver;
|
||||
|
||||
class Repository
|
||||
{
|
||||
use EventTrait;
|
||||
use EventTrait, Repository\ConditionTrait;
|
||||
|
||||
const DEFAULT_ALIAS = "this";
|
||||
|
||||
@@ -27,7 +27,7 @@ class Repository
|
||||
$this->alias = $alias;
|
||||
$this->entityResolver = Ulmus::resolveEntity($entity);
|
||||
$this->adapter = $adapter ?? $this->entityResolver->databaseAdapter() ?? Ulmus::$defaultAdapter;
|
||||
$this->queryBuilder = new QueryBuilder( $this->adapter->adapter() );
|
||||
$this->queryBuilder = new QueryBuilder();
|
||||
}
|
||||
|
||||
public function loadOne() : ? object
|
||||
@@ -61,7 +61,14 @@ class Repository
|
||||
$this->queryBuilder->removeFragment($select);
|
||||
}
|
||||
|
||||
$this->select("COUNT(*)")->selectSqlQuery();
|
||||
if ( $this->queryBuilder->getFragment(Query\GroupBy::class) ) {
|
||||
$this->select( "DISTINCT COUNT(*) OVER ()" );
|
||||
}
|
||||
else {
|
||||
$this->select(Common\Sql::function("COUNT", "*"));
|
||||
}
|
||||
|
||||
$this->selectSqlQuery();
|
||||
|
||||
$this->finalizeQuery();
|
||||
|
||||
@@ -161,14 +168,35 @@ class Repository
|
||||
}
|
||||
}
|
||||
|
||||
public function truncate(? string $table = null, ? string $alias = null, ? string $schema = null) : self
|
||||
{
|
||||
$schema = $schema ?: $this->entityResolver->schemaName();
|
||||
|
||||
$this->queryBuilder->truncate($this->escapeTable($table ?: $this->entityResolver->tableName()), $alias ?: $this->alias, $this->escapeDatabase($this->adapter->adapter()->database), $schema ? $this->escapeSchema($schema) : null);
|
||||
|
||||
$this->finalizeQuery();
|
||||
|
||||
$result = Ulmus::runSelectQuery($this->queryBuilder, $this->adapter);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function generateDatasetDiff(object $entity) : array
|
||||
{
|
||||
return array_diff_assoc( array_change_key_case($entity->toArray()), array_change_key_case($entity->entityGetDataset(false, true)) );
|
||||
}
|
||||
|
||||
public function yieldAll() : \Generator
|
||||
|
||||
public function yield() : \Generator
|
||||
{
|
||||
$class = $this->entityClass;
|
||||
|
||||
$this->selectSqlQuery();
|
||||
|
||||
$this->finalizeQuery();
|
||||
|
||||
foreach(Ulmus::iterateQueryBuilder($this->queryBuilder, $this->adapter) as $entityData) {
|
||||
yield ( new $class() )->entityFillFromDataset($entityData);
|
||||
}
|
||||
}
|
||||
|
||||
public function select($fields) : self
|
||||
@@ -220,194 +248,23 @@ class Repository
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function join(string $type, $table, $field, $value, ? string $alias = null) : self
|
||||
public function join(string $type, $table, $field, $value, ? string $alias = null, ? callable $callback = null) : self
|
||||
{
|
||||
$this->queryBuilder->join($type, $this->escapeTable($table), $field, $value, false, $alias);
|
||||
$join = $this->queryBuilder->withJoin($type, $this->escapeTable($table), $field, $value, false, $alias);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function outerJoin(string $type, $table, $field, $value, ? string $alias = null) : self
|
||||
{
|
||||
$this->queryBuilder->join($type, $this->escapeTable($table), $field, $value, true, $alias);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function open(string $condition = Query\Where::CONDITION_AND) : self
|
||||
{
|
||||
$this->queryBuilder->open($condition);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orOpen() : self
|
||||
{
|
||||
return $this->open(Query\Where::CONDITION_OR);
|
||||
}
|
||||
|
||||
public function close() : self
|
||||
{
|
||||
$this->queryBuilder->close();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function where($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_AND);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function wheres(array $fieldValues, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
||||
{
|
||||
foreach($fieldValues as $field => $value) {
|
||||
if ( is_array($value) ) {
|
||||
switch ($value[1]) {
|
||||
case Query\Where::CONDITION_AND:
|
||||
$this->where($field, $value[0], $operator);
|
||||
break;
|
||||
|
||||
case Query\Where::CONDITION_OR:
|
||||
$this->or($field, $value[0], $operator);
|
||||
break;
|
||||
|
||||
case Query\Where::CONDITION_NOT:
|
||||
$this->notWhere($field, $value[0], $operator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->where($field, $value, $operator);
|
||||
}
|
||||
if ( $callback ) {
|
||||
$callback($join);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function and($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
||||
{
|
||||
return $this->where($field, $value, $operator);
|
||||
}
|
||||
|
||||
public function or($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
||||
public function outerJoin(string $type, $table, $field, $value, ? string $alias = null, ? callable $callback = null) : self
|
||||
{
|
||||
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_OR);
|
||||
$join = $this->queryBuilder->withJoin($type, $this->escapeTable($table), $field, $value, true, $alias);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function notWhere($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_AND, true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orNot($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->notWhere($field, $value, $operator, Query\Where::CONDITION_OR, true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function having($field, $value, string $operator = Query\Having::OPERATOR_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->having($field, $value, $operator, Query\Having::CONDITION_AND);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orHaving($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->having($field, $value, $operator, Query\Having::CONDITION_OR);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function notHaving($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->having($field, $value, $operator, Query\Having::CONDITION_AND, true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orNotHaving($field, $value) : self
|
||||
{
|
||||
$this->queryBuilder->having($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Having::CONDITION_OR, true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function in($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->where($field, $value, $operator);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orIn($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
|
||||
{
|
||||
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_OR);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function notIn($field, $value) : self
|
||||
{
|
||||
$this->queryBuilder->where($field, $value, Query\Where::OPERATOR_NOT_EQUAL);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orNotIn($field, $value) : self
|
||||
{
|
||||
return $this->orNot($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR, true);
|
||||
}
|
||||
|
||||
public function like($field, $value) : self
|
||||
{
|
||||
$this->where($field, $value, Query\Where::OPERATOR_LIKE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function orLike($field, $value) : self
|
||||
{
|
||||
$this->or($field, $value, Query\Where::OPERATOR_LIKE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function notLike($field, $value) : self
|
||||
{
|
||||
$this->notWhere($field, $value, Query\Where::OPERATOR_LIKE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function likes(array $fieldValues, string $condition = Query\Where::CONDITION_AND) : self
|
||||
{
|
||||
foreach($fieldValues as $field => $value) {
|
||||
if ( is_array($value) ) {
|
||||
switch ($value[1]) {
|
||||
case Query\Where::CONDITION_AND:
|
||||
$this->like($field, $value[0]);
|
||||
break;
|
||||
|
||||
case Query\Where::CONDITION_OR:
|
||||
$this->orLike($field, $value[0]);
|
||||
break;
|
||||
|
||||
case Query\Where::CONDITION_NOT:
|
||||
$this->notLike($field, $value[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->like($field, $value);
|
||||
}
|
||||
if ( $callback ) {
|
||||
$callback($join);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -432,15 +289,20 @@ class Repository
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function groupBy() : self
|
||||
|
||||
public function groupBy($field) : self
|
||||
{
|
||||
$this->queryBuilder->groupBy($field);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function groups(array $groups) : self
|
||||
{
|
||||
# foreach($this->groups)
|
||||
foreach($groups as $field ) {
|
||||
$this->groupBy($field);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -454,7 +316,7 @@ class Repository
|
||||
public function orders(array $orderList) : self
|
||||
{
|
||||
foreach($orderList as $field => $direction) {
|
||||
$this->queryBuilder->orderBy($field, $direction);
|
||||
$this->orderBy($field, $direction);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -502,7 +364,10 @@ class Repository
|
||||
public function withJoin(/*string|array*/ $fields) : self
|
||||
{
|
||||
$resolvedEntity = Ulmus::resolveEntity($this->entityClass);
|
||||
$this->select("{$this->alias}.*");
|
||||
|
||||
if ( null === $this->queryBuilder->getFragment(Query\Select::class) ) {
|
||||
$this->select("{$this->alias}.*");
|
||||
}
|
||||
|
||||
foreach((array) $fields as $item) {
|
||||
if ( null !== $join = $resolvedEntity->searchFieldAnnotation($item, new Annotation\Property\Join) ) {
|
||||
@@ -528,17 +393,21 @@ class Repository
|
||||
|
||||
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest) : self
|
||||
{
|
||||
$searchRequest->count = $searchRequest->filter( clone $this )
|
||||
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
|
||||
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
|
||||
->groups($searchRequest->groups())
|
||||
$likes = $searchRequest->likes();
|
||||
$wheres = $searchRequest->wheres();
|
||||
$groups = $searchRequest->groups();
|
||||
|
||||
$searchRequest->count = $searchRequest->skipCount ? 0 : $searchRequest->filter( clone $this )
|
||||
->wheres($wheres, Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
|
||||
->likes($likes, Query\Where::CONDITION_OR)
|
||||
->groups($groups)
|
||||
->count();
|
||||
|
||||
return $searchRequest->filter($this)
|
||||
->wheres($searchRequest->wheres(), Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
|
||||
->likes($searchRequest->likes(), Query\Where::CONDITION_OR)
|
||||
->wheres($wheres, Query\Where::OPERATOR_EQUAL, Query\Where::CONDITION_AND)
|
||||
->likes($likes, Query\Where::CONDITION_OR)
|
||||
->orders($searchRequest->orders())
|
||||
->groups($searchRequest->groups())
|
||||
->groups($groups)
|
||||
->offset($searchRequest->offset())
|
||||
->limit($searchRequest->limit());
|
||||
}
|
||||
@@ -546,8 +415,8 @@ class Repository
|
||||
public function collectionFromQuery(? string $entityClass = null) : EntityCollection
|
||||
{
|
||||
$class = $entityClass ?: $this->entityClass;
|
||||
|
||||
$entityCollection = $this->instanciateEntityCollection();
|
||||
|
||||
$entityCollection = $class::entityCollection();
|
||||
|
||||
$this->selectSqlQuery();
|
||||
|
||||
@@ -557,7 +426,7 @@ class Repository
|
||||
$entityCollection->append( ( new $class() )->entityFillFromDataset($entityData) );
|
||||
}
|
||||
|
||||
$this->eventExecute(Event\RepositoryCollectionFromQueryInterface::class, $entityCollection);
|
||||
$this->eventExecute(Event\Repository\CollectionFromQueryInterface::class, $entityCollection);
|
||||
|
||||
return $entityCollection;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user