Search in sources :

Example 6 with ConvertedExpression

use of io.jans.orm.cloud.spanner.model.ConvertedExpression in project jans by JanssenProject.

the class SpannerFilterConverter method convertToSqlFilter.

public ConvertedExpression convertToSqlFilter(TableMapping tableMapping, Filter genericFilter, Map<String, PropertyAnnotation> propertiesAnnotationsMap, Function<? super Filter, Boolean> processor, boolean skipAlias) throws SearchException {
    Map<String, ValueWithStructField> queryParameters = new HashMap<>();
    Map<String, Join> joinTables = new HashMap<>();
    ConvertedExpression convertedExpression = convertToSqlFilterImpl(tableMapping, genericFilter, propertiesAnnotationsMap, queryParameters, joinTables, processor, skipAlias);
    return convertedExpression;
}
Also used : HashMap(java.util.HashMap) ConvertedExpression(io.jans.orm.cloud.spanner.model.ConvertedExpression) Join(net.sf.jsqlparser.statement.select.Join) ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField)

Example 7 with ConvertedExpression

use of io.jans.orm.cloud.spanner.model.ConvertedExpression in project jans by JanssenProject.

the class SpannerFilterConverter method convertToSqlFilterImpl.

private ConvertedExpression convertToSqlFilterImpl(TableMapping tableMapping, Filter genericFilter, Map<String, PropertyAnnotation> propertiesAnnotationsMap, Map<String, ValueWithStructField> queryParameters, Map<String, Join> joinTables, Function<? super Filter, Boolean> processor, boolean skipAlias) throws SearchException {
    if (genericFilter == null) {
        return null;
    }
    Filter currentGenericFilter = genericFilter;
    FilterType type = currentGenericFilter.getType();
    if (FilterType.RAW == type) {
        LOG.warn("RAW Ldap filter to SQL convertion will be removed in new version!!!");
        currentGenericFilter = ldapFilterConverter.convertRawLdapFilterToFilter(currentGenericFilter.getFilterString());
        LOG.debug(String.format("Converted RAW filter: %s", currentGenericFilter));
        type = currentGenericFilter.getType();
    }
    if (processor != null) {
        processor.apply(currentGenericFilter);
    }
    if ((FilterType.NOT == type) || (FilterType.AND == type) || (FilterType.OR == type)) {
        Filter[] genericFilters = currentGenericFilter.getFilters();
        Expression[] expFilters = new Expression[genericFilters.length];
        if (genericFilters != null) {
            // We can replace only multiple OR with IN
            boolean canJoinOrFilters = FilterType.OR == type;
            List<Filter> joinOrFilters = new ArrayList<Filter>();
            String joinOrAttributeName = null;
            for (int i = 0; i < genericFilters.length; i++) {
                Filter tmpFilter = genericFilters[i];
                expFilters[i] = convertToSqlFilterImpl(tableMapping, tmpFilter, propertiesAnnotationsMap, queryParameters, joinTables, processor, skipAlias).expression();
                // Check if we can replace OR with IN
                if (!canJoinOrFilters) {
                    continue;
                }
                if (tmpFilter.getMultiValued() != null) {
                    canJoinOrFilters = false;
                    continue;
                }
                if ((FilterType.EQUALITY != tmpFilter.getType()) || (tmpFilter.getFilters() != null)) {
                    canJoinOrFilters = false;
                    continue;
                }
                Boolean isMultiValuedDetected = determineMultiValuedByType(tmpFilter.getAttributeName(), propertiesAnnotationsMap);
                if (!Boolean.FALSE.equals(isMultiValuedDetected)) {
                    if (!Boolean.FALSE.equals(currentGenericFilter.getMultiValued())) {
                        canJoinOrFilters = false;
                        continue;
                    }
                }
                if (joinOrAttributeName == null) {
                    joinOrAttributeName = tmpFilter.getAttributeName();
                    joinOrFilters.add(tmpFilter);
                    continue;
                }
                if (!joinOrAttributeName.equals(tmpFilter.getAttributeName())) {
                    canJoinOrFilters = false;
                    continue;
                }
                joinOrFilters.add(tmpFilter);
            }
            if (FilterType.NOT == type) {
                return ConvertedExpression.build(new NotExpression(expFilters[0]), queryParameters, joinTables);
            } else if (FilterType.AND == type) {
                Expression result = expFilters[0];
                for (int i = 1; i < expFilters.length; i++) {
                    result = new AndExpression(result, expFilters[i]);
                }
                return ConvertedExpression.build(new Parenthesis(result), queryParameters, joinTables);
            } else if (FilterType.OR == type) {
                if (canJoinOrFilters) {
                    ExpressionList expressionList = new ExpressionList();
                    for (Expression expFilter : expFilters) {
                        expressionList.addExpressions(((EqualsTo) expFilter).getRightExpression());
                    }
                    Expression inExpression = new InExpression(buildExpression(tableMapping, joinOrFilters.get(0), false, false, propertiesAnnotationsMap, queryParameters, joinTables, processor, skipAlias), expressionList);
                    return ConvertedExpression.build(inExpression, queryParameters, joinTables);
                } else {
                    Expression result = expFilters[0];
                    for (int i = 1; i < expFilters.length; i++) {
                        result = new OrExpression(result, expFilters[i]);
                    }
                    return ConvertedExpression.build(new Parenthesis(result), queryParameters, joinTables);
                }
            }
        }
    }
    // Generic part for rest of expression types
    String internalAttribute = toInternalAttribute(currentGenericFilter);
    boolean multiValued = isMultiValue(tableMapping, internalAttribute, currentGenericFilter, propertiesAnnotationsMap);
    boolean hasChildTableForAttribute = tableMapping.hasChildTableForAttribute(internalAttribute.toLowerCase());
    Expression leftExpression = buildExpression(tableMapping, currentGenericFilter, multiValued, !hasChildTableForAttribute, propertiesAnnotationsMap, queryParameters, joinTables, processor, skipAlias);
    if (FilterType.EQUALITY == type) {
        Expression variableExpression = buildVariableExpression(tableMapping, internalAttribute, currentGenericFilter.getAssertionValue(), queryParameters);
        Expression expression = new EqualsTo(leftExpression, variableExpression);
        if (multiValued) {
            if (hasChildTableForAttribute) {
                // JOIN jansClnt_Interleave_jansRedirectURI jansRedirectURI ON doc.doc_id = jansRedirectURI.doc_id
                // WHERE jansRedirectURI.jansRedirectURI = '10'
                addJoinTable(tableMapping, internalAttribute, joinTables);
            } else {
                // EXISTS (SELECT _jansRedirectURI FROM UNNEST(doc.jansRedirectURI) _jansRedirectURI WHERE _jansRedirectURI = '10')
                expression = buildExistsInArrayExpression(internalAttribute, expression);
            }
            return ConvertedExpression.build(expression, queryParameters, joinTables);
        }
        return ConvertedExpression.build(expression, queryParameters, joinTables);
    }
    if (FilterType.LESS_OR_EQUAL == type) {
        Expression variableExpression = buildVariableExpression(tableMapping, internalAttribute, currentGenericFilter.getAssertionValue(), queryParameters);
        Expression expression = new MinorThanEquals().withLeftExpression(leftExpression).withRightExpression(variableExpression);
        if (multiValued) {
            if (hasChildTableForAttribute) {
                addJoinTable(tableMapping, internalAttribute, joinTables);
            } else {
                expression = buildExistsInArrayExpression(internalAttribute, expression);
            }
            return ConvertedExpression.build(expression, queryParameters, joinTables);
        }
        return ConvertedExpression.build(expression, queryParameters, joinTables);
    }
    if (FilterType.GREATER_OR_EQUAL == type) {
        Expression variableExpression = buildVariableExpression(tableMapping, internalAttribute, currentGenericFilter.getAssertionValue(), queryParameters);
        Expression expression = new GreaterThanEquals().withLeftExpression(leftExpression).withRightExpression(variableExpression);
        if (multiValued) {
            if (hasChildTableForAttribute) {
                addJoinTable(tableMapping, internalAttribute, joinTables);
            } else {
                expression = buildExistsInArrayExpression(internalAttribute, expression);
            }
            return ConvertedExpression.build(expression, queryParameters, joinTables);
        }
        return ConvertedExpression.build(expression, queryParameters, joinTables);
    }
    if (FilterType.PRESENCE == type) {
        Expression expression = new IsNullExpression().withLeftExpression(leftExpression).withNot(true);
        if (multiValued) {
            if (hasChildTableForAttribute) {
                addJoinTable(tableMapping, internalAttribute, joinTables);
            } else {
                expression = buildExistsInArrayExpression(internalAttribute, expression);
            }
            return ConvertedExpression.build(expression, queryParameters, joinTables);
        }
        return ConvertedExpression.build(expression, queryParameters, joinTables);
    }
    if (FilterType.APPROXIMATE_MATCH == type) {
        throw new SearchException("Convertion from APPROXIMATE_MATCH LDAP filter to SQL filter is not implemented");
    }
    if (FilterType.SUBSTRING == type) {
        StringBuilder like = new StringBuilder();
        if (currentGenericFilter.getSubInitial() != null) {
            like.append(currentGenericFilter.getSubInitial());
        }
        like.append("%");
        String[] subAny = currentGenericFilter.getSubAny();
        if ((subAny != null) && (subAny.length > 0)) {
            for (String any : subAny) {
                like.append(any);
                like.append("%");
            }
        }
        if (currentGenericFilter.getSubFinal() != null) {
            like.append(currentGenericFilter.getSubFinal());
        }
        String likeValue = like.toString();
        Expression variableExpression = buildVariableExpression(tableMapping, internalAttribute, likeValue, queryParameters);
        Expression expression = new LikeExpression().withLeftExpression(leftExpression).withRightExpression(variableExpression);
        if (multiValued) {
            if (hasChildTableForAttribute) {
                addJoinTable(tableMapping, internalAttribute, joinTables);
            } else {
                expression = buildExistsInArrayExpression(internalAttribute, expression);
            }
            return ConvertedExpression.build(expression, queryParameters, joinTables);
        }
        return ConvertedExpression.build(expression, queryParameters, joinTables);
    }
    if (FilterType.LOWERCASE == type) {
        net.sf.jsqlparser.expression.Function lowerFunction = new net.sf.jsqlparser.expression.Function();
        lowerFunction.setName("LOWER");
        lowerFunction.setParameters(new ExpressionList(leftExpression));
        return ConvertedExpression.build(lowerFunction, queryParameters, joinTables);
    }
    throw new SearchException(String.format("Unknown filter type '%s'", type));
}
Also used : MinorThanEquals(net.sf.jsqlparser.expression.operators.relational.MinorThanEquals) InExpression(net.sf.jsqlparser.expression.operators.relational.InExpression) ArrayList(java.util.ArrayList) SearchException(io.jans.orm.exception.operation.SearchException) NotExpression(net.sf.jsqlparser.expression.NotExpression) OrExpression(net.sf.jsqlparser.expression.operators.conditional.OrExpression) Function(java.util.function.Function) TableFunction(net.sf.jsqlparser.statement.select.TableFunction) Parenthesis(net.sf.jsqlparser.expression.Parenthesis) AndExpression(net.sf.jsqlparser.expression.operators.conditional.AndExpression) ExpressionList(net.sf.jsqlparser.expression.operators.relational.ExpressionList) IsNullExpression(net.sf.jsqlparser.expression.operators.relational.IsNullExpression) GreaterThanEquals(net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals) FilterType(io.jans.orm.search.filter.FilterType) LikeExpression(net.sf.jsqlparser.expression.operators.relational.LikeExpression) Filter(io.jans.orm.search.filter.Filter) LikeExpression(net.sf.jsqlparser.expression.operators.relational.LikeExpression) ExistsExpression(net.sf.jsqlparser.expression.operators.relational.ExistsExpression) InExpression(net.sf.jsqlparser.expression.operators.relational.InExpression) AndExpression(net.sf.jsqlparser.expression.operators.conditional.AndExpression) NotExpression(net.sf.jsqlparser.expression.NotExpression) ConvertedExpression(io.jans.orm.cloud.spanner.model.ConvertedExpression) IsNullExpression(net.sf.jsqlparser.expression.operators.relational.IsNullExpression) Expression(net.sf.jsqlparser.expression.Expression) OrExpression(net.sf.jsqlparser.expression.operators.conditional.OrExpression) EqualsTo(net.sf.jsqlparser.expression.operators.relational.EqualsTo)

Example 8 with ConvertedExpression

use of io.jans.orm.cloud.spanner.model.ConvertedExpression in project jans by JanssenProject.

the class SpannerOperationServiceImpl method deleteImpl.

private long deleteImpl(TableMapping tableMapping, ConvertedExpression expression, int count) throws DeleteException {
    try {
        Table table = buildTable(tableMapping);
        // select
        PlainSelect sqlSelectQuery = new PlainSelect();
        sqlSelectQuery.setFromItem(table);
        // doc_id
        Column selectDocIdColumn = new Column(tableAlias, DOC_ID);
        SelectExpressionItem selectDocIdItem = new SelectExpressionItem(selectDocIdColumn);
        sqlSelectQuery.addSelectItems(selectDocIdItem);
        applyWhereExpression(sqlSelectQuery, expression);
        long useCount = connectionProvider.getMaximumResultDeleteSize();
        if (count > 0) {
            useCount = Math.min(count, useCount);
        }
        Limit limit = new Limit();
        limit.setRowCount(new LongValue(useCount));
        sqlSelectQuery.setLimit(limit);
        SubSelect subSelect = new SubSelect();
        subSelect.setSelectBody(sqlSelectQuery);
        subSelect.withUseBrackets(true);
        Expression inExpression = new InExpression(selectDocIdColumn, subSelect);
        Delete sqlDeleteQuery = new Delete();
        sqlDeleteQuery.setTable(table);
        sqlDeleteQuery.setWhere(inExpression);
        Statement.Builder statementBuilder = Statement.newBuilder(sqlDeleteQuery.toString());
        applyParametersBinding(statementBuilder, expression);
        Statement statement = statementBuilder.build();
        LOG.debug("Executing delete query: '{}'", statement);
        Long rowDeleted = databaseClient.readWriteTransaction().run(new TransactionCallable<Long>() {

            @Override
            public Long run(TransactionContext transaction) throws Exception {
                long rowCount = transaction.executeUpdate(statement);
                return rowCount;
            }
        });
        return rowDeleted;
    } catch (SpannerException | IncompatibleTypeException ex) {
        throw new DeleteException(String.format("Failed to delete entries. Expression: '%s'", expression.expression()), ex);
    }
}
Also used : Delete(net.sf.jsqlparser.statement.delete.Delete) Table(net.sf.jsqlparser.schema.Table) Statement(com.google.cloud.spanner.Statement) DeleteException(io.jans.orm.exception.operation.DeleteException) SelectExpressionItem(net.sf.jsqlparser.statement.select.SelectExpressionItem) InExpression(net.sf.jsqlparser.expression.operators.relational.InExpression) PlainSelect(net.sf.jsqlparser.statement.select.PlainSelect) DeleteException(io.jans.orm.exception.operation.DeleteException) IncompatibleTypeException(io.jans.orm.exception.operation.IncompatibleTypeException) PersistenceException(io.jans.orm.exception.operation.PersistenceException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) EntryConvertationException(io.jans.orm.exception.operation.EntryConvertationException) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) SpannerException(com.google.cloud.spanner.SpannerException) SearchException(io.jans.orm.exception.operation.SearchException) EntryNotFoundException(io.jans.orm.exception.operation.EntryNotFoundException) Column(net.sf.jsqlparser.schema.Column) Expression(net.sf.jsqlparser.expression.Expression) InExpression(net.sf.jsqlparser.expression.operators.relational.InExpression) ConvertedExpression(io.jans.orm.cloud.spanner.model.ConvertedExpression) TransactionContext(com.google.cloud.spanner.TransactionContext) LongValue(net.sf.jsqlparser.expression.LongValue) IncompatibleTypeException(io.jans.orm.exception.operation.IncompatibleTypeException) Limit(net.sf.jsqlparser.statement.select.Limit) SpannerException(com.google.cloud.spanner.SpannerException) SubSelect(net.sf.jsqlparser.statement.select.SubSelect) Builder(com.google.cloud.spanner.Statement.Builder)

Example 9 with ConvertedExpression

use of io.jans.orm.cloud.spanner.model.ConvertedExpression in project jans by JanssenProject.

the class SpannerOperationServiceImpl method applyWhereExpression.

private void applyWhereExpression(Delete sqlDeleteQuery, ConvertedExpression expression) {
    if (expression == null) {
        return;
    }
    Expression whereExp = expression.expression();
    sqlDeleteQuery.setWhere(whereExp);
    Map<String, Join> joinTables = expression.joinTables();
    if (joinTables != null) {
        sqlDeleteQuery.setJoins(new ArrayList<>(joinTables.values()));
    }
}
Also used : Expression(net.sf.jsqlparser.expression.Expression) InExpression(net.sf.jsqlparser.expression.operators.relational.InExpression) ConvertedExpression(io.jans.orm.cloud.spanner.model.ConvertedExpression) Join(net.sf.jsqlparser.statement.select.Join)

Aggregations

ConvertedExpression (io.jans.orm.cloud.spanner.model.ConvertedExpression)9 SearchException (io.jans.orm.exception.operation.SearchException)6 Filter (io.jans.orm.search.filter.Filter)5 AuthenticationException (io.jans.orm.exception.AuthenticationException)4 EntryDeleteException (io.jans.orm.exception.EntryDeleteException)4 EntryPersistenceException (io.jans.orm.exception.EntryPersistenceException)4 MappingException (io.jans.orm.exception.MappingException)4 PropertyAnnotation (io.jans.orm.reflect.property.PropertyAnnotation)4 Expression (net.sf.jsqlparser.expression.Expression)4 InExpression (net.sf.jsqlparser.expression.operators.relational.InExpression)4 EntryData (io.jans.orm.model.EntryData)3 Join (net.sf.jsqlparser.statement.select.Join)3 SpannerException (com.google.cloud.spanner.SpannerException)1 Statement (com.google.cloud.spanner.Statement)1 Builder (com.google.cloud.spanner.Statement.Builder)1 TransactionContext (com.google.cloud.spanner.TransactionContext)1 ValueWithStructField (io.jans.orm.cloud.spanner.model.ValueWithStructField)1 DeleteException (io.jans.orm.exception.operation.DeleteException)1 DuplicateEntryException (io.jans.orm.exception.operation.DuplicateEntryException)1 EntryConvertationException (io.jans.orm.exception.operation.EntryConvertationException)1