redgraph 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +8 -0
- data/CHANGELOG.md +26 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +22 -1
- data/README.md +70 -8
- data/lib/redgraph.rb +11 -0
- data/lib/redgraph/edge.rb +17 -4
- data/lib/redgraph/graph.rb +44 -79
- data/lib/redgraph/graph/edge_methods.rb +105 -0
- data/lib/redgraph/graph/node_methods.rb +104 -0
- data/lib/redgraph/node.rb +11 -3
- data/lib/redgraph/node_model.rb +123 -0
- data/lib/redgraph/node_model/class_methods.rb +76 -0
- data/lib/redgraph/query_response.rb +82 -5
- data/lib/redgraph/util.rb +21 -0
- data/lib/redgraph/version.rb +1 -1
- data/redgraph.gemspec +2 -1
- data/test/graph_edge_methods_test.rb +100 -0
- data/test/graph_manipulation_test.rb +59 -0
- data/test/graph_node_methods_test.rb +112 -0
- data/test/graph_queries_test.rb +22 -35
- data/test/graph_test.rb +26 -0
- data/test/node_model_class_methods_test.rb +66 -0
- data/test/node_model_labels_test.rb +57 -0
- data/test/node_model_test.rb +126 -0
- data/test/test_helper.rb +21 -0
- metadata +27 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5a64b5cffa36368ac0664e813ab61f0329a055237b7e4acd473820d9c73409d
|
4
|
+
data.tar.gz: 371cde906c0a80370e39763a9b3ba9f3fcb83cdd2c19e97f635bfea6e35c5540
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac0481573ed2d41bb20de03ab1dc36d6781f5a121a865358e296654dc09abe168868104df92deeb623594b6d68363a0c9333268a059c7b8caf362504039e1431
|
7
|
+
data.tar.gz: dcb4c293c0a1003926d8776930123c81a5d35981a0896d447a03cc8ee1082f837ce1d73a1f7ca664478980fb485eefb39dad120f703b4584d40ffd6a3ff509c2
|
data/.github/workflows/main.yml
CHANGED
@@ -5,6 +5,12 @@ on: [push,pull_request]
|
|
5
5
|
jobs:
|
6
6
|
build:
|
7
7
|
runs-on: ubuntu-latest
|
8
|
+
|
9
|
+
services:
|
10
|
+
redis:
|
11
|
+
image: redislabs/redisgraph
|
12
|
+
ports: ["6379:6379"]
|
13
|
+
|
8
14
|
steps:
|
9
15
|
- uses: actions/checkout@v2
|
10
16
|
- name: Set up Ruby
|
@@ -12,6 +18,8 @@ jobs:
|
|
12
18
|
with:
|
13
19
|
ruby-version: 3.0.0
|
14
20
|
- name: Run the default task
|
21
|
+
env:
|
22
|
+
TEST_REDIS_URL: redis://localhost:6379/0
|
15
23
|
run: |
|
16
24
|
gem install bundler -v 2.2.15
|
17
25
|
bundle install
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,29 @@
|
|
1
|
-
## [
|
1
|
+
## [0.2.0]
|
2
|
+
|
3
|
+
- revamp the NodeModel mixin, the Node to model mapping is now handled by the `_type` property
|
4
|
+
|
5
|
+
## [0.1.4]
|
6
|
+
|
7
|
+
- add NodeModel mixin for a basic ActiveRecord-like syntax
|
8
|
+
- add Graph#merge_node and Graph#merge_edge
|
9
|
+
- edge and node properties are now a HashWithIndifferentAccess
|
10
|
+
|
11
|
+
## [0.1.3] - 2021-04-13
|
12
|
+
|
13
|
+
- allow custom queries
|
14
|
+
- nodes and edges query now allow the `order` option
|
15
|
+
|
16
|
+
## [0.1.2] - 2021-04-12
|
17
|
+
|
18
|
+
- Add Graph#relationship_types
|
19
|
+
- Add Graph#count_nodes
|
20
|
+
- Add Graph#edges
|
21
|
+
|
22
|
+
## [0.1.1] - 2021-04-11
|
23
|
+
|
24
|
+
- Graph#nodes:
|
25
|
+
- filter by properties
|
26
|
+
- skip and limit options
|
2
27
|
|
3
28
|
## [0.1.0] - 2021-04-08
|
4
29
|
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
redgraph (0.
|
4
|
+
redgraph (0.2.0)
|
5
|
+
activesupport (>= 3.0.0)
|
5
6
|
redis (~> 4)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
11
|
+
activesupport (6.1.3.1)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (>= 1.6, < 2)
|
14
|
+
minitest (>= 5.1)
|
15
|
+
tzinfo (~> 2.0)
|
16
|
+
zeitwerk (~> 2.3)
|
10
17
|
coderay (1.1.3)
|
18
|
+
concurrent-ruby (1.1.8)
|
19
|
+
docile (1.3.5)
|
20
|
+
i18n (1.8.10)
|
21
|
+
concurrent-ruby (~> 1.0)
|
11
22
|
method_source (1.0.0)
|
12
23
|
minitest (5.14.4)
|
13
24
|
pry (0.14.0)
|
@@ -15,6 +26,15 @@ GEM
|
|
15
26
|
method_source (~> 1.0)
|
16
27
|
rake (13.0.3)
|
17
28
|
redis (4.2.5)
|
29
|
+
simplecov (0.21.2)
|
30
|
+
docile (~> 1.1)
|
31
|
+
simplecov-html (~> 0.11)
|
32
|
+
simplecov_json_formatter (~> 0.1)
|
33
|
+
simplecov-html (0.12.3)
|
34
|
+
simplecov_json_formatter (0.1.2)
|
35
|
+
tzinfo (2.0.4)
|
36
|
+
concurrent-ruby (~> 1.0)
|
37
|
+
zeitwerk (2.4.2)
|
18
38
|
|
19
39
|
PLATFORMS
|
20
40
|
x86_64-darwin-20
|
@@ -24,6 +44,7 @@ DEPENDENCIES
|
|
24
44
|
pry (~> 0.14.0)
|
25
45
|
rake (~> 13.0)
|
26
46
|
redgraph!
|
47
|
+
simplecov (~> 0.21.2)
|
27
48
|
|
28
49
|
BUNDLED WITH
|
29
50
|
2.2.15
|
data/README.md
CHANGED
@@ -20,33 +20,97 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
+
The gem assumes you have a recent version of [RedisGraph](https://oss.redislabs.com/redisgraph/) up and running.
|
24
|
+
|
23
25
|
Basic usage:
|
24
26
|
|
25
27
|
graph = Redgraph::Graph.new('movies', url: "redis://localhost:6379/1")
|
28
|
+
=> #<Redgraph::Graph:0x00007f8d5c2b7e38 @connection=#<Redis client v4.2.5 for redis://localhost:6379/1>, @graph_name="movies", @module_version=999999>
|
26
29
|
|
27
30
|
Create a couple nodes:
|
28
31
|
|
29
|
-
actor = Redgraph::Node.new(label: 'actor',
|
32
|
+
actor = Redgraph::Node.new(label: 'actor', properties: {name: "Al Pacino"})
|
33
|
+
=> #<Redgraph::Node:0x00007f8d5f95cf88 @label="actor", @properties={:name=>"Al Pacino"}>
|
30
34
|
graph.add_node(actor)
|
31
|
-
|
35
|
+
=> #<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>
|
36
|
+
film = Redgraph::Node.new(label: 'film', properties: {name: "Scarface"})
|
37
|
+
=> #<Redgraph::Node:0x00007f8d5f85ccc8 @label="film", @properties={:name=>"Scarface"}>
|
32
38
|
graph.add_node(film)
|
39
|
+
=> #<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>
|
33
40
|
|
34
41
|
Create an edge between those nodes:
|
35
42
|
|
36
43
|
edge = Redgraph::Edge.new(src: actor, dest: film, type: 'ACTOR_IN', properties: {role: "Tony Montana"})
|
37
|
-
|
44
|
+
=> #<Redgraph::Edge:0x00007f8d5f9ae3d8 @dest=#<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>, @dest_id=1, @properties={:role=>"Tony Montana"}, @src=#<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>, @src_id=0, @type="ACTOR_IN">
|
45
|
+
@graph.add_edge(edge)
|
46
|
+
=> #<Redgraph::Edge:0x00007f8d5f9ae3d8 @dest=#<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>, @dest_id=1, @id=0, @properties={:role=>"Tony Montana"}, @src=#<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>, @src_id=0, @type="ACTOR_IN">
|
47
|
+
|
48
|
+
You can merge nodes - the node will be created only if there isn't another with the same label and properties:
|
49
|
+
|
50
|
+
graph.merge_node(film)
|
51
|
+
=> #<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>
|
52
|
+
|
53
|
+
Same with edges:
|
54
|
+
|
55
|
+
@graph.merge_edge(edge)
|
56
|
+
=> #<Redgraph::Edge:0x00007f8d5f9ae3d8 @dest=#<Redgraph::Node:0x00007f8d5f85ccc8 @id=1, @label="film", @properties={:name=>"Scarface"}>, @dest_id=1, @id=0, @properties={:role=>"Tony Montana"}, @src=#<Redgraph::Node:0x00007f8d5f95cf88 @id=0, @label="actor", @properties={:name=>"Al Pacino"}>, @src_id=0, @type="ACTOR_IN">
|
38
57
|
|
39
58
|
Find a node by id:
|
40
59
|
|
41
|
-
@graph.find_node_by_id(
|
60
|
+
@graph.find_node_by_id(1)
|
61
|
+
=> #<Redgraph::Node:0x00007f8d5c2c6e88 @id=1, @label="film", @properties={"name"=>"Scarface"}>
|
42
62
|
|
43
63
|
To get all nodes:
|
44
64
|
|
45
65
|
@graph.nodes
|
66
|
+
=> [#<Redgraph::Node:0x00007f8d5c2ee0a0 @id=0, @label="actor", @properties={"name"=>"Al Pacino"}>, #<Redgraph::Node:0x00007f8d5c2edfd8 @id=1, @label="film", @properties={"name"=>"Scarface"}>]
|
46
67
|
|
47
|
-
Optional filters:
|
68
|
+
Optional filters that can be combined:
|
48
69
|
|
49
70
|
@graph.nodes(label: 'actor')
|
71
|
+
@graph.nodes(properties: {name: "Al Pacino"})
|
72
|
+
@graph.nodes(limit: 10, skip: 20)
|
73
|
+
|
74
|
+
Counting nodes
|
75
|
+
|
76
|
+
@graph.count_nodes(label: 'actor')
|
77
|
+
=> 1
|
78
|
+
|
79
|
+
Getting edges:
|
80
|
+
|
81
|
+
@graph.edges
|
82
|
+
@graph.edges(src: actor, dest: film)
|
83
|
+
@graph.edges(kind: 'FRIEND_OF', limit: 10, skip: 20)
|
84
|
+
@graph.count_edges
|
85
|
+
|
86
|
+
Running custom queries
|
87
|
+
|
88
|
+
@graph.query("MATCH (src)-[edge:FRIEND_OF]->(dest) RETURN src, edge")
|
89
|
+
|
90
|
+
### NodeModel
|
91
|
+
|
92
|
+
You can use the `NodeModel` mixin for a limited ActiveRecord-like interface:
|
93
|
+
|
94
|
+
class Actor
|
95
|
+
include Redgraph::NodeModel
|
96
|
+
self.graph = Redgraph::Graph.new("movies", url: $REDIS_URL)
|
97
|
+
attribute :name
|
98
|
+
end
|
99
|
+
|
100
|
+
And this will give you stuff such as
|
101
|
+
|
102
|
+
Actor.count
|
103
|
+
john = Actor.new(name: "John Travolta")
|
104
|
+
john.add_to_graph # Will add the node to the graph
|
105
|
+
john.add_relation(type: "ACTED_IN", node: film, properties: {role: "Tony Manero"})
|
106
|
+
|
107
|
+
`NodeModel` models will automatically set a `_type` property to keep track of the object class.
|
108
|
+
|
109
|
+
You will then be able to run custom queries such as:
|
110
|
+
|
111
|
+
Actor.query("MATCH (node) RETURN node ORDER BY node.name")
|
112
|
+
|
113
|
+
And the result rows object will be instances of the classes defined by the `_type` attribute.
|
50
114
|
|
51
115
|
## Development
|
52
116
|
|
@@ -54,7 +118,7 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
54
118
|
|
55
119
|
TEST_REDIS_URL=YOUR-REDIS-URL rake test
|
56
120
|
|
57
|
-
to run the tests.
|
121
|
+
to run the tests. Test coverage will be enabled if you set the `COVERAGE` environment variable to any value.
|
58
122
|
|
59
123
|
You can use a `TEST_REDIS_URL` such as `redis://localhost:6379/1`. Make sure you're not overwriting important databases.
|
60
124
|
|
@@ -62,8 +126,6 @@ You can also run `bin/console` for an interactive prompt that will allow you to
|
|
62
126
|
|
63
127
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
64
128
|
|
65
|
-
Run `bin/console` for an interactive prompt.
|
66
|
-
|
67
129
|
## Contributing
|
68
130
|
|
69
131
|
Bug reports and pull requests are welcome on GitHub at https://github.com/pzac/redgraph.
|
data/lib/redgraph.rb
CHANGED
@@ -1,13 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "redis"
|
3
|
+
require "active_support/core_ext/hash/indifferent_access"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
6
|
+
require "active_support/concern"
|
3
7
|
|
4
8
|
require_relative "redgraph/version"
|
9
|
+
require_relative "redgraph/util"
|
5
10
|
require_relative "redgraph/graph"
|
6
11
|
require_relative "redgraph/node"
|
7
12
|
require_relative "redgraph/edge"
|
8
13
|
require_relative "redgraph/query_response"
|
14
|
+
require_relative "redgraph/node_model"
|
9
15
|
|
10
16
|
module Redgraph
|
11
17
|
class Error < StandardError; end
|
12
18
|
class ServerError < Error; end
|
19
|
+
class MissingAliasPrefixError < Error
|
20
|
+
def message
|
21
|
+
"The order clause requires the node/edge alias prefix, ie order('node.foo') instead order('foo')"
|
22
|
+
end
|
23
|
+
end
|
13
24
|
end
|
data/lib/redgraph/edge.rb
CHANGED
@@ -2,17 +2,30 @@
|
|
2
2
|
|
3
3
|
module Redgraph
|
4
4
|
class Edge
|
5
|
-
|
5
|
+
include Util
|
6
6
|
|
7
|
-
|
7
|
+
attr_accessor :id, :src, :dest, :src_id, :dest_id, :type, :properties
|
8
|
+
|
9
|
+
def initialize(src: nil, dest: nil, type: nil, properties: {})
|
8
10
|
@src = src
|
11
|
+
@src_id = @src.id if @src
|
9
12
|
@dest = dest
|
13
|
+
@dest_id = @dest.id if @dest
|
10
14
|
@type = type
|
11
|
-
@properties = properties
|
15
|
+
@properties = (properties || {}).with_indifferent_access
|
12
16
|
end
|
13
17
|
|
14
18
|
def persisted?
|
15
|
-
|
19
|
+
id.present?
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
super || other.instance_of?(self.class) && !id.nil? && other.id == id
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_query_string(item_alias: 'edge', src_alias: 'src', dest_alias: 'dest')
|
27
|
+
_type = ":#{type}" if type
|
28
|
+
"(#{src_alias})-[#{item_alias}#{_type} #{properties_to_string(properties)}]->(#{dest_alias})"
|
16
29
|
end
|
17
30
|
end
|
18
31
|
end
|
data/lib/redgraph/graph.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "graph/node_methods"
|
4
|
+
require_relative "graph/edge_methods"
|
5
|
+
|
3
6
|
module Redgraph
|
4
7
|
class Graph
|
8
|
+
include NodeMethods
|
9
|
+
include EdgeMethods
|
10
|
+
|
5
11
|
attr_accessor :connection, :graph_name
|
6
12
|
|
7
|
-
|
8
|
-
|
13
|
+
# @example Graph.new("foobar", url: "redis://localhost:6379/0", logger: Logger.new(STDOUT))
|
14
|
+
# @param graph_name [String] Name of the graph
|
15
|
+
# @param redis_options [Hash] Redis client options
|
16
|
+
#
|
17
|
+
def initialize(graph_name, redis_options = {})
|
18
|
+
@graph_name = graph_name
|
9
19
|
@connection = Redis.new(redis_options)
|
10
20
|
@module_version = module_version
|
11
21
|
raise ServerError unless @module_version
|
@@ -29,112 +39,67 @@ module Redgraph
|
|
29
39
|
raise e
|
30
40
|
end
|
31
41
|
|
32
|
-
#
|
42
|
+
# @return [Array] Existing graph names
|
33
43
|
#
|
34
44
|
def list
|
35
45
|
@connection.call("GRAPH.LIST")
|
36
46
|
end
|
37
47
|
|
38
|
-
#
|
48
|
+
# @return [Array] Existing labels
|
39
49
|
#
|
40
50
|
def labels
|
41
|
-
result =
|
51
|
+
result = _query("CALL db.labels()")
|
42
52
|
result.resultset.map(&:values).flatten
|
43
53
|
end
|
44
54
|
|
45
|
-
#
|
55
|
+
# @return [Array] Existing properties
|
46
56
|
#
|
47
57
|
def properties
|
48
|
-
result =
|
58
|
+
result = _query("CALL db.propertyKeys()")
|
49
59
|
result.resultset.map(&:values).flatten
|
50
60
|
end
|
51
61
|
|
52
|
-
#
|
53
|
-
#
|
54
|
-
def add_node(node)
|
55
|
-
result = query("CREATE (n:`#{node.label}` #{quote_hash(node.properties)}) RETURN ID(n)")
|
56
|
-
return false if result.stats[:nodes_created] != 1
|
57
|
-
id = result.resultset.first["ID(n)"]
|
58
|
-
node.id = id
|
59
|
-
node
|
60
|
-
end
|
61
|
-
|
62
|
-
def find_node_by_id(id)
|
63
|
-
result = query("MATCH (node) WHERE ID(node) = #{id} RETURN node")
|
64
|
-
return nil if result.resultset.empty?
|
65
|
-
(node_id, labels, properties) = result.resultset.first["node"]
|
66
|
-
attrs = {}
|
67
|
-
|
68
|
-
properties.each do |(index, type, value)|
|
69
|
-
attrs[get_property(index)] = value
|
70
|
-
end
|
71
|
-
Node.new(label: get_label(labels.first), properties: attrs).tap do |node|
|
72
|
-
node.id = node_id
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def nodes(label: nil)
|
77
|
-
node_or_node_with_label = label ? "node:`#{label}`" : "node"
|
78
|
-
|
79
|
-
cmd = "MATCH (#{node_or_node_with_label}) RETURN node"
|
80
|
-
result = query(cmd)
|
81
|
-
|
82
|
-
result.resultset.map do |item|
|
83
|
-
(node_id, labels, properties) = item["node"]
|
84
|
-
attrs = {}
|
85
|
-
|
86
|
-
properties.each do |(index, type, value)|
|
87
|
-
attrs[get_property(index)] = value
|
88
|
-
end
|
89
|
-
Node.new(label: get_label(labels.first), properties: attrs).tap do |node|
|
90
|
-
node.id = node_id
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# Adds an edge. If successul it returns the created object, otherwise false
|
62
|
+
# @return [Array] Existing relationship types
|
96
63
|
#
|
97
|
-
def
|
98
|
-
result =
|
99
|
-
|
100
|
-
CREATE (src)-[e:`#{edge.type}` #{quote_hash(edge.properties)}]->(dest) RETURN ID(e)")
|
101
|
-
return false if result.stats[:relationships_created] != 1
|
102
|
-
id = result.resultset.first["ID(e)"]
|
103
|
-
edge.id = id
|
104
|
-
edge
|
64
|
+
def relationship_types
|
65
|
+
result = _query("CALL db.relationshipTypes()")
|
66
|
+
result.resultset.map(&:values).flatten
|
105
67
|
end
|
106
68
|
|
107
|
-
|
108
|
-
|
69
|
+
# You can run custom cypher queries
|
109
70
|
def query(cmd)
|
110
|
-
|
111
|
-
QueryResponse.new(data)
|
112
|
-
end
|
113
|
-
|
114
|
-
def quote_hash(hash)
|
115
|
-
out = "{"
|
116
|
-
hash.each do |k,v|
|
117
|
-
out += "#{k}:#{escape_value(v)}"
|
118
|
-
end
|
119
|
-
out + "}"
|
120
|
-
end
|
121
|
-
|
122
|
-
def escape_value(x)
|
123
|
-
case x
|
124
|
-
when Integer then x
|
125
|
-
else
|
126
|
-
"'#{x}'"
|
127
|
-
end
|
71
|
+
_query(cmd).rows
|
128
72
|
end
|
129
73
|
|
74
|
+
# @param id [Integer] label id
|
75
|
+
# @return [String, nil] label
|
76
|
+
#
|
130
77
|
def get_label(id)
|
131
78
|
@labels ||= labels
|
132
79
|
@labels[id] || (@labels = labels)[id]
|
133
80
|
end
|
134
81
|
|
82
|
+
# @param id [Integer] property id
|
83
|
+
# @return [String, nil] property
|
84
|
+
#
|
135
85
|
def get_property(id)
|
136
86
|
@properties ||= properties
|
137
87
|
@properties[id] || (@properties = properties)[id]
|
138
88
|
end
|
89
|
+
|
90
|
+
# @param id [Integer] relationship type id
|
91
|
+
# @return [String, nil] relationship type
|
92
|
+
#
|
93
|
+
def get_relationship_type(id)
|
94
|
+
@relationship_types ||= relationship_types
|
95
|
+
@relationship_types[id] || (@relationship_types = relationship_types)[id]
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def _query(cmd)
|
101
|
+
data = @connection.call("GRAPH.QUERY", graph_name, cmd, "--compact")
|
102
|
+
QueryResponse.new(data, self)
|
103
|
+
end
|
139
104
|
end
|
140
105
|
end
|