red_grape 0.0.7 → 0.0.8
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/bin/redgrape +4 -4
- data/bin/trellis +3 -3
- data/lib/ext/array_ext.rb +2 -1
- data/lib/ext/object_ext.rb +4 -11
- data/lib/red_grape/edge.rb +3 -0
- data/lib/red_grape/graph.rb +13 -0
- data/lib/red_grape/pipe/base.rb +24 -3
- data/lib/red_grape/pipe/context.rb +0 -6
- data/lib/red_grape/pipe/copy_split_pipe.rb +22 -0
- data/lib/red_grape/pipe/exhaust_merge_pipe.rb +12 -0
- data/lib/red_grape/pipe/in_e_pipe.rb +26 -0
- data/lib/red_grape/pipe/in_v_pipe.rb +7 -0
- data/lib/red_grape/pipe/loop_pipe.rb +14 -3
- data/lib/red_grape/pipe/out_v_pipe.rb +19 -0
- data/lib/red_grape/pipe/underscore_pipe.rb +17 -0
- data/lib/red_grape/tools/graph_store.rb +68 -0
- data/lib/red_grape/tools/irg.rb +70 -0
- data/lib/red_grape/version.rb +1 -1
- data/lib/red_grape/vertex.rb +1 -0
- data/lib/red_grape.rb +19 -15
- data/test/test_graph.rb +7 -0
- data/test/test_traversal_patterns.rb +11 -0
- metadata +11 -6
- data/lib/red_grape/graph_store.rb +0 -66
- data/lib/red_grape/irg.rb +0 -68
data/bin/redgrape
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
$: << File.expand_path('../../lib', __FILE__)
|
3
3
|
|
4
4
|
require 'optparse'
|
5
|
-
require 'red_grape/graph_store'
|
6
|
-
require 'red_grape/irg'
|
5
|
+
require 'red_grape/tools/graph_store'
|
6
|
+
require 'red_grape/tools/irg'
|
7
7
|
require 'red_grape/version'
|
8
8
|
|
9
9
|
# interprete options
|
10
10
|
::Version = RedGrape::VERSION
|
11
11
|
COMMAND_LINE = "#{$0} #{ARGV.join(' ')}"
|
12
12
|
OPT = {
|
13
|
-
port:RedGrape::GraphStore::DEFAULT_PORT
|
13
|
+
port:RedGrape::Tools::GraphStore::DEFAULT_PORT
|
14
14
|
}
|
15
15
|
opts = OptionParser.new
|
16
16
|
opts.on('-p', '--port <port number>',
|
@@ -20,7 +20,7 @@ opts.on_tail('-h', '--help', 'Show this message.'){puts(opts.help); exit}
|
|
20
20
|
opts.order! ARGV
|
21
21
|
|
22
22
|
# start
|
23
|
-
RedGrape::IRG.start(OPT[:port]) do
|
23
|
+
RedGrape::Tools::IRG.start(OPT[:port]) do
|
24
24
|
puts <<-EOS
|
25
25
|
T
|
26
26
|
oOOOo
|
data/bin/trellis
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
$: << File.expand_path('../../lib', __FILE__)
|
3
3
|
|
4
4
|
require 'optparse'
|
5
|
-
require 'red_grape/graph_store'
|
5
|
+
require 'red_grape/tools/graph_store'
|
6
6
|
require 'red_grape/version'
|
7
7
|
|
8
8
|
# interprete options
|
9
9
|
::Version = RedGrape::VERSION
|
10
10
|
COMMAND_LINE = "#{$0} #{ARGV.join(' ')}"
|
11
11
|
OPT = {
|
12
|
-
port:RedGrape::GraphStore::DEFAULT_PORT,
|
12
|
+
port:RedGrape::Tools::GraphStore::DEFAULT_PORT,
|
13
13
|
dbfile:'dbfile.bin'
|
14
14
|
}
|
15
15
|
opts = OptionParser.new
|
@@ -23,7 +23,7 @@ opts.order! ARGV
|
|
23
23
|
|
24
24
|
# start
|
25
25
|
Signal.trap :INT, 'EXIT'
|
26
|
-
RedGrape::GraphStore.start(OPT[:port], OPT[:dbfile]) do
|
26
|
+
RedGrape::Tools::GraphStore.start(OPT[:port], OPT[:dbfile]) do
|
27
27
|
puts <<-EOS
|
28
28
|
+=================+
|
29
29
|
| + T + |
|
data/lib/ext/array_ext.rb
CHANGED
data/lib/ext/object_ext.rb
CHANGED
@@ -1,16 +1,9 @@
|
|
1
|
+
require 'red_grape/pipe/underscore_pipe'
|
2
|
+
|
1
3
|
class Object
|
4
|
+
include RedGrape::Pipe::Underscore
|
5
|
+
|
2
6
|
def pass_through(pipe, context)
|
3
7
|
pipe.pass self, context
|
4
8
|
end
|
5
|
-
|
6
|
-
def _
|
7
|
-
ret = self.dup
|
8
|
-
ret.extend RedGrape::Pipe::Out
|
9
|
-
ret.extend RedGrape::Pipe::OutE
|
10
|
-
ret.extend RedGrape::Pipe::In
|
11
|
-
ret.extend RedGrape::Pipe::SideEffect
|
12
|
-
ret.extend RedGrape::Pipe::As
|
13
|
-
ret.extend RedGrape::Pipe::Fill
|
14
|
-
ret
|
15
|
-
end
|
16
9
|
end
|
data/lib/red_grape/edge.rb
CHANGED
data/lib/red_grape/graph.rb
CHANGED
@@ -5,6 +5,8 @@ require 'red_grape/serializer/graphml_serializer'
|
|
5
5
|
|
6
6
|
module RedGrape
|
7
7
|
class Graph
|
8
|
+
UID = nil
|
9
|
+
|
8
10
|
include RedGrape::Pipe::V
|
9
11
|
include RedGrape::Pipe::E
|
10
12
|
|
@@ -115,6 +117,7 @@ module RedGrape
|
|
115
117
|
end
|
116
118
|
|
117
119
|
def add_vertex(id, v=nil)
|
120
|
+
id = uid(@vertices.keys) unless id
|
118
121
|
if v
|
119
122
|
if v.is_a? Hash
|
120
123
|
id = id.to_s
|
@@ -154,6 +157,7 @@ module RedGrape
|
|
154
157
|
end
|
155
158
|
|
156
159
|
def add_edge(id, from, to, label, opts={})
|
160
|
+
id = uid(@edges.keys) unless id
|
157
161
|
if id.is_a? Edge
|
158
162
|
raise ArgumentError.new "#{id.id} already exists." if @edges[id.id]
|
159
163
|
@edges[id.id] = id
|
@@ -227,6 +231,15 @@ module RedGrape
|
|
227
231
|
obj
|
228
232
|
end
|
229
233
|
|
234
|
+
def uid(denies=[]) # :nodoc:
|
235
|
+
id = "##{Time.now.to_i}-#{rand(10000)}"
|
236
|
+
if denies.include? id
|
237
|
+
uid denies
|
238
|
+
else
|
239
|
+
id
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
230
243
|
def to_s
|
231
244
|
"redgrape[vertices:#{@vertices.size} edges:#{@edges.size}]"
|
232
245
|
end
|
data/lib/red_grape/pipe/base.rb
CHANGED
@@ -2,6 +2,16 @@ require 'red_grape/pipe/context'
|
|
2
2
|
|
3
3
|
module RedGrape
|
4
4
|
module Pipe
|
5
|
+
class Pipelines # TODO: Arrayのpass_throughが邪魔して使えないので・・・
|
6
|
+
def initialize(pipes)
|
7
|
+
@pipes = pipes
|
8
|
+
end
|
9
|
+
|
10
|
+
def take(context)
|
11
|
+
@pipes.map {|p| p.take(context)}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
@@auto_take = false
|
6
16
|
|
7
17
|
def self.auto_take
|
@@ -26,6 +36,12 @@ module RedGrape
|
|
26
36
|
self.class.name.split('::').last.sub(/Pipe$/, '')
|
27
37
|
end
|
28
38
|
|
39
|
+
def first_pipe
|
40
|
+
pipe = self
|
41
|
+
pipe = pipe.prev until pipe.first?
|
42
|
+
pipe
|
43
|
+
end
|
44
|
+
|
29
45
|
def first?
|
30
46
|
not @prev.kind_of? RedGrape::Pipe::Base
|
31
47
|
end
|
@@ -38,9 +54,9 @@ module RedGrape
|
|
38
54
|
not @value.nil?
|
39
55
|
end
|
40
56
|
|
41
|
-
def take
|
57
|
+
def take(context=Context.new)
|
42
58
|
if first?
|
43
|
-
context = Context.new
|
59
|
+
#context = Context.new
|
44
60
|
val = @prev.pass_through self, context
|
45
61
|
if context.aggregating?
|
46
62
|
context.resume_from_aggregating
|
@@ -53,6 +69,7 @@ module RedGrape
|
|
53
69
|
@prev.take
|
54
70
|
end
|
55
71
|
end
|
72
|
+
alias [] take
|
56
73
|
|
57
74
|
def pass_next(context, pushed_obj, next_obj=nil, &block)
|
58
75
|
next_obj ||= pushed_obj
|
@@ -74,6 +91,8 @@ module RedGrape
|
|
74
91
|
Pipe.auto_take ? take.to_s : super
|
75
92
|
end
|
76
93
|
|
94
|
+
def to_ary; nil end # TODO: i dont know why.
|
95
|
+
|
77
96
|
def to_a
|
78
97
|
pipe = self
|
79
98
|
ret = [pipe.pipe_name]
|
@@ -112,8 +131,10 @@ module RedGrape
|
|
112
131
|
end
|
113
132
|
|
114
133
|
def method_missing(name, *args, &block)
|
134
|
+
#auto_take = name =~ /(.*)!$/ # TODO
|
135
|
+
#name = $1
|
115
136
|
class_name = "#{name.to_s.sub(/^./){$&.upcase}.gsub(/_(.)/){$1.upcase}}Pipe"
|
116
|
-
args.unshift block if block
|
137
|
+
args.unshift block if block # 引数の数は変わるので、blockは必ず1番目に追加しておく
|
117
138
|
pipe_class =
|
118
139
|
if Pipe.const_defined? class_name
|
119
140
|
eval "RedGrape::Pipe::#{class_name}"
|
@@ -88,12 +88,6 @@ module RedGrape
|
|
88
88
|
|
89
89
|
def eval(args={}, &block)
|
90
90
|
args.each {|k, v| self.send "#{k}=", v}
|
91
|
-
if @it
|
92
|
-
# so aggressive way...
|
93
|
-
def @it.loops=(l); @loops = l end
|
94
|
-
def @it.loops; @loops end
|
95
|
-
@it.loops = @loops
|
96
|
-
end
|
97
91
|
instance_eval(&block)
|
98
92
|
end
|
99
93
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'red_grape/pipe/context'
|
2
|
+
|
3
|
+
module RedGrape
|
4
|
+
module Pipe
|
5
|
+
class CopySplitPipe < Pipe::Base
|
6
|
+
def initialize(prev, *opts, &block)
|
7
|
+
super
|
8
|
+
@opts2 = @opts.dup # TODO: bug!
|
9
|
+
end
|
10
|
+
|
11
|
+
def pass(obj, context)
|
12
|
+
#pipelines = self.opts
|
13
|
+
pipelines = @opts2.map do |pipeline| # TODO: opts2??
|
14
|
+
pipe = pipeline.first_pipe
|
15
|
+
pipe.prev = obj
|
16
|
+
pipe
|
17
|
+
end
|
18
|
+
pass_next context, Pipelines.new(pipelines)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'red_grape/pipe/base'
|
2
|
+
|
3
|
+
module RedGrape
|
4
|
+
module Pipe
|
5
|
+
module InE
|
6
|
+
def in_e(*opts)
|
7
|
+
InEPipe.new self, *opts
|
8
|
+
end
|
9
|
+
alias inE in_e
|
10
|
+
end
|
11
|
+
|
12
|
+
class InEPipe < Pipe::Base
|
13
|
+
def pass(obj, context)
|
14
|
+
label = self.opts.first
|
15
|
+
label = nil if label.is_a?(Array) && label.empty? # TODO
|
16
|
+
edges = if label
|
17
|
+
obj.in_edges.dup.find_all{|e| e.label == label}
|
18
|
+
else
|
19
|
+
obj.in_edges.dup
|
20
|
+
end
|
21
|
+
pass_next context, obj, edges
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -3,8 +3,14 @@ require 'red_grape/pipe/base'
|
|
3
3
|
module RedGrape
|
4
4
|
module Pipe
|
5
5
|
class LoopPipe < Pipe::Base
|
6
|
+
LoopContext = Struct.new :loops, :path, :object
|
7
|
+
|
6
8
|
def pass(obj, context)
|
7
|
-
|
9
|
+
if self.opts.first.is_a? Proc
|
10
|
+
loop_condition, label = *self.opts
|
11
|
+
else
|
12
|
+
label, loop_condition, emit_condition = *self.opts
|
13
|
+
end
|
8
14
|
|
9
15
|
anchor_pipe = self;
|
10
16
|
case label
|
@@ -18,11 +24,16 @@ module RedGrape
|
|
18
24
|
raise 'label should be an integer or a string.'
|
19
25
|
end
|
20
26
|
context.loops += 1
|
21
|
-
|
27
|
+
it = LoopContext.new context.loops, context.history, obj
|
28
|
+
if context.eval :it => it, &loop_condition
|
22
29
|
obj.pass_through anchor_pipe, context
|
23
30
|
else
|
24
31
|
context.loops = 1
|
25
|
-
|
32
|
+
if emit_condition && !context.eval(:it => it, &emit_condition)
|
33
|
+
nil
|
34
|
+
else
|
35
|
+
pass_next context, nil, obj
|
36
|
+
end
|
26
37
|
end
|
27
38
|
end
|
28
39
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'red_grape/pipe/base'
|
2
|
+
|
3
|
+
module RedGrape
|
4
|
+
module Pipe
|
5
|
+
module OutV
|
6
|
+
def out_v(*opts)
|
7
|
+
OutVPipe.new self, *opts
|
8
|
+
end
|
9
|
+
alias outV out_v
|
10
|
+
end
|
11
|
+
|
12
|
+
class OutVPipe < Pipe::Base
|
13
|
+
def pass(obj, context)
|
14
|
+
source = obj.source
|
15
|
+
pass_next context, obj, source
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'red_grape/pipe/base'
|
2
|
+
|
3
|
+
module RedGrape
|
4
|
+
module Pipe
|
5
|
+
module Underscore
|
6
|
+
def _(*opts)
|
7
|
+
UnderscorePipe.new self.dup, *opts#
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class UnderscorePipe < Pipe::Base
|
12
|
+
def pass(obj, context)
|
13
|
+
obj.pass_through self.next, context
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
require 'red_grape'
|
3
|
+
|
4
|
+
module RedGrape
|
5
|
+
module Tools
|
6
|
+
class GraphStore
|
7
|
+
DEFAULT_PORT = 28282
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def start(port=nil, filename=nil, &block)
|
11
|
+
self.new(filename).start port, &block
|
12
|
+
end
|
13
|
+
|
14
|
+
def uri(port=nil)
|
15
|
+
"druby://localhost:#{port || DEFAULT_PORT}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def open(port=nil)
|
19
|
+
DRbObject.new_with_uri(uri port)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(filename=nil)
|
24
|
+
@filename = filename
|
25
|
+
@graphs =
|
26
|
+
if @filename && File.exist?(@filename)
|
27
|
+
File.open @filename, 'r' do |file|
|
28
|
+
Marshal.load file
|
29
|
+
end
|
30
|
+
else
|
31
|
+
{tinker:RedGrape::Graph.create_tinker_graph}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def graphs
|
36
|
+
@graphs.keys.sort
|
37
|
+
end
|
38
|
+
|
39
|
+
def graph(key)
|
40
|
+
self[key]
|
41
|
+
end
|
42
|
+
|
43
|
+
def put_graph(key, graph)
|
44
|
+
self[key] = graph
|
45
|
+
end
|
46
|
+
|
47
|
+
def [](key)
|
48
|
+
@graphs[key.to_sym]
|
49
|
+
end
|
50
|
+
|
51
|
+
def []=(key, graph)
|
52
|
+
@graphs[key.to_sym] = graph
|
53
|
+
end
|
54
|
+
|
55
|
+
def start(port=nil, &block)
|
56
|
+
at_exit do
|
57
|
+
File.open @filename, 'w' do |file|
|
58
|
+
Marshal.dump @graphs, file
|
59
|
+
end if @filename
|
60
|
+
end
|
61
|
+
|
62
|
+
DRb.start_service self.class.uri(port), self
|
63
|
+
block.call if block
|
64
|
+
sleep
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
require 'irb'
|
3
|
+
require 'irb/completion'
|
4
|
+
require 'red_grape'
|
5
|
+
require 'red_grape/tools/graph_store'
|
6
|
+
|
7
|
+
module RedGrape
|
8
|
+
module Tools
|
9
|
+
class IRG
|
10
|
+
module Help
|
11
|
+
module_function
|
12
|
+
def redgrape?(key=nil)
|
13
|
+
case key
|
14
|
+
when NilClass
|
15
|
+
puts help_message
|
16
|
+
:OK
|
17
|
+
when 'pipe', 'pipes', :pipe, :pieps
|
18
|
+
puts pipe_help_message
|
19
|
+
:OK
|
20
|
+
else
|
21
|
+
puts '?'
|
22
|
+
:NG
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def help_message
|
27
|
+
<<-EOS
|
28
|
+
Subcommands:
|
29
|
+
redgrape? :pipe : list all pipes.
|
30
|
+
EOS
|
31
|
+
#redgrape? '[pipe name]' : describe the given pipe.
|
32
|
+
end
|
33
|
+
|
34
|
+
def pipe_help_message
|
35
|
+
pipes = RedGrape::Pipe.constants.map(&:to_s).select{|p|
|
36
|
+
p =~ /.*Pipe$/}.map{|p| underscore p.sub(/Pipe$/, '')}
|
37
|
+
"Available pipes:\n #{pipes.sort.join ', '}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def underscore(str)
|
41
|
+
str.sub(/^[A-Z]/){|p| p.downcase}.gsub(/([a-z])([A-Z])/){"#{$1}_#{$2.downcase}"}
|
42
|
+
end
|
43
|
+
|
44
|
+
def camelcase(str)
|
45
|
+
str.sub(/^[a-z]/){|p| p.upcase}.gsub(/_([a-z])/){"#{$1.upcase}"}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class << self
|
50
|
+
def start(port=nil, &block)
|
51
|
+
self.new.start port, &block
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def start(port=nil, &block)
|
56
|
+
Kernel.module_eval %Q{
|
57
|
+
def redgrape?(key=nil)
|
58
|
+
RedGrape::IRG::Help.redgrape? key
|
59
|
+
end
|
60
|
+
alias rg? redgrape?
|
61
|
+
}
|
62
|
+
|
63
|
+
RedGrape.set_auto_take
|
64
|
+
$store = RedGrape::Tools::GraphStore.open port if port
|
65
|
+
block.call if block
|
66
|
+
IRB.start
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/red_grape/version.rb
CHANGED
data/lib/red_grape/vertex.rb
CHANGED
data/lib/red_grape.rb
CHANGED
@@ -2,26 +2,30 @@ require 'ext/nil_class_ext'
|
|
2
2
|
require 'ext/object_ext'
|
3
3
|
require 'ext/array_ext'
|
4
4
|
require 'red_grape/version'
|
5
|
-
require 'red_grape/pipe/
|
6
|
-
require 'red_grape/pipe/
|
7
|
-
require 'red_grape/pipe/
|
8
|
-
require 'red_grape/pipe/
|
5
|
+
require 'red_grape/pipe/aggregate_pipe'
|
6
|
+
require 'red_grape/pipe/as_pipe'
|
7
|
+
require 'red_grape/pipe/back_pipe'
|
8
|
+
require 'red_grape/pipe/cap_pipe'
|
9
|
+
require 'red_grape/pipe/copy_split_pipe'
|
10
|
+
require 'red_grape/pipe/except_pipe'
|
11
|
+
require 'red_grape/pipe/exhaust_merge_pipe'
|
12
|
+
require 'red_grape/pipe/fill_pipe'
|
9
13
|
require 'red_grape/pipe/filter_pipe'
|
10
|
-
require 'red_grape/pipe/
|
11
|
-
require 'red_grape/pipe/
|
14
|
+
require 'red_grape/pipe/group_count_pipe'
|
15
|
+
require 'red_grape/pipe/has_pipe'
|
12
16
|
require 'red_grape/pipe/if_then_else_pipe'
|
13
|
-
require 'red_grape/pipe/
|
14
|
-
require 'red_grape/pipe/
|
17
|
+
require 'red_grape/pipe/in_pipe'
|
18
|
+
require 'red_grape/pipe/in_e_pipe'
|
19
|
+
require 'red_grape/pipe/in_v_pipe'
|
15
20
|
require 'red_grape/pipe/loop_pipe'
|
16
|
-
require 'red_grape/pipe/
|
21
|
+
require 'red_grape/pipe/out_pipe'
|
17
22
|
require 'red_grape/pipe/out_e_pipe'
|
18
|
-
require 'red_grape/pipe/
|
19
|
-
require 'red_grape/pipe/
|
20
|
-
require 'red_grape/pipe/
|
23
|
+
require 'red_grape/pipe/out_v_pipe'
|
24
|
+
require 'red_grape/pipe/property_pipe'
|
25
|
+
require 'red_grape/pipe/paths_pipe'
|
21
26
|
require 'red_grape/pipe/retain_pipe'
|
22
|
-
require 'red_grape/pipe/
|
23
|
-
require 'red_grape/pipe/
|
24
|
-
require 'red_grape/pipe/cap_pipe'
|
27
|
+
require 'red_grape/pipe/side_effect_pipe'
|
28
|
+
require 'red_grape/pipe/transform_pipe'
|
25
29
|
require 'red_grape/pipe/v_pipe'
|
26
30
|
require 'red_grape/pipe/e_pipe'
|
27
31
|
require 'red_grape/graph'
|
data/test/test_graph.rb
CHANGED
@@ -138,6 +138,13 @@ class GraphTest < Test::Unit::TestCase
|
|
138
138
|
assert v3.in_edges.map(&:id).include?(e23.id)
|
139
139
|
end
|
140
140
|
|
141
|
+
def test_auto_index
|
142
|
+
g = RedGrape::Graph.new
|
143
|
+
g.add_vertex RedGrape::Graph::UID, name:'ando'
|
144
|
+
assert_equal 1, g.vertex.size
|
145
|
+
assert_not_nil g.vertex.first.id
|
146
|
+
end
|
147
|
+
|
141
148
|
def test_remove_edge
|
142
149
|
g = RedGrape::Graph.new
|
143
150
|
v1 = g.add_vertex 1
|
@@ -85,5 +85,16 @@ class TraversalPatternsTest < Test::Unit::TestCase
|
|
85
85
|
assert_equal RedGrape::Vertex, path[2].class
|
86
86
|
assert_equal RedGrape::Edge, path[3].class
|
87
87
|
assert_equal RedGrape::Vertex, path[4].class
|
88
|
+
|
89
|
+
#assert_equal 70307, v89.out.loop(1, proc{it.loops < 4}).take.size #=> OK
|
90
|
+
#assert_equal 71972, v89.out.loop(1, proc{it.loops < 4}, proc{true}).take.size #=> 70307
|
91
|
+
#assert_equal 582, v89.out.loop(1, proc{it.loops < 4}, proc{it.object.id == '89'}).take.size #=> 564
|
92
|
+
end
|
93
|
+
|
94
|
+
# https://github.com/tinkerpop/gremlin/wiki/Split-Merge-Pattern
|
95
|
+
def test_split_marge
|
96
|
+
v1 = @graph.vertex 1
|
97
|
+
#assert_equal ['ripple', 27, 'lop', 32], v1.out('knows').copy_split(_.out('created').name, _.age).fair_merge.take # TODO: not yet
|
98
|
+
assert_equal [27, 'ripple', 'lop', 32], v1.out('knows').copy_split(_.out('created').name, _.age).exhaust_merge.take
|
88
99
|
end
|
89
100
|
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.8
|
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-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &70196102597160 !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: *70196102597160
|
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.
|
@@ -49,8 +49,6 @@ files:
|
|
49
49
|
- lib/red_grape/edge.rb
|
50
50
|
- lib/red_grape/element.rb
|
51
51
|
- lib/red_grape/graph.rb
|
52
|
-
- lib/red_grape/graph_store.rb
|
53
|
-
- lib/red_grape/irg.rb
|
54
52
|
- lib/red_grape/path_group.rb
|
55
53
|
- lib/red_grape/pipe/aggregate_pipe.rb
|
56
54
|
- lib/red_grape/pipe/as_pipe.rb
|
@@ -58,26 +56,33 @@ files:
|
|
58
56
|
- lib/red_grape/pipe/base.rb
|
59
57
|
- lib/red_grape/pipe/cap_pipe.rb
|
60
58
|
- lib/red_grape/pipe/context.rb
|
59
|
+
- lib/red_grape/pipe/copy_split_pipe.rb
|
61
60
|
- lib/red_grape/pipe/e_pipe.rb
|
62
61
|
- lib/red_grape/pipe/except_pipe.rb
|
62
|
+
- lib/red_grape/pipe/exhaust_merge_pipe.rb
|
63
63
|
- lib/red_grape/pipe/fill_pipe.rb
|
64
64
|
- lib/red_grape/pipe/filter_pipe.rb
|
65
65
|
- lib/red_grape/pipe/group_count_pipe.rb
|
66
66
|
- lib/red_grape/pipe/has_pipe.rb
|
67
67
|
- lib/red_grape/pipe/if_then_else_pipe.rb
|
68
|
+
- lib/red_grape/pipe/in_e_pipe.rb
|
68
69
|
- lib/red_grape/pipe/in_pipe.rb
|
69
70
|
- lib/red_grape/pipe/in_v_pipe.rb
|
70
71
|
- lib/red_grape/pipe/loop_pipe.rb
|
71
72
|
- lib/red_grape/pipe/out_e_pipe.rb
|
72
73
|
- lib/red_grape/pipe/out_pipe.rb
|
74
|
+
- lib/red_grape/pipe/out_v_pipe.rb
|
73
75
|
- lib/red_grape/pipe/paths_pipe.rb
|
74
76
|
- lib/red_grape/pipe/property_pipe.rb
|
75
77
|
- lib/red_grape/pipe/retain_pipe.rb
|
76
78
|
- lib/red_grape/pipe/side_effect_pipe.rb
|
77
79
|
- lib/red_grape/pipe/transform_pipe.rb
|
80
|
+
- lib/red_grape/pipe/underscore_pipe.rb
|
78
81
|
- lib/red_grape/pipe/v_pipe.rb
|
79
82
|
- lib/red_grape/property_description.rb
|
80
83
|
- lib/red_grape/serializer/graphml_serializer.rb
|
84
|
+
- lib/red_grape/tools/graph_store.rb
|
85
|
+
- lib/red_grape/tools/irg.rb
|
81
86
|
- lib/red_grape/version.rb
|
82
87
|
- lib/red_grape/vertex.rb
|
83
88
|
- red_grape.gemspec
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'drb/drb'
|
2
|
-
require 'red_grape'
|
3
|
-
|
4
|
-
module RedGrape
|
5
|
-
class GraphStore
|
6
|
-
DEFAULT_PORT = 28282
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def start(port=nil, filename=nil, &block)
|
10
|
-
self.new(filename).start port, &block
|
11
|
-
end
|
12
|
-
|
13
|
-
def uri(port=nil)
|
14
|
-
"druby://localhost:#{port || DEFAULT_PORT}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def open(port=nil)
|
18
|
-
DRbObject.new_with_uri(uri port)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(filename=nil)
|
23
|
-
@filename = filename
|
24
|
-
@graphs =
|
25
|
-
if @filename && File.exist?(@filename)
|
26
|
-
File.open @filename, 'r' do |file|
|
27
|
-
Marshal.load file
|
28
|
-
end
|
29
|
-
else
|
30
|
-
{tinker:RedGrape::Graph.create_tinker_graph}
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def graphs
|
35
|
-
@graphs.keys.sort
|
36
|
-
end
|
37
|
-
|
38
|
-
def graph(key)
|
39
|
-
self[key]
|
40
|
-
end
|
41
|
-
|
42
|
-
def put_graph(key, graph)
|
43
|
-
self[key] = graph
|
44
|
-
end
|
45
|
-
|
46
|
-
def [](key)
|
47
|
-
@graphs[key.to_sym]
|
48
|
-
end
|
49
|
-
|
50
|
-
def []=(key, graph)
|
51
|
-
@graphs[key.to_sym] = graph
|
52
|
-
end
|
53
|
-
|
54
|
-
def start(port=nil, &block)
|
55
|
-
at_exit do
|
56
|
-
File.open @filename, 'w' do |file|
|
57
|
-
Marshal.dump @graphs, file
|
58
|
-
end if @filename
|
59
|
-
end
|
60
|
-
|
61
|
-
DRb.start_service self.class.uri(port), self
|
62
|
-
block.call if block
|
63
|
-
sleep
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
data/lib/red_grape/irg.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
require 'drb/drb'
|
2
|
-
require 'irb'
|
3
|
-
require 'irb/completion'
|
4
|
-
require 'red_grape'
|
5
|
-
require 'red_grape/graph_store'
|
6
|
-
|
7
|
-
module RedGrape
|
8
|
-
class IRG
|
9
|
-
module Help
|
10
|
-
module_function
|
11
|
-
def redgrape?(key=nil)
|
12
|
-
case key
|
13
|
-
when NilClass
|
14
|
-
puts help_message
|
15
|
-
:OK
|
16
|
-
when 'pipe', 'pipes', :pipe, :pieps
|
17
|
-
puts pipe_help_message
|
18
|
-
:OK
|
19
|
-
else
|
20
|
-
puts '?'
|
21
|
-
:NG
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def help_message
|
26
|
-
<<-EOS
|
27
|
-
Subcommands:
|
28
|
-
redgrape? :pipe : list all pipes.
|
29
|
-
EOS
|
30
|
-
#redgrape? '[pipe name]' : describe the given pipe.
|
31
|
-
end
|
32
|
-
|
33
|
-
def pipe_help_message
|
34
|
-
pipes = RedGrape::Pipe.constants.map(&:to_s).select{|p|
|
35
|
-
p =~ /.*Pipe$/}.map{|p| underscore p.sub(/Pipe$/, '')}
|
36
|
-
"Available pipes:\n #{pipes.sort.join ', '}"
|
37
|
-
end
|
38
|
-
|
39
|
-
def underscore(str)
|
40
|
-
str.sub(/^[A-Z]/){|p| p.downcase}.gsub(/([a-z])([A-Z])/){"#{$1}_#{$2.downcase}"}
|
41
|
-
end
|
42
|
-
|
43
|
-
def camelcase(str)
|
44
|
-
str.sub(/^[a-z]/){|p| p.upcase}.gsub(/_([a-z])/){"#{$1.upcase}"}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class << self
|
49
|
-
def start(port=nil, &block)
|
50
|
-
self.new.start port, &block
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def start(port=nil, &block)
|
55
|
-
Kernel.module_eval %Q{
|
56
|
-
def redgrape?(key=nil)
|
57
|
-
RedGrape::IRG::Help.redgrape? key
|
58
|
-
end
|
59
|
-
alias rg? redgrape?
|
60
|
-
}
|
61
|
-
|
62
|
-
RedGrape.set_auto_take
|
63
|
-
$store = RedGrape::GraphStore.open port if port
|
64
|
-
block.call if block
|
65
|
-
IRB.start
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|