GH-1862 - Support combining startingWith and endingWith with IgnoreCase in derived queries.
This closes #1862
This commit is contained in:
@@ -17,8 +17,11 @@ package org.springframework.data.neo4j.repository.query.filter;
|
||||
|
||||
import static org.springframework.data.repository.query.parser.Part.Type.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.neo4j.ogm.cypher.BooleanOperator;
|
||||
@@ -34,6 +37,17 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
class PropertyComparisonBuilder extends FilterBuilder {
|
||||
|
||||
private static final Set<Part.Type> TYPES_SUPPORTING_IGNORE_CASE;
|
||||
|
||||
static {
|
||||
Set<Part.Type> typesSupportingIgnoreCase = new HashSet<>();
|
||||
typesSupportingIgnoreCase.add(SIMPLE_PROPERTY);
|
||||
typesSupportingIgnoreCase.add(CONTAINING);
|
||||
typesSupportingIgnoreCase.add(STARTING_WITH);
|
||||
typesSupportingIgnoreCase.add(ENDING_WITH);
|
||||
TYPES_SUPPORTING_IGNORE_CASE = Collections.unmodifiableSet(typesSupportingIgnoreCase);
|
||||
}
|
||||
|
||||
PropertyComparisonBuilder(Part part, BooleanOperator booleanOperator, Class<?> entityType) {
|
||||
super(part, booleanOperator, entityType);
|
||||
}
|
||||
@@ -128,7 +142,6 @@ class PropertyComparisonBuilder extends FilterBuilder {
|
||||
}
|
||||
|
||||
private boolean isSupportedIgnoreKeyword(Part part) {
|
||||
Part.Type type = part.getType();
|
||||
return type == SIMPLE_PROPERTY || type == CONTAINING;
|
||||
return TYPES_SUPPORTING_IGNORE_CASE.contains(part.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
@@ -370,23 +372,26 @@ public class RestaurantTests {
|
||||
assertEquals(0, results.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* All findByPropertyLike does currently is to require an exact match, ignoring case.
|
||||
*/
|
||||
@Test // DATAGRAPH-904
|
||||
public void shouldFindByNameNotLike() {
|
||||
|
||||
void runTestThatShouldReturnOnlySFO(Supplier<List<Restaurant>> restaurantSupplier) {
|
||||
Restaurant restaurant = new Restaurant("San Francisco International Airport (SFO)", 68.0);
|
||||
restaurantRepository.save(restaurant);
|
||||
|
||||
Restaurant kuroda = new Restaurant("Kuroda", 72.4);
|
||||
restaurantRepository.save(kuroda);
|
||||
|
||||
List<Restaurant> results = restaurantRepository.findByNameNotLike("kuroda");
|
||||
List<Restaurant> results = restaurantSupplier.get();
|
||||
assertNotNull(results);
|
||||
assertEquals(1, results.size());
|
||||
assertEquals("San Francisco International Airport (SFO)", results.get(0).getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* All findByPropertyLike does currently is to require an exact match, ignoring case.
|
||||
*/
|
||||
@Test // DATAGRAPH-904
|
||||
public void shouldFindByNameNotLike() {
|
||||
|
||||
runTestThatShouldReturnOnlySFO(() -> restaurantRepository.findByNameNotLike("kuroda"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,49 +400,32 @@ public class RestaurantTests {
|
||||
@Test // DATAGRAPH-904
|
||||
public void shouldFindByNameLike() {
|
||||
|
||||
Restaurant restaurant = new Restaurant("San Francisco International Airport (SFO)", 68.0);
|
||||
restaurantRepository.save(restaurant);
|
||||
|
||||
Restaurant kuroda = new Restaurant("Kuroda", 72.4);
|
||||
restaurantRepository.save(kuroda);
|
||||
|
||||
List<Restaurant> results = restaurantRepository.findByNameLike("*san francisco international*");
|
||||
assertNotNull(results);
|
||||
assertEquals(1, results.size());
|
||||
assertEquals("San Francisco International Airport (SFO)", results.get(0).getName());
|
||||
|
||||
runTestThatShouldReturnOnlySFO(() -> restaurantRepository.findByNameLike("*san francisco international*"));
|
||||
}
|
||||
|
||||
@Test // DATAGRAPH-904
|
||||
public void shouldFindByNameStartingWith() {
|
||||
|
||||
Restaurant restaurant = new Restaurant("San Francisco International Airport (SFO)", 68.0);
|
||||
restaurantRepository.save(restaurant);
|
||||
runTestThatShouldReturnOnlySFO(() -> restaurantRepository.findByNameStartingWith("San Francisco"));
|
||||
|
||||
Restaurant kuroda = new Restaurant("Kuroda", 72.4);
|
||||
restaurantRepository.save(kuroda);
|
||||
}
|
||||
|
||||
List<Restaurant> results = restaurantRepository.findByNameStartingWith("San Francisco");
|
||||
assertNotNull(results);
|
||||
assertEquals(1, results.size());
|
||||
assertEquals("San Francisco International Airport (SFO)", results.get(0).getName());
|
||||
@Test // DATAGRAPH-1862
|
||||
public void shouldFindByNameStartingWithIgnoringCase() {
|
||||
|
||||
runTestThatShouldReturnOnlySFO(() -> restaurantRepository.findByNameStartingWithIgnoreCase("San Francisco".toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
@Test // DATAGRAPH-904
|
||||
public void shouldFindByNameEndingWith() {
|
||||
|
||||
Restaurant restaurant = new Restaurant("San Francisco International Airport (SFO)", 68.0);
|
||||
restaurantRepository.save(restaurant);
|
||||
runTestThatShouldReturnOnlySFO(() -> restaurantRepository.findByNameEndingWith("Airport (SFO)"));
|
||||
}
|
||||
|
||||
Restaurant kuroda = new Restaurant("Kuroda", 72.4);
|
||||
restaurantRepository.save(kuroda);
|
||||
|
||||
List<Restaurant> results = restaurantRepository.findByNameEndingWith("Airport (SFO)");
|
||||
assertNotNull(results);
|
||||
assertEquals(1, results.size());
|
||||
assertEquals("San Francisco International Airport (SFO)", results.get(0).getName());
|
||||
@Test // DATAGRAPH-1862
|
||||
public void shouldFindByNameEndingWithIgnoringCase() {
|
||||
|
||||
runTestThatShouldReturnOnlySFO(() -> restaurantRepository.findByNameEndingWithIgnoreCase("Airport (SFO)".toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
@Test // DATAGRAPH-904
|
||||
@@ -510,17 +498,7 @@ public class RestaurantTests {
|
||||
@Test // DATAGRAPH-904
|
||||
public void shouldFindByNameMatchesRegEx() {
|
||||
|
||||
Restaurant restaurant = new Restaurant("San Francisco International Airport (SFO)", 68.0);
|
||||
restaurantRepository.save(restaurant);
|
||||
|
||||
Restaurant kuroda = new Restaurant("Kuroda", 72.4);
|
||||
restaurantRepository.save(kuroda);
|
||||
|
||||
List<Restaurant> results = restaurantRepository.findByNameMatchesRegex("(?i)san francisco.*");
|
||||
assertNotNull(results);
|
||||
assertEquals(1, results.size());
|
||||
assertEquals("San Francisco International Airport (SFO)", results.get(0).getName());
|
||||
|
||||
runTestThatShouldReturnOnlySFO(() -> restaurantRepository.findByNameMatchesRegex("(?i)san francisco.*"));
|
||||
}
|
||||
|
||||
@Test // DATAGRAPH-904
|
||||
|
||||
@@ -61,8 +61,12 @@ public interface RestaurantRepository extends Neo4jRepository<Restaurant, Long>
|
||||
|
||||
List<Restaurant> findByNameStartingWith(String string);
|
||||
|
||||
List<Restaurant> findByNameStartingWithIgnoreCase(String string);
|
||||
|
||||
List<Restaurant> findByNameEndingWith(String string);
|
||||
|
||||
List<Restaurant> findByNameEndingWithIgnoreCase(String string);
|
||||
|
||||
List<Restaurant> findByNameContaining(String string);
|
||||
|
||||
List<Restaurant> findByNameNotContaining(String string);
|
||||
|
||||
Reference in New Issue
Block a user