Jirutka / rsql-parser and QueryDSL

I have a Spring framework created by the back-end of REST services, and now I need to find a way to handle complex filters in some front-end requests.

I use the QueryDsl structure (v3.4.2) to create queries across all internal content.

I think using a FIQL or RSQL parser is the best approach, so I'm trying to integrate jirutka / rsql-parser into my back-end project.

I am very familiar with this, as well as QueryDsl.

Now I'm confused, so here is my request for help:
Has anyone integrated jirutka / rsql-parser and QueryDsl in Spring's vacation project before? and how?

The Jirutka / rsql-parser documentation only says:

Nodes are available for visiting, therefore, to go through the analyzed AST (and convert it to a SQL query, perhaps), you can implement the provided RSQLVisitor interface or the simplified NoArgRSQLVisitor adapter.

And has the following example on how to do this:

Node rootNode = new RSQLParser().parse("name==RSQL;version=ge=2.0"); rootNode.accept(yourShinyVisitor); 

Seems pretty easy, right?

So, I broke my visitor like this:

 public class RsqlParserVisitor extends NoArgRSQLVisitorAdapter<BooleanExpression> { 

All methods with which I need interfaces are implemented.

Here I add two examples:

 @Override public BooleanExpression visit(AndNode arg0) { // TODO Auto-generated method stub String methodNameTmp = "AndNode"; logger.debug(methodNameTmp + ". arg0: " + arg0); logger.debug("operator: " + arg0.getOperator().name()); for (Node node : arg0) { logger.debug(methodNameTmpp + ". node: " + node); } return null; //DO SOMETHING TO CREATE A BooleanExpression; } 

and

 @Override public BooleanExpression visit(EqualNode arg0) { // TODO Auto-generated method stub String methodNameTmp = "EqualNode"; logger.debug(methodNameTmp + ". arg0: " + arg0); logger.debug("operator: " + arg0.getOperator()); for (String arg: arg0.getArguments()) { logger.debug(methodNameTmp + ". arg: " + arg); } return null; //DO SOMETHING TO CREATE A BooleanExpression; } 

Now I'm stuck:

a) To create a BooleanExpression QueryDsl, I need to know the class I'm processing, for example:

  QUser qUser = QUser.user; BooleanExpression filter = qUser.firstName.eq("Bob"); 

or

  PathBuilder<User> user = new PathBuilder<User>(User.class, "user"); BooleanExpression filter = user.getString("firstName").eq("Bob"); 

b) When I check my code, it only executes the public BooleanExpression visit(OrNode arg0) , and then nothing. He stops right there.

At this moment I can’t do much. So far, I have not been able to create a BooleanExpression, since I need to go through some ComparisonNode methods first and then join them using the expressions "either" or "and" boolean. Right?

If I could go through all the nodes, then I managed to find a way to pass the class, I'm not worried about that. But do not understand how to get through all the nodes and could not do it.

Any pointers to fix this would be really appreciated.

+5
source share
1 answer

As always, after the question asked made a big (I think) progress.

Found a way around all the nodes and found a way to pass the QueryDsl PathBuilder<?> Object to the visitor.

PathBuilder<?> Is the parent class of all QSomething classes created by QueryDsl.

Now I am again stuck looking for a way to create a BooleanExpression.

Any help would be greatly appreciated.

Now I have the following in my service:

 @Override public Page<User> getUsers(Emisor pEmisor, int pPage, int pSize, Sort pSort, String pRSQLFilters) { Pageable pageable = new PageRequest(pPage, pSize, pSort); BooleanExpression filters = null; Node queryTree; try { logger.debug("Parsing query: {}", pRSQLFilters); queryTree = new RSQLParser().parse(pRSQLFilters); RsqlParserVisitor<BooleanExpression, QUser> rsqlParserVisitor = new RsqlParserVisitor<BooleanExpression, QUser>(); filters = queryTree.accept(rsqlParserVisitor, QUser.user); } catch (TokenMgrError e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RSQLParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } Page<User> lista = userRepository.findAll(filtros, pageable); return lista; } 

And this is with the visitor:

 public class RsqlParserVisitor<BooleanExpression, A> implements RSQLVisitor<BooleanExpression, EntityPathBase<?>> { ... @Override public BooleanExpression visit(OrNode node, EntityPathBase<?> param) { // TODO Auto-generated method stub String nombreTmp = "OrNode"; printLogicalNode(nombreTmp, node, param); return null; } @Override public BooleanExpression visit(EqualNode node, EntityPathBase<?> param) { // TODO Auto-generated method stub String nombreTmp = "EqualNode"; printComparisonNode(nombreTmp, node, param); return null; } ... public void printLogicalNode(String pNombreNodo, LogicalNode pNode, EntityPathBase<?> pParam) { logger.debug(pNombreNodo + ". node: " + pNode + ". param: " + pParam); logger.debug("operator: " + pNode.getOperator().name()); for (Node subNode : pNode) { logger.debug(pNombreNodo + ". subNode: " + subNode); subNode.accept(this, pParam); <=========== this was the key to be able to traverse every node } } public void printComparisonNode(String pNombreNodo, ComparisonNode pNode, EntityPathBase<?> pParam) { logger.debug(pNombreNodo + ". node: " + pNode + ". param: " + pParam); logger.debug("Selector: " + pNode.getSelector()); logger.debug("operator: " + pNode.getOperator()); for (String argTmp : pNode.getArguments()) { logger.debug(pNombreNodo + ". argTmp: " + argTmp); } } } 
0
source

Source: https://habr.com/ru/post/1205204/


All Articles