Finished draft implementation with some TODO's left

This commit is contained in:
msmock 2018-01-04 14:30:51 +01:00
parent 063f94e382
commit 5e2a797b17
13 changed files with 703 additions and 291 deletions

View File

@ -13,38 +13,39 @@ import li.strolch.soql.core.expresssion.WhereExpression;
*/
public class CompiledStatement {
// the map of entities declared in the FROM clause with their nicknames as keys
Map<String, String> entities = new HashMap<>();
// the map of entities declared in the FROM clause with their nicknames as keys
Map<String, String> entities = new HashMap<>();
// the decision tree as defined in the WHERE clause
WhereExpression whereExpression;
// the decision tree as defined in the WHERE clause
WhereExpression whereExpression;
// the expression evaluating to the selected objects according to the SELECT
// clause
public SelectClause selectClause;
// the expression evaluating to the selected objects according to the SELECT clause
public SelectClause selectClause;
/**
*
* @return List of objects resulting from running the compiled code
*/
public List<Object> evaluate(Map<String, Object> inputObjects, Map<String, Object> injectedObjects) {
/**
*
* @param inputObjects
* @param queryParameter
*
* @return List of objects resulting from running the compiled code
*/
public List<Object> evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
boolean evaluateWhereExpression = true;
if (whereExpression != null) {
evaluateWhereExpression = whereExpression.evaluate(inputObjects, injectedObjects);
}
boolean evaluateWhereExpression = true;
if (whereExpression != null)
evaluateWhereExpression = whereExpression.evaluate(inputObjects, queryParameter);
if (evaluateWhereExpression) {
return selectClause.evaluate(inputObjects, injectedObjects);
}
if (evaluateWhereExpression)
return selectClause.evaluate(inputObjects, queryParameter);
return new ArrayList<>();
}
// else return empty list
return new ArrayList<>();
}
@Override
public String toString() {
return "CompiledStatement [entities=" + entities + ", whereExpression=" + whereExpression + ", selectClause="
+ selectClause + "]";
}
@Override
public String toString() {
return "CompiledStatement [entities=" + entities + ", whereExpression=" + whereExpression + ", selectClause="
+ selectClause + "]";
}
}

View File

@ -0,0 +1,43 @@
package li.strolch.soql.core;
import java.util.Iterator;
/**
* Iterator used to build the cartesian product defined in the FROM clause
*/
public class IndexPointer implements Iterator {
final int[] numberOfEntities;
final int[] pointer;
public IndexPointer(int[] numberOfEntities) {
this.numberOfEntities = numberOfEntities;
this.pointer = new int[numberOfEntities.length];
this.pointer[pointer.length-1]--;
}
public int[] next() {
pointer[pointer.length - 1]++;
normalize();
return pointer;
}
public boolean hasNext() {
for (int i = 0; i < pointer.length; i++) {
if (pointer[i] < numberOfEntities[i] - 1) {
return true;
}
}
return false;
}
private void normalize() {
for (int i = pointer.length - 1; i >= 0; i--) {
if (pointer[i] == numberOfEntities[i]) {
pointer[i] = 0;
pointer[i - 1]++;
}
}
}
}

View File

@ -0,0 +1,210 @@
package li.strolch.soql.core;
import li.strolch.model.StrolchRootElement;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.ResourceQuery;
import li.strolch.model.query.StrolchElementQuery;
import li.strolch.soql.antlr4.generated.SOQLLexer;
import li.strolch.soql.antlr4.generated.SOQLParser;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.util.*;
/**
* Main class to process a SOQL query. It performs the queries to retrieve the
* input objects as defined in the FROM clause and evaluates the compiled
* statement on any cartesian product, returning the objects defined in the
* SELECT clause.
*
* @author msmock
*/
public class QueryProcessor {
// Map of queries to retrieve the input objects
protected Map<String, StrolchElementQuery> queries;
// Map of entities the input objects are taken from
protected Map<String, List<StrolchRootElement>> inputCollections;
/**
* empty constructor
*/
public QueryProcessor() {
}
/**
* Set the input map of collections to take the input objects from. For testing
* purposes only.
*
* @param inputCollections
*/
void setInputCollections(Map<String, List<StrolchRootElement>> inputCollections) {
this.inputCollections = inputCollections;
}
/**
* @param request
* @return the query response object covering the result set
*/
public QueryResponse process(QueryRequest request) {
String statement = request.getStatement();
CompiledStatement compiledStatement = null;
try {
ParseTree tree = parseStatement(statement);
compiledStatement = compile(tree);
} catch (Exception e) {
// TODO add error handling
e.printStackTrace();
throw new SOQLParseException(e.getMessage());
}
// build the input collections, if not set already
if (inputCollections == null) {
queries = entity2Query(compiledStatement.entities);
// TODO perform the queries
}
// build cartesian product
Object[] keys = inputCollections.keySet().toArray();
List<List<StrolchRootElement>> cartesianProduct = buildCartesianProduct(inputCollections, keys);
ResultSet resultSet = new ResultSet();
// apply the compiled statement to any row of the cartesian product
for (List<StrolchRootElement> row : cartesianProduct) {
Map<String, Object> inputObjects = new HashMap<>();
for (int i = 0; i < row.size(); i++) {
inputObjects.put((String) keys[i], row.get(i));
}
List<Object> resultRow = compiledStatement.evaluate(inputObjects, request.getParameter());
if (!resultRow.isEmpty())
resultSet.add(resultRow);
}
QueryResponse response = new QueryResponse();
response.setStatement(statement);
response.setParameter(request.getParameter());
response.setResultSet(resultSet);
return response;
}
/**
* @param inputCollections
* @param keys
* @return List of Lists of the elements to be taken as input for the compiled statement
*/
private List<List<StrolchRootElement>> buildCartesianProduct(Map<String, List<StrolchRootElement>> inputCollections, Object[] keys) {
int numberOfKeys = keys.length;
// get an overview of how many elements we have to take into account
int[] numberOfEntities = new int[numberOfKeys];
for (int keyIndex = 0; keyIndex < numberOfKeys; keyIndex++) {
numberOfEntities[keyIndex] = inputCollections.get(keys[keyIndex]).size();
}
// build cartesian product
List<List<StrolchRootElement>> cartesianProduct = new ArrayList<>();
IndexPointer indexPointer = new IndexPointer(numberOfEntities);
while (indexPointer.hasNext()) {
List<StrolchRootElement> row = new ArrayList<>();
cartesianProduct.add(row);
int[] pointer = indexPointer.next();
// fasten your seat belts, here we go
for (int keyIndex = 0; keyIndex < numberOfKeys; keyIndex++) {
Object key = keys[keyIndex];
List<StrolchRootElement> elements = inputCollections.get(key);
StrolchRootElement element = elements.get(pointer[keyIndex]);
row.add(element);
}
}
return cartesianProduct;
}
/**
* parse the string and return the antlr tree
*
* @throws Exception
*/
ParseTree parseStatement(String s) throws Exception {
// build a buffer of tokens pulled from the lexer
CharStream input = CharStreams.fromString(s);
SOQLLexer lexer = new SOQLLexer(input);
// build a parser that feeds off the tokens buffer
CommonTokenStream tokens = new CommonTokenStream(lexer);
SOQLParser parser = new SOQLParser(tokens);
parser.addErrorListener(new VerboseListener());
return parser.select_statement();
}
/**
* compile the antlr tree to executeable code
*
* @param tree
* @return CompiledSOQLStatement
* @throws Exception
*/
CompiledStatement compile(ParseTree tree) throws Exception {
ParseTreeWalker walker = new ParseTreeWalker();
SOQLListener listener = new SOQLListener();
walker.walk(listener, tree);
CompiledStatement soqlStatement = new CompiledStatement();
soqlStatement.entities = listener.getEntities();
soqlStatement.whereExpression = listener.getWhereExpression();
soqlStatement.selectClause = listener.getSelectClause();
return soqlStatement;
}
/**
* Resolve the entities extracted from the FROM clause to the
* StrolchElementQuery to be performed to retrieve the input objects.
*
* @param entities
* @return Map of queries for the entities defining the objects returned
*/
Map<String, StrolchElementQuery> entity2Query(Map<String, String> entities) {
Map<String, StrolchElementQuery> result = new HashMap<>();
Set<String> keys = entities.keySet();
for (String key : keys) {
String clazzKey = entities.get(key);
switch (clazzKey) {
case "Resource":
result.put(key, new ResourceQuery());
break;
case "Order":
result.put(key, new OrderQuery());
break;
case "Activity":
result.put(key, new ActivityQuery());
break;
default:
String s = "Unable to resolve " + clazzKey + " to strolch entity query.";
throw new SOQLParseException(s);
}
}
return result;
}
}

View File

@ -14,66 +14,70 @@ import java.util.Set;
*/
public class QueryRequest {
public static final String STATEMENT = "statement";
public static final String PARAMETER = "parameter";
public static final String STATEMENT = "statement";
public static final String PARAMETER = "queryParameter";
// the SOQL query string
private String statement;
// the SOQL query string
String statement;
// the parameter of the SOQL query
private Map<String, String> parameter = new HashMap<>();
// the parameter of the SOQL query
Map<String, Object> parameter = new HashMap<>();
public String getStatement() {
return statement;
}
public String getStatement() {
return statement;
}
public void setStatement(String statement) {
this.statement = statement;
}
public void setStatement(String statement) {
this.statement = statement;
}
public Map<String, String> getParameter() {
return parameter;
}
public Map<String, Object> getParameter() {
return parameter;
}
/**
* @return the query as JsonObject
*/
public JsonObject asJson() {
public void setParameter(Map<String, Object> parameter) {
this.parameter = parameter;
}
final JsonObject rootJ = new JsonObject();
rootJ.addProperty(Tags.Json.OBJECT_TYPE, "QueryRequest");
rootJ.addProperty(STATEMENT, statement);
/**
* @return the query as JsonObject
*/
public JsonObject asJson() {
final JsonObject parameterJ = new JsonObject();
rootJ.add(PARAMETER, parameterJ);
JsonObject rootJ = new JsonObject();
rootJ.addProperty(Tags.Json.OBJECT_TYPE, "QueryRequest");
rootJ.addProperty(STATEMENT, statement);
final Set<String> keys = parameter.keySet();
for (Iterator<String> iterator = keys.iterator(); iterator.hasNext(); ) {
final String key = iterator.next();
final Object param = parameter.get(key);
parameterJ.addProperty(key, param.toString());
}
JsonObject parameterJ = new JsonObject();
rootJ.add(PARAMETER, parameterJ);
return rootJ;
}
Set<String> keys = parameter.keySet();
for (Iterator<String> iterator = keys.iterator(); iterator.hasNext();) {
String key = iterator.next();
Object param = parameter.get(key);
parameterJ.addProperty(key, param.toString());
}
/**
* build request from Json object
*
* @return
*/
public QueryRequest fromJson(JsonObject jsonObject) {
return rootJ;
}
final String statement = jsonObject.get(STATEMENT).getAsString();
setStatement(statement);
/**
* build request from Json object
*
* @return
*/
public QueryRequest fromJson(JsonObject jsonObject) {
final JsonObject params = jsonObject.getAsJsonObject(PARAMETER);
final Set<Map.Entry<String, JsonElement>> entrySet = params.entrySet();
for (final Map.Entry<String, JsonElement> entry : entrySet) {
parameter.put(entry.getKey(), entry.getValue().getAsString());
}
String statement = jsonObject.get(STATEMENT).getAsString();
setStatement(statement);
return this;
}
JsonObject params = jsonObject.getAsJsonObject(PARAMETER);
Set<Map.Entry<String, JsonElement>> entrySet = params.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
parameter.put(entry.getKey(), entry.getValue().getAsString());
}
return this;
}
}

View File

@ -2,34 +2,49 @@ package li.strolch.soql.core;
import com.google.gson.JsonObject;
import li.strolch.model.Tags;
/**
* @author msmock
*/
public class QueryResponse extends QueryRequest {
// the returned objects
static final String RESULT_SET = "resultSet";
static final String RESULT_SET = "resultSet";
// an exception or error message in case of error
public String message;
// an exception or error message in case of error
public String message;
//
public final ResultSet resultSet = new ResultSet();
// the returned objects
public ResultSet resultSet = new ResultSet();
/**
* @return the query as JsonObject
*/
public JsonObject asJson() {
/**
* @param resultSet the resultSet to set
*/
public void setResultSet(ResultSet resultSet) {
this.resultSet = resultSet;
}
final JsonObject rootJ = super.asJson();
/**
* @return the resultSet
*/
public ResultSet getResultSet() {
return resultSet;
}
if (message != null && !message.isEmpty()) {
rootJ.addProperty("Message", message);
}
/**
* @return the query as JsonObject
*/
public JsonObject asJson() {
rootJ.add(RESULT_SET, resultSet.asJson());
JsonObject rootJ = super.asJson();
rootJ.addProperty(Tags.Json.OBJECT_TYPE, "QueryResponse");
return rootJ;
}
if (message != null && !message.isEmpty()) {
rootJ.addProperty("Message", message);
}
rootJ.add(RESULT_SET, resultSet.asJson());
return rootJ;
}
}

View File

@ -1,56 +1,71 @@
package li.strolch.soql.core;
import com.google.gson.JsonArray;
import li.strolch.model.StrolchRootElement;
import li.strolch.model.json.StrolchElementToJsonVisitor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import com.google.gson.JsonArray;
import li.strolch.model.StrolchRootElement;
import li.strolch.model.json.StrolchElementToJsonVisitor;
/**
* The query result set as List of Lists
* <p>
*
* TODO: the result set should carry arbitrary objects, not only StrolchRootElements
* TODO: the result set should carry arbitrary objects, not only
* StrolchRootElements
*
* @author msmock
*/
public class ResultSet {
final StrolchElementToJsonVisitor visitor = new StrolchElementToJsonVisitor();
final StrolchElementToJsonVisitor visitor = new StrolchElementToJsonVisitor();
public final List<List<StrolchRootElement>> rows = new ArrayList<>();
public final List<List<StrolchRootElement>> rows = new ArrayList<>();
/**
* @param row the result of the execution of a single statement
*/
public void add(final List<StrolchRootElement> row) {
rows.add(row);
}
/**
* @param row
* the result of the execution of a single statement
*/
public void add(final List<Object> row) {
/**
* @return all rows as JSON Array
*/
public JsonArray asJson() {
List<StrolchRootElement> toBeAdded = new LinkedList<>();
for (Object object : row) {
if (object instanceof StrolchRootElement) {
toBeAdded.add((StrolchRootElement) object);
} else {
System.out.println("Could not add object " + object + " of class " + object.getClass()
+ " to result set. Only StrolchRootElements are supported yet.");
}
}
final JsonArray rowsAsJson = new JsonArray();
rows.add(toBeAdded);
}
for (Iterator<List<StrolchRootElement>> rowsIter = rows.iterator(); rowsIter.hasNext(); )
rowsAsJson.add(row2Json(rowsIter.next()));
/**
* @return all rows as JSON Array
*/
public JsonArray asJson() {
return rowsAsJson;
}
JsonArray rowsAsJson = new JsonArray();
/**
* @return a single row as JSON Array
*/
private JsonArray row2Json(final List<StrolchRootElement> evalResult) {
final JsonArray rowAsJson = new JsonArray();
for (Iterator<StrolchRootElement> iterator = evalResult.iterator(); iterator.hasNext(); ) {
rowAsJson.add(iterator.next().accept(visitor));
}
return rowAsJson;
}
for (Iterator<List<StrolchRootElement>> rowsIter = rows.iterator(); rowsIter.hasNext();)
rowsAsJson.add(row2Json(rowsIter.next()));
return rowsAsJson;
}
/**
* @return a single row as JSON Array
*/
private JsonArray row2Json(final List<StrolchRootElement> evalResult) {
JsonArray rowAsJson = new JsonArray();
for (Iterator<StrolchRootElement> iterator = evalResult.iterator(); iterator.hasNext();) {
rowAsJson.add(iterator.next().accept(visitor));
}
return rowAsJson;
}
}

View File

@ -1,125 +1,156 @@
package li.strolch.soql.core;
import li.strolch.model.*;
import li.strolch.model.parameter.FloatParameter;
import li.strolch.model.parameter.Parameter;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.ResourceQuery;
import li.strolch.model.query.StrolchElementQuery;
import li.strolch.soql.antlr4.generated.SOQLLexer;
import li.strolch.soql.antlr4.generated.SOQLParser;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import li.strolch.model.Order;
import li.strolch.model.ParameterBag;
import li.strolch.model.Resource;
import li.strolch.model.State;
import li.strolch.model.StrolchRootElement;
import li.strolch.model.activity.Activity;
import li.strolch.model.parameter.FloatParameter;
import li.strolch.model.parameter.Parameter;
import li.strolch.soql.antlr4.generated.SOQLLexer;
import li.strolch.soql.antlr4.generated.SOQLParser;
/**
* @author msmock
*/
public abstract class BaseTest {
/**
* parse the string and return the antlr tree
*
* @throws Exception
*/
ParseTree parseString(final String s) throws Exception {
/**
* parse the string and return the antlr tree
*
* @throws Exception
*/
ParseTree parseString(final String s) throws Exception {
final CharStream input = CharStreams.fromString(s);
final SOQLLexer lexer = new SOQLLexer(input); // create a buffer of tokens pulled from the lexer
final CharStream input = CharStreams.fromString(s);
final SOQLLexer lexer = new SOQLLexer(input); // create a buffer of tokens pulled from the lexer
final CommonTokenStream tokens = new CommonTokenStream(lexer); // create a parser that feeds off the tokens buffer
final SOQLParser parser = new SOQLParser(tokens);
parser.addErrorListener(new VerboseListener());
final CommonTokenStream tokens = new CommonTokenStream(lexer); // create a parser that feeds off the tokens
// buffer
final SOQLParser parser = new SOQLParser(tokens);
parser.addErrorListener(new VerboseListener());
final ParseTree tree = parser.select_statement(); // begin parsing at block
final ParseTree tree = parser.select_statement(); // begin parsing at block
// System.out.println(tree.toStringTree(parser)); // print LISP-style tree
// System.out.println(tree.toStringTree(parser)); // print LISP-style tree
return tree;
}
return tree;
}
/**
* compile the antlr tree to executable
*
* @param tree
* @return CompiledSOQLStatement
* @throws Exception
*/
CompiledStatement compile(final ParseTree tree) throws Exception {
/**
* compile the antlr tree to executable
*
* @param tree
* @return CompiledSOQLStatement
* @throws Exception
*/
CompiledStatement compile(final ParseTree tree) throws Exception {
final ParseTreeWalker walker = new ParseTreeWalker();
final SOQLListener listener = new SOQLListener();
walker.walk(listener, tree);
final ParseTreeWalker walker = new ParseTreeWalker();
final SOQLListener listener = new SOQLListener();
walker.walk(listener, tree);
final CompiledStatement soqlStatement = new CompiledStatement();
soqlStatement.entities = listener.getEntities();
soqlStatement.whereExpression = listener.getWhereExpression();
soqlStatement.selectClause = listener.getSelectClause();
final CompiledStatement soqlStatement = new CompiledStatement();
soqlStatement.entities = listener.getEntities();
soqlStatement.whereExpression = listener.getWhereExpression();
soqlStatement.selectClause = listener.getSelectClause();
return soqlStatement;
}
return soqlStatement;
}
/**
* @return a test resource
*/
StrolchRootElement getTestResource(final String id) {
final Resource resource = new Resource();
resource.setId(id);
/**
* @return a test resource
*/
StrolchRootElement getTestResource(final String id) {
final Resource resource = new Resource();
resource.setId(id);
final ParameterBag bag = new ParameterBag();
bag.setId("testBag");
resource.addParameterBag(bag);
final ParameterBag bag = new ParameterBag();
bag.setId("testBag");
resource.addParameterBag(bag);
final Parameter parameter = new FloatParameter();
parameter.setId("testId");
parameter.setValue(100d);
final Parameter<Double> parameter = new FloatParameter();
parameter.setId("testId");
parameter.setValue(100d);
resource.addParameter("testBag", parameter);
return resource;
}
resource.addParameter("testBag", parameter);
return resource;
}
/**
* @return a test order
*/
StrolchRootElement getTestOrder(final String id) {
final Order order = new Order();
order.setId("testId");
/**
* @return a test order
*/
StrolchRootElement getTestOrder(String id) {
Order order = new Order();
order.setId(id);
order.setState(State.CREATED);
final ParameterBag bag = new ParameterBag();
bag.setId("testBag");
order.addParameterBag(bag);
order.setDate(new Date());
final Parameter parameter = new FloatParameter();
parameter.setId("testId");
parameter.setValue(100d);
ParameterBag bag = new ParameterBag();
bag.setId("testBag");
order.addParameterBag(bag);
order.addParameter("testBag", parameter);
return order;
}
Parameter<Double> parameter = new FloatParameter();
parameter.setId("testId");
parameter.setValue(100d);
List<StrolchRootElement> getTestRessources(int n) {
final List<StrolchRootElement> result = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
result.add(getTestResource(String.valueOf(n)));
}
return result;
}
order.addParameter("testBag", parameter);
return order;
}
List<StrolchRootElement> getTestOrders(int n) {
final List<StrolchRootElement> result = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
result.add(getTestOrder(String.valueOf(n)));
}
return result;
}
/**
* @return a test order
*/
StrolchRootElement getTestActivity(final String id) {
final Activity activity = new Activity();
activity.setId(id);
final ParameterBag bag = new ParameterBag();
bag.setId("testBag");
activity.addParameterBag(bag);
final Parameter<Double> parameter = new FloatParameter();
parameter.setId("testId");
parameter.setValue(100d);
activity.addParameter("testBag", parameter);
return activity;
}
List<StrolchRootElement> getTestRessources(int n) {
final List<StrolchRootElement> result = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
result.add(getTestResource(String.valueOf(i)));
}
return result;
}
List<StrolchRootElement> getTestOrders(int n) {
final List<StrolchRootElement> result = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
result.add(getTestOrder(String.valueOf(i)));
}
return result;
}
List<StrolchRootElement> getTestActivities(int n) {
final List<StrolchRootElement> result = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
result.add(getTestActivity(String.valueOf(i)));
}
return result;
}
}

View File

@ -0,0 +1,60 @@
package li.strolch.soql.core;
import li.strolch.model.StrolchRootElement;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class DataStructureTest extends BaseTest {
Map<String, List<StrolchRootElement>> structure;
@Before
public void init() {
structure = new LinkedHashMap<>();
structure.put("r", getTestRessources(6));
structure.put("o", getTestOrders(3));
structure.put("a", getTestActivities(4));
// System.out.println(structure);
}
@Test
public void buildProduct() {
// it's ugly indexing stuff, so here we go
final Object[] keys = structure.keySet().toArray(); // TODO the nickname of the entities
final int numberOfKeys = keys.length;
// get an overview of how many elements we have to take into account
final int[] numberOfEntities = new int[numberOfKeys];
for (int keyIndex = 0; keyIndex < numberOfKeys; keyIndex++) {
numberOfEntities[keyIndex] = structure.get(keys[keyIndex]).size();
}
// build cartesian product
final List<List<StrolchRootElement>> cartesianProduct = new ArrayList<>();
final IndexPointer indexPointer = new IndexPointer(numberOfEntities);
while(indexPointer.hasNext()){
final List<StrolchRootElement> row = new ArrayList<>();
cartesianProduct.add(row);
int[] pointer = indexPointer.next();
// fasten your seat belts, here we go
for (int keyIndex = 0; keyIndex < numberOfKeys; keyIndex++) {
final Object key = keys[keyIndex];
final List<StrolchRootElement> elements = structure.get(key);
final StrolchRootElement element = elements.get(pointer[keyIndex]);
row.add(element);
}
}
// TODO
}
}

View File

@ -1,23 +1,21 @@
package li.strolch.soql.core;
import com.google.gson.JsonObject;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import li.strolch.model.ParameterBag;
import li.strolch.model.Resource;
import li.strolch.model.StrolchElement;
import li.strolch.model.StrolchRootElement;
import li.strolch.model.json.StrolchElementToJsonVisitor;
import li.strolch.model.parameter.Parameter;
import li.strolch.model.parameter.StringParameter;
import li.strolch.soql.core.expresssion.ChainedMethodExpression;
import li.strolch.soql.core.expresssion.MethodArgumentDeclaration;
import li.strolch.soql.core.expresssion.MethodExpression;
import li.strolch.soql.core.expresssion.ParameterReference;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
/**
* @author msmock
@ -32,7 +30,7 @@ public class MethodExpressionTest {
bag.setId("testBag");
resource.addParameterBag(bag);
final Parameter parameter = new StringParameter();
final Parameter<String> parameter = new StringParameter();
parameter.setId("testId");
parameter.setValue("testValue");

View File

@ -0,0 +1,49 @@
package li.strolch.soql.core;
import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import li.strolch.model.StrolchRootElement;
public class QueryProcessorTest extends BaseTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testProcess() {
List<StrolchRootElement> resources = getTestRessources(10);
List<StrolchRootElement> orders = getTestOrders(10);
Map<String, List<StrolchRootElement>> inputCollections = new HashMap<>();
inputCollections.put("r", resources);
inputCollections.put("o", orders);
QueryProcessor processor = new QueryProcessor();
processor.setInputCollections(inputCollections);
QueryRequest request = new QueryRequest();
request.getParameter().put("id", "0");
request.setStatement("SELECT r,o FROM Resource r, Order o WHERE r.getId() = :id AND o.getId() = :id");
QueryResponse response = processor.process(request);
System.out.println(response.asJson());
// TBD what to assert
}
}

View File

@ -1,28 +1,19 @@
package li.strolch.soql.core;
import li.strolch.model.Order;
import li.strolch.model.ParameterBag;
import li.strolch.model.Resource;
import li.strolch.model.StrolchElement;
import li.strolch.model.parameter.FloatParameter;
import li.strolch.model.parameter.Parameter;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.antlr.v4.runtime.tree.ParseTree;
import org.junit.Test;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.ResourceQuery;
import li.strolch.model.query.StrolchElementQuery;
import li.strolch.soql.antlr4.generated.SOQLLexer;
import li.strolch.soql.antlr4.generated.SOQLParser;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author msmock
@ -31,7 +22,7 @@ public class QueryTest extends BaseTest {
/**
* @param entities
* @return Map<String , StrolchElementQuery> of queries for the entities
* @return Map of queries for the entities defining the objects returned
*/
public Map<String, StrolchElementQuery> resolveEntities(final Map<String, String> entities) {

View File

@ -13,66 +13,61 @@ import static org.junit.Assert.assertEquals;
*/
public class SerialisationTest extends BaseTest {
private QueryRequest buildTestRequest() {
String s = "SELECT a FROM Activity a WHERE a.getId() = :p";
final QueryRequest request = new QueryRequest();
request.setStatement(s);
request.getParameter().put("r", "Just a string!");
return request;
}
private QueryRequest buildTestRequest() {
String s = "SELECT a FROM Activity a WHERE a.getId() = :p";
final QueryRequest request = new QueryRequest();
request.setStatement(s);
request.getParameter().put("r", "Just a string!");
return request;
}
private QueryResponse buildTestResponse() {
String s = "SELECT a FROM Activity a WHERE a.getId() = :p";
final QueryResponse response = new QueryResponse();
response.setStatement(s);
response.getParameter().put("r", "Just a string!");
return response;
}
private QueryResponse buildTestResponse() {
String s = "SELECT a FROM Activity a WHERE a.getId() = :p";
final QueryResponse response = new QueryResponse();
response.setStatement(s);
response.getParameter().put("r", "Just a string!");
return response;
}
@Test
public void testQuery2JSON() {
final QueryRequest request = buildTestRequest();
JsonObject jsonObject = request.asJson();
@Test
public void testQuery2JSON() {
final QueryRequest request = buildTestRequest();
JsonObject jsonObject = request.asJson();
String expected = "{\"objectType\":\"QueryRequest\",\"statement\":\"SELECT a FROM Activity a WHERE a.getId() "
+ "= :p\",\"queryParameter\":{\"r\":\"Just a string!\"}}";
assertEquals(expected.trim(), jsonObject.toString());
}
String expected = "{\"objectType\":\"QueryRequest\",\"statement\":\"SELECT a FROM Activity a WHERE a.getId() " +
"= :p\",\"parameter\":{\"r\":\"Just a string!\"}}";
assertEquals(expected.trim(), jsonObject.toString());
}
@Test
public void testJSON2Query() {
@Test
public void testJSON2Query() {
String s = "SELECT a FROM Activity a WHERE a.getId() = :p";
String s = "SELECT a FROM Activity a WHERE a.getId() = :p";
final QueryRequest initial = new QueryRequest();
initial.setStatement(s);
initial.getParameter().put("p", "10010");
final JsonObject jsonObject = initial.asJson();
final QueryRequest initial = new QueryRequest();
initial.setStatement(s);
initial.getParameter().put("p", "10010");
final JsonObject jsonObject = initial.asJson();
final QueryRequest query = new QueryRequest();
query.fromJson(jsonObject);
final QueryRequest query = new QueryRequest();
query.fromJson(jsonObject);
assertEquals(s, query.getStatement());
assertEquals("10010", query.getParameter().get("p"));
}
assertEquals(s, query.getStatement());
assertEquals("10010", query.getParameter().get("p"));
}
@Test
public void testResponse2JSON() {
final QueryResponse response = buildTestResponse();
final List evalResult = getTestRessources(2);
response.getResultSet().add(evalResult);
@Test
public void testResponse2JSON() {
final QueryResponse response = buildTestResponse();
final List<StrolchRootElement> evalResult = getTestRessources(2);
response.resultSet.add(evalResult);
String expected = "{\"objectType\":\"QueryResponse\",\"statement\":\"SELECT a FROM Activity a WHERE a.getId() = :p\",\"queryParameter\":{\"r\":\"Just a string!\"},\"resultSet\":[[{\"objectType\":\"Resource\",\"id\":\"0\",\"name\":null,\"type\":null,\"parameterBags\":{\"testBag\":{\"id\":\"testBag\",\"name\":null,\"type\":null,\"parameters\":{\"testId\":{\"id\":\"testId\",\"name\":null,\"type\":\"Float\",\"value\":\"100.0\"}}}}},{\"objectType\":\"Resource\",\"id\":\"1\",\"name\":null,\"type\":null,\"parameterBags\":{\"testBag\":{\"id\":\"testBag\",\"name\":null,\"type\":null,\"parameters\":{\"testId\":{\"id\":\"testId\",\"name\":null,\"type\":\"Float\",\"value\":\"100.0\"}}}}}]]}";
String expected = "{\"objectType\":\"QueryRequest\",\"statement\":\"SELECT a FROM Activity a WHERE a.getId() " +
"= :p\",\"parameter\":{\"r\":\"Just a string!\"},\"resultSet\":[[{\"objectType\":\"Resource\"," +
"\"id\":\"2\",\"name\":null,\"type\":null,\"parameterBags\":{\"testBag\":{\"id\":\"testBag\"," +
"\"name\":null,\"type\":null,\"parameters\":{\"testId\":{\"id\":\"testId\",\"name\":null,\"type\"" +
":\"Float\",\"value\":\"100.0\"}}}}},{\"objectType\":\"Resource\",\"id\":\"2\",\"name\":null,\"type\"" +
":null,\"parameterBags\":{\"testBag\":{\"id\":\"testBag\",\"name\":null,\"type\":null,\"parameters\"" +
":{\"testId\":{\"id\":\"testId\",\"name\":null,\"type\":\"Float\",\"value\":\"100.0\"}}}}}]]}";
final JsonObject jsonObject = response.asJson();
assertEquals(expected.trim(), jsonObject.toString());
final JsonObject jsonObject = response.asJson();
assertEquals(expected.trim(), jsonObject.toString());
}
System.out.println(jsonObject.toString());
}
}