Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions src/main/java/com/aerospike/dsl/DSLParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.aerospike.dsl;

import com.aerospike.client.exp.Expression;
import com.aerospike.client.query.Filter;
import com.aerospike.dsl.exception.AerospikeDSLException;

import java.util.List;

/**
* Contains API to convert dot separated String path into an Aerospike filter -
* a functional language for applying predicates to bin data and record metadata.
* <br>
* Such filters are used in different areas of Aerospike Server functionality including the following:
* <ul>
* <li> filtering queries (acting as the WHERE clause),</li>
* <li> filtering batch operations,</li>
* <li> conditionally executing single key operations (get, put, delete, operate),</li>
* <li> defining secondary indexes.</li>
* </ul>
*/
public interface DSLParser {

/**
* Parse String DSL path into Aerospike filter Expression.
* <br><br>
* Examples:
* <table border="1">
* <tr>
* <td> $.binName </td> <td> Bin “binName” </td>
* </tr>
* <tr>
* <td> a </td> <td> Map key “a” </td>
* </tr>
* <tr>
* <td> '1' </td> <td> Map key (String) “1” </td>
* </tr>
* <tr>
* <td> 1 </td> <td> Map key 1 </td>
* </tr>
* <tr>
* <td> {1} </td> <td> Map index 1 </td>
* </tr>
* <tr>
* <td> {=1} </td> <td> Map value (int) 1 </td>
* </tr>
* <tr>
* <td> {=bb} </td> <td> Map value “bb” </td>
* </tr>
* <tr>
* <td> {='1'} </td> <td> Map value (String) “1” </td>
* </tr>
* <td> {#1} </td> <td> Map rank 1 </td>
* </tr>
* <tr>
* <td> [1] </td> <td> List index 1 </td>
* </tr>
* <tr>
* <td> [=1] </td> <td> List value 1 </td>
* </tr>
* <tr>
* <td> [#1] </td> <td> List rank 1 </td>
* </table>
* <br>
* <table border="1">
* <tr>
* <td> $.binName </td> <td> [binName] </td>
* </tr>
* <tr>
* <td> $.mapBinName.k </td> <td> [mapBinName -> mapKey("a")] </td>
* </tr>
* <tr>
* <td> $.mapBinName.a.aa.aaa </td> <td> [mapBinName -> mapKey("a") -> mapKey("aa") -> mapKey("aaa")] </td>
* </tr>
* <tr>
* <td> $.mapBinName.a.55 </td> <td> [mapBinName -> mapKey("a") -> mapKey(55)] </td>
* </tr>
* <tr>
* <td> $.listBinName.[1].aa </td> <td> [listBinName -> listIndex(1) -> mapKey("aa")] </td>
* </tr>
* <tr>
* <td> $.mapBinName.ab.cd.[-1].'10' </td> <td> [mapBinName -> mapKey("ab") -> mapKey("cd") -> listIndex(-1) ->
* mapKey("10")] </td>
* </tr>
* </table>
* @param input String consisting of dot separated elements, typically bin name and optional context
* @return Expression object
* @throws AerospikeDSLException in case of unsupported DSL String or invalid syntax
*/
Expression parseExpression(String input);

/**
* Parse String DSL path into Aerospike secondary index Filter.
* <br><br>
* Examples:
* <table border="1">
* <tr>
* <td> $.intBin1 == 10 </td> <td> Filter.equal("intBin1", 10) </td>
* </tr>
* <tr>
* <td> $.intBin1 > 10 </td> <td> Filter.range("intBin1", 11, Long.MAX_VALUE) </td>
* </tr>
* <tr>
* <td> $.stringBin1 == 'text' </td> <td> Filter.equal("stringBin1", "text") </td>
* </tr>
* </table>
* @param input String consisting of dot separated elements, typically bin name and value
* @return List of Filter objects
* @throws AerospikeDSLException in case of unsupported DSL String or invalid syntax
*/
List<Filter> parseFilters(String input);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@

import com.aerospike.client.exp.Exp;
import com.aerospike.client.exp.Expression;
import com.aerospike.client.query.Filter;
import com.aerospike.dsl.annotation.Beta;
import com.aerospike.dsl.exception.AerospikeDSLException;
import com.aerospike.dsl.model.AbstractPart;
import lombok.experimental.UtilityClass;
import com.aerospike.dsl.visitor.ExpressionConditionVisitor;
import com.aerospike.dsl.visitor.FilterConditionVisitor;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;

@UtilityClass
public class ConditionTranslator {
import java.util.List;

public class DSLParserImpl implements DSLParser {

@Beta
public static Expression translate(String input) {
public Expression parseExpression(String input) {
ConditionLexer lexer = new ConditionLexer(CharStreams.fromString(input));
ConditionParser parser = new ConditionParser(new CommonTokenStream(lexer));
ParseTree tree = parser.parse();
Expand All @@ -29,4 +32,19 @@ public static Expression translate(String input) {
Exp expResult = abstractPart.getExp();
return Exp.build(expResult);
}

@Beta
public List<Filter> parseFilters(String input) {
ConditionLexer lexer = new ConditionLexer(CharStreams.fromString(input));
ConditionParser parser = new ConditionParser(new CommonTokenStream(lexer));
ParseTree tree = parser.parse();

FilterConditionVisitor visitor = new FilterConditionVisitor();
AbstractPart abstractPart = visitor.visit(tree);

if (abstractPart == null) {
throw new AerospikeDSLException("Could not parse given input, wrong syntax");
}
return abstractPart.getSIndexFilter().getFilters();
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/aerospike/dsl/model/AbstractPart.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public abstract class AbstractPart {
protected Exp.Type expType;
protected PartType partType;
protected Exp exp;
protected SIndexFilter sIndexFilter;

protected AbstractPart(PartType partType) {
this.partType = partType;
Expand All @@ -22,6 +23,11 @@ protected AbstractPart(PartType partType, Exp exp) {
this.exp = exp;
}

protected AbstractPart(PartType partType, SIndexFilter filters) {
this.partType = partType;
this.sIndexFilter = filters;
}

public enum PartType {
INT_OPERAND,
FLOAT_OPERAND,
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/aerospike/dsl/model/BinPart.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class BinPart extends Expr {
private final String binName;

public BinPart(String binName) {
super(null); // Exp unknown
super((Exp) null); // Exp unknown
this.binName = binName;
this.partType = PartType.BIN_PART;
this.expType = null; // Exp type unknown
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/aerospike/dsl/model/Expr.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,29 @@
@Getter
public class Expr extends AbstractPart {

protected AbstractPart left;
protected AbstractPart right;
private ExprPartsOperation operationType;

public Expr(Exp exp) {
super(PartType.EXPR, exp);
}

public Expr(SIndexFilter filter) {
super(PartType.EXPR, filter);
}

public Expr(AbstractPart left, AbstractPart right, ExprPartsOperation operationType) {
super(PartType.EXPR);
this.left = left;
this.right = right;
this.operationType = operationType;
}

public enum ExprPartsOperation {
ADD,
SUB,
DIV,
MUL
}
}
22 changes: 22 additions & 0 deletions src/main/java/com/aerospike/dsl/model/SIndexFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.aerospike.dsl.model;

import com.aerospike.client.query.Filter;
import lombok.Getter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class SIndexFilter {

@Getter
protected final List<Filter> filters = new ArrayList<>();

public SIndexFilter(Filter filter) {
filters.add(filter);
}

public SIndexFilter(Collection<Filter> filters) {
this.filters.addAll(filters);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import com.aerospike.dsl.ConditionParser;
import com.aerospike.dsl.exception.AerospikeDSLException;
import com.aerospike.dsl.model.BasePath;
import com.aerospike.dsl.util.ParsingUtils;

import static com.aerospike.dsl.util.ParsingUtils.unquote;
import static com.aerospike.dsl.util.ParsingUtils.subtractNullable;

public class ListRankRangeRelative extends ListPart {
Expand Down Expand Up @@ -51,7 +51,7 @@ public static ListRankRangeRelative from(ConditionParser.ListRankRangeRelativeCo
} else if (valueIdentifierContext.NAME_IDENTIFIER() != null) {
relativeValue = valueIdentifierContext.NAME_IDENTIFIER().getText();
} else if (valueIdentifierContext.QUOTED_STRING() != null) {
relativeValue = ParsingUtils.getWithoutQuotes(valueIdentifierContext.QUOTED_STRING().getText());
relativeValue = unquote(valueIdentifierContext.QUOTED_STRING().getText());
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/aerospike/dsl/model/cdt/list/ListValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import com.aerospike.client.exp.ListExp;
import com.aerospike.dsl.ConditionParser;
import com.aerospike.dsl.model.BasePath;
import com.aerospike.dsl.util.ParsingUtils;

import static com.aerospike.dsl.util.ParsingUtils.unquote;

public class ListValue extends ListPart {
private final Object value;
Expand All @@ -21,7 +22,7 @@ public static ListValue from(ConditionParser.ListValueContext ctx) {
if (ctx.valueIdentifier().NAME_IDENTIFIER() != null) {
listValue = ctx.valueIdentifier().NAME_IDENTIFIER().getText();
} else if (ctx.valueIdentifier().QUOTED_STRING() != null) {
listValue = ParsingUtils.getWithoutQuotes(ctx.valueIdentifier().QUOTED_STRING().getText());
listValue = unquote(ctx.valueIdentifier().QUOTED_STRING().getText());
} else if (ctx.valueIdentifier().INT() != null) {
listValue = Integer.parseInt(ctx.valueIdentifier().INT().getText());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import java.util.List;

import static com.aerospike.dsl.util.ParsingUtils.getWithoutQuotes;
import static com.aerospike.dsl.util.ParsingUtils.unquote;

public class ListValueList extends ListPart {
private final boolean inverted;
Expand All @@ -36,7 +36,7 @@ public static ListValueList from(ConditionParser.ListValueListContext ctx) {
if (listValue.NAME_IDENTIFIER() != null) {
return listValue.NAME_IDENTIFIER().getText();
} else if (listValue.QUOTED_STRING() != null) {
return getWithoutQuotes(listValue.QUOTED_STRING().getText());
return unquote(listValue.QUOTED_STRING().getText());
}
return Integer.parseInt(listValue.INT().getText());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import com.aerospike.dsl.ConditionParser;
import com.aerospike.dsl.exception.AerospikeDSLException;
import com.aerospike.dsl.model.BasePath;
import com.aerospike.dsl.util.ParsingUtils;

import static com.aerospike.dsl.util.ParsingUtils.unquote;
import static com.aerospike.dsl.util.ParsingUtils.subtractNullable;

public class MapIndexRangeRelative extends MapPart {
Expand Down Expand Up @@ -47,7 +47,7 @@ public static MapIndexRangeRelative from(ConditionParser.MapIndexRangeRelativeCo
if (mapKeyContext.NAME_IDENTIFIER() != null) {
relativeKey = mapKeyContext.NAME_IDENTIFIER().getText();
} else if (mapKeyContext.QUOTED_STRING() != null) {
relativeKey = ParsingUtils.getWithoutQuotes(mapKeyContext.QUOTED_STRING().getText());
relativeKey = unquote(mapKeyContext.QUOTED_STRING().getText());
}
}
return new MapIndexRangeRelative(isInverted, start, end, relativeKey);
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/aerospike/dsl/model/cdt/map/MapKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import com.aerospike.dsl.ConditionParser;
import com.aerospike.dsl.exception.AerospikeDSLException;
import com.aerospike.dsl.model.BasePath;
import com.aerospike.dsl.util.ParsingUtils;

import static com.aerospike.dsl.util.ParsingUtils.unquote;

public class MapKey extends MapPart {
private final String key;
Expand All @@ -19,7 +20,7 @@ public MapKey(String key) {

public static MapKey from(ConditionParser.MapKeyContext ctx) {
if (ctx.QUOTED_STRING() != null) {
return new MapKey(ParsingUtils.getWithoutQuotes(ctx.QUOTED_STRING().getText()));
return new MapKey(unquote(ctx.QUOTED_STRING().getText()));
}
if (ctx.NAME_IDENTIFIER() != null) {
return new MapKey(ctx.NAME_IDENTIFIER().getText());
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/aerospike/dsl/model/cdt/map/MapKeyList.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
import com.aerospike.dsl.ConditionParser;
import com.aerospike.dsl.exception.AerospikeDSLException;
import com.aerospike.dsl.model.BasePath;
import com.aerospike.dsl.util.ParsingUtils;

import java.util.List;

import static com.aerospike.dsl.util.ParsingUtils.unquote;

public class MapKeyList extends MapPart {
private final boolean inverted;
private final List<String> keyList;
Expand All @@ -35,7 +36,7 @@ public static MapKeyList from(ConditionParser.MapKeyListContext ctx) {
if (mapKey.NAME_IDENTIFIER() != null) {
return mapKey.NAME_IDENTIFIER().getText();
} else {
return ParsingUtils.getWithoutQuotes(mapKey.QUOTED_STRING().getText());
return unquote(mapKey.QUOTED_STRING().getText());
}
}
).toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
import com.aerospike.dsl.ConditionParser;
import com.aerospike.dsl.exception.AerospikeDSLException;
import com.aerospike.dsl.model.BasePath;
import com.aerospike.dsl.util.ParsingUtils;

import java.util.Optional;

import static com.aerospike.dsl.util.ParsingUtils.unquote;

public class MapKeyRange extends MapPart {
private final boolean inverted;
private final String start;
Expand All @@ -34,12 +35,12 @@ public static MapKeyRange from(ConditionParser.MapKeyRangeContext ctx) {

String startKey = range.mapKey(0).NAME_IDENTIFIER() != null
? range.mapKey(0).NAME_IDENTIFIER().getText()
: ParsingUtils.getWithoutQuotes(range.mapKey(0).QUOTED_STRING().getText());
: unquote(range.mapKey(0).QUOTED_STRING().getText());

String endKey = Optional.ofNullable(range.mapKey(1))
.map(keyCtx -> keyCtx.NAME_IDENTIFIER() != null
? keyCtx.NAME_IDENTIFIER().getText()
: ParsingUtils.getWithoutQuotes(keyCtx.QUOTED_STRING().getText()))
: unquote(keyCtx.QUOTED_STRING().getText()))
.orElse(null);

return new MapKeyRange(isInverted, startKey, endKey);
Expand Down
Loading