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
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,13 @@ public class RedisGraphExample {
// general context api. Not bound to graph key or connection
RedisGraph graph = new RedisGraph();

// send queries to a specific graph called "social"
graph.query("social","CREATE (:person{name:'roi',age:32})");
graph.query("social","CREATE (:person{name:%s,age:%d})", "amit", 30);
Map<String, Object> params = new HashMap<>();
params.put("age", 30);
params.put("name", "amit");

// send queries to a specific graph called "social"
graph.query("social","CREATE (:person{name:'roi',age:32})");
graph.query("social","CREATE (:person{name:$name,age:$age})", params);
graph.query("social","MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') CREATE (a)-[:knows]->(b)");

ResultSet resultSet = graph.query("social", "MATCH (a:person)-[r:knows]->(b:person) RETURN a, r, b");
Expand Down Expand Up @@ -131,7 +135,7 @@ public class RedisGraphExample {
// get connection context - closable object
try(RedisGraphContext context = graph.getContext()) {
context.query("contextSocial","CREATE (:person{name:'roi',age:32})");
context.query("contextSocial","CREATE (:person{name:%s,age:%d})", "amit", 30);
context.query("social","CREATE (:person{name:$name,age:$age})", params);
context.query("contextSocial", "MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') CREATE (a)-[:knows]->(b)");
// WATCH/MULTI/EXEC
context.watch("contextSocial");
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/com/redislabs/redisgraph/RedisGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,35 @@

public interface RedisGraph extends Closeable {

/**
* Execute a Cypher query.
* @param graphId a graph to perform the query on
* @param query Cypher query
* @return a result set
*/
ResultSet query(String graphId, String query);


/**
* Execute a Cypher query with arguments
* @param graphId a graph to perform the query on
* @param query Cypher query
* @param args
* @return a result set
* @deprecated use {@link #query(String, String, Map)} instead.
*/
@Deprecated
ResultSet query(String graphId, String query, Object ...args);

/**
* Executes a cypher query with parameters.
* @param graphId a graph to perform the query on.
* @param query Cypher query.
* @param params parameters map.
* @return a result set.
*/
ResultSet query(String graphId, String query, Map<String, Object> params);

/**
* Invokes stored procedures without arguments
* @param graphId a graph to perform the query on
Expand Down
53 changes: 48 additions & 5 deletions src/main/java/com/redislabs/redisgraph/impl/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
import org.apache.commons.text.translate.CharSequenceTranslator;
import org.apache.commons.text.translate.LookupTranslator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -50,12 +46,15 @@ private static String quoteString(String str){
return sb.toString();
}


/**
* Prepare and formats a query and query arguments
* @param query - query
* @param args - query arguments
* @return formatted query
* @deprecated use {@link #prepareQuery(String, Map)} instead.
*/
@Deprecated
public static String prepareQuery(String query, Object ...args){
if(args.length > 0) {
for(int i=0; i<args.length; ++i) {
Expand All @@ -68,6 +67,50 @@ public static String prepareQuery(String query, Object ...args){
return query;
}

/**
* Prepare and formats a query and query arguments
* @param query - query
* @param params - query parameters
* @return query with parameters header
*/
public static String prepareQuery(String query, Map<String, Object> params){
StringBuilder sb = new StringBuilder("CYPHER ");
for(Map.Entry<String, Object> entry : params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
sb.append(key).append('=');
sb.append(valueToString(value));
sb.append(' ');
}
sb.append(query);
return sb.toString();
}

private static String arrayToString(Object[] arr) {
StringBuilder sb = new StringBuilder().append('[');
sb.append(String.join(", ", Arrays.stream(arr).map(obj->valueToString(obj)).collect(Collectors.toList())));
sb.append(']');
return sb.toString();
}

private static String valueToString(Object value) {
if(value == null)
return "null";
if(String.class.isInstance(value)){
return quoteString((String) value);
}

if(value.getClass().isArray()){
return arrayToString((Object[]) value);

}
if(List.class.isInstance(value)){
List<Object> list = (List<Object>)value;
return arrayToString(list.toArray());
}
return value.toString();
}

/**
* Prepare and format a procedure call and its arguments
* @param procedure - procedure to invoke
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,42 @@ public abstract class AbstractRedisGraph implements RedisGraph {
*/
protected abstract ResultSet sendQuery(String graphId, String preparedQuery);

/**
* Execute a Cypher query.
* @param graphId a graph to perform the query on
* @param query Cypher query
* @return a result set
*/
public ResultSet query(String graphId, String query) {
return sendQuery(graphId, query);
}

/**
* Execute a Cypher query with arguments
* @param graphId a graph to perform the query on
* @param query Cypher query
* @param args
* @return a result set
* @deprecated use {@link #query(String, String, Map)} instead.
*/
@Deprecated
public ResultSet query(String graphId, String query, Object ...args) {
String preparedQuery = Utils.prepareQuery(query, args);
return sendQuery(graphId, preparedQuery);
}

/**
* Executes a cypher query with parameters.
* @param graphId a graph to perform the query on.
* @param query Cypher query.
* @param params parameters map.
* @return a result set.
*/
public ResultSet query(String graphId, String query, Map<String, Object> params) {
String preparedQuery = Utils.prepareQuery(query, params);
return sendQuery(graphId, preparedQuery);
}


public ResultSet callProcedure(String graphId, String procedure){
return callProcedure(graphId, procedure, Utils.DUMMY_LIST, Utils.DUMMY_MAP);
Expand Down
33 changes: 31 additions & 2 deletions src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,13 @@ public void testRecord(){
+ "nullValue=Property{name='nullValue', value=null}, "
+ "since=Property{name='since', value=2000}}}", expectedEdge.toString());

Assert.assertNotNull(api.query("social", "CREATE (:person{name:%s,age:%d, doubleValue:%f, boolValue:%b, nullValue:null})", name, age, doubleValue, boolValue));
Map<String, Object> params = new HashMap<>();
params.put("name", name);
params.put("age", age);
params.put("boolValue", boolValue);
params.put("doubleValue", doubleValue);

Assert.assertNotNull(api.query("social", "CREATE (:person{name:$name,age:$age, doubleValue:$doubleValue, boolValue:$boolValue, nullValue:null})", params));
Assert.assertNotNull(api.query("social", "CREATE (:person{name:'amit',age:30})"));
Assert.assertNotNull(api.query("social", "MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') " +
"CREATE (a)-[:knows{place:'TLV', since:2000,doubleValue:3.14, boolValue:false, nullValue:null}]->(b)"));
Expand Down Expand Up @@ -654,8 +660,13 @@ public void testContextedAPI() {
expectedEdge.addProperty(falseBooleanProperty);
expectedEdge.addProperty(nullProperty);

Map<String, Object> params = new HashMap<>();
params.put("name", name);
params.put("age", age);
params.put("boolValue", boolValue);
params.put("doubleValue", doubleValue);
try (RedisGraphContext c = api.getContext()) {
Assert.assertNotNull(c.query("social", "CREATE (:person{name:%s,age:%d, doubleValue:%f, boolValue:%b, nullValue:null})", name, age, doubleValue, boolValue));
Assert.assertNotNull(c.query("social", "CREATE (:person{name:$name, age:$age, doubleValue:$doubleValue, boolValue:$boolValue, nullValue:null})", params));
Assert.assertNotNull(c.query("social", "CREATE (:person{name:'amit',age:30})"));
Assert.assertNotNull(c.query("social", "MATCH (a:person), (b:person) WHERE (a.name = 'roi' AND b.name='amit') " +
"CREATE (a)-[:knows{place:'TLV', since:2000,doubleValue:3.14, boolValue:false, nullValue:null}]->(b)"));
Expand Down Expand Up @@ -920,4 +931,22 @@ public void testPath(){

}

@Test
public void testParameters(){
Object[] parameters = {1, 2.3, true, false, null, "str", Arrays.asList(1,2,3), new Integer[]{1,2,3}};
Map<String, Object> param = new HashMap<>();
for (int i=0; i < parameters.length; i++) {
Object expected = parameters[i];
param.put("param", expected);
ResultSet resultSet = api.query("social", "RETURN $param", param);
Assert.assertEquals(1, resultSet.size());
Record r = resultSet.next();
Object o = r.getValue(0);
if(i == parameters.length-1) {
expected = Arrays.asList((Object[])expected);
}
Assert.assertEquals(expected, o);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.util.HashMap;


public class JRedisGraphErrorTest {

Expand Down Expand Up @@ -86,6 +88,20 @@ public void testContextSyntaxErrorReporting() {

}

@Test
public void testMissingParametersSyntaxErrorReporting(){
exceptionRule.expect(JRedisGraphCompileTimeException.class);
exceptionRule.expectMessage("Missing parameters");
api.query("social","RETURN $param");
}

@Test
public void testMissingParametersSyntaxErrorReporting2(){
exceptionRule.expect(JRedisGraphCompileTimeException.class);
exceptionRule.expectMessage("Missing parameters");
api.query("social","RETURN $param", new HashMap<>());
}

@Test
public void testContextRuntimeErrorReporting() {
exceptionRule.expect(JRedisGraphRunTimeException.class);
Expand Down
35 changes: 30 additions & 5 deletions src/test/java/com/redislabs/redisgraph/impl/UtilsTest.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package com.redislabs.redisgraph.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.IllegalFormatConversionException;
import java.util.List;
import java.util.Map;
import java.util.*;

import org.junit.Assert;
import org.junit.Rule;
Expand Down Expand Up @@ -41,4 +37,33 @@ public void prepareQuery() {
Assert.assertEquals("CAL prc(\"a\",\"b\")ka,kb", Utils.prepareQuery("query %s %d end of query", "a", "b"));
}

@Test
public void testParamsPrep(){
Map<String, Object> params = new HashMap<>();
params.put("param", 1);
Assert.assertEquals("CYPHER param=1 RETURN $param", Utils.prepareQuery("RETURN $param", params));
params.put("param", 2.3);
Assert.assertEquals("CYPHER param=2.3 RETURN $param", Utils.prepareQuery("RETURN $param", params));
params.put("param", true);
Assert.assertEquals("CYPHER param=true RETURN $param", Utils.prepareQuery("RETURN $param", params));
params.put("param", false);
Assert.assertEquals("CYPHER param=false RETURN $param", Utils.prepareQuery("RETURN $param", params));
params.put("param", null);
Assert.assertEquals("CYPHER param=null RETURN $param", Utils.prepareQuery("RETURN $param", params));
params.put("param", "str");
Assert.assertEquals("CYPHER param=\"str\" RETURN $param", Utils.prepareQuery("RETURN $param", params));
Integer arr[] = {1,2,3};
params.put("param", arr);
Assert.assertEquals("CYPHER param=[1, 2, 3] RETURN $param", Utils.prepareQuery("RETURN $param", params));
List<Integer> list = Arrays.asList(1,2,3);
params.put("param", list);
Assert.assertEquals("CYPHER param=[1, 2, 3] RETURN $param", Utils.prepareQuery("RETURN $param", params));
String strArr[] = {"1", "2", "3"};
params.put("param", strArr);
Assert.assertEquals("CYPHER param=[\"1\", \"2\", \"3\"] RETURN $param", Utils.prepareQuery("RETURN $param", params));
List<String> stringList = Arrays.asList("1", "2", "3");
params.put("param", stringList);
Assert.assertEquals("CYPHER param=[\"1\", \"2\", \"3\"] RETURN $param", Utils.prepareQuery("RETURN $param", params));
}

}