This commit is contained in:
Yuri Kuznetsov
2023-02-24 15:59:45 +02:00
parent 1d6745396d
commit 66b06b8baa
8 changed files with 174 additions and 181 deletions
+33 -34
View File
@@ -43,23 +43,22 @@ use Espo\ORM\Query\Select;
class Condition
{
private function __construct()
{
}
{}
/**
* Create 'AND' group.
*/
public static function and(WhereItem ...$itemList): AndGroup
public static function and(WhereItem ...$items): AndGroup
{
return AndGroup::create(...$itemList);
return AndGroup::create(...$items);
}
/**
* Create 'OR' group.
*/
public static function or(WhereItem ...$itemList): OrGroup
public static function or(WhereItem ...$items): OrGroup
{
return OrGroup::create(...$itemList);
return OrGroup::create(...$items);
}
/**
@@ -91,23 +90,23 @@ class Condition
/**
* Create '=' comparison.
*
* @param Expression $arg1 An expression.
* @param Expression|string|int|float|bool|null $arg2 A value (if scalar) or expression.
* @param Expression $argument1 An expression.
* @param Expression|string|int|float|bool|null $argument2 A value (if scalar) or expression.
*/
public static function equal(Expression $arg1, $arg2): Comparison
public static function equal(Expression $argument1, Expression|string|int|float|bool|null $argument2): Comparison
{
return Comparison::equal($arg1, $arg2);
return Comparison::equal($argument1, $argument2);
}
/**
* Create '!=' comparison.
*
* @param Expression $arg1 An expression.
* @param Expression|string|int|float|bool|null $arg2 A value (if scalar) or expression.
* @param Expression $argument1 An expression.
* @param Expression|string|int|float|bool|null $argument2 A value (if scalar) or expression.
*/
public static function notEqual(Expression $arg1, $arg2): Comparison
public static function notEqual(Expression $argument1, Expression|string|int|float|bool|null $argument2): Comparison
{
return Comparison::notEqual($arg1, $arg2);
return Comparison::notEqual($argument1, $argument2);
}
/**
@@ -116,7 +115,7 @@ class Condition
* @param Expression $subject What to test.
* @param Expression|string $pattern A pattern.
*/
public static function like(Expression $subject, $pattern): Comparison
public static function like(Expression $subject, Expression|string $pattern): Comparison
{
return Comparison::like($subject, $pattern);
}
@@ -127,7 +126,7 @@ class Condition
* @param Expression $subject What to test.
* @param Expression|string $pattern A pattern.
*/
public static function notLike(Expression $subject, $pattern): Comparison
public static function notLike(Expression $subject, Expression|string $pattern): Comparison
{
return Comparison::notLike($subject, $pattern);
}
@@ -135,45 +134,45 @@ class Condition
/**
* Create '>' comparison.
*
* @param Expression $arg1 An expression.
* @param Expression|string|int|float $arg2 A value (if scalar) or expression.
* @param Expression $argument1 An expression.
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
*/
public static function greater(Expression $arg1, $arg2): Comparison
public static function greater(Expression $argument1, Expression|string|int|float $argument2): Comparison
{
return Comparison::greater($arg1, $arg2);
return Comparison::greater($argument1, $argument2);
}
/**
* Create '>=' comparison.
*
* @param Expression $arg1 An expression.
* @param Expression|string|int|float $arg2 A value (if scalar) or expression.
* @param Expression $argument1 An expression.
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
*/
public static function greaterOrEqual(Expression $arg1, $arg2): Comparison
public static function greaterOrEqual(Expression $argument1, Expression|string|int|float $argument2): Comparison
{
return Comparison::greaterOrEqual($arg1, $arg2);
return Comparison::greaterOrEqual($argument1, $argument2);
}
/**
* Create '<' comparison.
*
* @param Expression $arg1 An expression.
* @param Expression|string|int|float $arg2 A value (if scalar) or expression.
* @param Expression $argument1 An expression.
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
*/
public static function less(Expression $arg1, $arg2): Comparison
public static function less(Expression $argument1, Expression|string|int|float $argument2): Comparison
{
return Comparison::less($arg1, $arg2);
return Comparison::less($argument1, $argument2);
}
/**
* Create '<=' comparison.
*
* @param Expression $arg1 An expression.
* @param Expression|string|int|float $arg2 A value (if scalar) or expression.
* @param Expression $argument1 An expression.
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
*/
public static function lessOrEqual(Expression $arg1, $arg2): Comparison
public static function lessOrEqual(Expression $argument1, Expression|string|int|float $argument2): Comparison
{
return Comparison::lessOrEqual($arg1, $arg2);
return Comparison::lessOrEqual($argument1, $argument2);
}
/**
@@ -182,7 +181,7 @@ class Condition
* @param Expression $subject What to test.
* @param Select|scalar[] $set A set of values. A select query or array of scalars.
*/
public static function in(Expression $subject, $set): Comparison
public static function in(Expression $subject, Select|array $set): Comparison
{
return Comparison::in($subject, $set);
}
@@ -193,7 +192,7 @@ class Condition
* @param Expression $subject What to test.
* @param Select|scalar[] $set A set of values. A select query or array of scalars.
*/
public static function notIn(Expression $subject, $set): Comparison
public static function notIn(Expression $subject, Select|array $set): Comparison
{
return Comparison::notIn($subject, $set);
}
+71 -45
View File
@@ -91,7 +91,7 @@ class Expression implements WhereItem
*
* @param string|float|int|bool|null $value A scalar or NULL.
*/
public static function value($value): self
public static function value(string|float|int|bool|null $value): self
{
return self::create(self::stringifyArgument($value));
}
@@ -173,12 +173,16 @@ class Expression implements WhereItem
/**
* 'IF' function. Return $then if a condition is true, $else otherwise.
*
* @param Expression $condition
* @param Expression|string|int|float|bool|null $then
* @param Expression|string|int|float|bool|null $else
* @param Expression $condition A condition.
* @param Expression|string|int|float|bool|null $then Then.
* @param Expression|string|int|float|bool|null $else Else.
*/
public static function if(Expression $condition, $then, $else): self
{
public static function if(
Expression $condition,
Expression|string|int|float|bool|null $then,
Expression|string|int|float|bool|null $else
): self {
return self::composeFunction('IF', $condition, $then, $else);
}
@@ -186,10 +190,10 @@ class Expression implements WhereItem
* 'IFNULL' function. If the first argument is not NULL, returns it,
* otherwise returns the second argument.
*
* @param Expression $value
* @param Expression|string|int|float|bool $fallbackValue
* @param Expression $value A value.
* @param Expression|string|int|float|bool $fallbackValue A fallback value.
*/
public static function ifNull(Expression $value, $fallbackValue): self
public static function ifNull(Expression $value, Expression|string|int|float|bool $fallbackValue): self
{
return self::composeFunction('IFNULL', $value, $fallbackValue);
}
@@ -201,8 +205,11 @@ class Expression implements WhereItem
* @param Expression|string|int|float|bool $argument1
* @param Expression|string|int|float|bool $argument2
*/
public static function nullIf($argument1, $argument2): self
{
public static function nullIf(
Expression|string|int|float|bool $argument1,
Expression|string|int|float|bool $argument2
): self {
return self::composeFunction('NULLIF', $argument1, $argument2);
}
@@ -211,10 +218,10 @@ class Expression implements WhereItem
*
* Example: `like(Expression:column('test'), 'test%'`.
*
* @param Expression $subject
* @param Expression|string $pattern
* @param Expression $subject A subject.
* @param Expression|string $pattern A pattern.
*/
public static function like(Expression $subject, $pattern): self
public static function like(Expression $subject, Expression|string $pattern): self
{
return self::composeFunction('LIKE', $subject, $pattern);
}
@@ -225,8 +232,11 @@ class Expression implements WhereItem
* @param Expression|string|int|float|bool $argument1
* @param Expression|string|int|float|bool $argument2
*/
public static function equal($argument1, $argument2): self
{
public static function equal(
Expression|string|int|float|bool $argument1,
Expression|string|int|float|bool $argument2
): self {
return self::composeFunction('EQUAL', $argument1, $argument2);
}
@@ -236,8 +246,11 @@ class Expression implements WhereItem
* @param Expression|string|int|float|bool $argument1
* @param Expression|string|int|float|bool $argument2
*/
public static function notEqual($argument1, $argument2): self
{
public static function notEqual(
Expression|string|int|float|bool $argument1,
Expression|string|int|float|bool $argument2
): self {
return self::composeFunction('NOT_EQUAL', $argument1, $argument2);
}
@@ -247,8 +260,11 @@ class Expression implements WhereItem
* @param Expression|string|int|float|bool $argument1
* @param Expression|string|int|float|bool $argument2
*/
public static function greater($argument1, $argument2): self
{
public static function greater(
Expression|string|int|float|bool $argument1,
Expression|string|int|float|bool $argument2
): self {
return self::composeFunction('GREATER_THAN', $argument1, $argument2);
}
@@ -258,8 +274,11 @@ class Expression implements WhereItem
* @param Expression|string|int|float|bool $argument1
* @param Expression|string|int|float|bool $argument2
*/
public static function less($argument1, $argument2): self
{
public static function less(
Expression|string|int|float|bool $argument1,
Expression|string|int|float|bool $argument2
): self {
return self::composeFunction('LESS_THAN', $argument1, $argument2);
}
@@ -269,8 +288,11 @@ class Expression implements WhereItem
* @param Expression|string|int|float|bool $argument1
* @param Expression|string|int|float|bool $argument2
*/
public static function greaterOrEqual($argument1, $argument2): self
{
public static function greaterOrEqual(
Expression|string|int|float|bool $argument1,
Expression|string|int|float|bool $argument2
): self {
return self::composeFunction('GREATER_THAN_OR_EQUAL', $argument1, $argument2);
}
@@ -280,8 +302,11 @@ class Expression implements WhereItem
* @param Expression|string|int|float|bool $argument1
* @param Expression|string|int|float|bool $argument2
*/
public static function lessOrEqual($argument1, $argument2): self
{
public static function lessOrEqual(
Expression|string|int|float|bool $argument1,
Expression|string|int|float|bool $argument2
): self {
return self::composeFunction('LESS_THAN_OR_EQUAL', $argument1, $argument2);
}
@@ -480,11 +505,11 @@ class Expression implements WhereItem
/**
* 'CONCAT' function. Concatenates multiple strings.
*
* @param Expression|string ...$stringList
* @param Expression|string ...$strings Strings.
*/
public static function concat(...$stringList): self
public static function concat(Expression|string ...$strings): self
{
return self::composeFunction('CONCAT', ...$stringList);
return self::composeFunction('CONCAT', ...$strings);
}
/**
@@ -542,8 +567,12 @@ class Expression implements WhereItem
* @param Expression|string $needle A string to be replaced.
* @param Expression|string $replaceWith A string to replace with.
*/
public static function replace(Expression $haystack, $needle, $replaceWith): self
{
public static function replace(
Expression $haystack,
Expression|string $needle,
Expression|string $replaceWith
): self {
return self::composeFunction('REPLACE', $haystack, $needle, $replaceWith);
}
@@ -564,7 +593,7 @@ class Expression implements WhereItem
*
* @param Expression|int|float ...$arguments
*/
public static function add(...$arguments): self
public static function add(Expression|int|float ...$arguments): self
{
if (count($arguments) < 2) {
throw new RuntimeException("Too few arguments");
@@ -578,7 +607,7 @@ class Expression implements WhereItem
*
* @param Expression|int|float ...$arguments
*/
public static function subtract(...$arguments): self
public static function subtract(Expression|int|float ...$arguments): self
{
if (count($arguments) < 2) {
throw new RuntimeException("Too few arguments");
@@ -592,7 +621,7 @@ class Expression implements WhereItem
*
* @param Expression|int|float ...$arguments
*/
public static function multiply(...$arguments): self
public static function multiply(Expression|int|float ...$arguments): self
{
if (count($arguments) < 2) {
throw new RuntimeException("Too few arguments");
@@ -606,7 +635,7 @@ class Expression implements WhereItem
*
* @param Expression|int|float ...$arguments
*/
public static function divide(...$arguments): self
public static function divide(Expression|int|float ...$arguments): self
{
if (count($arguments) < 2) {
throw new RuntimeException("Too few arguments");
@@ -620,7 +649,7 @@ class Expression implements WhereItem
*
* @param Expression|int|float ...$arguments
*/
public static function modulo(...$arguments): self
public static function modulo(Expression|int|float ...$arguments): self
{
if (count($arguments) < 2) {
throw new RuntimeException("Too few arguments");
@@ -693,18 +722,15 @@ class Expression implements WhereItem
return self::composeFunction('NOT', $argument);
}
/**
* @param Expression|bool|int|float|string|null ...$arguments
*/
private static function composeFunction(string $function, ...$arguments): self
{
private static function composeFunction(
string $function,
Expression|bool|int|float|string|null ...$arguments
): self {
return Util::composeFunction($function, ...$arguments);
}
/**
* @param Expression|bool|int|float|string|null $argument
*/
private static function stringifyArgument($argument): string
private static function stringifyArgument(Expression|bool|int|float|string|null $argument): string
{
return Util::stringifyArgument($argument);
}
@@ -29,65 +29,60 @@
namespace Espo\ORM\Query\Part\Expression;
use Espo\ORM\Query\Part\Expression as Expr;
use InvalidArgumentException;
use Espo\ORM\Query\Part\Expression;
class Util
{
/**
* Compose an expression by a function name and arguments.
*
* @param Expr|bool|int|float|string|null ...$argumentList
* @param Expression|bool|int|float|string|null ...$arguments Arguments
*/
public static function composeFunction(string $function, ...$argumentList): Expr
{
$stringifiedItemList = array_map(
public static function composeFunction(
string $function,
Expression|bool|int|float|string|null ...$arguments
): Expression {
$stringifiedItems = array_map(
function ($item) {
return self::stringifyArgument($item);
},
$argumentList
$arguments
);
$expression = $function . ':(' . implode(', ', $stringifiedItemList) . ')';
$expression = $function . ':(' . implode(', ', $stringifiedItems) . ')';
return Expr::create($expression);
return Expression::create($expression);
}
/**
* Stringify an argument.
*
* @param Expr|bool|int|float|string|null $arg
* @throws InvalidArgumentException
* @param Expression|bool|int|float|string|null $argument
*/
public static function stringifyArgument($arg): string
public static function stringifyArgument(Expression|bool|int|float|string|null $argument): string
{
/** @phpstan-var mixed $arg */
if ($arg instanceof Expr) {
return $arg->getValue();
if ($argument instanceof Expression) {
return $argument->getValue();
}
if (is_null($arg)) {
if (is_null($argument)) {
return 'NULL';
}
if (is_bool($arg)) {
return $arg ? 'TRUE': 'FALSE';
if (is_bool($argument)) {
return $argument ? 'TRUE': 'FALSE';
}
if (is_int($arg)) {
return strval($arg);
}
if (is_int($argument)) {
return strval($argument);
}
if (is_float($arg)) {
return strval($arg);
}
if (is_float($argument)) {
return strval($argument);
}
if (is_string($arg)) {
return '\'' . str_replace('\'', '\\\'', $arg) . '\'';
}
throw new InvalidArgumentException("Bad argument type.");
return '\'' . str_replace('\'', '\\\'', $argument) . '\'';
}
}
+4 -7
View File
@@ -38,16 +38,13 @@ use RuntimeException;
*/
class Join
{
private string $target;
private ?string $alias = null;
private ?WhereItem $conditions = null;
private bool $onlyMiddle = false;
private function __construct(string $target, ?string $alias = null)
{
$this->target = $target;
$this->alias = $alias;
private function __construct(
private string $target,
private ?string $alias = null
) {
if ($target === '' || $alias === '') {
throw new RuntimeException("Bad join.");
}
@@ -36,14 +36,10 @@ namespace Espo\ORM\Query\Part;
*/
class Selection
{
private $expression;
private $alias = null;
private function __construct(Expression $expression, ?string $alias = null)
{
$this->expression = $expression;
$this->alias = $alias;
}
private function __construct(
private Expression $expression,
private ?string $alias = null
) {}
public function getExpression(): Expression
{
@@ -33,10 +33,8 @@ use Espo\ORM\Query\Part\WhereItem;
class AndGroupBuilder
{
/**
* @var array<mixed,mixed>
*/
private $raw = [];
/** @var array<string|int, mixed> */
private array $raw = [];
public function build(): AndGroup
{
@@ -83,8 +81,8 @@ class AndGroupBuilder
}
/**
* @param array<mixed,mixed> $raw
* @return array<mixed,mixed>
* @param array<string|int, mixed> $raw
* @return array<string|int, mixed>
*/
private static function normalizeRaw(array $raw): array
{
@@ -34,7 +34,6 @@ use Espo\ORM\Query\Part\WhereItem;
use Espo\ORM\Query\Select;
use RuntimeException;
use InvalidArgumentException;
/**
* Compares an expression to a value or another expression. Immutable.
@@ -85,7 +84,7 @@ class Comparison implements WhereItem
* @param Expression|string|int|float|bool|null $argument2 A value (if scalar) or expression.
* @return self
*/
public static function equal(Expression $argument1, $argument2): self
public static function equal(Expression $argument1, Expression|string|int|float|bool|null $argument2): self
{
return self::createComparison(self::OPERATOR_EQUAL, $argument1, $argument2);
}
@@ -97,7 +96,7 @@ class Comparison implements WhereItem
* @param Expression|string|int|float|bool|null $argument2 A value (if scalar) or expression.
* @return self
*/
public static function notEqual(Expression $argument1, $argument2): self
public static function notEqual(Expression $argument1, Expression|string|int|float|bool|null $argument2): self
{
return self::createComparison(self::OPERATOR_NOT_EQUAL, $argument1, $argument2);
}
@@ -109,7 +108,7 @@ class Comparison implements WhereItem
* @param Expression|string $pattern A pattern.
* @return self
*/
public static function like(Expression $subject, $pattern): self
public static function like(Expression $subject, Expression|string $pattern): self
{
return self::createComparison(self::OPERATOR_LIKE, $subject, $pattern);
}
@@ -121,7 +120,7 @@ class Comparison implements WhereItem
* @param Expression|string $pattern A pattern.
* @return self
*/
public static function notLike(Expression $subject, $pattern): self
public static function notLike(Expression $subject, Expression|string $pattern): self
{
return self::createComparison(self::OPERATOR_NOT_LIKE, $subject, $pattern);
}
@@ -133,7 +132,7 @@ class Comparison implements WhereItem
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
* @return self
*/
public static function greater(Expression $argument1, $argument2): self
public static function greater(Expression $argument1, Expression|string|int|float $argument2): self
{
return self::createComparison(self::OPERATOR_GREATER, $argument1, $argument2);
}
@@ -145,7 +144,7 @@ class Comparison implements WhereItem
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
* @return self
*/
public static function greaterOrEqual(Expression $argument1, $argument2): self
public static function greaterOrEqual(Expression $argument1, Expression|string|int|float $argument2): self
{
return self::createComparison(self::OPERATOR_GREATER_OR_EQUAL, $argument1, $argument2);
}
@@ -157,7 +156,7 @@ class Comparison implements WhereItem
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
* @return self
*/
public static function less(Expression $argument1, $argument2): self
public static function less(Expression $argument1, Expression|string|int|float $argument2): self
{
return self::createComparison(self::OPERATOR_LESS, $argument1, $argument2);
}
@@ -169,7 +168,7 @@ class Comparison implements WhereItem
* @param Expression|string|int|float $argument2 A value (if scalar) or expression.
* @return self
*/
public static function lessOrEqual(Expression $argument1, $argument2): self
public static function lessOrEqual(Expression $argument1, Expression|string|int|float $argument2): self
{
return self::createComparison(self::OPERATOR_LESS_OR_EQUAL, $argument1, $argument2);
}
@@ -181,7 +180,7 @@ class Comparison implements WhereItem
* @param Select|scalar[] $set A set of values. A select query or array of scalars.
* @return self
*/
public static function in(Expression $subject, $set): self
public static function in(Expression $subject, Select|array $set): self
{
if ($set instanceof Select) {
return self::createInOrNotInSubQuery(self::OPERATOR_IN_SUB_QUERY, $subject, $set);
@@ -197,7 +196,7 @@ class Comparison implements WhereItem
* @param Select|scalar[] $set A set of values. A select query or array of scalars.
* @return self
*/
public static function notIn(Expression $subject, $set): self
public static function notIn(Expression $subject, Select|array $set): self
{
if ($set instanceof Select) {
return self::createInOrNotInSubQuery(self::OPERATOR_NOT_IN_SUB_QUERY, $subject, $set);
@@ -206,14 +205,11 @@ class Comparison implements WhereItem
return self::createInOrNotInArray(self::OPERATOR_NOT_EQUAL, $subject, $set);
}
/**
* @param Expression|string $argument1
* @param Expression|string|int|float|bool|null $argument2
*/
private static function createComparison(string $operator, $argument1, $argument2): self
{
/** @phpstan-var mixed $argument1 */
/** @phpstan-var mixed $argument2 */
private static function createComparison(
string $operator,
Expression|string $argument1,
Expression|string|int|float|bool|null $argument2
): self {
if (is_string($argument1)) {
$key = $argument1;
@@ -222,11 +218,8 @@ class Comparison implements WhereItem
throw new RuntimeException("Expression can't be empty.");
}
}
else if ($argument1 instanceof Expression) {
$key = $argument1->getValue();
}
else {
throw new InvalidArgumentException("First argument must be Expression or string.");
$key = $argument1->getValue();
}
if (str_ends_with($key, ':')) {
@@ -240,9 +233,6 @@ class Comparison implements WhereItem
$value = $argument2->getValue();
}
else if (!is_scalar($argument2) && !is_null($argument2)) {
throw new InvalidArgumentException("Second argument must be scalar or Expression.");
}
else {
$value = $argument2;
}
@@ -251,19 +241,20 @@ class Comparison implements WhereItem
}
/**
* @param Expression|string $argument1
* @param scalar[] $valueList
*/
private static function createInOrNotInArray(string $operator, $argument1, array $valueList): self
{
private static function createInOrNotInArray(
string $operator,
Expression|string $argument1,
array $valueList
): self {
foreach ($valueList as $item) {
if (!is_scalar($item)) {
throw new RuntimeException("Array items must be scalar.");
}
}
/** @phpstan-var mixed $argument1 */
if (is_string($argument1)) {
$key = $argument1;
@@ -275,11 +266,8 @@ class Comparison implements WhereItem
throw new RuntimeException("Expression can't end with `:`.");
}
}
else if ($argument1 instanceof Expression) {
$key = $argument1->getValue();
}
else {
throw new InvalidArgumentException("First argument must be Expression or string.");
$key = $argument1->getValue();
}
$key .= $operator;
@@ -287,12 +275,11 @@ class Comparison implements WhereItem
return new self($key, $valueList);
}
/**
* @param Expression|string $argument1
*/
private static function createInOrNotInSubQuery(string $operator, $argument1, Select $query): self
{
/** @phpstan-var mixed $argument1 */
private static function createInOrNotInSubQuery(
string $operator,
Expression|string $argument1,
Select $query
): self {
if (is_string($argument1)) {
$key = $argument1;
@@ -305,11 +292,8 @@ class Comparison implements WhereItem
throw new RuntimeException("Expression can't end with `:`.");
}
}
else if ($argument1 instanceof Expression) {
$key = $argument1->getValue();
}
else {
throw new InvalidArgumentException("First argument must be Expression or string.");
$key = $argument1->getValue();
}
$key .= $operator;
@@ -33,10 +33,8 @@ use Espo\ORM\Query\Part\WhereItem;
class OrGroupBuilder
{
/**
* @var array<mixed,mixed>
*/
private $raw = [];
/** @var array<string|int, mixed> */
private array $raw = [];
public function build(): OrGroup
{
@@ -83,8 +81,8 @@ class OrGroupBuilder
}
/**
* @param array<mixed,mixed> $raw
* @return array<mixed,mixed>
* @param array<string|int, mixed> $raw
* @return array<string|int, mixed>
*/
private static function normalizeRaw(array $raw): array
{