red_grape 0.0.6 → 0.0.7
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.
- data/README.md +23 -23
- data/lib/red_grape/edge.rb +4 -0
- data/lib/red_grape/element.rb +45 -1
- data/lib/red_grape/graph.rb +7 -10
- data/lib/red_grape/pipe/as_pipe.rb +2 -11
- data/lib/red_grape/pipe/base.rb +1 -1
- data/lib/red_grape/pipe/e_pipe.rb +20 -0
- data/lib/red_grape/pipe/v_pipe.rb +19 -0
- data/lib/red_grape/version.rb +1 -1
- data/lib/red_grape/vertex.rb +17 -0
- data/lib/red_grape.rb +2 -0
- data/test/test_element.rb +24 -0
- data/test/test_graph.rb +11 -11
- data/test/test_on_the_nature_of_pipes.rb +8 -8
- data/test/test_traversal_patterns.rb +11 -8
- data/test/test_vertex.rb +16 -0
- metadata +6 -4
data/README.md
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
|
5
5
|
## Description:
|
6
6
|
|
7
|
-
redGrape is an in-memory graph database written in ruby. I made this in order to learn how graph
|
7
|
+
redGrape is an in-memory graph database written in ruby. I made this application in order to learn how a graph database works so that please do not use this for any serious purpose.
|
8
8
|
|
9
9
|
## Features/Problems:
|
10
10
|
|
11
11
|
* REPL
|
12
12
|
* load GraphML
|
13
13
|
* construct a graph programmatically
|
14
|
-
* traverse nodes and edges
|
14
|
+
* traverse nodes and edges using a gremlin-like DSL
|
15
15
|
|
16
16
|
## Synopsis:
|
17
17
|
|
@@ -30,35 +30,35 @@ redGrape is an in-memory graph database written in ruby. I made this in order to
|
|
30
30
|
oOOOo
|
31
31
|
oOo
|
32
32
|
-------- O --------
|
33
|
-
|
33
|
+
irb(main):001:0> g = RedGrape.create_tinker_graph
|
34
34
|
=> redgrape[vertices:6 edges:6]
|
35
|
-
|
35
|
+
irb(main):002:0> g.class
|
36
36
|
=> RedGrape::Graph
|
37
|
-
|
37
|
+
irb(main):003:0> g.V
|
38
38
|
=> [v[1], v[2], v[3], v[4], v[5], v[6]]
|
39
|
-
|
39
|
+
irb(main):004:0> g.V.name
|
40
40
|
=> ["marko", "vadas", "lop", "josh", "ripple", "peter"]
|
41
|
-
|
41
|
+
irb(main):005:0> g.E
|
42
42
|
=> [e[7][1-knows->2], e[8][1-knows->4], e[9][1-created->3], e[10][4-created->5], e[11][4-created->3], e[12][6-created->3]]
|
43
|
-
|
43
|
+
irb(main):006:0> v = g.v(1)
|
44
44
|
=> v[1]
|
45
|
-
|
45
|
+
irb(main):007:0> "#{v.name} is #{v.age} years old."
|
46
46
|
=> "marko is 29 years old."
|
47
|
-
|
47
|
+
irb(main):008:0> v.out
|
48
48
|
=> [v[2], v[4], v[3]]
|
49
|
-
|
49
|
+
irb(main):009:0> v.out('knows')
|
50
50
|
=> [v[2], v[4]]
|
51
|
-
|
51
|
+
irb(main):010:0> v.outE
|
52
52
|
=> [e[7][1-knows->2], e[8][1-knows->4], e[9][1-created->3]]
|
53
|
-
|
53
|
+
irb(main):011:0> v.outE('knows')
|
54
54
|
=> [e[7][1-knows->2], e[8][1-knows->4]]
|
55
|
-
|
55
|
+
irb(main):012:0> v.outE.weight
|
56
56
|
=> [0.5, 1.0, 0.4]
|
57
|
-
|
57
|
+
irb(main):013:0> v.outE.has('weight', :lt, 1).inV
|
58
58
|
=> [v[2], v[3]]
|
59
|
-
|
59
|
+
irb(main):014:0> v.outE.filter{it.weight < 1}.inV
|
60
60
|
=> [v[2], v[3]]
|
61
|
-
|
61
|
+
irb(main):015:0> v.out('knows').filter{it.age:0> 30}.out('created').name
|
62
62
|
=> ["ripple", "lop"]
|
63
63
|
|
64
64
|
In REPL, the `take' method which invokes all pipes is automatically called.
|
@@ -83,18 +83,18 @@ In REPL, the `take' method which invokes all pipes is automatically called.
|
|
83
83
|
oOOOo
|
84
84
|
oOo
|
85
85
|
-------- O --------
|
86
|
-
|
86
|
+
irb(main):001:0> $store
|
87
87
|
=> #<RedGrape::GraphStore:0x007fb615137a90>
|
88
|
-
|
88
|
+
irb(main):002:0> $store.graphs
|
89
89
|
=> [:tinker]
|
90
|
-
|
90
|
+
irb(main):003:0> g = $store.graph :tinker
|
91
91
|
=> redgrape[vertices:6 edges:6]
|
92
|
-
|
92
|
+
irb(main):004:0> g.add_vertex 7
|
93
93
|
=> redgrape[vertices:7 edges:6]
|
94
|
-
|
94
|
+
irb(main):005:0> store.put_graph :tinker, g
|
95
95
|
=> redgrape[vertices:7 edges:6]
|
96
96
|
|
97
|
-
Changes on a graph are not committed until the put_graph method called.
|
97
|
+
Changes on a graph are not committed until the put_graph method is called.
|
98
98
|
|
99
99
|
## Requirements:
|
100
100
|
|
data/lib/red_grape/edge.rb
CHANGED
data/lib/red_grape/element.rb
CHANGED
@@ -26,6 +26,10 @@ module RedGrape
|
|
26
26
|
set_property k, v.default if v.has_default?
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
def property_keys
|
31
|
+
@property.keys
|
32
|
+
end
|
29
33
|
|
30
34
|
# set property value with type checking if its definition exists
|
31
35
|
def set_property(kid, v)
|
@@ -42,6 +46,18 @@ module RedGrape
|
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
49
|
+
def property(k=nil)
|
50
|
+
if k
|
51
|
+
self[k]
|
52
|
+
else
|
53
|
+
@property
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def remove_property(k)
|
58
|
+
@property.delete k.to_s
|
59
|
+
end
|
60
|
+
|
45
61
|
# set property value without type checking
|
46
62
|
def []=(k, v)
|
47
63
|
@property[k.to_s] = v
|
@@ -59,8 +75,36 @@ module RedGrape
|
|
59
75
|
self.class == obj.class && self.id == obj.id
|
60
76
|
end
|
61
77
|
|
78
|
+
def directed_value(direction, out_value, in_value, error=true)
|
79
|
+
case direction.to_s
|
80
|
+
when 'out'
|
81
|
+
if out_value.is_a? Proc
|
82
|
+
out_value.call
|
83
|
+
else
|
84
|
+
out_value
|
85
|
+
end
|
86
|
+
when 'in'
|
87
|
+
if in_value.is_a? Proc
|
88
|
+
in_value.call
|
89
|
+
else
|
90
|
+
in_value
|
91
|
+
end
|
92
|
+
else error
|
93
|
+
raise ArgumentError.new '"out" or "in"'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
62
97
|
def method_missing(name, *args, &block)
|
63
|
-
|
98
|
+
if name.to_s =~ /(.*)=$/
|
99
|
+
name = $1
|
100
|
+
if self[name]
|
101
|
+
self[name] = args.first
|
102
|
+
else
|
103
|
+
raise NoMethodError.new(name.to_s)
|
104
|
+
end
|
105
|
+
else
|
106
|
+
self[name.to_s] or raise NoMethodError.new(name.to_s)
|
107
|
+
end
|
64
108
|
end
|
65
109
|
end
|
66
110
|
end
|
data/lib/red_grape/graph.rb
CHANGED
@@ -5,6 +5,9 @@ require 'red_grape/serializer/graphml_serializer'
|
|
5
5
|
|
6
6
|
module RedGrape
|
7
7
|
class Graph
|
8
|
+
include RedGrape::Pipe::V
|
9
|
+
include RedGrape::Pipe::E
|
10
|
+
|
8
11
|
class << self
|
9
12
|
def load(filename)
|
10
13
|
self.new.load filename
|
@@ -107,20 +110,10 @@ module RedGrape
|
|
107
110
|
items :vertex, *id
|
108
111
|
end
|
109
112
|
|
110
|
-
def v(*id)
|
111
|
-
vertex(*id)._
|
112
|
-
end
|
113
|
-
alias V v
|
114
|
-
|
115
113
|
def edge(*id)
|
116
114
|
items :edge, *id
|
117
115
|
end
|
118
116
|
|
119
|
-
def e(*id)
|
120
|
-
edge(*id)._
|
121
|
-
end
|
122
|
-
alias E e
|
123
|
-
|
124
117
|
def add_vertex(id, v=nil)
|
125
118
|
if v
|
126
119
|
if v.is_a? Hash
|
@@ -221,6 +214,10 @@ module RedGrape
|
|
221
214
|
false
|
222
215
|
end
|
223
216
|
|
217
|
+
def shutdown
|
218
|
+
# do nothing
|
219
|
+
end
|
220
|
+
|
224
221
|
def dup
|
225
222
|
obj = self.class.new
|
226
223
|
obj.instance_variable_set :@serializer, @serializer
|
@@ -11,17 +11,8 @@ module RedGrape
|
|
11
11
|
class AsPipe < Pipe::Base
|
12
12
|
def pass(obj, context)
|
13
13
|
label = self.opts.first.to_s
|
14
|
-
|
15
|
-
|
16
|
-
# TODO: why??
|
17
|
-
context.mark! label
|
18
|
-
obj
|
19
|
-
when Vertex, Array
|
20
|
-
context.mark! label, obj
|
21
|
-
obj.pass_through self.next, context
|
22
|
-
else
|
23
|
-
raise 'not yet'
|
24
|
-
end
|
14
|
+
context.mark! label, obj
|
15
|
+
obj.pass_through self.next, context
|
25
16
|
end
|
26
17
|
end
|
27
18
|
end
|
data/lib/red_grape/pipe/base.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'red_grape/pipe/base'
|
2
|
+
|
3
|
+
module RedGrape
|
4
|
+
module Pipe
|
5
|
+
module E
|
6
|
+
def e(*opts)
|
7
|
+
EPipe.new self, *opts
|
8
|
+
end
|
9
|
+
alias E e
|
10
|
+
end
|
11
|
+
|
12
|
+
class EPipe < Pipe::Base
|
13
|
+
def pass(obj, context)
|
14
|
+
edges = obj.edge(*self.opts)
|
15
|
+
pass_next context, obj, edges
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'red_grape/pipe/base'
|
2
|
+
|
3
|
+
module RedGrape
|
4
|
+
module Pipe
|
5
|
+
module V
|
6
|
+
def v(*opts)
|
7
|
+
VPipe.new self, *opts
|
8
|
+
end
|
9
|
+
alias V v
|
10
|
+
end
|
11
|
+
|
12
|
+
class VPipe < Pipe::Base
|
13
|
+
def pass(obj, context)
|
14
|
+
vertices = obj.vertex(*self.opts)
|
15
|
+
pass_next context, obj, vertices
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/red_grape/version.rb
CHANGED
data/lib/red_grape/vertex.rb
CHANGED
@@ -18,6 +18,23 @@ module RedGrape
|
|
18
18
|
@in_edges = []
|
19
19
|
end
|
20
20
|
|
21
|
+
# Returns edges
|
22
|
+
# _direction_ :: :out or :in
|
23
|
+
# _labels_ :: labels
|
24
|
+
def edges(direction, *labels)
|
25
|
+
edges = directed_value direction, @out_edges, @in_edges
|
26
|
+
if labels.empty?
|
27
|
+
edges
|
28
|
+
else
|
29
|
+
edges.select {|e| labels.include? e.label}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def vertices(direction, *labels)
|
34
|
+
edges = edges direction, *labels
|
35
|
+
directed_value direction, proc{edges.map &:target}, proc{edges.map &:source}
|
36
|
+
end
|
37
|
+
|
21
38
|
def add_out_edge(edge)
|
22
39
|
@out_edges << edge
|
23
40
|
end
|
data/lib/red_grape.rb
CHANGED
@@ -22,6 +22,8 @@ require 'red_grape/pipe/retain_pipe'
|
|
22
22
|
require 'red_grape/pipe/fill_pipe'
|
23
23
|
require 'red_grape/pipe/group_count_pipe'
|
24
24
|
require 'red_grape/pipe/cap_pipe'
|
25
|
+
require 'red_grape/pipe/v_pipe'
|
26
|
+
require 'red_grape/pipe/e_pipe'
|
25
27
|
require 'red_grape/graph'
|
26
28
|
|
27
29
|
module RedGrape
|
data/test/test_element.rb
CHANGED
@@ -39,4 +39,28 @@ class ElementTest < Test::Unit::TestCase
|
|
39
39
|
assert_nil desc[:name].default
|
40
40
|
assert_equal 'male', desc[:sex].default
|
41
41
|
end
|
42
|
+
|
43
|
+
def test_property_keys
|
44
|
+
v = RedGrape::Vertex.new nil, 1, name:'ando', lang:'ruby'
|
45
|
+
assert_equal %w(name lang).sort, v.property_keys.sort
|
46
|
+
assert_equal %w(name lang).sort, v.property.keys.sort
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_remove_property
|
50
|
+
v = RedGrape::Vertex.new nil, 1, name:'ando', lang:'ruby'
|
51
|
+
assert_equal %w(name lang).sort, v.property_keys.sort
|
52
|
+
v.remove_property :name
|
53
|
+
assert_equal %w(lang).sort, v.property_keys.sort
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_method_missing
|
57
|
+
v = RedGrape::Vertex.new nil, 1, name:'ando', lang:'ruby'
|
58
|
+
assert_equal 'ando', v.name
|
59
|
+
assert_equal 'ruby', v.lang
|
60
|
+
v.lang = 'javascript'
|
61
|
+
assert_equal 'javascript', v.lang
|
62
|
+
assert_raise(NoMethodError) do
|
63
|
+
v.unknow
|
64
|
+
end
|
65
|
+
end
|
42
66
|
end
|
data/test/test_graph.rb
CHANGED
@@ -81,18 +81,18 @@ class GraphTest < Test::Unit::TestCase
|
|
81
81
|
def test_add_vertex
|
82
82
|
g = RedGrape::Graph.new
|
83
83
|
g.add_vertex id:1, val:'a'
|
84
|
-
v1 = g.
|
84
|
+
v1 = g.vertex(1)
|
85
85
|
assert_equal '1', v1.id
|
86
86
|
assert_equal 'a', v1.val
|
87
87
|
|
88
88
|
g.add_vertex '2', val:'b'
|
89
|
-
v2 = g.
|
89
|
+
v2 = g.vertex(2)
|
90
90
|
assert_equal '2', v2.id
|
91
91
|
assert_equal 'b', v2.val
|
92
92
|
|
93
93
|
v3 = RedGrape::Vertex.new nil, 3, val:'c'
|
94
94
|
g.add_vertex '3', v3
|
95
|
-
assert_equal v3, g.
|
95
|
+
assert_equal v3, g.vertex(3)
|
96
96
|
assert_equal '3', v3.id
|
97
97
|
assert_equal 'c', v3.val
|
98
98
|
|
@@ -118,11 +118,11 @@ class GraphTest < Test::Unit::TestCase
|
|
118
118
|
assert !v3.in_edges.map(&:id).include?(e23.id)
|
119
119
|
|
120
120
|
g = RedGrape.create_tinker_graph
|
121
|
-
assert_equal 6, g.
|
122
|
-
assert_equal 6, g.
|
121
|
+
assert_equal 6, g.vertex.size
|
122
|
+
assert_equal 6, g.edge.size
|
123
123
|
g.remove_vertex 1
|
124
|
-
assert_equal 5, g.
|
125
|
-
assert_equal 3, g.
|
124
|
+
assert_equal 5, g.vertex.size
|
125
|
+
assert_equal 3, g.edge.size
|
126
126
|
end
|
127
127
|
|
128
128
|
def test_add_edge
|
@@ -166,19 +166,19 @@ class GraphTest < Test::Unit::TestCase
|
|
166
166
|
g2 = g1.readonly
|
167
167
|
assert !g1.readonly?
|
168
168
|
assert g2.readonly?
|
169
|
-
assert_equal 1, g2.
|
169
|
+
assert_equal 1, g2.vertex.size
|
170
170
|
assert_raise(NoMethodError) do
|
171
171
|
g2.add_vertex 2
|
172
172
|
end
|
173
173
|
g1.add_vertex 2
|
174
|
-
assert_equal 2, g1.
|
175
|
-
assert_equal 1, g2.
|
174
|
+
assert_equal 2, g1.vertex.size
|
175
|
+
assert_equal 1, g2.vertex.size
|
176
176
|
|
177
177
|
g1.readonly!
|
178
178
|
assert g1.readonly?
|
179
179
|
assert_raise(NoMethodError) do
|
180
180
|
g1.add_vertex 3
|
181
181
|
end
|
182
|
-
assert_equal 2, g1.
|
182
|
+
assert_equal 2, g1.vertex.size
|
183
183
|
end
|
184
184
|
end
|
@@ -9,7 +9,7 @@ class OnTheNatureOfPipesTest < Test::Unit::TestCase
|
|
9
9
|
|
10
10
|
def test_basic
|
11
11
|
assert_equal '1',
|
12
|
-
@graph.v(1).id
|
12
|
+
@graph.v(1).take.id
|
13
13
|
|
14
14
|
assert_equal %w(2 3 4),
|
15
15
|
@graph.v(1).out.take.map(&:id).sort
|
@@ -21,10 +21,10 @@ class OnTheNatureOfPipesTest < Test::Unit::TestCase
|
|
21
21
|
assert_equal 3,
|
22
22
|
paths.size
|
23
23
|
|
24
|
-
assert_equal [
|
24
|
+
assert_equal [4, 4, 4],
|
25
25
|
paths.map(&:size)
|
26
26
|
|
27
|
-
assert_equal %w[
|
27
|
+
assert_equal %w[V Out Property(name) Paths],
|
28
28
|
@graph.v(1).out.name.paths.to_a
|
29
29
|
end
|
30
30
|
|
@@ -41,7 +41,7 @@ class OnTheNatureOfPipesTest < Test::Unit::TestCase
|
|
41
41
|
assert_equal [5],
|
42
42
|
@graph.v(1).out('knows').filter{it.age < 30}.name.transform{it.size}.take.sort
|
43
43
|
|
44
|
-
assert_equal %w[
|
44
|
+
assert_equal %w[V Out(knows) Filter Property(name) Transform],
|
45
45
|
@graph.v(1).out('knows').filter{it.age < 30}.name.transform{it.size}.to_a
|
46
46
|
end
|
47
47
|
|
@@ -58,7 +58,7 @@ class OnTheNatureOfPipesTest < Test::Unit::TestCase
|
|
58
58
|
assert_equal %w(4 6),
|
59
59
|
@graph.v(1).side_effect{@x = it}.out('created').in('created').filter{it != @x}.take.map(&:id).sort
|
60
60
|
|
61
|
-
assert_equal %w(
|
61
|
+
assert_equal %w(V SideEffect Out(created) In(created) Filter),
|
62
62
|
@graph.v(1).side_effect{@x = it}.out('created').in('created').filter{it != @x}.to_a
|
63
63
|
end
|
64
64
|
|
@@ -78,10 +78,10 @@ class OnTheNatureOfPipesTest < Test::Unit::TestCase
|
|
78
78
|
assert_equal %w(2),
|
79
79
|
@graph.v(1).out('knows').name.filter{it[0] == 'v'}.back(2).take.to_a.map(&:id)
|
80
80
|
|
81
|
-
assert_equal %w(
|
81
|
+
assert_equal %w(V Out(knows) Property(name) Filter Back),
|
82
82
|
@graph.v(1).out('knows').name.filter{it[0] == 'v'}.back(2).to_a
|
83
83
|
|
84
|
-
assert_equal %w(2
|
84
|
+
assert_equal %w(2),
|
85
85
|
@graph.v(1).out('knows').as('here').name.filter{it[0] == 'v'}.back('here').take.to_a.map(&:id)
|
86
86
|
end
|
87
87
|
|
@@ -95,7 +95,7 @@ class OnTheNatureOfPipesTest < Test::Unit::TestCase
|
|
95
95
|
assert_equal %w(lop ripple),
|
96
96
|
@graph.v(1).out.loop(1){loops < 3}.name.take.sort
|
97
97
|
|
98
|
-
assert_equal %w(
|
98
|
+
assert_equal %w(V Out Loop Property(name)),
|
99
99
|
@graph.v(1).out.loop(1){loops < 3}.name.to_a
|
100
100
|
end
|
101
101
|
end
|
@@ -22,7 +22,7 @@ class TraversalPatternsTest < Test::Unit::TestCase
|
|
22
22
|
|
23
23
|
# https://github.com/tinkerpop/gremlin/wiki/Flow-Rank-Pattern
|
24
24
|
def test_flow_rank_pattern
|
25
|
-
assert_equal %w(3 5), @graph.V('lang', 'java').map(&:id).sort
|
25
|
+
assert_equal %w(3 5), @graph.V('lang', 'java').take.map(&:id).sort
|
26
26
|
software = []
|
27
27
|
@graph.V('lang', 'java').fill(software).take
|
28
28
|
assert_equal %w(3 5), software.map(&:id).sort
|
@@ -39,27 +39,30 @@ class TraversalPatternsTest < Test::Unit::TestCase
|
|
39
39
|
|
40
40
|
# https://github.com/tinkerpop/gremlin/wiki/Path-Pattern
|
41
41
|
def test_path_pattern
|
42
|
-
|
42
|
+
v1 = @graph.vertex(1)
|
43
43
|
|
44
|
-
|
44
|
+
assert_equal %w(josh lop vadas), v1.out.name.take.sort
|
45
|
+
|
46
|
+
path = v1.out.name.path.take
|
45
47
|
assert_equal 3, path.size
|
46
48
|
assert_equal 3, path.first.size
|
47
49
|
assert_equal '[[v[1], v[2], "vadas"], [v[1], v[4], "josh"], [v[1], v[3], "lop"]]', path.to_s
|
48
50
|
|
49
|
-
path =
|
51
|
+
path = v1.outE.inV.name.path.take
|
50
52
|
assert_equal '[[v[1], e[7][1-knows->2], v[2], "vadas"], [v[1], e[8][1-knows->4], v[4], "josh"], [v[1], e[9][1-created->3], v[3], "lop"]]', path.to_s
|
51
53
|
|
52
54
|
assert_equal(
|
53
55
|
[["marko", 0.5, "vadas"], ["marko", 1.0, "josh"], ["marko", 0.4, "lop"]].to_s,
|
54
|
-
|
56
|
+
v1.outE.inV.path(proc{it.name}, proc{it.weight}, proc{it.name}).take.to_s
|
55
57
|
)
|
56
58
|
end
|
57
59
|
|
58
60
|
def test_loop_pattern
|
59
61
|
g = RedGrape.load_graph 'data/graph-example-2.xml'
|
62
|
+
v89 = g.vertex 89
|
60
63
|
assert_equal 36, g.v(89).outE.inV.path.take.size
|
61
64
|
|
62
|
-
path =
|
65
|
+
path = v89.outE.inV.loop(2){it.loops < 3}.path.take.first
|
63
66
|
assert_equal '[v[89], e[7006][89-followed_by->127], v[127], e[7786][127-sung_by->340], v[340]]', path.to_s
|
64
67
|
assert_equal RedGrape::Vertex, path[0].class
|
65
68
|
assert_equal RedGrape::Edge, path[1].class
|
@@ -67,7 +70,7 @@ class TraversalPatternsTest < Test::Unit::TestCase
|
|
67
70
|
assert_equal RedGrape::Edge, path[3].class
|
68
71
|
assert_equal RedGrape::Vertex, path[4].class
|
69
72
|
|
70
|
-
path =
|
73
|
+
path = v89.as('x').outE.inV.loop('x'){it.loops < 3}.path.take.first
|
71
74
|
assert_equal '[v[89], e[7006][89-followed_by->127], v[127], e[7786][127-sung_by->340], v[340]]', path.to_s
|
72
75
|
assert_equal RedGrape::Vertex, path[0].class
|
73
76
|
assert_equal RedGrape::Edge, path[1].class
|
@@ -75,7 +78,7 @@ class TraversalPatternsTest < Test::Unit::TestCase
|
|
75
78
|
assert_equal RedGrape::Edge, path[3].class
|
76
79
|
assert_equal RedGrape::Vertex, path[4].class
|
77
80
|
|
78
|
-
path =
|
81
|
+
path = v89.outE.inV.outE.inV.path.take.first
|
79
82
|
assert_equal '[v[89], e[7006][89-followed_by->127], v[127], e[7786][127-sung_by->340], v[340]]', path.to_s
|
80
83
|
assert_equal RedGrape::Vertex, path[0].class
|
81
84
|
assert_equal RedGrape::Edge, path[1].class
|
data/test/test_vertex.rb
CHANGED
@@ -22,6 +22,22 @@ class VertexTest < Test::Unit::TestCase
|
|
22
22
|
assert_raise(ArgumentError) {v.set_property :age, 'not integer'}
|
23
23
|
end
|
24
24
|
|
25
|
+
def test_edges
|
26
|
+
g = RedGrape::Graph.create_tinker_graph
|
27
|
+
v = g.vertex(1)
|
28
|
+
assert_equal %w(7 8 9), v.edges(:out).map(&:id).sort
|
29
|
+
assert_equal %w(created), v.edges(:out, 'created').map(&:label)
|
30
|
+
assert_equal %w(knows knows), v.edges(:out, 'knows').map(&:label)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_vertices
|
34
|
+
g = RedGrape::Graph.create_tinker_graph
|
35
|
+
v = g.vertex(1)
|
36
|
+
assert_equal %w(2 3 4), v.vertices(:out).map(&:id).sort
|
37
|
+
assert_equal %w(lop), v.vertices(:out, 'created').map(&:name)
|
38
|
+
assert_equal %w(vadas josh), v.vertices(:out, 'knows').map(&:name)
|
39
|
+
end
|
40
|
+
|
25
41
|
def test_method_missing
|
26
42
|
g = RedGrape::Graph.new
|
27
43
|
v = RedGrape::Vertex.new g, '12345'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: red_grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &70127387275840 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70127387275840
|
25
25
|
description: RedGrape is an in-memory graph database written in ruby. I made this
|
26
26
|
in order to learn how graph databases work so that please do not use this for any
|
27
27
|
serious purpose.
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- lib/red_grape/pipe/base.rb
|
59
59
|
- lib/red_grape/pipe/cap_pipe.rb
|
60
60
|
- lib/red_grape/pipe/context.rb
|
61
|
+
- lib/red_grape/pipe/e_pipe.rb
|
61
62
|
- lib/red_grape/pipe/except_pipe.rb
|
62
63
|
- lib/red_grape/pipe/fill_pipe.rb
|
63
64
|
- lib/red_grape/pipe/filter_pipe.rb
|
@@ -74,6 +75,7 @@ files:
|
|
74
75
|
- lib/red_grape/pipe/retain_pipe.rb
|
75
76
|
- lib/red_grape/pipe/side_effect_pipe.rb
|
76
77
|
- lib/red_grape/pipe/transform_pipe.rb
|
78
|
+
- lib/red_grape/pipe/v_pipe.rb
|
77
79
|
- lib/red_grape/property_description.rb
|
78
80
|
- lib/red_grape/serializer/graphml_serializer.rb
|
79
81
|
- lib/red_grape/version.rb
|