diff --git a/compat-driver-5.x/src/test/java/com/github/starnowski/jamolingo/compat/driver/operators/filter/FilterOperatorTest.java b/compat-driver-5.x/src/test/java/com/github/starnowski/jamolingo/compat/driver/operators/filter/FilterOperatorTest.java index db36fe6..8277be4 100644 --- a/compat-driver-5.x/src/test/java/com/github/starnowski/jamolingo/compat/driver/operators/filter/FilterOperatorTest.java +++ b/compat-driver-5.x/src/test/java/com/github/starnowski/jamolingo/compat/driver/operators/filter/FilterOperatorTest.java @@ -249,7 +249,8 @@ private static Stream provideShouldReturnExpectedProjectedDocument() } /** - * String comparison is case-sensitive, case-insensitive comparison can be achieved in combination with tolower or toupper. + * String comparison is case-sensitive, case-insensitive comparison can be achieved in combination + * with tolower or toupper. * https://docs.oasis-open.org/odata/odata/v4.01/os/part2-url-conventions/odata-v4.01-os-part2-url-conventions.html#sec_contains * https://docs.oasis-open.org/odata/odata/v4.01/os/part2-url-conventions/odata-v4.01-os-part2-url-conventions.html#sec_endswith * https://docs.oasis-open.org/odata/odata/v4.01/os/part2-url-conventions/odata-v4.01-os-part2-url-conventions.html#sec_startswith diff --git a/demos/quarkus-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoResource.java b/demos/quarkus-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoResource.java index 19d6f83..3205e7b 100644 --- a/demos/quarkus-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoResource.java +++ b/demos/quarkus-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoResource.java @@ -8,8 +8,10 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriInfo; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -24,6 +26,15 @@ public class DemoResource { @Inject MongoClient mongoClient; + @GET + @Path("/query-with-dollar-parameters") + public Map queryWithDollarParameterOperators(@Context UriInfo uriInfo) + throws Exception { + ODataQueryService.QueryPlan plan = + oDataQueryService.buildQueryPlan(uriInfo.getRequestUri().getQuery()); + return executeQueryPlan(plan); + } + @GET @Path("/query") public Map query( diff --git a/demos/quarkus-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoResourceIntegrationTest.java b/demos/quarkus-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoResourceIntegrationTest.java index b975fd3..7502926 100644 --- a/demos/quarkus-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoResourceIntegrationTest.java +++ b/demos/quarkus-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoResourceIntegrationTest.java @@ -95,6 +95,72 @@ public void shouldReturnCount() { .body("'@odata.count'", is(6)); } + @Test + public void shouldFilterByPlainStringWithDollarParameters() { + given() + .queryParam("$filter", "plainString eq 'Poem'") + .when() + .get("/query-with-dollar-parameters") + .then() + .statusCode(200) + .body("value", hasSize(1)) + .body("value[0].plainString", is("Poem")); + } + + @Test + public void shouldOrderAndLimitWithDollarParameters() { + given() + .queryParam("$orderby", "plainString desc") + .queryParam("$top", "2") + .when() + .get("/query-with-dollar-parameters") + .then() + .statusCode(200) + .body("value", hasSize(2)) + .body("value[0].plainString", is("example2")) + .body("value[1].plainString", is("example1")); + } + + @Test + public void shouldSkipAndLimitWithDollarParameters() { + given() + .queryParam("$orderby", "plainString desc") + .queryParam("$skip", "3") + .queryParam("$top", "1") + .when() + .get("/query-with-dollar-parameters") + .then() + .statusCode(200) + .body("value", hasSize(1)) + .body("value[0].plainString", is("Some text")); + } + + @Test + public void shouldSelectFieldsWithDollarParameters() { + given() + .queryParam("$filter", "plainString eq 'Poem'") + .queryParam("$select", "plainString") + .when() + .get("/query-with-dollar-parameters") + .then() + .statusCode(200) + .body("value[0].plainString", is("Poem")) + .body("value[0].tags", is((Object) null)); + } + + @Test + public void shouldReturnCountWithDollarParameters() { + given() + .queryParam("$filter", "contains(plainString, 'e')") + .queryParam("$count", "true") + .when() + .get("/query-with-dollar-parameters") + .then() + .statusCode(200) + .body("value", hasSize(6)) + .body("'@odata.count'", is(6)); + } + @Test public void shouldReturn400WhenNoIndexUsed() { given() diff --git a/demos/spring-boot-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoController.java b/demos/spring-boot-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoController.java index 3d7d7b5..0078200 100644 --- a/demos/spring-boot-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoController.java +++ b/demos/spring-boot-webapp/src/main/java/com/github/starnowski/jamolingo/demo/DemoController.java @@ -2,6 +2,7 @@ import com.github.starnowski.jamolingo.perf.ExplainAnalyzeResult; import com.github.starnowski.jamolingo.perf.ExplainAnalyzeResultFactory; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -21,6 +22,13 @@ public class DemoController { @Autowired private MongoTemplate mongoTemplate; + @GetMapping("/query-with-dollar-parameters") + public Map queryWithDollarParameterOperators(HttpServletRequest request) + throws Exception { + ODataQueryService.QueryPlan plan = oDataQueryService.buildQueryPlan(request.getQueryString()); + return executeQueryPlan(plan); + } + @GetMapping("/query") public Map query( @RequestParam(name = "filter", required = false) String filter, diff --git a/demos/spring-boot-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoControllerIntegrationTest.java b/demos/spring-boot-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoControllerIntegrationTest.java index 6a632e0..414be90 100644 --- a/demos/spring-boot-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoControllerIntegrationTest.java +++ b/demos/spring-boot-webapp/src/test/java/com/github/starnowski/jamolingo/demo/DemoControllerIntegrationTest.java @@ -87,6 +87,67 @@ public void shouldReturnCount() throws Exception { .andExpect(jsonPath("$['@odata.count']", is(6))); } + @Test + public void shouldFilterByPlainStringWithDollarParameters() throws Exception { + mockMvc + .perform( + get("/query-with-dollar-parameters").queryParam("$filter", "plainString eq 'Poem'")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.value", hasSize(1))) + .andExpect(jsonPath("$.value[0].plainString", is("Poem"))); + } + + @Test + public void shouldOrderAndLimitWithDollarParameters() throws Exception { + mockMvc + .perform( + get("/query-with-dollar-parameters") + .queryParam("$orderby", "plainString desc") + .queryParam("$top", "2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.value", hasSize(2))) + .andExpect(jsonPath("$.value[0].plainString", is("example2"))) + .andExpect(jsonPath("$.value[1].plainString", is("example1"))); + } + + @Test + public void shouldSkipAndLimitWithDollarParameters() throws Exception { + // sorted desc: example2, example1, eOMtThyhVNLWUZNRcBaQKxI, Some text, Poem, Oleksa, Mario + mockMvc + .perform( + get("/query-with-dollar-parameters") + .queryParam("$orderby", "plainString desc") + .queryParam("$skip", "3") + .queryParam("$top", "1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.value", hasSize(1))) + .andExpect(jsonPath("$.value[0].plainString", is("Some text"))); + } + + @Test + public void shouldSelectFieldsWithDollarParameters() throws Exception { + mockMvc + .perform( + get("/query-with-dollar-parameters") + .queryParam("$filter", "plainString eq 'Poem'") + .queryParam("$select", "plainString")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.value[0].plainString", is("Poem"))) + .andExpect(jsonPath("$.value[0].tags").doesNotExist()); + } + + @Test + public void shouldReturnCountWithDollarParameters() throws Exception { + mockMvc + .perform( + get("/query-with-dollar-parameters") + .queryParam("$filter", "contains(plainString, 'e')") + .queryParam("$count", "true")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.value", hasSize(6))) + .andExpect(jsonPath("$['@odata.count']", is(6))); + } + @Test public void shouldReturn400WhenNoIndexUsed() throws Exception { mockMvc