jirutka/rsql-parser

How to represent an empty filter in rsql

therohk opened this issue · 2 comments

I am not sure if this is already implemented but I have not found this anywhere in the docs.

I am letting the user enter an rsql query to filter records in a table within a spring webservice. This works perfectly fine when a valid query is provided.

But, how to I represent an empty filter? i.e select * from x without any where clause. Passing an empty or null query string to the rsql parser does not work with error: "Encountered EOF at line 0, column 0".

I am currently forced to use workarounds like primaryKey!=-1 or create a similar condition that does not skip any records to achieve this.

I have spent some time coming up with a better solution than my previous approach.

You can plug this stateless class EntityUtils into any spring project.

It exposes the functions below that handle null or empty queries:

public static <T> CriteriaQuery<T> buildCriteriaQuery(EntityManager em, Class<T> entityClass, String query)

public static <T> CriteriaQuery<Long> buildCountQuery(EntityManager em, Class<T> entityClass, String query)

In the end, Rsql parser returns an object Specification<M> for entity M. The method findAll(Specification<M>, Pageable) of JpaSpecificationExecutor<M> accepts null as first argument, thus you can simply check your query beforehand. I usually do like this:

    private final RSQLParser parser;
    public <M> Page<M> findByQuery(@Nullable String query,
                                   Pageable pageable,
                                   JpaSpecificationExecutor<M> repository) throws RSQLParserException {
        try {
            return repository.findAll(query == null || query.isBlank() ? null :
                                              parser.parse(URLDecoder.decode(query, StandardCharsets.UTF_8))
                                                    .accept(new CustomRsqlVisitor<>()), pageable);
        } catch (RSQLParserException | ParserException | IllegalArgumentException e) {
            throw new RSQLParserException(e);
        }
    }