2015-07-06 06:00:01 -04:00
< ? php
2024-05-23 03:26:56 -04:00
2015-07-06 06:00:01 -04:00
/**
2024-05-23 03:26:56 -04:00
* SPDX - FileCopyrightText : 2016 - 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX - FileCopyrightText : 2016 ownCloud , Inc .
* SPDX - License - Identifier : AGPL - 3.0 - only
2015-07-06 06:00:01 -04:00
*/
2016-02-05 09:32:34 -05:00
namespace OC\DB\QueryBuilder\ExpressionBuilder ;
2015-07-06 06:00:01 -04:00
use Doctrine\DBAL\Query\Expression\ExpressionBuilder as DoctrineExpressionBuilder ;
2021-01-03 09:28:31 -05:00
use OC\DB\ConnectionAdapter ;
2016-02-05 09:32:34 -05:00
use OC\DB\QueryBuilder\CompositeExpression ;
2017-12-20 09:51:37 -05:00
use OC\DB\QueryBuilder\FunctionBuilder\FunctionBuilder ;
2016-02-05 09:32:34 -05:00
use OC\DB\QueryBuilder\Literal ;
use OC\DB\QueryBuilder\QueryFunction ;
use OC\DB\QueryBuilder\QuoteHelper ;
2021-02-15 10:36:20 -05:00
use OCP\DB\QueryBuilder\ICompositeExpression ;
2015-07-07 11:30:26 -04:00
use OCP\DB\QueryBuilder\IExpressionBuilder ;
2017-01-05 05:45:10 -05:00
use OCP\DB\QueryBuilder\ILiteral ;
2020-10-02 12:59:53 -04:00
use OCP\DB\QueryBuilder\IParameter ;
2017-07-25 09:34:59 -04:00
use OCP\DB\QueryBuilder\IQueryBuilder ;
2017-01-05 05:45:10 -05:00
use OCP\DB\QueryBuilder\IQueryFunction ;
2015-07-06 06:00:01 -04:00
use OCP\IDBConnection ;
2024-07-04 05:26:17 -04:00
use Psr\Log\LoggerInterface ;
2015-07-06 06:00:01 -04:00
class ExpressionBuilder implements IExpressionBuilder {
/** @var \Doctrine\DBAL\Query\Expression\ExpressionBuilder */
2016-01-18 10:03:41 -05:00
protected $expressionBuilder ;
2015-07-06 06:00:01 -04:00
2015-07-07 11:30:26 -04:00
/** @var QuoteHelper */
2016-01-18 10:03:41 -05:00
protected $helper ;
2015-07-07 11:30:26 -04:00
2017-01-05 05:45:10 -05:00
/** @var IDBConnection */
protected $connection ;
2024-07-04 05:26:17 -04:00
/** @var LoggerInterface */
protected $logger ;
2017-12-20 09:51:37 -05:00
/** @var FunctionBuilder */
protected $functionBuilder ;
2024-07-04 05:26:17 -04:00
public function __construct ( ConnectionAdapter $connection , IQueryBuilder $queryBuilder , LoggerInterface $logger ) {
2017-01-05 05:45:10 -05:00
$this -> connection = $connection ;
2024-07-04 05:26:17 -04:00
$this -> logger = $logger ;
2015-07-07 11:30:26 -04:00
$this -> helper = new QuoteHelper ();
2021-01-03 09:28:31 -05:00
$this -> expressionBuilder = new DoctrineExpressionBuilder ( $connection -> getInner ());
2018-01-12 07:44:30 -05:00
$this -> functionBuilder = $queryBuilder -> func ();
2015-07-06 06:00:01 -04:00
}
/**
* Creates a conjunction of the given boolean expressions .
*
* Example :
*
* [ php ]
* // (u.type = ?) AND (u.role = ?)
* $expr -> andX ( 'u.type = ?' , 'u.role = ?' ));
*
2018-03-13 04:35:09 -04:00
* @ param mixed ... $x Optional clause . Defaults = null , but requires
2015-07-06 06:00:01 -04:00
* at least one defined when converting to string .
*
2015-07-07 11:30:26 -04:00
* @ return \OCP\DB\QueryBuilder\ICompositeExpression
2015-07-06 06:00:01 -04:00
*/
2021-02-15 10:36:20 -05:00
public function andX ( ... $x ) : ICompositeExpression {
2024-07-04 05:26:17 -04:00
if ( empty ( $x )) {
$this -> logger -> debug ( 'Calling ' . IQueryBuilder :: class . '::' . __FUNCTION__ . ' without parameters is deprecated and will throw soon.' , [ 'exception' => new \Exception ( 'No parameters in call to ' . __METHOD__ )]);
}
2024-07-05 09:03:50 -04:00
return new CompositeExpression ( CompositeExpression :: TYPE_AND , $x );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a disjunction of the given boolean expressions .
*
* Example :
*
* [ php ]
* // (u.type = ?) OR (u.role = ?)
* $qb -> where ( $qb -> expr () -> orX ( 'u.type = ?' , 'u.role = ?' ));
*
2018-03-13 04:35:09 -04:00
* @ param mixed ... $x Optional clause . Defaults = null , but requires
2015-07-06 06:00:01 -04:00
* at least one defined when converting to string .
*
2015-07-07 11:30:26 -04:00
* @ return \OCP\DB\QueryBuilder\ICompositeExpression
2015-07-06 06:00:01 -04:00
*/
2021-02-15 10:36:20 -05:00
public function orX ( ... $x ) : ICompositeExpression {
2024-07-04 05:26:17 -04:00
if ( empty ( $x )) {
$this -> logger -> debug ( 'Calling ' . IQueryBuilder :: class . '::' . __FUNCTION__ . ' without parameters is deprecated and will throw soon.' , [ 'exception' => new \Exception ( 'No parameters in call to ' . __METHOD__ )]);
}
2024-07-05 09:03:50 -04:00
return new CompositeExpression ( CompositeExpression :: TYPE_OR , $x );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a comparison expression .
*
* @ param mixed $x The left expression .
2016-01-26 05:27:35 -05:00
* @ param string $operator One of the IExpressionBuilder ::* constants .
2015-07-06 06:00:01 -04:00
* @ param mixed $y The right expression .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function comparison ( $x , string $operator , $y , $type = null ) : string {
2021-04-13 10:57:48 -04:00
$x = $this -> prepareColumn ( $x , $type );
$y = $this -> prepareColumn ( $y , $type );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> comparison ( $x , $operator , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates an equality comparison expression with the given arguments .
*
* First argument is considered the left expression and the second is the right expression .
* When converted to string , it will generated a < left expr > = < right expr >. Example :
*
* [ php ]
* // u.id = ?
* $expr -> eq ( 'u.id' , '?' );
*
* @ param mixed $x The left expression .
* @ param mixed $y The right expression .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
2016-01-18 10:03:41 -05:00
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function eq ( $x , $y , $type = null ) : string {
2021-04-13 10:57:48 -04:00
$x = $this -> prepareColumn ( $x , $type );
$y = $this -> prepareColumn ( $y , $type );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> eq ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a non equality comparison expression with the given arguments .
* First argument is considered the left expression and the second is the right expression .
* When converted to string , it will generated a < left expr > <> < right expr >. Example :
*
* [ php ]
* // u.id <> 1
* $q -> where ( $q -> expr () -> neq ( 'u.id' , '1' ));
*
* @ param mixed $x The left expression .
* @ param mixed $y The right expression .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function neq ( $x , $y , $type = null ) : string {
2021-04-13 10:57:48 -04:00
$x = $this -> prepareColumn ( $x , $type );
$y = $this -> prepareColumn ( $y , $type );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> neq ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a lower - than comparison expression with the given arguments .
* First argument is considered the left expression and the second is the right expression .
* When converted to string , it will generated a < left expr > < < right expr >. Example :
*
* [ php ]
* // u.id < ?
* $q -> where ( $q -> expr () -> lt ( 'u.id' , '?' ));
*
* @ param mixed $x The left expression .
* @ param mixed $y The right expression .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function lt ( $x , $y , $type = null ) : string {
2021-04-13 10:57:48 -04:00
$x = $this -> prepareColumn ( $x , $type );
$y = $this -> prepareColumn ( $y , $type );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> lt ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a lower - than - equal comparison expression with the given arguments .
* First argument is considered the left expression and the second is the right expression .
* When converted to string , it will generated a < left expr > <= < right expr >. Example :
*
* [ php ]
* // u.id <= ?
* $q -> where ( $q -> expr () -> lte ( 'u.id' , '?' ));
*
* @ param mixed $x The left expression .
* @ param mixed $y The right expression .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function lte ( $x , $y , $type = null ) : string {
2021-04-13 10:57:48 -04:00
$x = $this -> prepareColumn ( $x , $type );
$y = $this -> prepareColumn ( $y , $type );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> lte ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a greater - than comparison expression with the given arguments .
* First argument is considered the left expression and the second is the right expression .
* When converted to string , it will generated a < left expr > > < right expr >. Example :
*
* [ php ]
* // u.id > ?
* $q -> where ( $q -> expr () -> gt ( 'u.id' , '?' ));
*
* @ param mixed $x The left expression .
* @ param mixed $y The right expression .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function gt ( $x , $y , $type = null ) : string {
2021-04-13 10:57:48 -04:00
$x = $this -> prepareColumn ( $x , $type );
$y = $this -> prepareColumn ( $y , $type );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> gt ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a greater - than - equal comparison expression with the given arguments .
* First argument is considered the left expression and the second is the right expression .
* When converted to string , it will generated a < left expr > >= < right expr >. Example :
*
* [ php ]
* // u.id >= ?
* $q -> where ( $q -> expr () -> gte ( 'u.id' , '?' ));
*
* @ param mixed $x The left expression .
* @ param mixed $y The right expression .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function gte ( $x , $y , $type = null ) : string {
2021-04-13 10:57:48 -04:00
$x = $this -> prepareColumn ( $x , $type );
$y = $this -> prepareColumn ( $y , $type );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> gte ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates an IS NULL expression with the given arguments .
*
2021-02-15 10:36:20 -05:00
* @ param string | ILiteral | IParameter | IQueryFunction $x The field in string format to be restricted by IS NULL .
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function isNull ( $x ) : string {
2015-07-07 11:30:26 -04:00
$x = $this -> helper -> quoteColumnName ( $x );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> isNull ( $x );
2015-07-06 06:00:01 -04:00
}
/**
* Creates an IS NOT NULL expression with the given arguments .
*
2021-02-15 10:36:20 -05:00
* @ param string | ILiteral | IParameter | IQueryFunction $x The field in string format to be restricted by IS NOT NULL .
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function isNotNull ( $x ) : string {
2015-07-07 11:30:26 -04:00
$x = $this -> helper -> quoteColumnName ( $x );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> isNotNull ( $x );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a LIKE () comparison expression with the given arguments .
*
2020-10-02 12:59:53 -04:00
* @ param ILiteral | IParameter | IQueryFunction | string $x Field in string format to be inspected by LIKE () comparison .
2015-07-06 06:00:01 -04:00
* @ param mixed $y Argument to be used in LIKE () comparison .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function like ( $x , $y , $type = null ) : string {
2015-07-07 11:30:26 -04:00
$x = $this -> helper -> quoteColumnName ( $x );
$y = $this -> helper -> quoteColumnName ( $y );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> like ( $x , $y );
2015-07-06 06:00:01 -04:00
}
2016-02-22 13:46:37 -05:00
/**
* Creates a ILIKE () comparison expression with the given arguments .
*
* @ param string $x Field in string format to be inspected by ILIKE () comparison .
* @ param mixed $y Argument to be used in ILIKE () comparison .
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
*
2022-06-20 11:53:20 -04:00
* @ return string
2016-02-22 13:46:37 -05:00
* @ since 9.0 . 0
*/
2022-06-20 11:53:20 -04:00
public function iLike ( $x , $y , $type = null ) : string {
return $this -> expressionBuilder -> like ( $this -> functionBuilder -> lower ( $x ), $this -> functionBuilder -> lower ( $y ));
2016-02-22 13:46:37 -05:00
}
2015-07-06 06:00:01 -04:00
/**
* Creates a NOT LIKE () comparison expression with the given arguments .
*
2020-10-02 12:59:53 -04:00
* @ param ILiteral | IParameter | IQueryFunction | string $x Field in string format to be inspected by NOT LIKE () comparison .
2015-07-06 06:00:01 -04:00
* @ param mixed $y Argument to be used in NOT LIKE () comparison .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function notLike ( $x , $y , $type = null ) : string {
2015-07-07 11:30:26 -04:00
$x = $this -> helper -> quoteColumnName ( $x );
$y = $this -> helper -> quoteColumnName ( $y );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> notLike ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a IN () comparison expression with the given arguments .
*
2020-10-02 12:59:53 -04:00
* @ param ILiteral | IParameter | IQueryFunction | string $x The field in string format to be inspected by IN () comparison .
2020-10-02 13:09:28 -04:00
* @ param ILiteral | IParameter | IQueryFunction | string | array $y The placeholder or the array of values to be used by IN () comparison .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function in ( $x , $y , $type = null ) : string {
2015-07-07 11:30:26 -04:00
$x = $this -> helper -> quoteColumnName ( $x );
$y = $this -> helper -> quoteColumnNames ( $y );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> in ( $x , $y );
2015-07-06 06:00:01 -04:00
}
/**
* Creates a NOT IN () comparison expression with the given arguments .
*
2020-10-02 12:59:53 -04:00
* @ param ILiteral | IParameter | IQueryFunction | string $x The field in string format to be inspected by NOT IN () comparison .
2020-10-02 13:09:28 -04:00
* @ param ILiteral | IParameter | IQueryFunction | string | array $y The placeholder or the array of values to be used by NOT IN () comparison .
2016-01-26 05:27:35 -05:00
* @ param mixed | null $type one of the IQueryBuilder :: PARAM_ * constants
* required when comparing text fields for oci compatibility
2015-07-06 06:00:01 -04:00
*
2022-06-20 11:53:20 -04:00
* @ return string
2015-07-06 06:00:01 -04:00
*/
2022-06-20 11:53:20 -04:00
public function notIn ( $x , $y , $type = null ) : string {
2015-07-07 11:30:26 -04:00
$x = $this -> helper -> quoteColumnName ( $x );
$y = $this -> helper -> quoteColumnNames ( $y );
2022-06-20 11:53:20 -04:00
return $this -> expressionBuilder -> notIn ( $x , $y );
2015-07-06 06:00:01 -04:00
}
2017-07-25 09:34:59 -04:00
/**
* Creates a $x = '' statement , because Oracle needs a different check
*
2021-02-15 10:36:20 -05:00
* @ param string | ILiteral | IParameter | IQueryFunction $x The field in string format to be inspected by the comparison .
2022-06-20 11:53:20 -04:00
* @ return string
2017-07-25 09:34:59 -04:00
* @ since 13.0 . 0
*/
2022-06-20 11:53:20 -04:00
public function emptyString ( $x ) : string {
return $this -> eq ( $x , $this -> literal ( '' , IQueryBuilder :: PARAM_STR ));
2017-07-25 09:34:59 -04:00
}
/**
* Creates a `$x <> ''` statement , because Oracle needs a different check
*
2021-02-15 10:36:20 -05:00
* @ param string | ILiteral | IParameter | IQueryFunction $x The field in string format to be inspected by the comparison .
2022-06-20 11:53:20 -04:00
* @ return string
2017-07-25 09:34:59 -04:00
* @ since 13.0 . 0
*/
2022-06-20 11:53:20 -04:00
public function nonEmptyString ( $x ) : string {
return $this -> neq ( $x , $this -> literal ( '' , IQueryBuilder :: PARAM_STR ));
2017-07-25 09:34:59 -04:00
}
2017-01-05 05:45:10 -05:00
/**
* Binary AND Operator copies a bit to the result if it exists in both operands .
*
* @ param string | ILiteral $x The field or value to check
* @ param int $y Bitmap that must be set
* @ return IQueryFunction
* @ since 12.0 . 0
*/
2021-02-15 10:36:20 -05:00
public function bitwiseAnd ( $x , int $y ) : IQueryFunction {
2017-01-05 05:45:10 -05:00
return new QueryFunction ( $this -> connection -> getDatabasePlatform () -> getBitAndComparisonExpression (
$this -> helper -> quoteColumnName ( $x ),
$y
));
}
/**
* Binary OR Operator copies a bit if it exists in either operand .
*
* @ param string | ILiteral $x The field or value to check
* @ param int $y Bitmap that must be set
* @ return IQueryFunction
* @ since 12.0 . 0
*/
2021-02-15 10:36:20 -05:00
public function bitwiseOr ( $x , int $y ) : IQueryFunction {
2017-01-05 05:45:10 -05:00
return new QueryFunction ( $this -> connection -> getDatabasePlatform () -> getBitOrComparisonExpression (
$this -> helper -> quoteColumnName ( $x ),
$y
));
}
2015-07-06 06:00:01 -04:00
/**
* Quotes a given input parameter .
*
* @ param mixed $input The parameter to be quoted .
2021-10-21 06:41:01 -04:00
* @ param int $type One of the IQueryBuilder :: PARAM_ * constants
2015-07-06 06:00:01 -04:00
*
2017-01-05 05:45:10 -05:00
* @ return ILiteral
2015-07-06 06:00:01 -04:00
*/
2021-10-21 06:41:01 -04:00
public function literal ( $input , $type = IQueryBuilder :: PARAM_STR ) : ILiteral {
2015-07-07 11:30:26 -04:00
return new Literal ( $this -> expressionBuilder -> literal ( $input , $type ));
2015-07-06 06:00:01 -04:00
}
2016-02-05 09:32:34 -05:00
/**
* Returns a IQueryFunction that casts the column to the given type
*
2021-07-07 08:20:24 -04:00
* @ param string | IQueryFunction $column
2016-02-05 09:32:34 -05:00
* @ param mixed $type One of IQueryBuilder :: PARAM_ *
2022-01-04 11:32:07 -05:00
* @ psalm - param IQueryBuilder :: PARAM_ * $type
2021-02-15 10:36:20 -05:00
* @ return IQueryFunction
2016-02-05 09:32:34 -05:00
*/
2021-07-07 08:20:24 -04:00
public function castColumn ( $column , $type ) : IQueryFunction {
2016-02-05 09:32:34 -05:00
return new QueryFunction (
$this -> helper -> quoteColumnName ( $column )
);
}
2021-04-13 10:57:48 -04:00
/**
* @ param mixed $column
* @ param mixed | null $type
* @ return array | IQueryFunction | string
*/
protected function prepareColumn ( $column , $type ) {
return $this -> helper -> quoteColumnNames ( $column );
}
2015-07-06 06:00:01 -04:00
}