mirror of
https://github.com/nextcloud/server.git
synced 2026-06-29 12:24:50 +02:00
feat: Add support for NOT ILIKE in query builder expressions
Signed-off-by: Kostiantyn Miakshyn <molodchick@gmail.com>
This commit is contained in:
@@ -315,6 +315,26 @@ class ExpressionBuilder implements IExpressionBuilder {
|
||||
return $this->expressionBuilder->notLike($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a NOT ILIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $x Field in string format to be inspected by NOT ILIKE() comparison.
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $y Argument to be used in NOT ILIKE() comparison.
|
||||
* @param int|string|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
* @return string
|
||||
* @since 35.0.0
|
||||
*/
|
||||
#[\Override]
|
||||
public function notILike(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
return $this->expressionBuilder->notLike((string)$this->functionBuilder->lower($x), (string)$this->functionBuilder->lower($y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a IN () comparison expression with the given arguments.
|
||||
*
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace OC\DB\QueryBuilder\ExpressionBuilder;
|
||||
|
||||
use OC\DB\ConnectionAdapter;
|
||||
use OC\DB\QueryBuilder\QueryFunction;
|
||||
use OCP\DB\QueryBuilder\ILiteral;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -34,6 +36,17 @@ class MySqlExpressionBuilder extends ExpressionBuilder {
|
||||
return $this->expressionBuilder->comparison($x, ' COLLATE ' . $this->collation . ' LIKE', $y);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function notILike(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->comparison($x, ' COLLATE ' . $this->collation . ' NOT LIKE', $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a IQueryFunction that casts the column to the given type
|
||||
*
|
||||
|
||||
@@ -140,4 +140,13 @@ class OCIExpressionBuilder extends ExpressionBuilder {
|
||||
public function iLike($x, $y, $type = null): string {
|
||||
return $this->like($this->functionBuilder->lower($x), $this->functionBuilder->lower($y));
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function notILike(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
return $this->notLike($this->functionBuilder->lower($x), $this->functionBuilder->lower($y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,4 +57,15 @@ class PgSqlExpressionBuilder extends ExpressionBuilder {
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->comparison($x, 'ILIKE', $y);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function notILike(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->comparison($x, 'NOT ILIKE', $y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,15 @@ class SqliteExpressionBuilder extends ExpressionBuilder {
|
||||
return $this->like($this->functionBuilder->lower($x), $this->functionBuilder->lower($y), $type);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function notILike(
|
||||
string|IParameter|ILiteral|IQueryFunction $x,
|
||||
string|IParameter|ILiteral|IQueryFunction $y,
|
||||
int|string|null $type = null,
|
||||
): string {
|
||||
return $this->notLike($this->functionBuilder->lower($x), $this->functionBuilder->lower($y), $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $column
|
||||
* @param mixed|null $type
|
||||
|
||||
@@ -315,6 +315,24 @@ interface IExpressionBuilder {
|
||||
*/
|
||||
public function iLike($x, $y, $type = null): string;
|
||||
|
||||
/**
|
||||
* Creates a NOT ILIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $x Field in string format to be inspected by NOT LIKE() comparison.
|
||||
* @param ILiteral|IParameter|IQueryFunction|string $y Argument to be used in NOT ILIKE() comparison.
|
||||
* @param IQueryBuilder::PARAM_*|null $type one of the IQueryBuilder::PARAM_* constants
|
||||
* required when comparing text fields for oci compatibility
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
* @since 35.0.0
|
||||
*
|
||||
* @psalm-taint-sink sql $x
|
||||
* @psalm-taint-sink sql $y
|
||||
* @psalm-taint-sink sql $type
|
||||
*/
|
||||
public function notILike(string|IParameter|ILiteral|IQueryFunction $x, string|IParameter|ILiteral|IQueryFunction $y, int|string|null $type = null): string;
|
||||
|
||||
/**
|
||||
* Creates a IN () comparison expression with the given arguments.
|
||||
*
|
||||
|
||||
@@ -103,6 +103,43 @@ class ExpressionBuilderDBTest extends TestCase {
|
||||
$this->assertEquals($match, $column);
|
||||
}
|
||||
|
||||
public static function notILikeProvider(): array {
|
||||
$connection = Server::get(IDBConnection::class);
|
||||
|
||||
return [
|
||||
['foo', 'bar', true],
|
||||
['foo', 'foo', false],
|
||||
['foo', 'Foo', false],
|
||||
['foo', 'f%', false],
|
||||
['foo', '%o', false],
|
||||
['foo', '%', false],
|
||||
['foo', 'fo_', false],
|
||||
['foo', 'foo_', true],
|
||||
['foo', $connection->escapeLikeParameter('fo_'), true],
|
||||
['foo', $connection->escapeLikeParameter('f%'), true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $param1
|
||||
* @param string $param2
|
||||
* @param boolean $match
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('notILikeProvider')]
|
||||
public function testNotILike($param1, $param2, $match): void {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
$query->select(new Literal('1'))
|
||||
->from('users')
|
||||
->where($query->expr()->notILike($query->createNamedParameter($param1), $query->createNamedParameter($param2)));
|
||||
|
||||
$result = $query->executeQuery();
|
||||
$column = $result->fetchOne();
|
||||
$result->closeCursor();
|
||||
$this->assertEquals($match, $column);
|
||||
}
|
||||
|
||||
public function testCastColumn(): void {
|
||||
$appId = $this->getUniqueID('testing');
|
||||
$this->createConfig($appId, '1', '4');
|
||||
|
||||
@@ -194,6 +194,18 @@ class ExpressionBuilderTest extends TestCase {
|
||||
);
|
||||
}
|
||||
|
||||
public function testILike(): void {
|
||||
// iLike is implemented using lower() on both sides, so we just verify it returns a string
|
||||
$result = $this->expressionBuilder->iLike('test', 'value');
|
||||
$this->assertIsString($result);
|
||||
}
|
||||
|
||||
public function testNotILike(): void {
|
||||
// notILike is implemented using notLike with lower() on both sides, so we just verify it returns a string
|
||||
$result = $this->expressionBuilder->notILike('test', 'value');
|
||||
$this->assertIsString($result);
|
||||
}
|
||||
|
||||
public static function dataIn(): array {
|
||||
return [
|
||||
['value', false],
|
||||
@@ -294,6 +306,10 @@ class ExpressionBuilderTest extends TestCase {
|
||||
['like', 'under\_%', IQueryBuilder::PARAM_STR, false, 1],
|
||||
['notLike', '%5%', IQueryBuilder::PARAM_STR, false, 8],
|
||||
['notLike', '%5%', IQueryBuilder::PARAM_STR, true, 6],
|
||||
['iLike', '%5%', IQueryBuilder::PARAM_STR, false, 3],
|
||||
['iLike', '%5%', IQueryBuilder::PARAM_STR, true, 1],
|
||||
['notILike', '%5%', IQueryBuilder::PARAM_STR, false, 8],
|
||||
['notILike', '%5%', IQueryBuilder::PARAM_STR, true, 6],
|
||||
['in', ['5'], IQueryBuilder::PARAM_STR_ARRAY, false, 3],
|
||||
['in', ['5'], IQueryBuilder::PARAM_STR_ARRAY, true, 1],
|
||||
['notIn', ['5'], IQueryBuilder::PARAM_STR_ARRAY, false, 8],
|
||||
|
||||
Reference in New Issue
Block a user