2014-10-21 19 views
5

Posiadam frameworka REST usługi Spring framework back-end i teraz muszę znaleźć sposób na przetwarzanie złożonych filtrów w niektórych żądaniach z poziomu front-end.jirutka/rsql-parser i QueryDSL

Korzystam z frameworka QueryDsl (v3.4.2) do konstruowania zapytań w całym back-end.

Myślę, że najlepszym rozwiązaniem jest użycie parsera FIQL lub RSQL, więc próbuję zintegrować jirutka/rsql-parser z moim projektem back-end.

Jestem bardzo nowy, a także do QueryDsl.

Teraz jestem zdezorientowany więc tutaj jest moja prośba o pomoc:
czy ktoś zintegrowany jirutka/rsql-parser i QueryDsl w spoczynku projektu wiosną przed? i Jak?

Jirutka dokumentacja/rsql-parser tylko mówi:

Węzły są visitable, więc przemierzać analizowany AST (i przekształcić ją w zapytania SQL może), można zaimplementować dostarczonego interfejs RSQLVisitor lub uproszczony NoArgRSQLVisitorAdapter.

i ma następujący przykład o tym, jak to zrobić:

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

wydaje się dość proste, prawda?

Więc crated mój gość tak:

public class RsqlParserVisitor extends NoArgRSQLVisitorAdapter<BooleanExpression> { 

Zaimplementowane wszystkie metody interfejsy wymagane do mnie.

Tu dodam dwa przykłady:

@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; 
} 

i

@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; 
} 

Teraz utknąłem:

a) W celu stworzenia QueryDsl BooleanExpression, muszę wiedzieć klasa przetwarzam na przykład:

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

lub

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

b) Kiedy przetestować mojego kodu, to tylko wykonuje public BooleanExpression visit(OrNode arg0) metoda, nic. Zatrzymuje się właśnie tam.

W tej chwili nie mogę wiele zrobić. Nie można jeszcze utworzyć BooleanExpression, ponieważ najpierw muszę przejść przez niektóre metody ComparisonNode, a następnie połączyć je z wyrażeniem logicznym "lub" lub "i". Dobrze?

Gdybym przynajmniej mógł przejść przez wszystkie węzły, mógłbym znaleźć sposób na przekazanie klasy, nie martwię się tym. Ale nie rozumiem, jak przejść przez wszystkie węzły i nie były w stanie tego zrobić.

Wszelkie wskazówki do rozwiązania tego problemu zostaną docenione.

+0

Czy kiedykolwiek znaleźć kompletne rozwiązanie dla tego? Chciałbym o tym usłyszeć. –

+0

Skończyłem na wyszukiwaniu własnych ... i do tej pory tak dobrze: to działa. Ale od czasu do czasu muszę naprawiać rzeczy, gdy nie działają; Wiem, że to nie jest doskonałe. Z chęcią pomogę, jeśli masz konkretne pytania. Mam nadzieję, że niedługo znajdę trochę wolnego czasu (ha ha) i mogę tu podać kilka wskazówek, ale nie mogę niczego obiecać. :) – elysch

Odpowiedz

0

Jak zwykle, po zadaniu pytania wykonałem świetny (jak sądzę) postęp.

Znaleziono sposób na przemierzanie wszystkich węzłów i znajdowanie sposobu przekazania obiektu QueryDsl PathBuilder<?> gościowi.

PathBuilder<?> to klasa nadrzędna wszystkich klas QSomething utworzonych przez QueryDsl.

Teraz utknąłem ponownie szukając sposobu na stworzenie BooleanExpression.

Każda pomoc zostanie bardzo doceniona.

teraz mam następujących w moim 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; 

}  

i to w odwiedzającego:

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

Witam, mam prosty projekt open-source, który łączy w sobie rsql-parser v2.x.x i querydsl-core v3.x.x, wciąż jest w toku. Wyniosłem go z mojego doświadczenia zawodowego, łącząc rsql-parser v1.x.x i querydsl. Tym razem chcę go odsłonić w githubie, możesz go znaleźć tutaj. https://github.com/vineey/rsql-querydsl Obecnie pracuję w tej branży https://github.com/vineey/rsql-querydsl/tree/feature/filter-api – vine

+0

FYI, Planuję skończyć tę bibliotekę przed końcem października 2015 roku. – vine

+0

FYI, mam przyjemność ogłosić pierwsze wydanie produkcyjne mojego projektu opensource rsql-queryds oznaczonego jako 1.0.0.RELEASE https://github.com/vineey/archelix-rsql/ – vine