red_grape 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +4 -2
- data/README.txt +31 -2
- data/bin/redgrape +4 -0
- data/bin/trellis +10 -0
- data/lib/red_grape/edge.rb +5 -0
- data/lib/red_grape/graph.rb +36 -5
- data/lib/red_grape/graph_store.rb +64 -0
- data/lib/red_grape/vertex.rb +1 -1
- data/lib/red_grape.rb +1 -1
- data/test/test_graph.rb +73 -1
- metadata +13 -10
data/Manifest.txt
CHANGED
@@ -4,15 +4,15 @@ Rakefile
|
|
4
4
|
README.txt
|
5
5
|
History.txt
|
6
6
|
bin/redgrape
|
7
|
+
bin/trellis
|
7
8
|
data/graph-example-1.xml
|
8
9
|
data/graph-example-2.xml
|
9
10
|
lib/ext/array_ext.rb
|
10
11
|
lib/ext/object_ext.rb
|
11
|
-
lib/red_grape.rb
|
12
|
-
lib/red_grape/vertex.rb
|
13
12
|
lib/red_grape/edge.rb
|
14
13
|
lib/red_grape/element.rb
|
15
14
|
lib/red_grape/graph.rb
|
15
|
+
lib/red_grape/graph_store.rb
|
16
16
|
lib/red_grape/path_group.rb
|
17
17
|
lib/red_grape/pipe/aggregate_pipe.rb
|
18
18
|
lib/red_grape/pipe/as_pipe.rb
|
@@ -38,6 +38,8 @@ lib/red_grape/pipe/side_effect_pipe.rb
|
|
38
38
|
lib/red_grape/pipe/transform_pipe.rb
|
39
39
|
lib/red_grape/property_description.rb
|
40
40
|
lib/red_grape/serializer/graphml_serializer.rb
|
41
|
+
lib/red_grape/vertex.rb
|
42
|
+
lib/red_grape.rb
|
41
43
|
test/test_element.rb
|
42
44
|
test/test_graph.rb
|
43
45
|
test/test_on_the_nature_of_pipes.rb
|
data/README.txt
CHANGED
@@ -4,7 +4,7 @@
|
|
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 databases work so that please do not use this for serious
|
7
|
+
RedGrape is an in-memory graph database written in ruby. I made this in order to learn how graph databases work so that please do not use this for any serious purpose.
|
8
8
|
|
9
9
|
## FEATURES/PROBLEMS:
|
10
10
|
|
@@ -25,7 +25,7 @@ RedGrape is an in-memory graph database written in ruby. I made this in order to
|
|
25
25
|
|
26
26
|
## REPL:
|
27
27
|
|
28
|
-
$ bin/redgrape
|
28
|
+
$ bin/redgrape
|
29
29
|
T
|
30
30
|
ooooo
|
31
31
|
----- ooo -----
|
@@ -64,6 +64,35 @@ RedGrape is an in-memory graph database written in ruby. I made this in order to
|
|
64
64
|
|
65
65
|
In REPL, the `take' method which invokes all pipes is automatically called.
|
66
66
|
|
67
|
+
## CLIENT/SERVER:
|
68
|
+
|
69
|
+
### SERVER:
|
70
|
+
|
71
|
+
$ ./bin/trellis
|
72
|
+
Start server: druby://localhost:28282
|
73
|
+
[Ctrl+C to stop]
|
74
|
+
|
75
|
+
### CLIENT:
|
76
|
+
|
77
|
+
$ ./bin/redgrape
|
78
|
+
T
|
79
|
+
ooooo
|
80
|
+
------ ooo ------
|
81
|
+
RED o GRAPE
|
82
|
+
-------------------
|
83
|
+
ruby-1.9.3-head :001 > store = RedGrape::GraphStore.open
|
84
|
+
=> #<RedGrape::GraphStore:0x007fb615137a90>
|
85
|
+
ruby-1.9.3-head :002 > store.graphs
|
86
|
+
=> [:tinker]
|
87
|
+
ruby-1.9.3-head :003 > g = store.graph :tinker
|
88
|
+
=> redgrape[vertices:6 edges:6]
|
89
|
+
ruby-1.9.3-head :004 > g.v
|
90
|
+
=> [v[1], v[2], v[3], v[4], v[5], v[6]]
|
91
|
+
ruby-1.9.3-head :005 > g.v.out
|
92
|
+
=> [v[2], v[4], v[3], v[5], v[3], v[3]]
|
93
|
+
ruby-1.9.3-head :006 > g.v.out.name
|
94
|
+
=> ["vadas", "josh", "lop", "ripple", "lop", "lop"]
|
95
|
+
|
67
96
|
## REQUIREMENTS:
|
68
97
|
|
69
98
|
* Nokogiri (http://nokogiri.org/)
|
data/bin/redgrape
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
$: << File.expand_path('../../lib', __FILE__)
|
3
3
|
|
4
|
+
require 'drb/drb'
|
4
5
|
require 'irb'
|
5
6
|
require 'irb/completion'
|
6
7
|
require 'optparse'
|
7
8
|
require 'red_grape'
|
9
|
+
require 'red_grape/graph_store'
|
8
10
|
|
9
11
|
RedGrape.set_auto_take
|
10
12
|
module RedGrape
|
@@ -67,6 +69,8 @@ opts.on_tail('-h', '--help', 'Show this message.'){puts(opts.help); exit}
|
|
67
69
|
opts.order! ARGV
|
68
70
|
CMD = ARGV.shift
|
69
71
|
|
72
|
+
$store = RedGrape::GraphStore.open
|
73
|
+
|
70
74
|
puts %Q{ T
|
71
75
|
ooooo
|
72
76
|
------ ooo ------
|
data/bin/trellis
ADDED
data/lib/red_grape/edge.rb
CHANGED
data/lib/red_grape/graph.rb
CHANGED
@@ -93,7 +93,7 @@ module RedGrape
|
|
93
93
|
else
|
94
94
|
if id.is_a? Hash
|
95
95
|
v = id
|
96
|
-
id = v[:id] || v['id']
|
96
|
+
id = (v[:id] || v['id']).to_s
|
97
97
|
elsif id.respond_to?(:id)
|
98
98
|
v = id
|
99
99
|
id = v.id
|
@@ -102,9 +102,24 @@ module RedGrape
|
|
102
102
|
end
|
103
103
|
v = Vertex.new self, id, v
|
104
104
|
end
|
105
|
-
|
105
|
+
id = id.to_s
|
106
|
+
raise ArgumentError.new "invalid id" unless id == v.id
|
106
107
|
|
107
|
-
@vertices[id
|
108
|
+
@vertices[id] = v
|
109
|
+
end
|
110
|
+
|
111
|
+
def remove_vertex(id)
|
112
|
+
id = id.id if id.is_a? Vertex
|
113
|
+
v = @vertices.delete id.to_s
|
114
|
+
if v
|
115
|
+
v.out_edges.each do |e|
|
116
|
+
remove_edge e
|
117
|
+
end
|
118
|
+
v.in_edges.each do |e|
|
119
|
+
remove_edge e
|
120
|
+
end
|
121
|
+
end
|
122
|
+
v
|
108
123
|
end
|
109
124
|
|
110
125
|
def add_edge(id, from, to, label, opts={})
|
@@ -112,8 +127,8 @@ module RedGrape
|
|
112
127
|
id
|
113
128
|
else
|
114
129
|
id = id.to_s
|
115
|
-
from = self.vertex
|
116
|
-
to = self.vertex
|
130
|
+
from = self.vertex(from.to_s) unless from.is_a? Vertex
|
131
|
+
to = self.vertex(to.to_s) unless to.is_a? Vertex
|
117
132
|
add_vertex from unless self.vertex(from.id)
|
118
133
|
add_vertex to unless self.vertex(to.id)
|
119
134
|
Edge.new self, id, from, to, label, opts
|
@@ -121,6 +136,22 @@ module RedGrape
|
|
121
136
|
@edges[edge.id] = edge
|
122
137
|
end
|
123
138
|
|
139
|
+
def remove_edge(id)
|
140
|
+
if id.is_a? Edge
|
141
|
+
e = id
|
142
|
+
id = id.id
|
143
|
+
else
|
144
|
+
id = id.to_s
|
145
|
+
e = @edges[id]
|
146
|
+
end
|
147
|
+
@edges.delete id
|
148
|
+
if e
|
149
|
+
e.source.out_edges.delete e
|
150
|
+
e.target.in_edges.delete e
|
151
|
+
end
|
152
|
+
e
|
153
|
+
end
|
154
|
+
|
124
155
|
def load(filename)
|
125
156
|
@serializer.load filename
|
126
157
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
require 'red_grape'
|
3
|
+
|
4
|
+
module RedGrape
|
5
|
+
class GraphStore
|
6
|
+
DEFAULT_PORT = 28282
|
7
|
+
DEFAULT_URI = "druby://localhost:#{DEFAULT_PORT}"
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def start(uri=nil, filename=nil, &block)
|
11
|
+
self.new(filename).start uri, &block
|
12
|
+
end
|
13
|
+
|
14
|
+
def open(uri=nil)
|
15
|
+
DRbObject.new_with_uri(uri || DEFAULT_URI)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(filename=nil)
|
20
|
+
@filename = filename
|
21
|
+
@graphs =
|
22
|
+
if @filename && File.exist?(@filename)
|
23
|
+
File.open @filename, 'r' do |file|
|
24
|
+
Marshal.load file
|
25
|
+
end
|
26
|
+
else
|
27
|
+
{tinker:RedGrape::Graph.create_tinker_graph}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def graphs
|
32
|
+
@graphs.keys.sort
|
33
|
+
end
|
34
|
+
|
35
|
+
def graph(key)
|
36
|
+
self[key]
|
37
|
+
end
|
38
|
+
|
39
|
+
def put_graph(key, graph)
|
40
|
+
self[key] = graph
|
41
|
+
end
|
42
|
+
|
43
|
+
def [](key)
|
44
|
+
@graphs[key.to_sym]
|
45
|
+
end
|
46
|
+
|
47
|
+
def []=(key, graph)
|
48
|
+
@graphs[key.to_sym] = graph
|
49
|
+
end
|
50
|
+
|
51
|
+
def start(uri=nil, &block)
|
52
|
+
at_exit do
|
53
|
+
File.open @filename, 'w' do |file|
|
54
|
+
Marshal.dump @graphs, file
|
55
|
+
end if @filename
|
56
|
+
end
|
57
|
+
|
58
|
+
uri = DEFAULT_URI if uri.nil? || uri == :default
|
59
|
+
DRb.start_service uri, self
|
60
|
+
block.call if block
|
61
|
+
sleep
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/red_grape/vertex.rb
CHANGED
data/lib/red_grape.rb
CHANGED
data/test/test_graph.rb
CHANGED
@@ -9,7 +9,7 @@ class GraphTest < Test::Unit::TestCase
|
|
9
9
|
graph.add_vertex id:3, val:'c'
|
10
10
|
|
11
11
|
assert_equal 3, graph.vertex.size
|
12
|
-
assert_equal 1, graph.vertex(1).id
|
12
|
+
assert_equal '1', graph.vertex(1).id
|
13
13
|
#assert_equal 2, graph.vertex(1, 2).size # TODO
|
14
14
|
assert_equal 3, graph.vertex(1, 2, 3).size
|
15
15
|
assert_equal 2, graph.vertex([1, 2]).size
|
@@ -68,4 +68,76 @@ class GraphTest < Test::Unit::TestCase
|
|
68
68
|
assert_equal 'marko', graph.edge(5).source.name
|
69
69
|
assert_equal 'lop', graph.edge(5).target.name
|
70
70
|
end
|
71
|
+
|
72
|
+
def test_add_vertex
|
73
|
+
g = RedGrape::Graph.new
|
74
|
+
g.add_vertex id:1, val:'a'
|
75
|
+
v1 = g.v(1)
|
76
|
+
assert_equal '1', v1.id
|
77
|
+
assert_equal 'a', v1.val
|
78
|
+
|
79
|
+
g.add_vertex '2', val:'b'
|
80
|
+
v2 = g.v(2)
|
81
|
+
assert_equal '2', v2.id
|
82
|
+
assert_equal 'b', v2.val
|
83
|
+
|
84
|
+
v3 = RedGrape::Vertex.new nil, 3, val:'c'
|
85
|
+
g.add_vertex '3', v3
|
86
|
+
assert_equal v3, g.v(3)
|
87
|
+
assert_equal '3', v3.id
|
88
|
+
assert_equal 'c', v3.val
|
89
|
+
|
90
|
+
assert_raise(ArgumentError) do
|
91
|
+
g.add_vertex '4', v3
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_remove_vertex
|
96
|
+
g = RedGrape::Graph.new
|
97
|
+
v1 = g.add_vertex 1
|
98
|
+
v2 = g.add_vertex 2
|
99
|
+
v3 = g.add_vertex 3
|
100
|
+
e12 = g.add_edge 1, 1, 2, :connect
|
101
|
+
e23 = g.add_edge 1, 2, 3, :connect
|
102
|
+
assert v1.out_edges.map(&:id).include?(e12.id)
|
103
|
+
assert v2.in_edges.map(&:id).include?(e12.id)
|
104
|
+
assert v2.out_edges.map(&:id).include?(e23.id)
|
105
|
+
assert v3.in_edges.map(&:id).include?(e23.id)
|
106
|
+
|
107
|
+
g.remove_vertex v2
|
108
|
+
assert !v1.out_edges.map(&:id).include?(e12.id)
|
109
|
+
assert !v3.in_edges.map(&:id).include?(e23.id)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_add_edge
|
113
|
+
g = RedGrape::Graph.new
|
114
|
+
v1 = g.add_vertex 1
|
115
|
+
v2 = g.add_vertex 2
|
116
|
+
v3 = g.add_vertex 3
|
117
|
+
e12 = g.add_edge 1, 1, 2, :connect
|
118
|
+
e23 = g.add_edge 1, 2, 3, :connect
|
119
|
+
assert v1.out_edges.map(&:id).include?(e12.id)
|
120
|
+
assert v2.in_edges.map(&:id).include?(e12.id)
|
121
|
+
assert v2.out_edges.map(&:id).include?(e23.id)
|
122
|
+
assert v3.in_edges.map(&:id).include?(e23.id)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_remove_edge
|
126
|
+
g = RedGrape::Graph.new
|
127
|
+
v1 = g.add_vertex 1
|
128
|
+
v2 = g.add_vertex 2
|
129
|
+
v3 = g.add_vertex 3
|
130
|
+
e12 = g.add_edge 1, 1, 2, :connect
|
131
|
+
e23 = g.add_edge 1, 2, 3, :connect
|
132
|
+
assert v1.out_edges.map(&:id).include?(e12.id)
|
133
|
+
assert v2.in_edges.map(&:id).include?(e12.id)
|
134
|
+
assert v2.out_edges.map(&:id).include?(e23.id)
|
135
|
+
assert v3.in_edges.map(&:id).include?(e23.id)
|
136
|
+
|
137
|
+
g.remove_edge e12
|
138
|
+
assert !v1.out_edges.map(&:id).include?(e12.id)
|
139
|
+
assert !v2.in_edges.map(&:id).include?(e12.id)
|
140
|
+
assert v2.out_edges.map(&:id).include?(e23.id)
|
141
|
+
assert v3.in_edges.map(&:id).include?(e23.id)
|
142
|
+
end
|
71
143
|
end
|
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.3
|
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-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rdoc
|
16
|
-
requirement: &
|
16
|
+
requirement: &70272812464840 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.10'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70272812464840
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: hoe
|
27
|
-
requirement: &
|
27
|
+
requirement: &70272812464400 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,14 +32,15 @@ dependencies:
|
|
32
32
|
version: '3.0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70272812464400
|
36
36
|
description: RedGrape is an in-memory graph database written in ruby. I made this
|
37
|
-
in order to learn how graph databases work so that please do not use this for
|
38
|
-
|
37
|
+
in order to learn how graph databases work so that please do not use this for any
|
38
|
+
serious purpose.
|
39
39
|
email:
|
40
40
|
- andyjpn@gmail.com
|
41
41
|
executables:
|
42
42
|
- redgrape
|
43
|
+
- trellis
|
43
44
|
extensions: []
|
44
45
|
extra_rdoc_files:
|
45
46
|
- Manifest.txt
|
@@ -52,15 +53,15 @@ files:
|
|
52
53
|
- README.txt
|
53
54
|
- History.txt
|
54
55
|
- bin/redgrape
|
56
|
+
- bin/trellis
|
55
57
|
- data/graph-example-1.xml
|
56
58
|
- data/graph-example-2.xml
|
57
59
|
- lib/ext/array_ext.rb
|
58
60
|
- lib/ext/object_ext.rb
|
59
|
-
- lib/red_grape.rb
|
60
|
-
- lib/red_grape/vertex.rb
|
61
61
|
- lib/red_grape/edge.rb
|
62
62
|
- lib/red_grape/element.rb
|
63
63
|
- lib/red_grape/graph.rb
|
64
|
+
- lib/red_grape/graph_store.rb
|
64
65
|
- lib/red_grape/path_group.rb
|
65
66
|
- lib/red_grape/pipe/aggregate_pipe.rb
|
66
67
|
- lib/red_grape/pipe/as_pipe.rb
|
@@ -86,6 +87,8 @@ files:
|
|
86
87
|
- lib/red_grape/pipe/transform_pipe.rb
|
87
88
|
- lib/red_grape/property_description.rb
|
88
89
|
- lib/red_grape/serializer/graphml_serializer.rb
|
90
|
+
- lib/red_grape/vertex.rb
|
91
|
+
- lib/red_grape.rb
|
89
92
|
- test/test_element.rb
|
90
93
|
- test/test_graph.rb
|
91
94
|
- test/test_on_the_nature_of_pipes.rb
|