Search in sources :

Example 1 with OrPart

use of org.springframework.data.repository.query.parser.PartTree.OrPart in project spring-data-keyvalue by spring-projects.

the class SpelQueryCreator method toPredicateExpression.

protected SpelExpression toPredicateExpression(PartTree tree) {
    int parameterIndex = 0;
    StringBuilder sb = new StringBuilder();
    for (Iterator<OrPart> orPartIter = tree.iterator(); orPartIter.hasNext(); ) {
        int partCnt = 0;
        StringBuilder partBuilder = new StringBuilder();
        OrPart orPart = orPartIter.next();
        for (Iterator<Part> partIter = orPart.iterator(); partIter.hasNext(); ) {
            Part part = partIter.next();
            if (!requiresInverseLookup(part)) {
                partBuilder.append("#it?.");
                partBuilder.append(part.getProperty().toDotPath().replace(".", "?."));
            }
            // TODO: check if we can have caseinsensitive search
            if (!part.shouldIgnoreCase().equals(IgnoreCaseType.NEVER)) {
                throw new InvalidDataAccessApiUsageException("Ignore case not supported!");
            }
            switch(part.getType()) {
                case TRUE:
                    partBuilder.append("?.equals(true)");
                    break;
                case FALSE:
                    partBuilder.append("?.equals(false)");
                    break;
                case SIMPLE_PROPERTY:
                    partBuilder.append("?.equals(").append("[").append(parameterIndex++).append("])");
                    break;
                case IS_NULL:
                    partBuilder.append(" == null");
                    break;
                case IS_NOT_NULL:
                    partBuilder.append(" != null");
                    break;
                case LIKE:
                    partBuilder.append("?.contains(").append("[").append(parameterIndex++).append("])");
                    break;
                case STARTING_WITH:
                    partBuilder.append("?.startsWith(").append("[").append(parameterIndex++).append("])");
                    break;
                case AFTER:
                case GREATER_THAN:
                    partBuilder.append(">").append("[").append(parameterIndex++).append("]");
                    break;
                case GREATER_THAN_EQUAL:
                    partBuilder.append(">=").append("[").append(parameterIndex++).append("]");
                    break;
                case BEFORE:
                case LESS_THAN:
                    partBuilder.append("<").append("[").append(parameterIndex++).append("]");
                    break;
                case LESS_THAN_EQUAL:
                    partBuilder.append("<=").append("[").append(parameterIndex++).append("]");
                    break;
                case ENDING_WITH:
                    partBuilder.append("?.endsWith(").append("[").append(parameterIndex++).append("])");
                    break;
                case BETWEEN:
                    int index = partBuilder.lastIndexOf("#it?.");
                    partBuilder.insert(index, "(");
                    partBuilder.append(">").append("[").append(parameterIndex++).append("]");
                    partBuilder.append("&&");
                    partBuilder.append("#it?.");
                    partBuilder.append(part.getProperty().toDotPath().replace(".", "?."));
                    partBuilder.append("<").append("[").append(parameterIndex++).append("]");
                    partBuilder.append(")");
                    break;
                case REGEX:
                    partBuilder.append(" matches ").append("[").append(parameterIndex++).append("]");
                    break;
                case IN:
                    partBuilder.append("[").append(parameterIndex++).append("].contains(");
                    partBuilder.append("#it?.");
                    partBuilder.append(part.getProperty().toDotPath().replace(".", "?."));
                    partBuilder.append(")");
                    break;
                case CONTAINING:
                case NOT_CONTAINING:
                case NEGATING_SIMPLE_PROPERTY:
                case EXISTS:
                default:
                    throw new InvalidDataAccessApiUsageException(String.format("Found invalid part '%s' in query", part.getType()));
            }
            if (partIter.hasNext()) {
                partBuilder.append("&&");
            }
            partCnt++;
        }
        if (partCnt > 1) {
            sb.append("(").append(partBuilder).append(")");
        } else {
            sb.append(partBuilder);
        }
        if (orPartIter.hasNext()) {
            sb.append("||");
        }
    }
    return StringUtils.hasText(sb) ? PARSER.parseRaw(sb.toString()) : PARSER.parseRaw("true");
}
Also used : Part(org.springframework.data.repository.query.parser.Part) OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException) OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart)

Example 2 with OrPart

use of org.springframework.data.repository.query.parser.PartTree.OrPart in project spring-data-commons by spring-projects.

the class AbstractQueryCreator method createCriteria.

/**
 * Actual query building logic. Traverses the {@link PartTree} and invokes callback methods to delegate actual
 * criteria creation and concatenation.
 *
 * @param tree must not be {@literal null}.
 * @return
 */
@Nullable
private S createCriteria(PartTree tree) {
    S base = null;
    Iterator<Object> iterator = parameters.map(ParameterAccessor::iterator).orElse(Collections.emptyIterator());
    for (OrPart node : tree) {
        Iterator<Part> parts = node.iterator();
        if (!parts.hasNext()) {
            throw new IllegalStateException(String.format("No part found in PartTree %s!", tree));
        }
        S criteria = create(parts.next(), iterator);
        while (parts.hasNext()) {
            criteria = and(parts.next(), criteria, iterator);
        }
        base = base == null ? criteria : or(base, criteria);
    }
    return base;
}
Also used : OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart) OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart) Nullable(org.springframework.lang.Nullable)

Example 3 with OrPart

use of org.springframework.data.repository.query.parser.PartTree.OrPart in project spring-data-commons by spring-projects.

the class PartTreeUnitTests method parsesNestedSpecialUnicodeCharactersMixedWithRegularCharactersCorrectly_Korean.

// DATACMNS-363
@Test
public void parsesNestedSpecialUnicodeCharactersMixedWithRegularCharactersCorrectly_Korean() {
    PartTree tree = new // 
    PartTree(// 
    "findBy" + "이름" + "And" + // 
    "OrderId" + "And" + // we use _ here to mark the beginning of a new property reference "이름"
    "Nested_이름" + "Or" + // 
    "NestedOrderId" + "OrderBy" + "생일" + "Asc", DomainObjectWithSpecialChars.class);
    Iterator<OrPart> parts = tree.iterator();
    assertPartsIn(parts.next(), new Part[] { // 
    new Part("이름", DomainObjectWithSpecialChars.class), // 
    new Part("order.id", DomainObjectWithSpecialChars.class), // 
    new Part("nested.이름", DomainObjectWithSpecialChars.class) });
    assertPartsIn(parts.next(), new Part[] { // 
    new Part("nested.order.id", DomainObjectWithSpecialChars.class) });
    assertThat(tree.getSort().getOrderFor("생일").isAscending()).isTrue();
}
Also used : OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart) OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart) Test(org.junit.Test)

Example 4 with OrPart

use of org.springframework.data.repository.query.parser.PartTree.OrPart in project spring-data-commons by spring-projects.

the class PartTreeUnitTests method assertPartsIn.

private void assertPartsIn(OrPart orPart, Part[] part) {
    Iterator<Part> partIterator = orPart.iterator();
    for (int k = 0; k < part.length; k++) {
        assertThat(partIterator.hasNext()).as("Expected %d parts but have %d", part.length, k).isTrue();
        Part next = partIterator.next();
        assertThat(part[k]).as("Expected %s but got %s!", part[k], next).isEqualTo(next);
    }
    assertThat(partIterator.hasNext()).as("Too many parts!").isFalse();
}
Also used : OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart)

Example 5 with OrPart

use of org.springframework.data.repository.query.parser.PartTree.OrPart in project spring-data-commons by spring-projects.

the class PartTreeUnitTests method parsesNestedSpecialUnicodeCharactersMixedWithRegularCharactersCorrectly_KoreanNumbersSymbols.

// DATACMNS-363
@Test
public void parsesNestedSpecialUnicodeCharactersMixedWithRegularCharactersCorrectly_KoreanNumbersSymbols() {
    PartTree tree = new // 
    PartTree(// 
    "findBy" + "이름" + "And" + // 
    "OrderId" + "And" + // 
    "Anders" + "And" + // 
    "Property1" + "And" + // 
    "Øre" + "And" + // 
    "År" + "Or" + // 
    "NestedOrderId" + "And" + // we use _ here to mark the beginning of a new property reference "이름"
    "Nested_property1" + "And" + // 
    "Property1" + "OrderBy" + "생일" + "Asc", DomainObjectWithSpecialChars.class);
    Iterator<OrPart> parts = tree.iterator();
    assertPartsIn(parts.next(), new Part[] { // 
    new Part("이름", DomainObjectWithSpecialChars.class), // 
    new Part("order.id", DomainObjectWithSpecialChars.class), // 
    new Part("anders", DomainObjectWithSpecialChars.class), // 
    new Part("property1", DomainObjectWithSpecialChars.class), // 
    new Part("øre", DomainObjectWithSpecialChars.class), // 
    new Part("år", DomainObjectWithSpecialChars.class) });
    assertPartsIn(parts.next(), new Part[] { // 
    new Part("nested.order.id", DomainObjectWithSpecialChars.class), // 
    new Part("nested.property1", DomainObjectWithSpecialChars.class), // 
    new Part("property1", DomainObjectWithSpecialChars.class) });
    assertThat(tree.getSort().getOrderFor("생일").isAscending()).isTrue();
}
Also used : OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart) OrPart(org.springframework.data.repository.query.parser.PartTree.OrPart) Test(org.junit.Test)

Aggregations

OrPart (org.springframework.data.repository.query.parser.PartTree.OrPart)5 Test (org.junit.Test)2 InvalidDataAccessApiUsageException (org.springframework.dao.InvalidDataAccessApiUsageException)1 Part (org.springframework.data.repository.query.parser.Part)1 Nullable (org.springframework.lang.Nullable)1