Skip to content

Commit

Permalink
feat: add ilike operator for Criterion (#4114)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndr-brt committed Apr 15, 2024
1 parent 949a7ed commit 5008004
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 6 deletions.
Expand Up @@ -42,6 +42,7 @@ public static CriterionOperatorRegistry ofDefaults() {
registry.registerOperatorPredicate(EQUAL, new EqualOperatorPredicate());
registry.registerOperatorPredicate(IN, new InOperatorPredicate());
registry.registerOperatorPredicate(LIKE, new LikeOperatorPredicate());
registry.registerOperatorPredicate(ILIKE, new IlikeOperatorPredicate());
registry.registerOperatorPredicate(CONTAINS, new ContainsOperatorPredicate());
return registry;
}
Expand Down
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.query;

import org.eclipse.edc.spi.query.OperatorPredicate;

import java.util.regex.Pattern;

public class IlikeOperatorPredicate implements OperatorPredicate {
@Override
public boolean test(Object property, Object operandRight) {
if (operandRight instanceof String stringOperand) {
var regexPattern = Pattern.quote(stringOperand.toLowerCase())
.replace("%", "\\E.*\\Q")
.replace("_", "\\E.\\Q");

return Pattern.compile("^" + regexPattern + "$")
.matcher(property.toString().toLowerCase())
.matches();
}

return false;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.query;

import org.eclipse.edc.spi.query.OperatorPredicate;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class IlikeOperatorPredicateTest {

private final OperatorPredicate predicate = new IlikeOperatorPredicate();

@Test
void shouldHandlePercentAtTheStartOfTheString() {
assertThat(predicate.test("THIS IS A TEST", "%test")).isTrue();
assertThat(predicate.test("NOT TESTED", "%test")).isFalse();
}

@Test
void shouldHandlePercentAtTheEndOfTheString() {
assertThat(predicate.test("TEST VALID", "test%")).isTrue();
assertThat(predicate.test(" TEST INVALID", "test%")).isFalse();
}

@Test
void shouldHandlePercentAtTheStartAndEndOfTheString() {
assertThat(predicate.test("THIS TEST VALID", "%test%")).isTrue();
assertThat(predicate.test("TEST ALSO VALID", "%test%")).isTrue();
assertThat(predicate.test("VALID IS THE TEST", "%test%")).isTrue();
assertThat(predicate.test("INVALID", "%test%")).isFalse();
}

}
Expand Up @@ -18,6 +18,7 @@

import static org.eclipse.edc.spi.query.CriterionOperatorRegistry.CONTAINS;
import static org.eclipse.edc.spi.query.CriterionOperatorRegistry.EQUAL;
import static org.eclipse.edc.spi.query.CriterionOperatorRegistry.ILIKE;
import static org.eclipse.edc.spi.query.CriterionOperatorRegistry.IN;
import static org.eclipse.edc.spi.query.CriterionOperatorRegistry.LIKE;

Expand All @@ -31,6 +32,7 @@ public SqlOperator translate(String operator) {
return switch (operator) {
case EQUAL -> new SqlOperator("=", Object.class);
case LIKE -> new SqlOperator("like", String.class);
case ILIKE -> new SqlOperator("ilike", String.class);
case IN -> new SqlOperator("in", Collection.class);
case CONTAINS -> new SqlOperator("??", Object.class);
default -> null;
Expand Down
Expand Up @@ -40,6 +40,14 @@ void shouldTranslate_like() {
assertThat(operator.rightOperandClass()).isEqualTo(String.class);
}

@Test
void shouldTranslate_ilike() {
var operator = translator.translate("ilike");

assertThat(operator.representation()).isEqualTo("ilike");
assertThat(operator.rightOperandClass()).isEqualTo(String.class);
}

@Test
void shouldTranslate_in() {
var operator = translator.translate("in");
Expand Down
Expand Up @@ -24,6 +24,7 @@ public interface CriterionOperatorRegistry {
String EQUAL = "=";
String IN = "in";
String LIKE = "like";
String ILIKE = "ilike";
String CONTAINS = "contains";

/**
Expand Down
Expand Up @@ -211,10 +211,7 @@ void shouldReturnAllTheAssets_whenQuerySpecIsEmpty() {
@Test
@DisplayName("Query assets with query spec")
void limit() {
for (var i = 1; i <= 10; i++) {
var asset = getAsset("id" + i);
getAssetIndex().create(asset);
}
range(1, 10).mapToObj(it -> getAsset("id" + it)).forEach(asset -> getAssetIndex().create(asset));
var querySpec = QuerySpec.Builder.newInstance().limit(3).offset(2).build();

var assetsFound = getAssetIndex().queryAssets(querySpec);
Expand Down Expand Up @@ -405,8 +402,7 @@ void withPrivateSorting() {
}

@Test
@DisplayName("Query assets using the LIKE operator")
void like() {
void shouldFilter_whenLikeOperator() {
var asset1 = getAsset("id1");
getAssetIndex().create(asset1);
var asset2 = getAsset("id2");
Expand All @@ -418,6 +414,17 @@ void like() {
assertThat(assetsFound).isNotNull().hasSize(2);
}

@Test
void shouldFilter_whenIlikeOperator() {
getAssetIndex().create(getAsset("ID1"));
getAssetIndex().create(getAsset("ID2"));
var criterion = new Criterion(Asset.PROPERTY_ID, "ilike", "id%");

var assetsFound = getAssetIndex().queryAssets(filter(criterion));

assertThat(assetsFound).isNotNull().hasSize(2);
}

@Test
@DisplayName("Query assets using the LIKE operator on a json value")
void likeJson() throws JsonProcessingException {
Expand Down

0 comments on commit 5008004

Please sign in to comment.