FQL improvements

This commit is contained in:
2020-11-13 22:25:36 +01:00
parent 2c234aee36
commit b756b7d614
8 changed files with 53 additions and 3 deletions

View File

@@ -21,7 +21,7 @@ orderByExpression
// regular expressions - NOT regex
regularExpression
: (stringExpression | intExpression | booleanExpression | dateExpression) ;
: (stringExpression | intExpression | booleanExpression | dateExpression | likeExpression) ;
stringExpression
: field=IDENTIFIER operator=STRING_OPERATOR value=STRING_VALUE ;
intExpression
@@ -32,6 +32,8 @@ booleanExpression
dateExpression
: field=IDENTIFIER operator=STRING_OPERATOR value=DATE_VALUE ;
likeExpression : field=IDENTIFIER LIKE value=STRING_VALUE ;
// BETWEEN expressions
betweenExpression
: (betweenStringExpression | betweenIntExpression ) ;
@@ -70,6 +72,8 @@ fragment Y : ('Y' | 'y') ;
fragment G : ('G' | 'g') ;
fragment O : ('O' | 'o') ;
fragment F : ('F' | 'f') ;
fragment I : ('I' | 'i') ;
fragment K : ('K' | 'k') ;
fragment SPACE : ' ' ;
// Keywords
@@ -81,6 +85,7 @@ DESC : D E S C ;
ASC : A S C ;
TRUE : T R U E ;
FALSE : F A L S E ;
LIKE : L I K E ;
// Constant values
CURRENT : C U R R E N T ;
@@ -96,7 +101,7 @@ L_PAREN : '(' ;
R_PAREN : ')' ;
IDENTIFIER : [a-zA-Z]+ ;
INT_VALUE : [0-9]+ ;
STRING_VALUE : '\'' [a-zA-Z0-9\-/ ]+ '\'' ;
STRING_VALUE : '\'' [a-zA-Z0-9\-/.&%@$ ]+ '\'' ;
DATE_VALUE : [0-9-]+ ;
NEWLINE : ('\r'? '\n' | '\r')+ ;

View File

@@ -140,6 +140,16 @@ public class FQLVisitorImpl extends FQLBaseVisitor<Predicate> {
.apply(fieldMapping, this.froms, this.criteriaBuilder, ctx.value.getText());
}
@Override
public Predicate visitLikeExpression(FQLParser.LikeExpressionContext ctx) {
final FieldMapping fieldMapping = FieldMapping.findByFieldName(ctx.field.getText());
fieldMapping.getJoinHandler().apply(this.froms, fieldMapping);
return fieldMapping.getFieldHandler()
.apply(fieldMapping, this.froms, this.criteriaBuilder, ctx.value.getText());
}
@Override
public Predicate visitIntExpression(FQLParser.IntExpressionContext ctx) {
final FieldMapping fieldMapping = FieldMapping.findByFieldName(ctx.field.getText());

View File

@@ -32,7 +32,10 @@ public enum FieldMapping {
TAX_RELEVANT("taxRelevant", Transaction_.TAX_RELEVANT, Transaction.class, NoopJoinHandler.class,
JoinKey.of(Transaction.class), null, BooleanHandler.class),
HAS_FILE("hasFile", File_.ID, File.class, FileJoinHandler.class, JoinKey.of(File.class), null, NotNullSyntheticHandler.class);
HAS_FILE("hasFile", File_.ID, File.class, FileJoinHandler.class, JoinKey.of(File.class), null, NotNullSyntheticHandler.class),
DESCRIPTION("description", Transaction_.DESCRIPTION, Transaction.class, NoopJoinHandler.class, JoinKey.of(Transaction.class),
null, LikeHandler.class);
/**
* The name of the field as used in FQL

View File

@@ -0,0 +1,21 @@
package de.financer.fql.field_handler;
import de.financer.fql.FieldMapping;
import de.financer.fql.join_handler.JoinKey;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Predicate;
import java.util.Map;
public class LikeHandler implements FieldHandler<String> {
@Override
public Predicate apply(FieldMapping fieldMapping, Map<JoinKey, From<?, ?>> froms, CriteriaBuilder criteriaBuilder, String value) {
return criteriaBuilder
.like(criteriaBuilder.lower(froms.get(fieldMapping.getJoinKey()).get(fieldMapping.getAttributeName())), removeQuotes(value).toLowerCase());
}
private String removeQuotes(String value) {
return value.replaceAll("'", "");
}
}

View File

@@ -140,6 +140,7 @@ financer.search-transactions.show-query-options.date=date\: the date of the tran
financer.search-transactions.show-query-options.recurring=recurring\: whether the transaction has been created from a recurring transaction
financer.search-transactions.show-query-options.taxRelevant=taxRelevant\: whether the transaction is relevant for tax declaration
financer.search-transactions.show-query-options.hasFile=hasFile\: whether the transaction has a file linked
financer.search-transactions.show-query-options.description=description\: the description of the transaction
financer.search-transactions.show-query-options.period=period\: the period the transaction is assigned to
financer.search-transactions.show-query-options.period.CURRENT=CURRENT\: denotes the current expense period
financer.search-transactions.show-query-options.period.LAST=LAST\: denotes the last expense period
@@ -153,6 +154,7 @@ financer.search-transactions.show-query-options.strings=Strings enclosed in sing
financer.search-transactions.show-query-options.case=Case-insensitive
financer.search-transactions.show-query-options.operators=Possible operators =, >, >=, <, <=, !=
financer.search-transactions.show-query-options.ordering=Ordering for a single field ASC, DESC via ORDER BY
financer.search-transactions.show-query-options.like=Fuzzy search with LIKE, % as wildcard (only applicable for field description)
financer.chart-select.title=Select a chart to generate
financer.chart-select.submit=Select

View File

@@ -140,6 +140,7 @@ financer.search-transactions.show-query-options.date=date\: das Datum der Buchun
financer.search-transactions.show-query-options.recurring=recurring\: ob die Buchung durch eine wiederkehrende Buchung erzeugt wurde
financer.search-transactions.show-query-options.taxRelevant=taxRelevant\: ob die Buchung als steuerrelevant markiert wurde
financer.search-transactions.show-query-options.hasFile=hasFile\: ob eine Datei der Buchung zugeordnet ist
financer.search-transactions.show-query-options.description=description\: die Beschreibung der Buchung
financer.search-transactions.show-query-options.period=period\: die Periode der Buchung
financer.search-transactions.show-query-options.period.CURRENT=CURRENT\: bezeichnet die aktuelle Ausgabenperiode
financer.search-transactions.show-query-options.period.LAST=LAST\: bezeichnet die letzte Ausgabenperiode
@@ -153,6 +154,7 @@ financer.search-transactions.show-query-options.strings=Zeichenketten werden dur
financer.search-transactions.show-query-options.case=Unterscheidung von Gro\u1E9E- und Kleinschreibung
financer.search-transactions.show-query-options.operators=Unterst\u00FCtzte Operatoren =, >, >=, <, <=, !=
financer.search-transactions.show-query-options.ordering=Sortierung \u00FCber ein einziges Feld mit ASC (aufsteigend), DESC (absteigend) via ORDER BY
financer.search-transactions.show-query-options.like=Platzhaltersuche mit LIKE, % als Platzhalter (nur anwendbar bei Feld description)
financer.chart-select.title=Ein Diagramm zum Erzeugen ausw\u00E4hlen
financer.chart-select.submit=Ausw\u00E4hlen

View File

@@ -1,3 +1,8 @@
v33 -> v34:
- Fix a bug in the parsing of FQL
- Add the transaction description field to the FQL search
- Add LIKE support to the FQL search
v32 -> v33:
- Introduce Holiday/Weekend Type SKIP to skip an occurrence of a recurring transaction once, if the due date is either a
holiday or a weekend day

View File

@@ -32,6 +32,7 @@
<li th:text="#{financer.search-transactions.show-query-options.recurring}" />
<li th:text="#{financer.search-transactions.show-query-options.taxRelevant}" />
<li th:text="#{financer.search-transactions.show-query-options.hasFile}" />
<li th:text="#{financer.search-transactions.show-query-options.description}" />
<li><span th:text="#{financer.search-transactions.show-query-options.period}" />
<ul>
<li th:text="#{financer.search-transactions.show-query-options.period.CURRENT}" />
@@ -52,6 +53,7 @@
<li th:text="#{financer.search-transactions.show-query-options.case}" />
<li th:text="#{financer.search-transactions.show-query-options.operators}" />
<li th:text="#{financer.search-transactions.show-query-options.ordering}" />
<li th:text="#{financer.search-transactions.show-query-options.like}" />
</ul>
</p>
</div>