Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the operator 'TRIM()' on both database fields and query parameters #3

Open
Seblink opened this issue Sep 28, 2021 · 1 comment

Comments

@Seblink
Copy link

Seblink commented Sep 28, 2021

We have a use case where we want to compare the trimmed contents of a database field with the trimmed contents of a provided value. In pseudo code:

WHERE TRIM({object:field}) = TRIM(?parameter1)

To support this use case while still being able to use your library, we created the following two classes:

package org.bitbucket.andriichukandrii.hybris.flexiblesearchbuilder;

import org.spockframework.util.Assert;

public class TrimmedField implements Field {

    private final Field decorated;

    public TrimmedField(Field decorated) {
        Assert.notNull(decorated, "The parameter decorated can not be null.");
        this.decorated = decorated;
    }

    @Override
    public String getFieldName() {
        return decorated.getFieldName();
    }

    @Override
    public String toString() {
        return "TRIM(" + decorated.toString() + ")";
    }
}

and

package org.bitbucket.andriichukandrii.hybris.flexiblesearchbuilder;

import java.util.Collection;
import java.util.Map;

public class TrimmedParameterFieldCondition extends AbstractFieldCondition {

    private final ParameterConditionType conditionType;
    private final Object conditionParameter;
    private String parameterCode;

    public TrimmedParameterFieldCondition(Field field, ParameterConditionType conditionType, Object conditionParameter) {
        super(field);
        this.conditionType = conditionType;
        this.conditionParameter = conditionParameter;
    }

    protected void appendQuery(StringBuilder sb) {
        super.appendQuery(sb);
        boolean collectionParameter = this.conditionParameter instanceof Collection;
        sb.append(this.conditionType.getOperator());
        if (collectionParameter) {
            sb.append("(");
        }

        sb.append("TRIM(?").append(this.parameterCode).append(")");
        if (collectionParameter) {
            sb.append(")");
        }
    }

    protected void addParameters(Map<String, Object> parameterMap) {
        super.addParameters(parameterMap);
        this.parameterCode = FlexibleSearchBuilderFieldUtils.createUniqueParameterCode(parameterMap, this.field.getFieldName());
        parameterMap.put(this.parameterCode, this.conditionParameter);
    }
}

The way we made this work is not ideal however:

  1. We have to keep our extensions in the same package, because the parent classes contain protected methods.
  2. We had to duplicate a lot of the code from the parent classes into our extensions to make it work

Perhaps a better way can be created to support both use cases? We saw classes called SqlFuntion and SqlFunctions. Adding TRIM there might be a good first step, but other places in the builder also need to be changed to accept and SqlFunction then. Changing some of the access modifiers to be less restrictive would also help users of the library to add extensions to it.

@avrilfanomar
Copy link
Owner

The idea with the protected access was mostly to simplify usage/autocompletion and not for restricting the extension possibility of course. Initially I didn't add such functions to be platform-independent and follow only SQL standard. I need to rethink it probably.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants