From 8aa70bb39f9d7b1b716ba4f5c2eb1506f87199b4 Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Thu, 4 Jul 2019 11:17:02 +0300 Subject: [PATCH 1/8] changed Jedis client to new 3.1.0 version. Modified send command flow --- pom.xml | 11 ++++-- .../com/redislabs/redisgraph/RedisGraph.java | 36 +++---------------- .../impl/JRedisGraphTransaction.java | 4 +++ 3 files changed, 17 insertions(+), 34 deletions(-) create mode 100644 src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java diff --git a/pom.xml b/pom.xml index 8fd22c7..5323061 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,14 @@ repo - + + + + snapshots-repo + https://oss.sonatype.org/content/repositories/snapshots + + + org.apache.commons @@ -62,7 +69,7 @@ redis.clients jedis - 3.0.1 + 3.1.0-SNAPSHOT org.apache.commons diff --git a/src/main/java/com/redislabs/redisgraph/RedisGraph.java b/src/main/java/com/redislabs/redisgraph/RedisGraph.java index 9c0871d..e738c95 100644 --- a/src/main/java/com/redislabs/redisgraph/RedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/RedisGraph.java @@ -10,6 +10,7 @@ import redis.clients.jedis.JedisPool; import redis.clients.jedis.commands.ProtocolCommand; import redis.clients.jedis.util.Pool; +import redis.clients.jedis.util.SafeEncoder; import java.io.Closeable; import java.util.*; @@ -29,7 +30,7 @@ public class RedisGraph implements Closeable { - private static final CharSequenceTranslator ESCAPE_CHYPER; + public static final CharSequenceTranslator ESCAPE_CHYPER; static { final Map escapeJavaMap = new HashMap<>(); escapeJavaMap.put("\'", "\\'"); @@ -91,7 +92,7 @@ public ResultSet query(String graphId, String query, Object ...args) { graphCaches.putIfAbsent(graphId, new GraphCache(graphId, this)); List rawResponse = null; try(Jedis conn = getConnection()){ - rawResponse= sendCompactCommand(conn, Command.QUERY, graphId, query).getObjectMultiBulkReply(); + rawResponse = (List) conn.sendCommand(Command.QUERY, graphId, query, "--COMPACT"); } return new ResultSetImpl(rawResponse, graphCaches.get(graphId)); @@ -129,40 +130,11 @@ public String deleteGraph(String graphId) { //clear local state graphCaches.remove(graphId); try (Jedis conn = getConnection()) { - return sendCommand(conn, Command.DELETE, graphId).getBulkReply(); + return SafeEncoder.encode((byte[]) conn.sendCommand(Command.DELETE, graphId)); } } - - /** - * Sends command - will be replaced with sendCompactCommand once graph.delete support --compact flag - * @param conn - connection - * @param provider - command type - * @param args - command arguments - * @return - */ - private BinaryClient sendCommand(Jedis conn, ProtocolCommand provider, String ...args) { - BinaryClient binaryClient = conn.getClient(); - binaryClient.sendCommand(provider, args); - return binaryClient; - } - - - /** - * Sends the command with --COMPACT flag - * @param conn - connection - * @param provider - command type - * @param args - command arguments - * @return - */ - private BinaryClient sendCompactCommand(Jedis conn, ProtocolCommand provider, String ...args) { - String[] t = new String[args.length +1]; - System.arraycopy(args, 0 , t, 0, args.length); - t[args.length]="--COMPACT"; - return sendCommand(conn, provider, t); - } - private Jedis getConnection() { return this.client.getResource(); } diff --git a/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java b/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java new file mode 100644 index 0000000..cc77969 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java @@ -0,0 +1,4 @@ +package com.redislabs.redisgraph.impl; + +public class JRedisGraphTransaction { +} From 62e9c432a97e006effe63afac8a11ce1c87b0ebf Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Thu, 4 Jul 2019 16:34:08 +0300 Subject: [PATCH 2/8] added multi exec support --- pom.xml | 2 +- .../com/redislabs/redisgraph/RedisGraph.java | 53 ++++----- .../java/com/redislabs/redisgraph/Utils.java | 56 ++++++++- .../impl/JRedisGraphTransaction.java | 104 ++++++++++++++++- .../redisgraph/RedisGraphAPITest.java | 109 ++++++++++++++++++ 5 files changed, 289 insertions(+), 35 deletions(-) diff --git a/pom.xml b/pom.xml index 5323061..10707ce 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ redis.clients jedis - 3.1.0-SNAPSHOT + 3.1.0-m4 org.apache.commons diff --git a/src/main/java/com/redislabs/redisgraph/RedisGraph.java b/src/main/java/com/redislabs/redisgraph/RedisGraph.java index e738c95..c33b44d 100644 --- a/src/main/java/com/redislabs/redisgraph/RedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/RedisGraph.java @@ -1,11 +1,13 @@ package com.redislabs.redisgraph; +import com.redislabs.redisgraph.impl.JRedisGraphTransaction; import com.redislabs.redisgraph.impl.graph_cache.GraphCache; import com.redislabs.redisgraph.impl.ResultSetImpl; import org.apache.commons.text.translate.AggregateTranslator; import org.apache.commons.text.translate.CharSequenceTranslator; import org.apache.commons.text.translate.LookupTranslator; import redis.clients.jedis.BinaryClient; +import redis.clients.jedis.Client; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.commands.ProtocolCommand; @@ -28,16 +30,6 @@ public class RedisGraph implements Closeable { private final Pool client; private final Map graphCaches = new ConcurrentHashMap<>(); - - - public static final CharSequenceTranslator ESCAPE_CHYPER; - static { - final Map escapeJavaMap = new HashMap<>(); - escapeJavaMap.put("\'", "\\'"); - escapeJavaMap.put("\"", "\\\""); - ESCAPE_CHYPER = new AggregateTranslator(new LookupTranslator(Collections.unmodifiableMap(escapeJavaMap))); - } - /** * Creates a client running on the local machine @@ -81,21 +73,13 @@ public void close(){ * @return a result set */ public ResultSet query(String graphId, String query, Object ...args) { - if(args.length > 0) { - for(int i=0; i rawResponse = null; try(Jedis conn = getConnection()){ - rawResponse = (List) conn.sendCommand(Command.QUERY, graphId, query, "--COMPACT"); + rawResponse = (List) conn.sendCommand(Command.QUERY, graphId, preparedQuery, "--COMPACT"); } return new ResultSetImpl(rawResponse, graphCaches.get(graphId)); - } /** @@ -104,7 +88,7 @@ public ResultSet query(String graphId, String query, Object ...args) { * @param procedure procedure name to invoke * @return result set with the procedure data */ - public ResultSet callProcedure(String graphId, String procedure ){ + public ResultSet callProcedure(String graphId, String procedure){ return callProcedure(graphId, procedure, new ArrayList<>(), new HashMap<>()); } @@ -120,10 +104,9 @@ public ResultSet callProcedure(String graphId, String procedure, List ar return callProcedure(graphId, procedure, args, new HashMap<>()); } - /** * Deletes the entire graph - * + * @param graphId graph to delete * @return delete running time statistics */ public String deleteGraph(String graphId) { @@ -146,17 +129,23 @@ private Jedis getConnection() { * @param procedure - procedure to execute * @param args - procedure arguments * @param kwargs - procedure output arguments - * @return + * @return result set with the procedure data */ public ResultSet callProcedure(String graphId, String procedure, List args , Map> kwargs ){ - args = args.stream().map( s -> Utils.quoteString(s)).collect(Collectors.toList()); - StringBuilder queryString = new StringBuilder(); - queryString.append(String.format("CALL %s(%s)", procedure, String.join(",", args))); - List kwargsList = kwargs.getOrDefault("y", null); - if(kwargsList != null){ - queryString.append(String.join(",", kwargsList)); - } - return query(graphId, queryString.toString()); + String preparedProcedure = Utils.prepareProcedure(procedure, args, kwargs); + return query(graphId, preparedProcedure); + } + + public JRedisGraphTransaction multi(){ + Jedis jedis = getConnection(); + Client client = jedis.getClient(); + client.multi(); + client.getOne(); + return new JRedisGraphTransaction(client,this, this.graphCaches); + } + + public Map getGraphCaches() { + return graphCaches; } } diff --git a/src/main/java/com/redislabs/redisgraph/Utils.java b/src/main/java/com/redislabs/redisgraph/Utils.java index 180e8fb..2be06d4 100644 --- a/src/main/java/com/redislabs/redisgraph/Utils.java +++ b/src/main/java/com/redislabs/redisgraph/Utils.java @@ -1,14 +1,32 @@ package com.redislabs.redisgraph; +import org.apache.commons.text.translate.AggregateTranslator; +import org.apache.commons.text.translate.CharSequenceTranslator; +import org.apache.commons.text.translate.LookupTranslator; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + /** * Utilities class */ public class Utils { + public static final CharSequenceTranslator ESCAPE_CHYPER; + static { + final Map escapeJavaMap = new HashMap<>(); + escapeJavaMap.put("\'", "\\'"); + escapeJavaMap.put("\"", "\\\""); + ESCAPE_CHYPER = new AggregateTranslator(new LookupTranslator(Collections.unmodifiableMap(escapeJavaMap))); + } + /** * * @param str - a string - * @return the input string surounded with quotation marks, if needed + * @return the input string surrounded with quotation marks, if needed */ public static String quoteString(String str){ if(str.startsWith("\"") && str.endsWith("\"")){ @@ -25,4 +43,40 @@ public 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 + */ + public static String prepareQuery(String query, Object ...args){ + if(args.length > 0) { + for(int i=0; i args , Map> kwargs){ + args = args.stream().map( s -> Utils.quoteString(s)).collect(Collectors.toList()); + StringBuilder queryStringBuilder = new StringBuilder(); + queryStringBuilder.append(String.format("CALL %s(%s)", procedure, String.join(",", args))); + List kwargsList = kwargs.getOrDefault("y", null); + if(kwargsList != null){ + queryStringBuilder.append(String.join(",", kwargsList)); + } + return queryStringBuilder.toString(); + } } diff --git a/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java b/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java index cc77969..5476c6d 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java +++ b/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java @@ -1,4 +1,106 @@ package com.redislabs.redisgraph.impl; -public class JRedisGraphTransaction { + +import com.redislabs.redisgraph.Command; +import com.redislabs.redisgraph.RedisGraph; +import com.redislabs.redisgraph.ResultSet; +import com.redislabs.redisgraph.Utils; +import com.redislabs.redisgraph.impl.graph_cache.GraphCache; +import redis.clients.jedis.Builder; +import redis.clients.jedis.BuilderFactory; +import redis.clients.jedis.Client; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Response; +import redis.clients.jedis.Transaction; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class is extending Jedis Transaction + */ +public class JRedisGraphTransaction extends Transaction { + + private final RedisGraph redisGraph; + private final Map graphCaches; + + + public JRedisGraphTransaction(Client client, RedisGraph redisGraph, Map graphCaches){ + // init as in Jedis + super(client); + + this.redisGraph = redisGraph; + this.graphCaches = graphCaches; + } + + /** + * Execute a Cypher query with arguments + * + * @param graphId a graph to perform the query on + * @param query Cypher query + * @param args + * @return response with a result set + */ + public Response graphQuery(String graphId, String query, Object ...args){ + String preparedQuery = Utils.prepareQuery(query, args); + graphCaches.putIfAbsent(graphId, new GraphCache(graphId, redisGraph)); + client.sendCommand(Command.QUERY, graphId, preparedQuery, "--COMPACT"); + return getResponse(new Builder() { + @Override + public ResultSet build(Object o) { + return new ResultSetImpl((List)o, graphCaches.get(graphId)); + } + }); + } + + + /** + * Invokes stored procedures without arguments, in multi/exec context + * @param graphId a graph to perform the query on + * @param procedure procedure name to invoke + * @return response with result set with the procedure data + */ + public Response graphCallProcedure(String graphId, String procedure){ + return graphCallProcedure(graphId, procedure, new ArrayList<>(), new HashMap<>()); + } + + /** + * Invokes stored procedure with arguments, in multi/exec context + * @param graphId a graph to perform the query on + * @param procedure procedure name to invoke + * @param args procedure arguments + * @return response with result set with the procedure data + */ + public Response graphCallProcedure(String graphId, String procedure, List args ){ + return graphCallProcedure(graphId, procedure, args, new HashMap<>()); + } + + + /** + * Invoke a stored procedure, in multi/exec context + * @param graphId a graph to perform the query on + * @param procedure - procedure to execute + * @param args - procedure arguments + * @param kwargs - procedure output arguments + * @return response with result set with the procedure data + */ + public Response graphCallProcedure(String graphId, String procedure, List args, + HashMap> kwargs) { + String preparedProcedure = Utils.prepareProcedure(procedure, args, kwargs); + return graphQuery(graphId, preparedProcedure); + } + + + /** + * Deletes the entire graph, in multi/exec context + * @param graphId graph to delete + * @return response with the deletion running time statistics + */ + public Response graphDeleteGraph(String graphId){ + graphCaches.remove(graphId); + client.sendCommand(Command.DELETE, graphId); + return getResponse(BuilderFactory.STRING); + } } diff --git a/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java b/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java index bf4be21..d8a6374 100644 --- a/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java +++ b/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java @@ -10,6 +10,8 @@ import com.redislabs.redisgraph.graph_entities.Edge; import com.redislabs.redisgraph.graph_entities.Node; import com.redislabs.redisgraph.graph_entities.Property; +import com.redislabs.redisgraph.impl.JRedisGraphTransaction; +import com.redislabs.redisgraph.impl.ResultSetImpl; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -494,4 +496,111 @@ public void testEscapedQuery() { Assert.assertNotNull(api.query("social", "MATCH (n) where n.s1=%s and n.s2=%s RETURN n", "S\"\'", "S\\'\\\"")); Assert.assertNotNull(api.query("social", "MATCH (n) where n.s1='S\"\\'' RETURN n")); } + + + @Test + public void testMultiExec(){ + JRedisGraphTransaction transaction = api.multi(); + + transaction.set("x", "1"); + transaction.graphQuery("social", "CREATE (:Person {name:'a'})"); + transaction.graphQuery("g", "CREATE (:Person {name:'a'})"); + transaction.incr("x"); + transaction.get("x"); + transaction.graphQuery("social", "MATCH (n:Person) RETURN n"); + transaction.graphDeleteGraph("g"); + transaction.graphCallProcedure("social", "db.labels"); + List results = transaction.exec(); + + // Redis set command + Assert.assertEquals(String.class, results.get(0).getClass()); + Assert.assertEquals("OK", results.get(0)); + + // Redis graph command + Assert.assertEquals(ResultSetImpl.class, results.get(1).getClass()); + ResultSet resultSet = (ResultSet) results.get(1); + Assert.assertEquals(1, resultSet.getStatistics().nodesCreated()); + Assert.assertEquals(1, resultSet.getStatistics().propertiesSet()); + + + Assert.assertEquals(ResultSetImpl.class, results.get(2).getClass()); + resultSet = (ResultSet) results.get(2); + Assert.assertEquals(1, resultSet.getStatistics().nodesCreated()); + Assert.assertEquals(1, resultSet.getStatistics().propertiesSet()); + + // Redis incr command + Assert.assertEquals(Long.class, results.get(3).getClass()); + Assert.assertEquals((long)2, results.get(3)); + + // Redis get command + Assert.assertEquals(String.class, results.get(4).getClass()); + Assert.assertEquals("2", results.get(4)); + + // Graph query result + Assert.assertEquals(ResultSetImpl.class, results.get(5).getClass()); + resultSet = (ResultSet) results.get(5); + + Assert.assertNotNull(resultSet.getHeader()); + Header header = resultSet.getHeader(); + + + List schemaNames = header.getSchemaNames(); + List schemaTypes = header.getSchemaTypes(); + + Assert.assertNotNull(schemaNames); + Assert.assertNotNull(schemaTypes); + + Assert.assertEquals(1, schemaNames.size()); + Assert.assertEquals(1, schemaTypes.size()); + + Assert.assertEquals("n", schemaNames.get(0)); + + Assert.assertEquals(COLUMN_NODE, schemaTypes.get(0)); + + Property nameProperty = new Property("name", ResultSet.ResultSetScalarTypes.PROPERTY_STRING, "a"); + + Node expectedNode = new Node(); + expectedNode.setId(0); + expectedNode.addLabel("Person"); + expectedNode.addProperty(nameProperty); + // see that the result were pulled from the right graph + Assert.assertEquals(1, resultSet.size()); + Assert.assertTrue(resultSet.hasNext()); + Record record = resultSet.next(); + Assert.assertFalse(resultSet.hasNext()); + Assert.assertEquals(Arrays.asList("n"), record.keys()); + Assert.assertEquals(expectedNode, record.getValue("n")); + + // Graph delete + Assert.assertTrue(((String)results.get(6)).startsWith("Graph removed")); + + + Assert.assertEquals(ResultSetImpl.class, results.get(7).getClass()); + resultSet = (ResultSet) results.get(7); + + Assert.assertNotNull(resultSet.getHeader()); + header = resultSet.getHeader(); + + + schemaNames = header.getSchemaNames(); + schemaTypes = header.getSchemaTypes(); + + Assert.assertNotNull(schemaNames); + Assert.assertNotNull(schemaTypes); + + Assert.assertEquals(1, schemaNames.size()); + Assert.assertEquals(1, schemaTypes.size()); + + Assert.assertEquals("label", schemaNames.get(0)); + + Assert.assertEquals(COLUMN_SCALAR, schemaTypes.get(0)); + + Assert.assertEquals(1, resultSet.size()); + Assert.assertTrue(resultSet.hasNext()); + record = resultSet.next(); + Assert.assertFalse(resultSet.hasNext()); + Assert.assertEquals(Arrays.asList("label"), record.keys()); + Assert.assertEquals("Person", record.getValue("label")); + + } } From 48329d4188a025fc0328010efed1018dfcd5e24a Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Wed, 10 Jul 2019 21:47:04 +0300 Subject: [PATCH 3/8] added watch support --- pom.xml | 7 - .../java/com/redislabs/redisgraph/Header.java | 6 +- .../com/redislabs/redisgraph/RedisGraph.java | 125 ++---------- .../redisgraph/RedisGraphContexted.java | 32 +++ .../redisgraph/RedisGraphGeneralContext.java | 13 ++ .../redisgraph/RedisGraphTransaction.java | 91 +++++++++ .../com/redislabs/redisgraph/ResultSet.java | 5 +- .../redisgraph/graph_entities/Edge.java | 2 +- .../graph_entities/GraphEntity.java | 4 +- .../redisgraph/graph_entities/Node.java | 2 +- .../redisgraph/{ => impl}/Utils.java | 11 +- .../impl/api/AbstractRedisGraph.java | 59 ++++++ .../impl/api/ContextedRedisGraph.java | 121 +++++++++++ .../redisgraph/impl/api/RedisGraph.java | 113 ++++++++++ .../impl/api/RedisGraphCacheHolder.java | 8 + .../api/RedisGraphCommand.java} | 6 +- .../RedisGraphTransaction.java} | 56 ++--- .../impl/graph_cache/GraphCache.java | 21 +- .../impl/graph_cache/GraphCacheList.java | 20 +- .../impl/graph_cache/RedisGraphCaches.java | 59 ++++++ .../impl/{ => resultset}/HeaderImpl.java | 2 +- .../impl/{ => resultset}/RecordImpl.java | 2 +- .../impl/{ => resultset}/ResultSetImpl.java | 29 ++- .../impl/{ => resultset}/StatisticsImpl.java | 8 +- .../redisgraph/RedisGraphAPITest.java | 193 ++++++++++++++++-- 25 files changed, 781 insertions(+), 214 deletions(-) create mode 100644 src/main/java/com/redislabs/redisgraph/RedisGraphContexted.java create mode 100644 src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java create mode 100644 src/main/java/com/redislabs/redisgraph/RedisGraphTransaction.java rename src/main/java/com/redislabs/redisgraph/{ => impl}/Utils.java (88%) create mode 100644 src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java create mode 100644 src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java create mode 100644 src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java create mode 100644 src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphCacheHolder.java rename src/main/java/com/redislabs/redisgraph/{Command.java => impl/api/RedisGraphCommand.java} (68%) rename src/main/java/com/redislabs/redisgraph/impl/{JRedisGraphTransaction.java => api/RedisGraphTransaction.java} (55%) create mode 100644 src/main/java/com/redislabs/redisgraph/impl/graph_cache/RedisGraphCaches.java rename src/main/java/com/redislabs/redisgraph/impl/{ => resultset}/HeaderImpl.java (98%) rename src/main/java/com/redislabs/redisgraph/impl/{ => resultset}/RecordImpl.java (97%) rename src/main/java/com/redislabs/redisgraph/impl/{ => resultset}/ResultSetImpl.java (88%) rename src/main/java/com/redislabs/redisgraph/impl/{ => resultset}/StatisticsImpl.java (93%) diff --git a/pom.xml b/pom.xml index 10707ce..a83a43c 100644 --- a/pom.xml +++ b/pom.xml @@ -47,13 +47,6 @@ - - - snapshots-repo - https://oss.sonatype.org/content/repositories/snapshots - - - org.apache.commons diff --git a/src/main/java/com/redislabs/redisgraph/Header.java b/src/main/java/com/redislabs/redisgraph/Header.java index 43cf8b3..a8156aa 100644 --- a/src/main/java/com/redislabs/redisgraph/Header.java +++ b/src/main/java/com/redislabs/redisgraph/Header.java @@ -3,16 +3,16 @@ import java.util.List; /** - * Query response header interface. Represents the response schame (column names and types) + * Query response header interface. Represents the response schema (column names and types) */ public interface Header { - public enum ResultSetColumnTypes { + enum ResultSetColumnTypes { COLUMN_UNKNOWN, COLUMN_SCALAR, COLUMN_NODE, - COLUMN_RELATION; + COLUMN_RELATION } diff --git a/src/main/java/com/redislabs/redisgraph/RedisGraph.java b/src/main/java/com/redislabs/redisgraph/RedisGraph.java index c33b44d..90432bd 100644 --- a/src/main/java/com/redislabs/redisgraph/RedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/RedisGraph.java @@ -1,86 +1,19 @@ package com.redislabs.redisgraph; -import com.redislabs.redisgraph.impl.JRedisGraphTransaction; -import com.redislabs.redisgraph.impl.graph_cache.GraphCache; -import com.redislabs.redisgraph.impl.ResultSetImpl; -import org.apache.commons.text.translate.AggregateTranslator; -import org.apache.commons.text.translate.CharSequenceTranslator; -import org.apache.commons.text.translate.LookupTranslator; -import redis.clients.jedis.BinaryClient; -import redis.clients.jedis.Client; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.commands.ProtocolCommand; -import redis.clients.jedis.util.Pool; -import redis.clients.jedis.util.SafeEncoder; - import java.io.Closeable; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - - -/** - * - */ -public class RedisGraph implements Closeable { - - - - private final Pool client; - private final Map graphCaches = new ConcurrentHashMap<>(); - - /** - * Creates a client running on the local machine - - */ - public RedisGraph() { - this("localhost", 6379); - } - - /** - * Creates a client running on the specific host/post - * - * @param host Redis host - * @param port Redis port - */ - public RedisGraph(String host, int port) { - this( new JedisPool(host, port)); - } - - /** - * Creates a client using provided Jedis pool - * - * @param jedis bring your own Jedis pool - */ - public RedisGraph( Pool jedis) { - - this.client = jedis; - } - - @Override - public void close(){ - this.client.close(); - } +import java.util.List; +import java.util.Map; +public interface RedisGraph extends Closeable { /** * 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 */ - public ResultSet query(String graphId, String query, Object ...args) { - String preparedQuery = Utils.prepareQuery(query, args); - graphCaches.putIfAbsent(graphId, new GraphCache(graphId, this)); - List rawResponse = null; - try(Jedis conn = getConnection()){ - rawResponse = (List) conn.sendCommand(Command.QUERY, graphId, preparedQuery, "--COMPACT"); - } - return new ResultSetImpl(rawResponse, graphCaches.get(graphId)); - } + ResultSet query(String graphId, String query, Object ...args); /** * Invokes stored procedures without arguments @@ -88,10 +21,7 @@ public ResultSet query(String graphId, String query, Object ...args) { * @param procedure procedure name to invoke * @return result set with the procedure data */ - public ResultSet callProcedure(String graphId, String procedure){ - return callProcedure(graphId, procedure, new ArrayList<>(), new HashMap<>()); - } - + ResultSet callProcedure(String graphId, String procedure); /** * Invokes stored procedure with arguments @@ -100,28 +30,7 @@ public ResultSet callProcedure(String graphId, String procedure){ * @param args procedure arguments * @return result set with the procedure data */ - public ResultSet callProcedure(String graphId, String procedure, List args ){ - return callProcedure(graphId, procedure, args, new HashMap<>()); - } - - /** - * Deletes the entire graph - * @param graphId graph to delete - * @return delete running time statistics - */ - public String deleteGraph(String graphId) { - //clear local state - graphCaches.remove(graphId); - try (Jedis conn = getConnection()) { - return SafeEncoder.encode((byte[]) conn.sendCommand(Command.DELETE, graphId)); - } - - } - - private Jedis getConnection() { - return this.client.getResource(); - } - + ResultSet callProcedure(String graphId, String procedure, List args); /** * Invoke a stored procedure @@ -131,21 +40,13 @@ private Jedis getConnection() { * @param kwargs - procedure output arguments * @return result set with the procedure data */ - public ResultSet callProcedure(String graphId, String procedure, List args , Map> kwargs ){ + ResultSet callProcedure(String graphId, String procedure, List args , Map> kwargs); - String preparedProcedure = Utils.prepareProcedure(procedure, args, kwargs); - return query(graphId, preparedProcedure); - } - - public JRedisGraphTransaction multi(){ - Jedis jedis = getConnection(); - Client client = jedis.getClient(); - client.multi(); - client.getOne(); - return new JRedisGraphTransaction(client,this, this.graphCaches); - } + /** + * Deletes the entire graph + * @param graphId graph to delete + * @return delete running time statistics + */ + String deleteGraph(String graphId); - public Map getGraphCaches() { - return graphCaches; - } } diff --git a/src/main/java/com/redislabs/redisgraph/RedisGraphContexted.java b/src/main/java/com/redislabs/redisgraph/RedisGraphContexted.java new file mode 100644 index 0000000..5ef1037 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/RedisGraphContexted.java @@ -0,0 +1,32 @@ +package com.redislabs.redisgraph; + +import redis.clients.jedis.Jedis; + +public interface RedisGraphContexted extends RedisGraph { + + + /** + * Returns implementing class connection context + * @return Jedis connection + */ + Jedis getConnectionContext(); + + /** + * Returns a Redis transactional object, over the connection context, with graph API capabilities + * @return Redis transactional object, over the connection context, with graph API capabilities + */ + RedisGraphTransaction multi(); + + /** + * Perform watch over given Redis keys + * @param keys + * @return "OK" + */ + String watch(String... keys); + + /** + * Removes watch from all keys + * @return + */ + String unwatch(); +} diff --git a/src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java b/src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java new file mode 100644 index 0000000..4596ec9 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java @@ -0,0 +1,13 @@ +package com.redislabs.redisgraph; + +import redis.clients.jedis.Jedis; + +public interface RedisGraphGeneralContext extends RedisGraph { + + /** + * Generate a connection bounded api + * @return a connection bounded api + */ + RedisGraphContexted getContextedAPI(); + +} diff --git a/src/main/java/com/redislabs/redisgraph/RedisGraphTransaction.java b/src/main/java/com/redislabs/redisgraph/RedisGraphTransaction.java new file mode 100644 index 0000000..c206640 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/RedisGraphTransaction.java @@ -0,0 +1,91 @@ +package com.redislabs.redisgraph; + +import redis.clients.jedis.Response; +import redis.clients.jedis.commands.BasicRedisPipeline; +import redis.clients.jedis.commands.BinaryRedisPipeline; +import redis.clients.jedis.commands.BinaryScriptingCommandsPipeline; +import redis.clients.jedis.commands.ClusterPipeline; +import redis.clients.jedis.commands.MultiKeyBinaryRedisPipeline; +import redis.clients.jedis.commands.MultiKeyCommandsPipeline; +import redis.clients.jedis.commands.RedisPipeline; +import redis.clients.jedis.commands.ScriptingCommandsPipeline; + +import java.io.Closeable; +import java.util.List; +import java.util.Map; + +/** + * An interface which aligned to Jedis transactional interface + */ +public interface RedisGraphTransaction extends + MultiKeyBinaryRedisPipeline, + MultiKeyCommandsPipeline, ClusterPipeline, + BinaryScriptingCommandsPipeline, ScriptingCommandsPipeline, + BasicRedisPipeline, BinaryRedisPipeline, RedisPipeline, Closeable { + /** + * Execute a Cypher query with arguments + * @param graphId a graph to perform the query on + * @param query Cypher query + * @param args + * @return a response which builds the result set with the query answer + */ + Response query(String graphId, String query, Object ...args); + + /** + * Invokes stored procedures without arguments + * @param graphId a graph to perform the query on + * @param procedure procedure name to invoke + * @return a response which builds result set with the procedure data + */ + Response callProcedure(String graphId, String procedure); + + /** + * Invokes stored procedure with arguments + * @param graphId a graph to perform the query on + * @param procedure procedure name to invoke + * @param args procedure arguments + * @return a response which builds result set with the procedure data + */ + Response callProcedure(String graphId, String procedure, List args); + + /** + * Invoke a stored procedure + * @param graphId a graph to perform the query on + * @param procedure - procedure to execute + * @param args - procedure arguments + * @param kwargs - procedure output arguments + * @return a response which builds result set with the procedure data + */ + Response callProcedure(String graphId, String procedure, List args , Map> kwargs); + + /** + * Deletes the entire graph + * @param graphId graph to delete + * @return a response which builds the delete running time statistics + */ + Response deleteGraph(String graphId); + + + /** + * executes the transaction + * @return a list of the executed transaction commands answers, in case of successful transaction, null otherwise + */ + List exec(); + + /** + * If object is in transaction mode, + * flushes all previously queued commands in a transaction and restores the connection state to normal + */ + void clear(); + + /** + * + * @return + */ + List> execGetResponse(); + + /** + * Flushes all previously queued commands in a transaction and restores the connection state to normal + */ + String discard(); +} diff --git a/src/main/java/com/redislabs/redisgraph/ResultSet.java b/src/main/java/com/redislabs/redisgraph/ResultSet.java index 7ac933a..251a4d0 100644 --- a/src/main/java/com/redislabs/redisgraph/ResultSet.java +++ b/src/main/java/com/redislabs/redisgraph/ResultSet.java @@ -1,14 +1,13 @@ package com.redislabs.redisgraph; import java.util.Iterator; -import java.util.List; /** * Hold a query result */ public interface ResultSet extends Iterator { - public enum ResultSetScalarTypes { + enum ResultSetScalarTypes { PROPERTY_UNKNOWN, PROPERTY_NULL, PROPERTY_STRING, @@ -17,7 +16,7 @@ public enum ResultSetScalarTypes { PROPERTY_DOUBLE, } - public int size(); + int size(); Statistics getStatistics(); diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java b/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java index fa30d03..f7c0135 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/Edge.java @@ -8,7 +8,7 @@ */ public class Edge extends GraphEntity { - //memebers + //members private String relationshipType; private int source; private int destination; diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java b/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java index d2083a6..42cc3f9 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java @@ -16,8 +16,8 @@ public abstract class GraphEntity { //members - protected int id; - protected final Map propertyMap = new HashMap<>(); + int id; + final Map propertyMap = new HashMap<>(); //setters & getters diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java b/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java index 6ede861..f118964 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java @@ -28,7 +28,7 @@ public void removeLabel(String label) { /** * @param index - label index - * @return the proprty label + * @return the property label * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= getNumberOfLabels()}) */ diff --git a/src/main/java/com/redislabs/redisgraph/Utils.java b/src/main/java/com/redislabs/redisgraph/impl/Utils.java similarity index 88% rename from src/main/java/com/redislabs/redisgraph/Utils.java rename to src/main/java/com/redislabs/redisgraph/impl/Utils.java index 2be06d4..b9d1873 100644 --- a/src/main/java/com/redislabs/redisgraph/Utils.java +++ b/src/main/java/com/redislabs/redisgraph/impl/Utils.java @@ -1,9 +1,10 @@ -package com.redislabs.redisgraph; +package com.redislabs.redisgraph.impl; import org.apache.commons.text.translate.AggregateTranslator; 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; @@ -14,8 +15,12 @@ * Utilities class */ public class Utils { + public static final List dummyList = new ArrayList<>(0); + public static final Map> dummyMap = new HashMap<>(0); - public static final CharSequenceTranslator ESCAPE_CHYPER; + + + private static final CharSequenceTranslator ESCAPE_CHYPER; static { final Map escapeJavaMap = new HashMap<>(); escapeJavaMap.put("\'", "\\'"); @@ -28,7 +33,7 @@ public class Utils { * @param str - a string * @return the input string surrounded with quotation marks, if needed */ - public static String quoteString(String str){ + private static String quoteString(String str){ if(str.startsWith("\"") && str.endsWith("\"")){ return str; } diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java new file mode 100644 index 0000000..1f33572 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java @@ -0,0 +1,59 @@ +package com.redislabs.redisgraph.impl.api; + +import com.redislabs.redisgraph.RedisGraph; +import com.redislabs.redisgraph.ResultSet; +import com.redislabs.redisgraph.impl.Utils; +import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; +import redis.clients.jedis.Jedis; + +import java.util.List; +import java.util.Map; + +/** + * An abstract class to handle non implementation specific user requests + */ +public abstract class AbstractRedisGraph implements RedisGraph { + + + + /** + * Inherited classes should return a Jedis connection, with respect to their context + * @return Jedis connection + */ + protected abstract Jedis getConnection(); + + /** + * Sends a query to the redis graph. Implementation and context dependent + * @param graphId graph to be queried + * @param preparedQuery prepared query + * @return Result set + */ + protected abstract ResultSet sendQuery(String graphId, String preparedQuery); + + /** + * 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 + */ + public ResultSet query(String graphId, String query, Object ...args) { + String preparedQuery = Utils.prepareQuery(query, args); + return sendQuery(graphId, preparedQuery); + } + + + public ResultSet callProcedure(String graphId, String procedure){ + return callProcedure(graphId, procedure, Utils.dummyList, Utils.dummyMap); + } + + public ResultSet callProcedure(String graphId, String procedure, List args){ + return callProcedure(graphId, procedure, args, Utils.dummyMap); + } + + public ResultSet callProcedure(String graphId, String procedure, List args , Map> kwargs){ + + String preparedProcedure = Utils.prepareProcedure(procedure, args, kwargs); + return query(graphId, preparedProcedure); + } +} diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java new file mode 100644 index 0000000..d242503 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java @@ -0,0 +1,121 @@ +package com.redislabs.redisgraph.impl.api; + +import com.redislabs.redisgraph.RedisGraphContexted; +import com.redislabs.redisgraph.ResultSet; +import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; +import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; +import redis.clients.jedis.Client; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.util.SafeEncoder; + +import java.util.List; + +/** + * An implementaion of RedisGraphContexted. Allows sending RedisGraph and some Redis commands, + * within a specific connection context + */ +public class ContextedRedisGraph extends AbstractRedisGraph implements RedisGraphContexted, RedisGraphCacheHolder { + + private Jedis connectionContext; + private RedisGraphCaches caches; + + /** + * Generates a new instance with a specific Jedis connection + * @param connectionContext + */ + public ContextedRedisGraph(Jedis connectionContext){ + this.connectionContext = connectionContext; + } + + /** + * Overrides the abstract method. Return the instance only connection + * @return + */ + @Override + protected Jedis getConnection() { + return this.connectionContext; + } + + /** + * Sends the query over the instance only connection + * @param graphId graph to be queried + * @param preparedQuery prepared query + * @return Result set with the query answer + */ + @Override + protected ResultSet sendQuery(String graphId, String preparedQuery) { + Jedis conn = getConnection(); + List rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, "--COMPACT"); + return new ResultSetImpl(rawResponse, this, graphId, caches.getGraphCache(graphId)); + } + + /** + * @return Returns the instance Jedis connection. + */ + @Override + public Jedis getConnectionContext() { + return this.connectionContext; + } + + /** + * Creates a new RedisGraphTransaction transactional object + * @return new RedisGraphTransaction + */ + @Override + public RedisGraphTransaction multi() { + Jedis jedis = getConnection(); + Client client = jedis.getClient(); + client.multi(); + client.getOne(); + RedisGraphTransaction transaction = new RedisGraphTransaction(client,this); + transaction.setRedisGraphCaches(caches); + return transaction; + } + + /** + * Perfrom watch over given Redis keys + * @param keys + * @return "OK" + */ + @Override + public String watch(String... keys) { + return this.getConnection().watch(keys); + } + + /** + * Removes watch from all keys + * @return + */ + @Override + public String unwatch() { + return this.getConnection().unwatch(); + } + + /** + * Deletes the entire graph + * @param graphId graph to delete + * @return delete running time statistics + */ + @Override + public String deleteGraph(String graphId) { + Object response = getConnection().sendCommand(RedisGraphCommand.DELETE, graphId); + //clear local state + caches.removeGraphCache(graphId); + return SafeEncoder.encode((byte[]) response); + } + + /** + * closes the Jedis connection + */ + @Override + public void close() { + this.connectionContext.close(); + + } + + @Override + public void setRedisGraphCaches(RedisGraphCaches caches) { + this.caches = caches; + } + +} diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java new file mode 100644 index 0000000..455bab6 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java @@ -0,0 +1,113 @@ +package com.redislabs.redisgraph.impl.api; + +import com.redislabs.redisgraph.RedisGraphContexted; +import com.redislabs.redisgraph.RedisGraphGeneralContext; +import com.redislabs.redisgraph.ResultSet; +import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; +import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.util.Pool; +import redis.clients.jedis.util.SafeEncoder; + +import java.util.*; + + + +/** + * + */ +public class RedisGraph extends AbstractRedisGraph implements RedisGraphGeneralContext { + + private final Pool client; + private RedisGraphCaches caches = new RedisGraphCaches(); + + /** + * Creates a client running on the local machine + + */ + public RedisGraph() { + this("localhost", 6379); + } + + /** + * Creates a client running on the specific host/post + * + * @param host Redis host + * @param port Redis port + */ + public RedisGraph(String host, int port) { + this( new JedisPool(host, port)); + } + + /** + * Creates a client using provided Jedis pool + * + * @param jedis bring your own Jedis pool + */ + public RedisGraph( Pool jedis) { + this.client = jedis; + } + + + /** + * Overrides the abstract function. Gets and returns a Jedis connection from the Jedis pool + * @return a Jedis connection + */ + @Override + protected Jedis getConnection() { + return client.getResource(); + } + + /** + * Overrides the abstract function. + * Sends the query from any Jedis connection received from the Jedis pool and closes it once done + * @param graphId graph to be queried + * @param preparedQuery prepared query + * @return Result set with the query answer + */ + @Override + protected ResultSet sendQuery(String graphId, String preparedQuery){ + List rawResponse; + try(Jedis conn = getConnection()){ + rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, "--COMPACT"); + } + return new ResultSetImpl(rawResponse, this, graphId, caches.getGraphCache(graphId)); + } + + + /** + * Closes the Jedis pool + */ + @Override + public void close(){ + this.client.close(); + } + + + /** + * Deletes the entire graph + * @param graphId graph to delete + * @return delete running time statistics + */ + @Override + public String deleteGraph(String graphId) { + try (Jedis conn = getConnection()) { + Object response = conn.sendCommand(RedisGraphCommand.DELETE, graphId); + //clear local state + caches.removeGraphCache(graphId); + return SafeEncoder.encode((byte[]) response); + } + } + + /** + * Returns a new ContextedRedisGraph bounded to a Jedis connection from the Jedis pool + * @return ContextedRedisGraph + */ + @Override + public RedisGraphContexted getContextedAPI() { + ContextedRedisGraph contextedRedisGraph = new ContextedRedisGraph(getConnection()); + contextedRedisGraph.setRedisGraphCaches(this.caches); + return contextedRedisGraph; + } +} diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphCacheHolder.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphCacheHolder.java new file mode 100644 index 0000000..97cab72 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphCacheHolder.java @@ -0,0 +1,8 @@ +package com.redislabs.redisgraph.impl.api; + +import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; + +public interface RedisGraphCacheHolder { + + void setRedisGraphCaches(RedisGraphCaches caches); +} diff --git a/src/main/java/com/redislabs/redisgraph/Command.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphCommand.java similarity index 68% rename from src/main/java/com/redislabs/redisgraph/Command.java rename to src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphCommand.java index 35dbd98..3db45d0 100644 --- a/src/main/java/com/redislabs/redisgraph/Command.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphCommand.java @@ -1,4 +1,4 @@ -package com.redislabs.redisgraph; +package com.redislabs.redisgraph.impl.api; import redis.clients.jedis.util.SafeEncoder; import redis.clients.jedis.commands.ProtocolCommand; @@ -7,13 +7,13 @@ * * */ -public enum Command implements ProtocolCommand { +public enum RedisGraphCommand implements ProtocolCommand { QUERY("graph.QUERY"), DELETE("graph.DELETE"); private final byte[] raw; - Command(String alt) { + RedisGraphCommand(String alt) { raw = SafeEncoder.encode(alt); } diff --git a/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java similarity index 55% rename from src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java rename to src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java index 5476c6d..786487e 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/JRedisGraphTransaction.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java @@ -1,38 +1,33 @@ -package com.redislabs.redisgraph.impl; +package com.redislabs.redisgraph.impl.api; - -import com.redislabs.redisgraph.Command; import com.redislabs.redisgraph.RedisGraph; import com.redislabs.redisgraph.ResultSet; -import com.redislabs.redisgraph.Utils; -import com.redislabs.redisgraph.impl.graph_cache.GraphCache; +import com.redislabs.redisgraph.impl.Utils; +import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; +import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; import redis.clients.jedis.Builder; import redis.clients.jedis.BuilderFactory; import redis.clients.jedis.Client; -import redis.clients.jedis.Jedis; import redis.clients.jedis.Response; import redis.clients.jedis.Transaction; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; /** * This class is extending Jedis Transaction */ -public class JRedisGraphTransaction extends Transaction { +public class RedisGraphTransaction extends Transaction implements com.redislabs.redisgraph.RedisGraphTransaction, RedisGraphCacheHolder { private final RedisGraph redisGraph; - private final Map graphCaches; + private RedisGraphCaches caches; - public JRedisGraphTransaction(Client client, RedisGraph redisGraph, Map graphCaches){ + public RedisGraphTransaction(Client client, RedisGraph redisGraph){ // init as in Jedis super(client); this.redisGraph = redisGraph; - this.graphCaches = graphCaches; } /** @@ -43,14 +38,13 @@ public JRedisGraphTransaction(Client client, RedisGraph redisGraph, Map graphQuery(String graphId, String query, Object ...args){ + public Response query(String graphId, String query, Object ...args){ String preparedQuery = Utils.prepareQuery(query, args); - graphCaches.putIfAbsent(graphId, new GraphCache(graphId, redisGraph)); - client.sendCommand(Command.QUERY, graphId, preparedQuery, "--COMPACT"); + client.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, "--COMPACT"); return getResponse(new Builder() { @Override public ResultSet build(Object o) { - return new ResultSetImpl((List)o, graphCaches.get(graphId)); + return new ResultSetImpl((List)o, redisGraph, graphId, caches.getGraphCache(graphId)); } }); } @@ -62,8 +56,8 @@ public ResultSet build(Object o) { * @param procedure procedure name to invoke * @return response with result set with the procedure data */ - public Response graphCallProcedure(String graphId, String procedure){ - return graphCallProcedure(graphId, procedure, new ArrayList<>(), new HashMap<>()); + public Response callProcedure(String graphId, String procedure){ + return callProcedure(graphId, procedure, Utils.dummyList, Utils.dummyMap); } /** @@ -73,8 +67,8 @@ public Response graphCallProcedure(String graphId, String procedure){ * @param args procedure arguments * @return response with result set with the procedure data */ - public Response graphCallProcedure(String graphId, String procedure, List args ){ - return graphCallProcedure(graphId, procedure, args, new HashMap<>()); + public Response callProcedure(String graphId, String procedure, List args ){ + return callProcedure(graphId, procedure, args, Utils.dummyMap); } @@ -86,10 +80,10 @@ public Response graphCallProcedure(String graphId, String procedure, * @param kwargs - procedure output arguments * @return response with result set with the procedure data */ - public Response graphCallProcedure(String graphId, String procedure, List args, - HashMap> kwargs) { + public Response callProcedure(String graphId, String procedure, List args, + Map> kwargs) { String preparedProcedure = Utils.prepareProcedure(procedure, args, kwargs); - return graphQuery(graphId, preparedProcedure); + return query(graphId, preparedProcedure); } @@ -98,9 +92,17 @@ public Response graphCallProcedure(String graphId, String procedure, * @param graphId graph to delete * @return response with the deletion running time statistics */ - public Response graphDeleteGraph(String graphId){ - graphCaches.remove(graphId); - client.sendCommand(Command.DELETE, graphId); - return getResponse(BuilderFactory.STRING); + public Response deleteGraph(String graphId){ + + client.sendCommand(RedisGraphCommand.DELETE, graphId); + Response response = getResponse(BuilderFactory.STRING); + caches.removeGraphCache(graphId); + return response; } + + @Override + public void setRedisGraphCaches(RedisGraphCaches caches) { + this.caches = caches; + } + } diff --git a/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCache.java b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCache.java index 765dff8..565c916 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCache.java +++ b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCache.java @@ -15,36 +15,35 @@ public class GraphCache { /** * * @param graphId - graph Id - * @param redisGraph - a client to use in the cache, for re-validate it by calling procedures */ - public GraphCache(String graphId, RedisGraph redisGraph) { - this.labels = new GraphCacheList(graphId, "db.labels", redisGraph); - this.propertyNames = new GraphCacheList(graphId, "db.propertyKeys", redisGraph); - this.relationshipTypes = new GraphCacheList(graphId, "db.relationshipTypes", redisGraph); + public GraphCache(String graphId) { + this.labels = new GraphCacheList(graphId, "db.labels"); + this.propertyNames = new GraphCacheList(graphId, "db.propertyKeys"); + this.relationshipTypes = new GraphCacheList(graphId, "db.relationshipTypes"); } /** * @param index - index of label * @return requested label */ - public String getLabel(int index) { - return labels.getCachedData(index); + public String getLabel(int index, RedisGraph redisGraph) { + return labels.getCachedData(index, redisGraph); } /** * @param index index of the relationship type * @return requested relationship type */ - public String getRelationshipType(int index) { - return relationshipTypes.getCachedData(index); + public String getRelationshipType(int index, RedisGraph redisGraph) { + return relationshipTypes.getCachedData(index, redisGraph); } /** * @param index index of property name * @return requested property */ - public String getPropertyName(int index) { + public String getPropertyName(int index, RedisGraph redisGraph) { - return propertyNames.getCachedData(index); + return propertyNames.getCachedData(index, redisGraph); } } diff --git a/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java index d608f16..7855931 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java +++ b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java @@ -7,17 +7,16 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.ReentrantReadWriteLock; + /** * Represents a local cache of list of strings. Holds data from a specific procedure, for a specific graph. */ -public class GraphCacheList { +class GraphCacheList { - private Object mutex = new Object(); + private final Object mutex = new Object(); private final String graphId; private final String procedure; - private final RedisGraph redisGraph; private final List data = new CopyOnWriteArrayList<>(); @@ -26,12 +25,10 @@ public class GraphCacheList { * * @param graphId - graph id * @param procedure - exact procedure command - * @param redisGraph - a client to use in the cache, for re-validate it by calling procedures */ - public GraphCacheList(String graphId, String procedure, RedisGraph redisGraph) { + public GraphCacheList(String graphId, String procedure) { this.graphId = graphId; this.procedure = procedure; - this.redisGraph = redisGraph; } @@ -40,23 +37,22 @@ public GraphCacheList(String graphId, String procedure, RedisGraph redisGraph) { * @param index index of data item * @return The string value of the specific procedure response, at the given index. */ - public String getCachedData(int index) { + public String getCachedData(int index, RedisGraph redisGraph) { if (index >= data.size()) { synchronized (mutex){ if (index >= data.size()) { - getProcedureInfo(); + getProcedureInfo(redisGraph); } } } - String s = data.get(index); - return s; + return data.get(index); } /** * Auxiliary method to parse a procedure result set and refresh the cache */ - private void getProcedureInfo() { + private void getProcedureInfo(RedisGraph redisGraph) { ResultSet resultSet = redisGraph.callProcedure(graphId, procedure); List newData = new ArrayList<>(); int i = 0; diff --git a/src/main/java/com/redislabs/redisgraph/impl/graph_cache/RedisGraphCaches.java b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/RedisGraphCaches.java new file mode 100644 index 0000000..528ed34 --- /dev/null +++ b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/RedisGraphCaches.java @@ -0,0 +1,59 @@ +package com.redislabs.redisgraph.impl.graph_cache; + +import com.redislabs.redisgraph.RedisGraph; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class RedisGraphCaches { + + private final Map graphCaches = new ConcurrentHashMap<>(); + + public GraphCache getGraphCache(String graphId){ + if (!graphCaches.containsKey(graphId)){ + graphCaches.putIfAbsent(graphId, new GraphCache(graphId)); + } + return graphCaches.get(graphId); + } + + /** + * Returns a String which represents the name of the label mapped to the label id + * @param graphId graph to perform the query + * @param index label index + * @param redisGraph RedisGraphAPI implementation + * @return label name + */ + public String getLabel(String graphId, int index, RedisGraph redisGraph) { + return getGraphCache(graphId).getLabel(index, redisGraph); + } + + /** + * Returns a String which represents the name of the relationship mapped to the label id + * @param graphId graph to perform the query + * @param index relationship index + * @param redisGraph RedisGraphAPI implementation + * @return relationship name + */ + public String getRelationshipType(String graphId, int index, RedisGraph redisGraph){ + return getGraphCache(graphId).getRelationshipType(index, redisGraph); + } + + /** + * Returns a String which represents the name of the property mapped to the label id + * @param graphId graph to perform the query + * @param index property index + * @param redisGraph RedisGraphAPI implementation + * @return property name + */ + public String getPropertyName(String graphId, int index, RedisGraph redisGraph){ + return getGraphCache(graphId).getPropertyName(index, redisGraph); + } + + /** + * Removes a graph meta data cache + * @param graphId + */ + public void removeGraphCache(String graphId){ + graphCaches.remove(graphId); + } +} diff --git a/src/main/java/com/redislabs/redisgraph/impl/HeaderImpl.java b/src/main/java/com/redislabs/redisgraph/impl/resultset/HeaderImpl.java similarity index 98% rename from src/main/java/com/redislabs/redisgraph/impl/HeaderImpl.java rename to src/main/java/com/redislabs/redisgraph/impl/resultset/HeaderImpl.java index 2a7a40f..a9ae068 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/HeaderImpl.java +++ b/src/main/java/com/redislabs/redisgraph/impl/resultset/HeaderImpl.java @@ -1,4 +1,4 @@ -package com.redislabs.redisgraph.impl; +package com.redislabs.redisgraph.impl.resultset; import com.redislabs.redisgraph.Header; import redis.clients.jedis.util.SafeEncoder; diff --git a/src/main/java/com/redislabs/redisgraph/impl/RecordImpl.java b/src/main/java/com/redislabs/redisgraph/impl/resultset/RecordImpl.java similarity index 97% rename from src/main/java/com/redislabs/redisgraph/impl/RecordImpl.java rename to src/main/java/com/redislabs/redisgraph/impl/resultset/RecordImpl.java index 8aca26c..adf68ad 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/RecordImpl.java +++ b/src/main/java/com/redislabs/redisgraph/impl/resultset/RecordImpl.java @@ -1,4 +1,4 @@ -package com.redislabs.redisgraph.impl; +package com.redislabs.redisgraph.impl.resultset; import java.util.List; import java.util.Objects; diff --git a/src/main/java/com/redislabs/redisgraph/impl/ResultSetImpl.java b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java similarity index 88% rename from src/main/java/com/redislabs/redisgraph/impl/ResultSetImpl.java rename to src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java index 9cfc5b8..ec74ec9 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/ResultSetImpl.java +++ b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java @@ -1,4 +1,4 @@ -package com.redislabs.redisgraph.impl; +package com.redislabs.redisgraph.impl.resultset; import com.redislabs.redisgraph.*; import com.redislabs.redisgraph.graph_entities.Edge; @@ -6,6 +6,7 @@ import com.redislabs.redisgraph.graph_entities.Node; import com.redislabs.redisgraph.graph_entities.Property; import com.redislabs.redisgraph.impl.graph_cache.GraphCache; +import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; import redis.clients.jedis.util.SafeEncoder; import java.util.ArrayList; @@ -20,15 +21,19 @@ public class ResultSetImpl implements ResultSet { private final List results ; private int position = 0; - private final GraphCache graphCache; + private final RedisGraph redisGraph; + private final String graphId; + private final GraphCache cache; /** * @param rawResponse the raw representation of response is at most 3 lists of objects. * The last list is the statistics list. - * @param graphCache, the graph local cache + * @param redisGraph, the graph local cache */ - public ResultSetImpl(List rawResponse, GraphCache graphCache) { - this.graphCache = graphCache; + public ResultSetImpl(List rawResponse, RedisGraph redisGraph, String graphId, GraphCache cache) { + this.redisGraph = redisGraph; + this.graphId = graphId; + this.cache = cache; if (rawResponse.size() != 3) { header = parseHeader(new ArrayList<>()); @@ -40,7 +45,7 @@ public ResultSetImpl(List rawResponse, GraphCache graphCache) { header = parseHeader((List>) rawResponse.get(0)); results = parseResult((List>) rawResponse.get(1)); - statistics = parseStatistics((List) rawResponse.get(2)); + statistics = parseStatistics(rawResponse.get(2)); } } @@ -130,7 +135,7 @@ private Node deserializeNode(List rawNodeData) { deserializeGraphEntityId(node, rawNodeData.get(0)); List labelsIndices = (List) rawNodeData.get(1); for (long labelIndex : labelsIndices) { - String label = graphCache.getLabel((int) labelIndex); + String label = cache.getLabel((int) labelIndex, redisGraph); node.addLabel(label); } deserializeGraphEntityProperties(node, (List>) rawNodeData.get(2)); @@ -162,7 +167,8 @@ private Edge deserializeEdge(List rawEdgeData) { Edge edge = new Edge(); deserializeGraphEntityId(edge, rawEdgeData.get(0)); - String relationshipType = graphCache.getRelationshipType(((Long) rawEdgeData.get(1)).intValue()); + String relationshipType = cache.getRelationshipType(((Long) rawEdgeData.get(1)).intValue(), + redisGraph); edge.setRelationshipType(relationshipType); edge.setSource((int) (long) rawEdgeData.get(2)); @@ -181,12 +187,13 @@ private Edge deserializeEdge(List rawEdgeData) { * rawProperty.get(1) - property type * rawProperty.get(2) - property value */ - void deserializeGraphEntityProperties(GraphEntity entity, List> rawProperties) { + private void deserializeGraphEntityProperties(GraphEntity entity, List> rawProperties) { for (List rawProperty : rawProperties) { Property property = new Property(); - property.setName(graphCache.getPropertyName(((Long) rawProperty.get(0)).intValue())); + property.setName(cache.getPropertyName(((Long) rawProperty.get(0)).intValue(), + redisGraph)); //trimmed for getting to value using deserializeScalar List propertyScalar = rawProperty.subList(1, rawProperty.size()); @@ -214,7 +221,7 @@ private Object deserializeScalar(List rawScalarData) { case PROPERTY_DOUBLE: return Double.parseDouble(SafeEncoder.encode((byte[]) obj)); case PROPERTY_INTEGER: - return (Integer) ((Long) obj).intValue(); + return ((Long) obj).intValue(); case PROPERTY_STRING: return SafeEncoder.encode((byte[]) obj); case PROPERTY_UNKNOWN: diff --git a/src/main/java/com/redislabs/redisgraph/impl/StatisticsImpl.java b/src/main/java/com/redislabs/redisgraph/impl/resultset/StatisticsImpl.java similarity index 93% rename from src/main/java/com/redislabs/redisgraph/impl/StatisticsImpl.java rename to src/main/java/com/redislabs/redisgraph/impl/resultset/StatisticsImpl.java index 68887e1..a6b24af 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/StatisticsImpl.java +++ b/src/main/java/com/redislabs/redisgraph/impl/resultset/StatisticsImpl.java @@ -1,4 +1,4 @@ -package com.redislabs.redisgraph.impl; +package com.redislabs.redisgraph.impl.resultset; import java.util.EnumMap; import java.util.List; @@ -18,7 +18,7 @@ public class StatisticsImpl implements Statistics { private final Map statistics; /** - * A raw representation of query exection statistics is a list of strings + * A raw representation of query execution statistics is a list of strings * (byte arrays which need to be de-serialized). * Each string is built in the form of "K:V" where K is statistics label and V is its value. * @param raw a raw representation of the query execution statistics @@ -95,7 +95,7 @@ public int indicesAdded() { /** * - * @return number of lables added after query execution + * @return number of labels added after query execution */ @Override public int labelsAdded() { @@ -134,7 +134,7 @@ public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof StatisticsImpl)) return false; StatisticsImpl that = (StatisticsImpl) o; - return Objects.equals(raw, raw) && + return Objects.equals(raw, that.raw) && Objects.equals(getStatistics(), that.getStatistics()); } diff --git a/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java b/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java index d8a6374..6c5514e 100644 --- a/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java +++ b/src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java @@ -1,6 +1,7 @@ package com.redislabs.redisgraph; +import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; @@ -10,8 +11,8 @@ import com.redislabs.redisgraph.graph_entities.Edge; import com.redislabs.redisgraph.graph_entities.Node; import com.redislabs.redisgraph.graph_entities.Property; -import com.redislabs.redisgraph.impl.JRedisGraphTransaction; -import com.redislabs.redisgraph.impl.ResultSetImpl; +import com.redislabs.redisgraph.impl.api.RedisGraph; +import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -22,7 +23,7 @@ import static com.redislabs.redisgraph.Header.ResultSetColumnTypes.*; public class RedisGraphAPITest { - RedisGraph api; + private RedisGraphGeneralContext api; public RedisGraphAPITest() { } @@ -35,11 +36,14 @@ public void createApi(){ public void deleteGraph() { api.deleteGraph("social"); - api.close(); + try { + api.close(); + } catch (IOException e) { + e.printStackTrace(); + } } - @Test public void testCreateNode() { // Create a node @@ -59,7 +63,7 @@ public void testCreateNode() { try { resultSet.next(); Assert.fail(); - } catch (NoSuchElementException e) { + } catch (NoSuchElementException ignored) { } } @@ -500,16 +504,16 @@ public void testEscapedQuery() { @Test public void testMultiExec(){ - JRedisGraphTransaction transaction = api.multi(); + RedisGraphTransaction transaction = api.getContextedAPI().multi(); transaction.set("x", "1"); - transaction.graphQuery("social", "CREATE (:Person {name:'a'})"); - transaction.graphQuery("g", "CREATE (:Person {name:'a'})"); + transaction.query("social", "CREATE (:Person {name:'a'})"); + transaction.query("g", "CREATE (:Person {name:'a'})"); transaction.incr("x"); transaction.get("x"); - transaction.graphQuery("social", "MATCH (n:Person) RETURN n"); - transaction.graphDeleteGraph("g"); - transaction.graphCallProcedure("social", "db.labels"); + transaction.query("social", "MATCH (n:Person) RETURN n"); + transaction.deleteGraph("g"); + transaction.callProcedure("social", "db.labels"); List results = transaction.exec(); // Redis set command @@ -603,4 +607,169 @@ record = resultSet.next(); Assert.assertEquals("Person", record.getValue("label")); } + + @Test + public void testContextedAPI(){ + + String name = "roi"; + int age = 32; + double doubleValue = 3.14; + boolean boolValue = true; + + String place = "TLV"; + int since = 2000; + + + + Property nameProperty = new Property("name", ResultSet.ResultSetScalarTypes.PROPERTY_STRING, name); + Property ageProperty = new Property("age", ResultSet.ResultSetScalarTypes.PROPERTY_INTEGER, age); + Property doubleProperty = new Property("doubleValue", ResultSet.ResultSetScalarTypes.PROPERTY_DOUBLE, doubleValue); + Property trueBooleanProperty = new Property("boolValue", ResultSet.ResultSetScalarTypes.PROPERTY_BOOLEAN, true); + Property falseBooleanProperty = new Property("boolValue", ResultSet.ResultSetScalarTypes.PROPERTY_BOOLEAN, false); + Property nullProperty = new Property("nullValue", ResultSet.ResultSetScalarTypes.PROPERTY_NULL, null); + + Property placeProperty = new Property("place", ResultSet.ResultSetScalarTypes.PROPERTY_STRING, place); + Property sinceProperty = new Property("since", ResultSet.ResultSetScalarTypes.PROPERTY_INTEGER, since); + + Node expectedNode = new Node(); + expectedNode.setId(0); + expectedNode.addLabel("person"); + expectedNode.addProperty(nameProperty); + expectedNode.addProperty(ageProperty); + expectedNode.addProperty(doubleProperty); + expectedNode.addProperty(trueBooleanProperty); + expectedNode.addProperty(nullProperty); + + Edge expectedEdge = new Edge(); + expectedEdge.setId(0); + expectedEdge.setSource(0); + expectedEdge.setDestination(1); + expectedEdge.setRelationshipType("knows"); + expectedEdge.addProperty(placeProperty); + expectedEdge.addProperty(sinceProperty); + expectedEdge.addProperty(doubleProperty); + expectedEdge.addProperty(falseBooleanProperty); + expectedEdge.addProperty(nullProperty); + + RedisGraphContexted c = api.getContextedAPI(); + + 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:'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)")); + + ResultSet resultSet = c.query("social", "MATCH (a:person)-[r:knows]->(b:person) RETURN a,r, " + + "a.name, a.age, a.doubleValue, a.boolValue, a.nullValue, " + + "r.place, r.since, r.doubleValue, r.boolValue, r.nullValue"); + Assert.assertNotNull(resultSet); + + + Assert.assertEquals(0, resultSet.getStatistics().nodesCreated()); + Assert.assertEquals(0, resultSet.getStatistics().nodesDeleted()); + Assert.assertEquals(0, resultSet.getStatistics().labelsAdded()); + Assert.assertEquals(0, resultSet.getStatistics().propertiesSet()); + Assert.assertEquals(0, resultSet.getStatistics().relationshipsCreated()); + Assert.assertEquals(0, resultSet.getStatistics().relationshipsDeleted()); + Assert.assertNotNull(resultSet.getStatistics().getStringValue(Label.QUERY_INTERNAL_EXECUTION_TIME)); + + + Assert.assertEquals(1, resultSet.size()); + Assert.assertTrue(resultSet.hasNext()); + Record record = resultSet.next(); + Assert.assertFalse(resultSet.hasNext()); + + Node node = record.getValue(0); + Assert.assertNotNull(node); + + Assert.assertEquals(expectedNode, node); + + node = record.getValue("a"); + Assert.assertEquals(expectedNode, node); + + Edge edge = record.getValue(1); + Assert.assertNotNull(edge); + Assert.assertEquals(expectedEdge, edge); + + edge = record.getValue("r"); + Assert.assertEquals(expectedEdge, edge); + + Assert.assertEquals(Arrays.asList("a", "r", "a.name", "a.age", "a.doubleValue", "a.boolValue", "a.nullValue", + "r.place", "r.since", "r.doubleValue", "r.boolValue", "r.nullValue"), record.keys()); + + Assert.assertEquals(Arrays.asList(expectedNode, expectedEdge, + name, age, doubleValue, true, null, + place, since, doubleValue, false, null), + record.values()); + + Node a = record.getValue("a"); + for (String propertyName : expectedNode.getEntityPropertyNames()){ + Assert.assertEquals(expectedNode.getProperty(propertyName) ,a.getProperty(propertyName)); + } + + Assert.assertEquals( "roi", record.getString(2)); + Assert.assertEquals( "32", record.getString(3)); + Assert.assertEquals( 32L, ((Integer)(record.getValue(3))).longValue()); + Assert.assertEquals( 32L, ((Integer)record.getValue("a.age")).longValue()); + Assert.assertEquals( "roi", record.getString("a.name")); + Assert.assertEquals( "32", record.getString("a.age")); + + + } + + @Test + public void testWriteTransactionWatch(){ + + RedisGraphContexted c1 = api.getContextedAPI(); + RedisGraphContexted c2 = api.getContextedAPI(); + + c1.watch("social"); + RedisGraphTransaction t1 = c1.multi(); + + + t1.query("social", "CREATE (:Person {name:'a'})"); + c2.query("social", "CREATE (:Person {name:'b'})"); + List returnValue = t1.exec(); + Assert.assertNull(returnValue); + + try { + c1.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + c2.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + @Test + public void testReadTransactionWatch(){ + + RedisGraphContexted c1 = api.getContextedAPI(); + RedisGraphContexted c2 = api.getContextedAPI(); + Assert.assertNotEquals(c1.getConnectionContext(), c2.getConnectionContext()); + c1.query("social", "CREATE (:Person {name:'a'})"); + c1.watch("social"); + RedisGraphTransaction t1 = c1.multi(); + + t1.query("social", "CREATE (:Person {name:'b'})"); + c2.query("social", "MATCH (n) return n"); + List returnValue = t1.exec(); + + Assert.assertNotNull(returnValue); + + try { + c1.close(); + } catch (IOException e) { + e.printStackTrace(); + } + try { + c2.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } } From 39092e0d13128ad04c7436950ce38487f2d5103f Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Sun, 21 Jul 2019 13:37:06 +0300 Subject: [PATCH 4/8] fixed according to PR. changed connection to context connection even in general queries --- pom.xml | 2 +- src/main/java/META-INF/MANIFEST.MF | 6 +++--- .../graph_entities/GraphEntity.java | 4 ++-- .../com/redislabs/redisgraph/impl/Utils.java | 18 +++++++++++++++-- .../impl/api/ContextedRedisGraph.java | 20 +++++++++++++++++-- .../redisgraph/impl/api/RedisGraph.java | 8 ++++---- .../impl/graph_cache/GraphCacheList.java | 5 +---- 7 files changed, 45 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index a83a43c..53bcd96 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ redis.clients jedis - 3.1.0-m4 + 3.1.0-rc org.apache.commons diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF index 425ebf5..7356ba4 100644 --- a/src/main/java/META-INF/MANIFEST.MF +++ b/src/main/java/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ -Manifest-Version: 1.0 -Main-Class: com.redislabs.redisgraph.RedisGraphAPI - +Manifest-Version: 1.0 +Main-Class: com.redislabs.redisgraph.RedisGraph + diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java b/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java index 42cc3f9..d2083a6 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/GraphEntity.java @@ -16,8 +16,8 @@ public abstract class GraphEntity { //members - int id; - final Map propertyMap = new HashMap<>(); + protected int id; + protected final Map propertyMap = new HashMap<>(); //setters & getters diff --git a/src/main/java/com/redislabs/redisgraph/impl/Utils.java b/src/main/java/com/redislabs/redisgraph/impl/Utils.java index b9d1873..2d0b42c 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/Utils.java +++ b/src/main/java/com/redislabs/redisgraph/impl/Utils.java @@ -17,6 +17,7 @@ public class Utils { public static final List dummyList = new ArrayList<>(0); public static final Map> dummyMap = new HashMap<>(0); + public static final String compactString = "--COMPACT"; @@ -77,10 +78,23 @@ public static String prepareQuery(String query, Object ...args){ public static String prepareProcedure(String procedure, List args , Map> kwargs){ args = args.stream().map( s -> Utils.quoteString(s)).collect(Collectors.toList()); StringBuilder queryStringBuilder = new StringBuilder(); - queryStringBuilder.append(String.format("CALL %s(%s)", procedure, String.join(",", args))); + queryStringBuilder.append("CALL ").append(procedure).append("("); + int i = 0; + for (; i < args.size() - 1; i++) { + queryStringBuilder.append(args.get(i)).append(","); + } + if (i == args.size()-1) { + queryStringBuilder.append(args.get(i)); + } + queryStringBuilder.append(")"); List kwargsList = kwargs.getOrDefault("y", null); if(kwargsList != null){ - queryStringBuilder.append(String.join(",", kwargsList)); + i = 0; + for (; i < kwargsList.size() - 1; i++) { + queryStringBuilder.append(kwargsList.get(i)).append(","); + + } + queryStringBuilder.append(kwargsList.get(i)); } return queryStringBuilder.toString(); } diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java index d242503..bbe7d27 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java @@ -2,6 +2,7 @@ import com.redislabs.redisgraph.RedisGraphContexted; import com.redislabs.redisgraph.ResultSet; +import com.redislabs.redisgraph.impl.Utils; import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; import redis.clients.jedis.Client; @@ -45,7 +46,14 @@ protected Jedis getConnection() { @Override protected ResultSet sendQuery(String graphId, String preparedQuery) { Jedis conn = getConnection(); - List rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, "--COMPACT"); + List rawResponse; + try { + rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, Utils.compactString); + } + catch (Exception e) { + conn.close(); + throw e; + } return new ResultSetImpl(rawResponse, this, graphId, caches.getGraphCache(graphId)); } @@ -98,7 +106,15 @@ public String unwatch() { */ @Override public String deleteGraph(String graphId) { - Object response = getConnection().sendCommand(RedisGraphCommand.DELETE, graphId); + Jedis conn = getConnection(); + Object response; + try { + response = conn.sendCommand(RedisGraphCommand.DELETE, graphId); + } + catch (Exception e) { + conn.close(); + throw e; + } //clear local state caches.removeGraphCache(graphId); return SafeEncoder.encode((byte[]) response); diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java index 455bab6..ae23b82 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java @@ -3,6 +3,7 @@ import com.redislabs.redisgraph.RedisGraphContexted; import com.redislabs.redisgraph.RedisGraphGeneralContext; import com.redislabs.redisgraph.ResultSet; +import com.redislabs.redisgraph.impl.Utils; import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; import redis.clients.jedis.Jedis; @@ -68,11 +69,10 @@ protected Jedis getConnection() { */ @Override protected ResultSet sendQuery(String graphId, String preparedQuery){ - List rawResponse; - try(Jedis conn = getConnection()){ - rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, "--COMPACT"); + try (ContextedRedisGraph contextedRedisGraph = new ContextedRedisGraph(getConnection())) { + contextedRedisGraph.setRedisGraphCaches(caches); + return contextedRedisGraph.sendQuery(graphId, preparedQuery); } - return new ResultSetImpl(rawResponse, this, graphId, caches.getGraphCache(graphId)); } diff --git a/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java index 7855931..55035d1 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java +++ b/src/main/java/com/redislabs/redisgraph/impl/graph_cache/GraphCacheList.java @@ -14,13 +14,10 @@ */ class GraphCacheList { - private final Object mutex = new Object(); private final String graphId; private final String procedure; private final List data = new CopyOnWriteArrayList<>(); - - /** * * @param graphId - graph id @@ -39,7 +36,7 @@ public GraphCacheList(String graphId, String procedure) { */ public String getCachedData(int index, RedisGraph redisGraph) { if (index >= data.size()) { - synchronized (mutex){ + synchronized (data){ if (index >= data.size()) { getProcedureInfo(redisGraph); } From 0be41a8631e3faa087e9538127d0756b13fd9db2 Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Mon, 22 Jul 2019 11:42:13 +0300 Subject: [PATCH 5/8] add some code cleanups --- .../redisgraph/RedisGraphGeneralContext.java | 2 -- .../redisgraph/impl/api/AbstractRedisGraph.java | 1 - .../redislabs/redisgraph/impl/api/RedisGraph.java | 6 ------ .../redisgraph/impl/resultset/ResultSetImpl.java | 15 +++++---------- 4 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java b/src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java index 4596ec9..cdf218a 100644 --- a/src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java +++ b/src/main/java/com/redislabs/redisgraph/RedisGraphGeneralContext.java @@ -1,7 +1,5 @@ package com.redislabs.redisgraph; -import redis.clients.jedis.Jedis; - public interface RedisGraphGeneralContext extends RedisGraph { /** diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java index 1f33572..3337fcd 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java @@ -3,7 +3,6 @@ import com.redislabs.redisgraph.RedisGraph; import com.redislabs.redisgraph.ResultSet; import com.redislabs.redisgraph.impl.Utils; -import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; import redis.clients.jedis.Jedis; import java.util.List; diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java index ae23b82..900e32c 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java @@ -3,18 +3,12 @@ import com.redislabs.redisgraph.RedisGraphContexted; import com.redislabs.redisgraph.RedisGraphGeneralContext; import com.redislabs.redisgraph.ResultSet; -import com.redislabs.redisgraph.impl.Utils; import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; -import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.util.Pool; import redis.clients.jedis.util.SafeEncoder; -import java.util.*; - - - /** * */ diff --git a/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java index ec74ec9..ff2a9c9 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java +++ b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java @@ -6,7 +6,6 @@ import com.redislabs.redisgraph.graph_entities.Node; import com.redislabs.redisgraph.graph_entities.Property; import com.redislabs.redisgraph.impl.graph_cache.GraphCache; -import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; import redis.clients.jedis.util.SafeEncoder; import java.util.ArrayList; @@ -22,7 +21,6 @@ public class ResultSetImpl implements ResultSet { private int position = 0; private final RedisGraph redisGraph; - private final String graphId; private final GraphCache cache; /** @@ -30,9 +28,8 @@ public class ResultSetImpl implements ResultSet { * The last list is the statistics list. * @param redisGraph, the graph local cache */ - public ResultSetImpl(List rawResponse, RedisGraph redisGraph, String graphId, GraphCache cache) { + public ResultSetImpl(List rawResponse, RedisGraph redisGraph, GraphCache cache) { this.redisGraph = redisGraph; - this.graphId = graphId; this.cache = cache; if (rawResponse.size() != 3) { @@ -78,10 +75,8 @@ private List parseResult(List> rawResultSet) { case COLUMN_RELATION: parsedRow.add(deserializeEdge(obj)); break; - case COLUMN_SCALAR: { + case COLUMN_SCALAR: parsedRow.add(deserializeScalar(obj)); - - } } } @@ -134,8 +129,8 @@ private Node deserializeNode(List rawNodeData) { Node node = new Node(); deserializeGraphEntityId(node, rawNodeData.get(0)); List labelsIndices = (List) rawNodeData.get(1); - for (long labelIndex : labelsIndices) { - String label = cache.getLabel((int) labelIndex, redisGraph); + for (Long labelIndex : labelsIndices) { + String label = cache.getLabel(labelIndex.intValue(), redisGraph); node.addLabel(label); } deserializeGraphEntityProperties(node, (List>) rawNodeData.get(2)); @@ -149,7 +144,7 @@ private Node deserializeNode(List rawNodeData) { * @param rawEntityId raw representation of entity id to be set to the graph entity */ private void deserializeGraphEntityId(GraphEntity graphEntity, Object rawEntityId) { - int id = (int) (long) rawEntityId; + int id = ((Long) rawEntityId).intValue(); graphEntity.setId(id); } From 2b82bac58089c43b7984712241aeff28b4e71edd Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Mon, 22 Jul 2019 11:46:20 +0300 Subject: [PATCH 6/8] fixed according to PR --- pom.xml | 10 +++++----- .../redisgraph/impl/api/ContextedRedisGraph.java | 2 +- .../redislabs/redisgraph/impl/api/RedisGraph.java | 5 ----- .../redisgraph/impl/api/RedisGraphTransaction.java | 2 +- .../redisgraph/impl/resultset/ResultSetImpl.java | 12 +++++++----- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 53bcd96..c99fd63 100644 --- a/pom.xml +++ b/pom.xml @@ -77,10 +77,10 @@ - 8 - 8 - 8 - 8 + 10 + 10 + 10 + 10 @@ -179,7 +179,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.11.0 + 3.12.0 diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java index bbe7d27..bdf69c9 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java @@ -54,7 +54,7 @@ protected ResultSet sendQuery(String graphId, String preparedQuery) { conn.close(); throw e; } - return new ResultSetImpl(rawResponse, this, graphId, caches.getGraphCache(graphId)); + return new ResultSetImpl(rawResponse, this, caches.getGraphCache(graphId)); } /** diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java index ae23b82..66b20f9 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraph.java @@ -3,17 +3,12 @@ import com.redislabs.redisgraph.RedisGraphContexted; import com.redislabs.redisgraph.RedisGraphGeneralContext; import com.redislabs.redisgraph.ResultSet; -import com.redislabs.redisgraph.impl.Utils; import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; -import com.redislabs.redisgraph.impl.resultset.ResultSetImpl; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.util.Pool; import redis.clients.jedis.util.SafeEncoder; -import java.util.*; - - /** * diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java index 786487e..91c96e8 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java @@ -44,7 +44,7 @@ public Response query(String graphId, String query, Object ...args){ return getResponse(new Builder() { @Override public ResultSet build(Object o) { - return new ResultSetImpl((List)o, redisGraph, graphId, caches.getGraphCache(graphId)); + return new ResultSetImpl((List)o, redisGraph, caches.getGraphCache(graphId)); } }); } diff --git a/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java index ec74ec9..429ab3a 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java +++ b/src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java @@ -6,7 +6,6 @@ import com.redislabs.redisgraph.graph_entities.Node; import com.redislabs.redisgraph.graph_entities.Property; import com.redislabs.redisgraph.impl.graph_cache.GraphCache; -import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches; import redis.clients.jedis.util.SafeEncoder; import java.util.ArrayList; @@ -22,7 +21,6 @@ public class ResultSetImpl implements ResultSet { private int position = 0; private final RedisGraph redisGraph; - private final String graphId; private final GraphCache cache; /** @@ -30,9 +28,8 @@ public class ResultSetImpl implements ResultSet { * The last list is the statistics list. * @param redisGraph, the graph local cache */ - public ResultSetImpl(List rawResponse, RedisGraph redisGraph, String graphId, GraphCache cache) { + public ResultSetImpl(List rawResponse, RedisGraph redisGraph, GraphCache cache) { this.redisGraph = redisGraph; - this.graphId = graphId; this.cache = cache; if (rawResponse.size() != 3) { @@ -80,8 +77,13 @@ private List parseResult(List> rawResultSet) { break; case COLUMN_SCALAR: { parsedRow.add(deserializeScalar(obj)); - + break; } + default: { + parsedRow.add(null); + break; + } + } } From 79c5dc58b82a9e093b51adcdd02d10d16580481b Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Mon, 22 Jul 2019 11:52:20 +0300 Subject: [PATCH 7/8] clean code --- .../com/redislabs/redisgraph/graph_entities/Node.java | 4 ++-- src/main/java/com/redislabs/redisgraph/impl/Utils.java | 10 +++++----- .../redisgraph/impl/api/AbstractRedisGraph.java | 4 ++-- .../redisgraph/impl/api/ContextedRedisGraph.java | 4 ++-- .../redisgraph/impl/api/RedisGraphTransaction.java | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java b/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java index f118964..91b9a4f 100644 --- a/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java +++ b/src/main/java/com/redislabs/redisgraph/graph_entities/Node.java @@ -10,7 +10,7 @@ public class Node extends GraphEntity { //members - final private List labels = new ArrayList<>(); + private final List labels = new ArrayList<>(); /** * @param label - a label to be add @@ -32,7 +32,7 @@ public void removeLabel(String label) { * @throws IndexOutOfBoundsException if the index is out of range * ({@code index < 0 || index >= getNumberOfLabels()}) */ - public String getLabel(int index) throws IndexOutOfBoundsException{ + public String getLabel(int index){ return labels.get(index); } diff --git a/src/main/java/com/redislabs/redisgraph/impl/Utils.java b/src/main/java/com/redislabs/redisgraph/impl/Utils.java index 2d0b42c..bb39c5b 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/Utils.java +++ b/src/main/java/com/redislabs/redisgraph/impl/Utils.java @@ -15,11 +15,9 @@ * Utilities class */ public class Utils { - public static final List dummyList = new ArrayList<>(0); - public static final Map> dummyMap = new HashMap<>(0); - public static final String compactString = "--COMPACT"; - - + public static final List DUMMY_LIST = new ArrayList<>(0); + public static final Map> DUMMY_MAP = new HashMap<>(0); + public static final String COMPACT_STRING = "--COMPACT"; private static final CharSequenceTranslator ESCAPE_CHYPER; static { @@ -28,6 +26,8 @@ public class Utils { escapeJavaMap.put("\"", "\\\""); ESCAPE_CHYPER = new AggregateTranslator(new LookupTranslator(Collections.unmodifiableMap(escapeJavaMap))); } + + private Utils() {} /** * diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java index 3337fcd..d659b22 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/AbstractRedisGraph.java @@ -43,11 +43,11 @@ public ResultSet query(String graphId, String query, Object ...args) { public ResultSet callProcedure(String graphId, String procedure){ - return callProcedure(graphId, procedure, Utils.dummyList, Utils.dummyMap); + return callProcedure(graphId, procedure, Utils.DUMMY_LIST, Utils.DUMMY_MAP); } public ResultSet callProcedure(String graphId, String procedure, List args){ - return callProcedure(graphId, procedure, args, Utils.dummyMap); + return callProcedure(graphId, procedure, args, Utils.DUMMY_MAP); } public ResultSet callProcedure(String graphId, String procedure, List args , Map> kwargs){ diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java index bbe7d27..a1fa081 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java @@ -48,13 +48,13 @@ protected ResultSet sendQuery(String graphId, String preparedQuery) { Jedis conn = getConnection(); List rawResponse; try { - rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, Utils.compactString); + rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, Utils.COMPACT_STRING); } catch (Exception e) { conn.close(); throw e; } - return new ResultSetImpl(rawResponse, this, graphId, caches.getGraphCache(graphId)); + return new ResultSetImpl(rawResponse, this, caches.getGraphCache(graphId)); } /** diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java index 786487e..21f2a5d 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/RedisGraphTransaction.java @@ -57,7 +57,7 @@ public ResultSet build(Object o) { * @return response with result set with the procedure data */ public Response callProcedure(String graphId, String procedure){ - return callProcedure(graphId, procedure, Utils.dummyList, Utils.dummyMap); + return callProcedure(graphId, procedure, Utils.DUMMY_LIST, Utils.DUMMY_MAP); } /** @@ -68,7 +68,7 @@ public Response callProcedure(String graphId, String procedure){ * @return response with result set with the procedure data */ public Response callProcedure(String graphId, String procedure, List args ){ - return callProcedure(graphId, procedure, args, Utils.dummyMap); + return callProcedure(graphId, procedure, args, Utils.DUMMY_MAP); } From c979990950976dffc32ab8ddcd30ebb3f76d77c4 Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Tue, 23 Jul 2019 10:58:11 +0300 Subject: [PATCH 8/8] changed Jedis Version. Minor code fix in ContextedRedisGraph --- pom.xml | 2 +- .../redislabs/redisgraph/impl/api/ContextedRedisGraph.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 2f205cd..2b2c133 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ redis.clients jedis - 3.1.0-rc + 3.1.0 org.apache.commons diff --git a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java index a1fa081..b2fe9f6 100644 --- a/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java +++ b/src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java @@ -46,15 +46,14 @@ protected Jedis getConnection() { @Override protected ResultSet sendQuery(String graphId, String preparedQuery) { Jedis conn = getConnection(); - List rawResponse; try { - rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, Utils.COMPACT_STRING); + List rawResponse = (List) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, Utils.COMPACT_STRING); + return new ResultSetImpl(rawResponse, this, caches.getGraphCache(graphId)); } catch (Exception e) { conn.close(); throw e; } - return new ResultSetImpl(rawResponse, this, caches.getGraphCache(graphId)); } /**