A super easy PHP Framework for web development!
https://github.com/exacti/phacil-framework
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
632 lines
12 KiB
632 lines
12 KiB
1 year ago
|
<?php
|
||
|
/**
|
||
|
* Copyright © 2023 ExacTI Technology Solutions. All rights reserved.
|
||
|
* GPLv3 General License.
|
||
|
* https://exacti.com.br
|
||
|
* Phacil PHP Framework - https://github.com/exacti/phacil-framework
|
||
|
*/
|
||
|
|
||
|
namespace Phacil\Framework\MagiQL\Syntax;
|
||
|
|
||
|
use Phacil\Framework\MagiQL\Manipulation\QueryException;
|
||
|
use Phacil\Framework\MagiQL\Manipulation\QueryFactory;
|
||
|
use Phacil\Framework\MagiQL\Api\QueryInterface;
|
||
|
use Phacil\Framework\MagiQL\Api\WhereInterface;
|
||
|
use Phacil\Framework\MagiQL\Manipulation\Select;
|
||
|
|
||
|
/**
|
||
|
* Class Where.
|
||
|
*/
|
||
|
class Where implements WhereInterface
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $comparisons = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $betweens = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $isNull = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $isNotNull = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $booleans = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $match = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $ins = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $notIns = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $subWheres = [];
|
||
|
|
||
|
/**
|
||
|
* @var string
|
||
|
*/
|
||
|
protected $conjunction = WhereInterface::CONJUNCTION_AND;
|
||
|
|
||
|
/**
|
||
|
* @var QueryInterface
|
||
|
*/
|
||
|
protected $query;
|
||
|
|
||
|
/**
|
||
|
* @var Table
|
||
|
*/
|
||
|
protected $table;
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $exists = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $notExists = [];
|
||
|
|
||
|
/**
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $notBetweens = [];
|
||
|
|
||
|
/**
|
||
|
* @param QueryInterface $query
|
||
|
*/
|
||
|
public function __construct(QueryInterface $query)
|
||
|
{
|
||
|
$this->query = $query;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Deep copy for nested references.
|
||
|
*
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public function __clone()
|
||
|
{
|
||
|
return \unserialize(\serialize($this));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function isEmpty()
|
||
|
{
|
||
|
$empty = \array_merge(
|
||
|
$this->comparisons,
|
||
|
$this->booleans,
|
||
|
$this->betweens,
|
||
|
$this->isNotNull,
|
||
|
$this->isNull,
|
||
|
$this->ins,
|
||
|
$this->notIns,
|
||
|
$this->subWheres,
|
||
|
$this->exists
|
||
|
);
|
||
|
|
||
|
return 0 == \count($empty);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getConjunction()
|
||
|
{
|
||
|
return $this->conjunction;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $operator
|
||
|
*
|
||
|
* @return $this
|
||
|
*
|
||
|
* @throws QueryException
|
||
|
*/
|
||
|
public function conjunction($operator)
|
||
|
{
|
||
|
if (false === \in_array(
|
||
|
$operator,
|
||
|
[WhereInterface::CONJUNCTION_AND, WhereInterface::CONJUNCTION_OR, WhereInterface::CONJUNCTION_OR_NOT, WhereInterface::CONJUNCTION_AND_NOT]
|
||
|
)
|
||
|
) {
|
||
|
throw new QueryException(
|
||
|
"Invalid conjunction specified, must be one of AND or OR, but '".$operator."' was found."
|
||
|
);
|
||
|
}
|
||
|
$this->conjunction = $operator;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getSubWheres()
|
||
|
{
|
||
|
return $this->subWheres;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $operator
|
||
|
*
|
||
|
* @return Where
|
||
|
*/
|
||
|
public function subWhere($operator = 'OR')
|
||
|
{
|
||
|
/** @var Where $filter */
|
||
|
$filter = QueryFactory::createWhere($this->query);
|
||
|
$filter->conjunction($operator);
|
||
|
$filter->setTable($this->getTable());
|
||
|
|
||
|
$this->subWheres[] = $filter;
|
||
|
|
||
|
return $filter;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return Table
|
||
|
*/
|
||
|
public function getTable()
|
||
|
{
|
||
|
return $this->query->getTable();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Used for subWhere query building.
|
||
|
*
|
||
|
* @param Table $table string
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function setTable($table)
|
||
|
{
|
||
|
$this->table = $table;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* equals alias.
|
||
|
*
|
||
|
* @param $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function eq($column, $value)
|
||
|
{
|
||
|
return $this->equals($column, $value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $column
|
||
|
* @param $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function equals($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_EQUAL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $column
|
||
|
* @param $value
|
||
|
* @param string $operator
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
protected function compare($column, $value, $operator)
|
||
|
{
|
||
|
$column = $this->prepareColumn($column);
|
||
|
|
||
|
$this->comparisons[] = [
|
||
|
'subject' => $column,
|
||
|
'conjunction' => $operator,
|
||
|
'target' => $value,
|
||
|
];
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $column
|
||
|
*
|
||
|
* @return Column|Select
|
||
|
*/
|
||
|
protected function prepareColumn($column)
|
||
|
{
|
||
|
//This condition handles the "Select as a a column" special case.
|
||
|
//or when compare column is customized.
|
||
|
if ($column instanceof Select || $column instanceof Column) {
|
||
|
return $column;
|
||
|
}
|
||
|
|
||
|
$newColumn = [$column];
|
||
|
|
||
|
return SyntaxFactory::createColumn($newColumn, $this->getTable());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function notEquals($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_NOT_EQUAL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function greaterThan($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_GREATER_THAN);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function greaterThanOrEqual($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_GREATER_THAN_OR_EQUAL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function lessThan($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_LESS_THAN);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function lessThanOrEqual($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_LESS_THAN_OR_EQUAL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function like($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_LIKE);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function notLike($column, $value)
|
||
|
{
|
||
|
return $this->compare($column, $value, WhereInterface::OPERATOR_NOT_LIKE);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string[] $columns
|
||
|
* @param mixed[] $values
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function match(array $columns, array $values)
|
||
|
{
|
||
|
return $this->genericMatch($columns, $values, 'natural');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string[] $columns
|
||
|
* @param mixed[] $values
|
||
|
* @param string $mode
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
protected function genericMatch(array &$columns, array &$values, $mode)
|
||
|
{
|
||
|
$this->match[] = [
|
||
|
'columns' => $columns,
|
||
|
'values' => $values,
|
||
|
'mode' => $mode,
|
||
|
];
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $literal
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function asLiteral($literal)
|
||
|
{
|
||
|
$this->comparisons[] = $literal;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string[] $columns
|
||
|
* @param mixed[] $values
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function matchBoolean(array $columns, array $values)
|
||
|
{
|
||
|
return $this->genericMatch($columns, $values, 'boolean');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string[] $columns
|
||
|
* @param mixed[] $values
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function matchWithQueryExpansion(array $columns, array $values)
|
||
|
{
|
||
|
return $this->genericMatch($columns, $values, 'query_expansion');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int[] $values
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function in($column, array $values)
|
||
|
{
|
||
|
$this->ins[$column] = $values;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int[] $values
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function notIn($column, array $values)
|
||
|
{
|
||
|
$this->notIns[$column] = $values;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $a
|
||
|
* @param int $b
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function between($column, $a, $b)
|
||
|
{
|
||
|
$column = $this->prepareColumn($column);
|
||
|
$this->betweens[] = ['subject' => $column, 'a' => $a, 'b' => $b];
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $a
|
||
|
* @param int $b
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function notBetween($column, $a, $b)
|
||
|
{
|
||
|
$column = $this->prepareColumn($column);
|
||
|
$this->notBetweens[] = ['subject' => $column, 'a' => $a, 'b' => $b];
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
*
|
||
|
* @return static
|
||
|
*/
|
||
|
public function isNull($column)
|
||
|
{
|
||
|
$column = $this->prepareColumn($column);
|
||
|
$this->isNull[] = ['subject' => $column];
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function isNotNull($column)
|
||
|
{
|
||
|
$column = $this->prepareColumn($column);
|
||
|
$this->isNotNull[] = ['subject' => $column];
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $column
|
||
|
* @param int $value
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function addBitClause($column, $value)
|
||
|
{
|
||
|
$column = $this->prepareColumn($column);
|
||
|
$this->booleans[] = ['subject' => $column, 'value' => $value];
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Select $select
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function exists(Select $select)
|
||
|
{
|
||
|
$this->exists[] = $select;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getExists()
|
||
|
{
|
||
|
return $this->exists;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Select $select
|
||
|
*
|
||
|
* @return $this
|
||
|
*/
|
||
|
public function notExists(Select $select)
|
||
|
{
|
||
|
$this->notExists[] = $select;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getNotExists()
|
||
|
{
|
||
|
return $this->notExists;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getMatches()
|
||
|
{
|
||
|
return $this->match;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getIns()
|
||
|
{
|
||
|
return $this->ins;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getNotIns()
|
||
|
{
|
||
|
return $this->notIns;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getBetweens()
|
||
|
{
|
||
|
return $this->betweens;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getNotBetweens()
|
||
|
{
|
||
|
return $this->notBetweens;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getBooleans()
|
||
|
{
|
||
|
return $this->booleans;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getComparisons()
|
||
|
{
|
||
|
return $this->comparisons;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getNotNull()
|
||
|
{
|
||
|
return $this->isNotNull;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getNull()
|
||
|
{
|
||
|
return $this->isNull;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return QueryInterface
|
||
|
*/
|
||
|
public function end()
|
||
|
{
|
||
|
return $this->query;
|
||
|
}
|
||
|
}
|