Skip to content

Commit

Permalink
Merge pull request #526 from eclipse/unsupported-contains-ends-with
Browse files Browse the repository at this point in the history
Include IgnoreCase as not supported
  • Loading branch information
otaviojava authored Jun 30, 2024
2 parents 3a982dd + 979445e commit d257d8a
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 42 deletions.
25 changes: 13 additions & 12 deletions antlr4/org/eclipse/jnosql/query/grammar/method/Method.g4
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ asc: 'Asc';
desc: 'Desc';
truth: variable 'True';
untruth: variable 'False';
eq: variable | variable not? 'Equals'| variable not;
gt: variable not? 'GreaterThan';
gte: variable not? 'GreaterThanEqual';
lt: variable not? 'LessThan';
lte: variable not? 'LessThanEqual';
between: variable not? 'Between';
in: variable not? 'In';
like: variable not? 'Like';
contains: variable not? 'Contains';
endsWith: variable not? 'EndsWith';
startsWith: variable not? 'StartsWith';
nullable: variable not? 'Null';
eq: variable | variable ignoreCase? not? 'Equals'?;
gt: variable ignoreCase? not? 'GreaterThan';
gte: variable ignoreCase? not? 'GreaterThanEqual';
lt: variable ignoreCase? not? 'LessThan';
lte: variable ignoreCase? not? 'LessThanEqual';
between: variable ignoreCase? not? 'Between';
in: variable ignoreCase? not? 'In';
like: variable ignoreCase? not? 'Like';
contains: variable ignoreCase? not? 'Contains';
endsWith: variable ignoreCase? not? 'EndsWith';
startsWith: variable ignoreCase? not? 'StartsWith';
nullable: variable ignoreCase? not? 'Null';
ignoreCase: 'IgnoreCase';
not: 'Not';
variable: ANY_NAME;
max: INT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ public void exitStartsWith(MethodParser.StartsWithContext ctx) {
throw new UnsupportedOperationException("StartsWith is not supported in Eclipse JNoSQL method query");
}

@Override
public void exitIgnoreCase(MethodParser.IgnoreCaseContext ctx) {
throw new UnsupportedOperationException("IgnoreCase is not supported in Eclipse JNoSQL method query");
}

private void appendCondition(boolean hasNot, String variable, Condition operator) {
ParamQueryValue queryValue = new MethodParamQueryValue(variable);
checkCondition(new MethodCondition(variable, operator, queryValue), hasNot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public final class MethodQuery implements Supplier<String> {

private final String value;
private static final Pattern PATTERN = Pattern.compile("findBy|deleteBy|countAll|countBy|existsBy|"
+ "OrderBy|First(?=\\d+By)|(?<=First\\d{1,})By|"
+ "OrderBy|First(?=\\d+By)|(?<=First\\d{1,})By|IgnoreCase|"
+ "And|Or(?!der)|Null|Not|Equals|GreaterThanEqual|True|False|Contains|EndsWith|StartsWith|" +
"LessThanEqual|GreaterThan|LessThan|Between|In|Like|Asc|Desc");
private static final Map<String, String> CACHE = Collections.synchronizedMap(new WeakHashMap<>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,14 +539,14 @@ void shouldReturnParserQuery37(String query) {
}

@ParameterizedTest(name = "Should parser the query {0}")
@ValueSource(strings = {"findByNameContains", "findByNameEndsWith", "findByNameStartsWith"})
@ValueSource(strings = {"findByNameContains", "findByNameEndsWith", "findByNameStartsWith", "findByStreetNameIgnoreCaseLike", "findByHexadecimalIgnoreCase"})
void shouldReturnUnsupportedOperationExceptionQuery(String query) {
String entity = "entity";
Assertions.assertThrows(UnsupportedOperationException.class, () -> queryProvider.apply(query, entity));
}

@ParameterizedTest(name = "Should parser the query {0}")
@ValueSource(strings = {"findByNameNotContains", "findByNameNotEndsWith", "findByNameNotStartsWith"})
@ValueSource(strings = {"findByNameNotContains", "findByNameNotEndsWith", "findByNameNotStartsWith", "findByStreetNameIgnoreCaseNotLike", "findByHexadecimalIgnoreCaseNot"})
void shouldReturnUnsupportedOperationExceptionQueryWithNegation(String query) {
String entity = "entity";
Assertions.assertThrows(UnsupportedOperationException.class, () -> queryProvider.apply(query, entity));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ public CommunicationPreparedStatement prepare(String query, String entity, Datab
}

private String extractQueryCommand(String query){
if(query.length() < 6){
return "";
}
return query.substring(0, 6).toUpperCase();
}

private void validation(String query, DatabaseManager manager, CommunicationObserverParser observer) {
Objects.requireNonNull(query, "query is required");
Objects.requireNonNull(manager, "manager is required");
Objects.requireNonNull(observer, "manager is observer");
if (query.length() < 6) {
throw new QueryException(String.format("The query %s is invalid", query));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,14 @@ public static Function<Supplier<Stream<?>>, Supplier<Optional<?>>> toSingleResul
* Finds {@link SpecialParameters} from array object
*
* @param params the params
* @param sortParser the sort parser
* @return a {@link SpecialParameters} instance
*/
public static SpecialParameters findSpecialParameters(Object[] params) {
public static SpecialParameters findSpecialParameters(Object[] params, Function<String, String> sortParser) {
if (params == null || params.length == 0) {
return SpecialParameters.EMPTY;
}
return SpecialParameters.of(params);
return SpecialParameters.of(params, sortParser);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
import jakarta.data.Sort;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;

/**
* The repository features has support for specific types like PageRequest and Sort,
Expand Down Expand Up @@ -124,23 +126,25 @@ public String toString() {
'}';
}

static SpecialParameters of(Object[] parameters) {
static SpecialParameters of(Object[] parameters, Function<String, String> sortParser) {
List<Sort<?>> sorts = new ArrayList<>();
PageRequest pageRequest = null;
Limit limit = null;
for (Object parameter : parameters) {
if (parameter instanceof Sort<?> sort) {
sorts.add(sort);
sorts.add(mapper(sort, sortParser));
} else if (parameter instanceof Limit limitInstance) {
limit = limitInstance;
} else if (parameter instanceof Order<?> order) {
order.iterator().forEachRemaining(sorts::add);
order.sorts().stream().map(s -> mapper(s, sortParser)).forEach(sorts::add);
} else if(parameter instanceof Sort<?>[] sortArray){
Arrays.stream(sortArray).map(s -> mapper(s, sortParser)).forEach(sorts::add);
} else if (parameter instanceof PageRequest request) {
pageRequest = request;
} else if (parameter instanceof Iterable<?> iterable) {
for (Object value : iterable) {
if (value instanceof Sort<?> sortValue) {
sorts.add(sortValue);
sorts.add(mapper(sortValue, sortParser));
}
}
}
Expand Down Expand Up @@ -193,4 +197,15 @@ public static boolean isSpecialParameter(Class<?> parameter) {
public static boolean isNotSpecialParameter(Class<?> parameter) {
return !isSpecialParameter(parameter);
}

/**
* Returns the sort with the property updated from the sort parser
* @param sort the sort
* @param sortParser the sort parser
* @return the special parameters
*/
private static Sort<?> mapper(Sort<?> sort, Function<String, String> sortParser) {
var property = sortParser.apply(sort.property());
return sort.isAscending()? Sort.asc(property): Sort.desc(property);
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -36,22 +37,24 @@

class SpecialParametersTest {

private static final Function<String, String> SORT_MAPPER = Function.identity();

@Test
void shouldReturnEmpty() {
SpecialParameters parameters = SpecialParameters.of(new Object[0]);
SpecialParameters parameters = SpecialParameters.of(new Object[0], SORT_MAPPER);
assertTrue(parameters.isEmpty());
}

@Test
void shouldReturnEmptyNonSpecialParameters() {
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio"});
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio"}, SORT_MAPPER);
assertTrue(parameters.isEmpty());
}

@Test
void shouldReturnPageRequest() {
PageRequest pageRequest = PageRequest.ofPage(10);
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", pageRequest});
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", pageRequest}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
Assertions.assertEquals(pageRequest, parameters.pageRequest().orElseThrow());
assertTrue(parameters.isSortEmpty());
Expand All @@ -60,7 +63,7 @@ void shouldReturnPageRequest() {
@Test
void shouldReturnSort() {
Sort<?> sort = Sort.asc("name");
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", sort});
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", sort}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
assertTrue(parameters.hasOnlySort());
assertTrue(parameters.pageRequest().isEmpty());
Expand All @@ -74,7 +77,7 @@ void shouldKeepOrder() {
Sort<?> sort = Sort.asc("name");
PageRequest pageRequest = PageRequest.ofPage(10);

SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", sort, pageRequest});
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", sort, pageRequest}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
assertFalse(parameters.hasOnlySort());
Assertions.assertEquals(pageRequest, parameters.pageRequest().orElseThrow());
Expand All @@ -85,7 +88,7 @@ void shouldKeepOrder() {

@Test
void shouldReturnLimit() {
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", Limit.of(10)});
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", Limit.of(10)}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
Optional<Limit> limit = parameters.limit();
assertTrue(limit.isPresent());
Expand All @@ -97,7 +100,7 @@ void shouldReturnLimit() {
@Test
void shouldReturnIterableSort(){
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio",
List.of(Sort.asc("name"), Sort.desc("age"))});
List.of(Sort.asc("name"), Sort.desc("age"))}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
assertThat(parameters.sorts()).hasSize(2)
.containsExactly(Sort.asc("name"),
Expand All @@ -107,7 +110,7 @@ void shouldReturnIterableSort(){
@Test
void shouldReturnOrder(){
Order<?> order = Order.by(Sort.asc("name"), Sort.desc("age"));
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", order});
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", order}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
assertFalse(parameters.isSortEmpty());
assertThat(parameters.sorts()).hasSize(2)
Expand All @@ -120,7 +123,7 @@ void shouldReturnIterableOrder(){
PageRequest pageRequest = PageRequest.ofPage(10);
Order<?> order = Order.by(Sort.asc("name"));
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio",
List.of(Sort.asc("name"), Sort.desc("age")), pageRequest, order});
List.of(Sort.asc("name"), Sort.desc("age")), pageRequest, order}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
Assertions.assertEquals(pageRequest, parameters.pageRequest().orElseThrow());
assertFalse(parameters.isSortEmpty());
Expand All @@ -129,6 +132,43 @@ void shouldReturnIterableOrder(){
Sort.desc("age"));
}

@Test
void shouldReturnArrayOrder(){
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio",
new Sort[]{Sort.asc("name"), Sort.desc("age")}}, SORT_MAPPER);
assertFalse(parameters.isEmpty());
assertThat(parameters.sorts()).hasSize(2)
.containsExactly(Sort.asc("name"),
Sort.desc("age"));
}

@Test
void shouldReturnOrderMapper(){
Function<String, String> upper = String::toUpperCase;
Order<?> order = Order.by(Sort.asc("name"), Sort.desc("age"));
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio", order}, upper);
assertFalse(parameters.isEmpty());
assertFalse(parameters.isSortEmpty());
assertThat(parameters.sorts()).hasSize(2)
.contains(Sort.asc("NAME"),
Sort.desc("AGE"));
}

@Test
void shouldReturnIterableOrderMapper(){
Function<String, String> upper = String::toUpperCase;
PageRequest pageRequest = PageRequest.ofPage(10);
Order<?> order = Order.by(Sort.asc("name"));
SpecialParameters parameters = SpecialParameters.of(new Object[]{10, "Otavio",
List.of(Sort.asc("name"), Sort.desc("age")), pageRequest, order}, upper);
assertFalse(parameters.isEmpty());
Assertions.assertEquals(pageRequest, parameters.pageRequest().orElseThrow());
assertFalse(parameters.isSortEmpty());
assertThat(parameters.sorts()).hasSize(3)
.contains(Sort.asc("NAME"),
Sort.desc("AGE"));
}

@ParameterizedTest
@ValueSource(classes = {Sort.class, Limit.class, PageRequest.class, Order.class})
void shouldReturnTrueSpecialParameter(Class<?> type){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ public org.eclipse.jnosql.mapping.PreparedStatement prepare(String query, String


@Override
public long count(String columnFamily) {
return manager().count(columnFamily);
public long count(String entity) {
return manager().count(entity);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ protected Object executeQuery(Object instance, Method method, Object[] params) {
protected Object executeCursorPagination(Object instance, Method method, Object[] params) {
if (method.getAnnotation(Find.class) == null) {
var query = query(method, params);
SpecialParameters special = DynamicReturn.findSpecialParameters(params);
SpecialParameters special = DynamicReturn.findSpecialParameters(params, sortParser());
PageRequest pageRequest = special.pageRequest()
.orElseThrow(() -> new IllegalArgumentException("Pageable is required in the method signature as parameter at " + method));
return this.template().selectCursor(query, pageRequest);
} else {
Map<String, Object> parameters = RepositoryReflectionUtils.INSTANCE.getBy(method, params);
var query = SemiStructuredParameterBasedQuery.INSTANCE.toQuery(parameters, getSorts(method, entityMetadata()), entityMetadata());
SpecialParameters special = DynamicReturn.findSpecialParameters(params);
SpecialParameters special = DynamicReturn.findSpecialParameters(params, sortParser());
PageRequest pageRequest = special.pageRequest()
.orElseThrow(() -> new IllegalArgumentException("Pageable is required in the method signature as parameter at " + method));
return this.template().selectCursor(query, pageRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ protected Function<PageRequest, Stream<T>> streamPagination(org.eclipse.jnosql.c
protected org.eclipse.jnosql.communication.semistructured.SelectQuery updateQueryDynamically(Object[] args,
org.eclipse.jnosql.communication.semistructured.SelectQuery query) {
var documentQuery = includeInheritance(query);
SpecialParameters special = DynamicReturn.findSpecialParameters(args);
SpecialParameters special = DynamicReturn.findSpecialParameters(args, sortParser());

if (special.isEmpty()) {
return documentQuery;
Expand Down Expand Up @@ -243,5 +243,9 @@ protected org.eclipse.jnosql.communication.semistructured.SelectQuery updateQuer
}).orElse(documentQuery);
}

protected Function<String, String> sortParser() {
return property -> parser().fireField(entityMetadata().name(), property);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

/**
Expand Down Expand Up @@ -90,12 +91,13 @@ public SelectQuery get() {
* Creates a {@link DynamicQuery} instance
* @param args the method parameters
* @param query the column query
* @param sortParser the sort parser
* @return the {@link DynamicQuery} instance
* @throws NullPointerException when either args or query are null
*/
public static DynamicQuery of(Object[] args, SelectQuery query) {
public static DynamicQuery of(Object[] args, SelectQuery query, Function<String, String> sortParser) {
Objects.requireNonNull(args, "args is required");
Objects.requireNonNull(query, "query is required");
return new DynamicQuery(DynamicReturn.findSpecialParameters(args), query);
return new DynamicQuery(DynamicReturn.findSpecialParameters(args, sortParser), query);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import static org.assertj.core.api.SoftAssertions.assertSoftly;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -139,8 +140,10 @@ void shouldReturnWhenThereIsLimitAndSort(){
when(query.skip()).thenReturn(0L);
when(query.limit()).thenReturn(10L);

Function<String, String> sortParser = Function.identity();

DynamicQuery dynamicQuery = DynamicQuery.of(new Object[]{Sort.asc("name"), Limit.of(20)}
, query);
, query, sortParser);

SelectQuery columnQuery = dynamicQuery.get();
assertEquals("sampleQuery", columnQuery.name());
Expand Down
Loading

0 comments on commit d257d8a

Please sign in to comment.