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
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Redgraph
|
4
|
+
module Util
|
5
|
+
def properties_to_string(hash)
|
6
|
+
return if hash.empty?
|
7
|
+
"{" +
|
8
|
+
hash.map {|k,v| "#{k}:#{escape_value(v)}" }.join(", ") +
|
9
|
+
"}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def escape_value(x)
|
13
|
+
case x
|
14
|
+
when Integer then x
|
15
|
+
when NilClass then "''"
|
16
|
+
else
|
17
|
+
'"' + x.gsub('"', '\"') + '"'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/redgraph/version.rb
CHANGED
data/redgraph.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
|
16
16
|
spec.metadata["homepage_uri"] = spec.homepage
|
17
17
|
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
-
spec.metadata["changelog_uri"] = "#{spec.homepage}/CHANGELOG.md"
|
18
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
|
19
19
|
|
20
20
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
21
21
|
`git ls-files -z`.split("\x0")
|
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
25
|
spec.add_dependency "redis", "~> 4"
|
26
|
+
spec.add_dependency "activesupport", ">= 3.0.0"
|
26
27
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class GraphEdgeMethodsTest < Minitest::Test
|
6
|
+
include TestHelpers
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@graph = Redgraph::Graph.new("movies", url: $REDIS_URL)
|
10
|
+
|
11
|
+
@al = quick_add_node(label: 'actor', properties: {name: "Al Pacino"})
|
12
|
+
@john = quick_add_node(label: 'actor', properties: {name: "John Travolta"})
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
@graph.delete
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_find_edge
|
20
|
+
quick_add_edge(type: 'FRIEND_OF', src: @al, dest: @john, properties: {since: 1980})
|
21
|
+
edge = @graph.edges.first
|
22
|
+
|
23
|
+
assert_equal('FRIEND_OF', edge.type)
|
24
|
+
assert_equal(1980, edge.properties["since"])
|
25
|
+
assert_equal(@al, edge.src)
|
26
|
+
assert_equal(@john, edge.dest)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_find_all_edges
|
30
|
+
marlon = quick_add_node(label: 'actor', properties: {name: "Marlon Brando"})
|
31
|
+
film = quick_add_node(label: 'film', properties: {name: "The Godfather"})
|
32
|
+
quick_add_edge(type: 'ACTOR_IN', src: marlon, dest: film, properties: {role: 'Don Vito'})
|
33
|
+
quick_add_edge(type: 'ACTOR_IN', src: @al, dest: film, properties: {role: 'Michael'})
|
34
|
+
|
35
|
+
edges = @graph.edges
|
36
|
+
assert_equal(2, edges.size)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_count_edges
|
40
|
+
marlon = quick_add_node(label: 'actor', properties: {name: "Marlon Brando"})
|
41
|
+
film = quick_add_node(label: 'film', properties: {name: "The Godfather"})
|
42
|
+
quick_add_edge(type: 'ACTOR_IN', src: marlon, dest: film, properties: {role: 'Don Vito'})
|
43
|
+
quick_add_edge(type: 'ACTOR_IN', src: @al, dest: film, properties: {role: 'Michael'})
|
44
|
+
|
45
|
+
assert_equal(2, @graph.count_edges)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_filter_edges
|
49
|
+
marlon = quick_add_node(label: 'actor', properties: {name: "Marlon Brando"})
|
50
|
+
film = quick_add_node(label: 'film', properties: {name: "The Godfather"})
|
51
|
+
other_film = quick_add_node(label: 'film', properties: {name: "Carlito's Way"})
|
52
|
+
e_donvito = quick_add_edge(type: 'ACTOR_IN', src: marlon, dest: film, properties: {role: 'Don Vito'})
|
53
|
+
e_michael = quick_add_edge(type: 'ACTOR_IN', src: @al, dest: film, properties: {role: 'Michael'})
|
54
|
+
e_carlito = quick_add_edge(type: 'ACTOR_IN', src: @al, dest: other_film, properties: {role: 'Carlito'})
|
55
|
+
quick_add_edge(type: 'FRIEND_OF', src: @al, dest: marlon, properties: {since: 1980})
|
56
|
+
|
57
|
+
edges = @graph.edges(type: "FRIEND_OF")
|
58
|
+
assert_equal(1, edges.size)
|
59
|
+
|
60
|
+
edges = @graph.edges(type: "ACTOR_IN")
|
61
|
+
assert_equal(3, edges.size)
|
62
|
+
|
63
|
+
edges = @graph.edges(type: "ACTOR_IN", limit: 2)
|
64
|
+
assert_equal(2, edges.size)
|
65
|
+
|
66
|
+
edges = @graph.edges(type: "ACTOR_IN", skip: 2, limit: 10)
|
67
|
+
assert_equal(1, edges.size)
|
68
|
+
|
69
|
+
edges = @graph.edges(properties: {role: "Carlito"})
|
70
|
+
assert_equal([e_carlito], edges)
|
71
|
+
|
72
|
+
edges = @graph.edges(src: marlon)
|
73
|
+
assert_equal([e_donvito], edges)
|
74
|
+
|
75
|
+
edges = @graph.edges(type: 'ACTOR_IN', dest: film)
|
76
|
+
assert_equal(2, edges.size)
|
77
|
+
assert_includes(edges, e_donvito)
|
78
|
+
assert_includes(edges, e_michael)
|
79
|
+
|
80
|
+
edges = @graph.edges(src: @al, dest: marlon)
|
81
|
+
assert_equal(1, edges.size)
|
82
|
+
edge = edges[0]
|
83
|
+
assert_equal('FRIEND_OF', edge.type)
|
84
|
+
assert_equal(1980, edge.properties["since"])
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_order_edges
|
88
|
+
marlon = quick_add_node(label: 'actor', properties: {name: "Marlon Brando"})
|
89
|
+
|
90
|
+
e1 = quick_add_edge(type: 'FRIEND_OF', src: @al, dest: marlon, properties: {since: 1980})
|
91
|
+
e2 = quick_add_edge(type: 'FRIEND_OF', src: @al, dest: @john, properties: {since: 2000})
|
92
|
+
e3 = quick_add_edge(type: 'FRIEND_OF', src: marlon, dest: @john, properties: {since: 1990})
|
93
|
+
|
94
|
+
edges = @graph.edges(type: 'FRIEND_OF', order: "edge.since ASC")
|
95
|
+
assert_equal([e1, e3, e2], edges)
|
96
|
+
|
97
|
+
edges = @graph.edges(type: 'FRIEND_OF', order: "edge.since DESC")
|
98
|
+
assert_equal([e2, e3, e1], edges)
|
99
|
+
end
|
100
|
+
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
require "test_helper"
|
4
4
|
|
5
5
|
class GraphManipulationTest < Minitest::Test
|
6
|
+
include TestHelpers
|
7
|
+
|
6
8
|
def setup
|
7
9
|
@graph = Redgraph::Graph.new("movies", url: $REDIS_URL)
|
8
10
|
end
|
@@ -17,6 +19,35 @@ class GraphManipulationTest < Minitest::Test
|
|
17
19
|
assert_predicate result, :persisted?
|
18
20
|
end
|
19
21
|
|
22
|
+
def test_add_node_with_special_chars
|
23
|
+
[
|
24
|
+
"apo'str",
|
25
|
+
"two''apos",
|
26
|
+
"Foø'bÆ®",
|
27
|
+
"aa\nbb",
|
28
|
+
'aaa "bbb" ccc'
|
29
|
+
].each do |name|
|
30
|
+
|
31
|
+
node = Redgraph::Node.new(label: 'actor', properties: {name: name})
|
32
|
+
result = @graph.add_node(node)
|
33
|
+
assert_predicate result, :persisted?
|
34
|
+
|
35
|
+
item = @graph.find_node_by_id(node.id)
|
36
|
+
|
37
|
+
assert_equal(name, item.properties["name"])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_add_node_with_nil_value
|
42
|
+
node = Redgraph::Node.new(label: 'actor', properties: {name: nil})
|
43
|
+
result = @graph.add_node(node)
|
44
|
+
assert_predicate result, :persisted?
|
45
|
+
|
46
|
+
item = @graph.find_node_by_id(node.id)
|
47
|
+
|
48
|
+
assert_equal("", item.properties["name"])
|
49
|
+
end
|
50
|
+
|
20
51
|
def test_add_edge
|
21
52
|
actor = Redgraph::Node.new(label: 'actor', properties: {name: "Al Pacino"})
|
22
53
|
@graph.add_node(actor)
|
@@ -29,4 +60,32 @@ class GraphManipulationTest < Minitest::Test
|
|
29
60
|
|
30
61
|
assert_predicate result, :persisted?
|
31
62
|
end
|
63
|
+
|
64
|
+
def test_merge_node
|
65
|
+
quick_add_node(label: 'actor', properties: {name: "Al Pacino"})
|
66
|
+
quick_add_node(label: 'actor', properties: {name: "John Travolta"})
|
67
|
+
|
68
|
+
nodes = @graph.nodes(label: 'actor')
|
69
|
+
assert_equal(2, nodes.size)
|
70
|
+
|
71
|
+
@graph.merge_node(Redgraph::Node.new(label: 'actor', properties: {name: "Joe Pesci"}))
|
72
|
+
assert_equal(3, @graph.nodes(label: 'actor').size)
|
73
|
+
|
74
|
+
@graph.merge_node(Redgraph::Node.new(label: 'actor', properties: {name: "Al Pacino"}))
|
75
|
+
assert_equal(3, @graph.nodes(label: 'actor').size)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_merge_edge
|
79
|
+
al = quick_add_node(label: 'actor', properties: {name: "Al Pacino"})
|
80
|
+
john = quick_add_node(label: 'actor', properties: {name: "John Travolta"})
|
81
|
+
|
82
|
+
assert_equal(0, @graph.edges.size)
|
83
|
+
|
84
|
+
edge = Redgraph::Edge.new(type: 'FRIEND_OF', src: al, dest: john, properties: {since: 1990})
|
85
|
+
@graph.merge_edge(edge)
|
86
|
+
assert_equal(1, @graph.edges.size)
|
87
|
+
|
88
|
+
@graph.merge_edge(edge)
|
89
|
+
assert_equal(1, @graph.edges.size)
|
90
|
+
end
|
32
91
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class GraphNodeMethodsTest < Minitest::Test
|
6
|
+
include TestHelpers
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@graph = Redgraph::Graph.new("movies", url: $REDIS_URL)
|
10
|
+
|
11
|
+
@al = quick_add_node(label: 'actor', properties: {name: "Al Pacino"})
|
12
|
+
@john = quick_add_node(label: 'actor', properties: {name: "John Travolta"})
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
@graph.delete
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_find_node_by_id
|
20
|
+
node = @graph.find_node_by_id(@al.id)
|
21
|
+
|
22
|
+
refute_nil(node)
|
23
|
+
assert_equal("actor", node.label)
|
24
|
+
assert_equal("Al Pacino", node.properties["name"])
|
25
|
+
assert_equal(@al.id, node.id)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_find_node_by_wrong_id
|
29
|
+
node = @graph.find_node_by_id("-1")
|
30
|
+
|
31
|
+
assert_nil(node)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_find_all_nodes
|
35
|
+
actors = @graph.nodes
|
36
|
+
|
37
|
+
assert_equal(2, actors.size)
|
38
|
+
assert_includes(actors, @al)
|
39
|
+
assert_includes(actors, @john)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_find_all_nodes_by_label
|
43
|
+
film = quick_add_node(label: 'film', properties: {name: "Scarface"})
|
44
|
+
|
45
|
+
actors = @graph.nodes(label: 'actor')
|
46
|
+
assert_equal(2, actors.size)
|
47
|
+
assert_includes(actors, @al)
|
48
|
+
assert_includes(actors, @john)
|
49
|
+
|
50
|
+
films = @graph.nodes(label: 'film')
|
51
|
+
assert_equal(1, films.size)
|
52
|
+
assert_includes(films, film)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_find_all_nodes_by_property
|
56
|
+
scarface = quick_add_node(label: 'film', properties: {name: "Scarface", genre: "drama"})
|
57
|
+
casino = quick_add_node(label: 'film', properties: {name: "Casino", genre: "drama"})
|
58
|
+
_mamma_mia = quick_add_node(label: 'film', properties: {name: "Mamma Mia", genre: "musical"})
|
59
|
+
|
60
|
+
dramas = @graph.nodes(properties: {genre: "drama"})
|
61
|
+
|
62
|
+
assert_equal(2, dramas.size)
|
63
|
+
assert_includes(dramas, scarface)
|
64
|
+
assert_includes(dramas, casino)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_order_nodes_by_property
|
68
|
+
scarface = quick_add_node(label: 'film', properties: {name: "Scarface", genre: "drama"})
|
69
|
+
casino = quick_add_node(label: 'film', properties: {name: "Casino", genre: "drama"})
|
70
|
+
mamma_mia = quick_add_node(label: 'film', properties: {name: "Mamma Mia", genre: "musical"})
|
71
|
+
|
72
|
+
items = @graph.nodes(label: 'film', order: "node.name")
|
73
|
+
assert_equal([casino, mamma_mia, scarface], items)
|
74
|
+
|
75
|
+
items = @graph.nodes(label: 'film', order: "node.name ASC")
|
76
|
+
assert_equal([casino, mamma_mia, scarface], items)
|
77
|
+
|
78
|
+
items = @graph.nodes(label: 'film', order: "node.name DESC")
|
79
|
+
assert_equal([scarface, mamma_mia, casino], items)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_count_nodes
|
83
|
+
quick_add_node(label: 'film', properties: {name: "Scarface", genre: "drama"})
|
84
|
+
quick_add_node(label: 'film', properties: {name: "Casino", genre: "drama"})
|
85
|
+
quick_add_node(label: 'film', properties: {name: "Mamma Mia", genre: "musical"})
|
86
|
+
|
87
|
+
|
88
|
+
assert_equal(5, @graph.count_nodes)
|
89
|
+
assert_equal(3, @graph.count_nodes(label: 'film'))
|
90
|
+
assert_equal(2, @graph.count_nodes(properties: {genre: "drama"}))
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_limit_nodes
|
94
|
+
10.times do |i|
|
95
|
+
quick_add_node(label: 'token', properties: {number: i})
|
96
|
+
end
|
97
|
+
|
98
|
+
items = @graph.nodes(label: 'token', limit: 5)
|
99
|
+
assert_equal(5, items.size)
|
100
|
+
assert_equal([0,1,2,3,4], items.map{|item| item.properties["number"]})
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_skip_nodes
|
104
|
+
10.times do |i|
|
105
|
+
quick_add_node(label: 'token', properties: {number: i})
|
106
|
+
end
|
107
|
+
|
108
|
+
items = @graph.nodes(label: 'token', limit: 3, skip: 3)
|
109
|
+
assert_equal(3, items.size)
|
110
|
+
assert_equal([3,4,5], items.map{|item| item.properties["number"]})
|
111
|
+
end
|
112
|
+
end
|
data/test/graph_queries_test.rb
CHANGED
@@ -3,56 +3,43 @@
|
|
3
3
|
require "test_helper"
|
4
4
|
|
5
5
|
class GraphQueriesTest < Minitest::Test
|
6
|
+
include TestHelpers
|
7
|
+
|
6
8
|
def setup
|
7
9
|
@graph = Redgraph::Graph.new("movies", url: $REDIS_URL)
|
8
|
-
@actor = Redgraph::Node.new(label: 'actor', properties: {name: "Al Pacino"})
|
9
|
-
@graph.add_node(@actor)
|
10
10
|
|
11
|
-
@
|
12
|
-
|
11
|
+
@al = quick_add_node(label: 'actor', properties: {name: "Al Pacino", born: 1940})
|
12
|
+
@john = quick_add_node(label: 'actor', properties: {name: "John Travolta", born: 1954})
|
13
13
|
end
|
14
14
|
|
15
15
|
def teardown
|
16
16
|
@graph.delete
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
refute_nil(node)
|
23
|
-
assert_equal("actor", node.label)
|
24
|
-
assert_equal("Al Pacino", node.properties["name"])
|
25
|
-
assert_equal(@actor.id, node.id)
|
19
|
+
def test_query_string_attribute
|
20
|
+
result = @graph.query("MATCH (n) RETURN n.name ORDER BY n.name")
|
21
|
+
assert_equal([["Al Pacino"], ["John Travolta"]], result)
|
26
22
|
end
|
27
23
|
|
28
|
-
def
|
29
|
-
@graph.
|
30
|
-
|
31
|
-
actors = @graph.nodes
|
32
|
-
|
33
|
-
assert_equal(2, actors.size)
|
34
|
-
assert_includes(actors, @actor)
|
35
|
-
assert_includes(actors, @other_actor)
|
24
|
+
def test_query_string_and_number_attributes
|
25
|
+
result = @graph.query("MATCH (n) RETURN n.name, n.born ORDER BY n.born")
|
26
|
+
assert_equal([["Al Pacino", 1940], ["John Travolta", 1954]], result)
|
36
27
|
end
|
37
28
|
|
38
|
-
def
|
39
|
-
@graph.
|
40
|
-
|
41
|
-
@graph.add_node(film)
|
42
|
-
|
43
|
-
actors = @graph.nodes(label: 'actor')
|
44
|
-
assert_equal(2, actors.size)
|
45
|
-
assert_includes(actors, @actor)
|
46
|
-
assert_includes(actors, @other_actor)
|
47
|
-
|
48
|
-
films = @graph.nodes(label: 'film')
|
49
|
-
assert_equal(1, films.size)
|
50
|
-
assert_includes(films, film)
|
29
|
+
def test_query_nodes
|
30
|
+
result = @graph.query("MATCH (n) RETURN n ORDER BY n.born")
|
31
|
+
assert_equal([[@al], [@john]], result)
|
51
32
|
end
|
52
33
|
|
53
|
-
def
|
54
|
-
|
34
|
+
def test_query_edge
|
35
|
+
edge = quick_add_edge(type: 'FRIEND_OF', src: @al, dest: @john, properties: {since: 1980})
|
36
|
+
result = @graph.query("MATCH (src)-[edge]->(dest) RETURN edge")
|
37
|
+
assert_equal([[edge]], result)
|
38
|
+
end
|
55
39
|
|
56
|
-
|
40
|
+
def test_query_node_and_edge
|
41
|
+
edge = quick_add_edge(type: 'FRIEND_OF', src: @al, dest: @john, properties: {since: 1980})
|
42
|
+
result = @graph.query("MATCH (src)-[edge:FRIEND_OF]->(dest) RETURN src, edge")
|
43
|
+
assert_equal([[@al, edge]], result)
|
57
44
|
end
|
58
45
|
end
|
data/test/graph_test.rb
CHANGED
@@ -12,11 +12,13 @@ class GraphTest < Minitest::Test
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_list
|
15
|
+
skip unless graph_list_supported?
|
15
16
|
list = @graph.list
|
16
17
|
assert_includes(list, "foobar")
|
17
18
|
end
|
18
19
|
|
19
20
|
def test_delete
|
21
|
+
skip unless graph_list_supported?
|
20
22
|
assert_includes(@graph.list, "foobar")
|
21
23
|
|
22
24
|
@graph.delete
|
@@ -42,6 +44,19 @@ class GraphTest < Minitest::Test
|
|
42
44
|
assert_equal(["name", "age"], @graph.properties)
|
43
45
|
end
|
44
46
|
|
47
|
+
def test_relationship_types
|
48
|
+
@graph = create_sample_graph("foobar")
|
49
|
+
|
50
|
+
actor = Redgraph::Node.new(label: "actor", properties: {"name": "Harrison Ford"})
|
51
|
+
@graph.add_node(actor)
|
52
|
+
film = Redgraph::Node.new(label: "film", properties: {"name": "Star Wars"})
|
53
|
+
@graph.add_node(film)
|
54
|
+
edge = Redgraph::Edge.new(type: "ACTED_IN", src: actor, dest: film)
|
55
|
+
@graph.add_edge(edge)
|
56
|
+
|
57
|
+
assert_equal(["ACTED_IN"], @graph.relationship_types)
|
58
|
+
end
|
59
|
+
|
45
60
|
private
|
46
61
|
|
47
62
|
def create_sample_graph(name)
|
@@ -53,4 +68,15 @@ class GraphTest < Minitest::Test
|
|
53
68
|
)
|
54
69
|
graph
|
55
70
|
end
|
71
|
+
|
72
|
+
# This command is only supported in the latest version
|
73
|
+
def graph_list_supported?
|
74
|
+
@graph.list
|
75
|
+
rescue Redis::CommandError => e
|
76
|
+
if e.message =~ /ERR unknown command `GRAPH.LIST`/
|
77
|
+
false
|
78
|
+
else
|
79
|
+
true
|
80
|
+
end
|
81
|
+
end
|
56
82
|
end
|