graphable 0.0.5 → 0.1.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.
- data/graphable.gemspec +2 -2
- data/lib/graphable.rb +31 -5
- data/lib/graphable/edge_creator.rb +35 -22
- data/lib/graphable/index_creator.rb +7 -5
- data/lib/graphable/node_creator.rb +7 -4
- data/lib/graphable/version.rb +1 -1
- metadata +19 -7
data/graphable.gemspec
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
require File.expand_path('../lib/graphable/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Joe Fredette"]
|
6
|
-
gem.email = ["jfredett@gmail.com"]
|
5
|
+
gem.authors = ["Joe Fredette", "Andrew Ross"]
|
6
|
+
gem.email = ["jfredett@gmail.com", "andrewslavinross@gmail.com"]
|
7
7
|
gem.description = %q{A library for extracting static graph representations of data from rails-y databases}
|
8
8
|
gem.summary = %q{A library for extracting static graph representations of data from rails-y databases}
|
9
9
|
gem.homepage = "http://www.github.com/jfredett/graphable"
|
data/lib/graphable.rb
CHANGED
@@ -10,7 +10,7 @@ module Graphable
|
|
10
10
|
|
11
11
|
included do
|
12
12
|
Graphable.register NodeCreator.new(self)
|
13
|
-
|
13
|
+
graph_indexes :id
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.register(registrant)
|
@@ -26,7 +26,7 @@ module Graphable
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.build!
|
29
|
-
puts "Building Graph"
|
29
|
+
puts "Building Graph..."
|
30
30
|
registry.select { |f| f.is_a? NodeCreator }.map(&:call)
|
31
31
|
registry.select { |f| f.is_a? IndexCreator }.map(&:call)
|
32
32
|
registry.select { |f| f.is_a? EdgeCreator }.map(&:call)
|
@@ -41,6 +41,18 @@ module Graphable
|
|
41
41
|
@completed_indicies ||= {}
|
42
42
|
end
|
43
43
|
|
44
|
+
def self.object_access_methods
|
45
|
+
@object_access_methods ||= {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.objects_of(klass)
|
49
|
+
klass.send(object_access_methods[klass] || 'all')
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.register_object_access_method(klass, method)
|
53
|
+
object_access_methods[klass] = method
|
54
|
+
end
|
55
|
+
|
44
56
|
def self.completed_index(klass, method)
|
45
57
|
completed_indicies[[klass, method]] = true
|
46
58
|
end
|
@@ -49,23 +61,33 @@ module Graphable
|
|
49
61
|
completed_indicies[[klass,method]]
|
50
62
|
end
|
51
63
|
|
64
|
+
def self.completed_edges
|
65
|
+
@completed_edges ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.completed_edge(source, target, name)
|
69
|
+
completed_edges[[source,target,name]] = true
|
70
|
+
end
|
52
71
|
|
72
|
+
def self.has_completed_edge?(source, target, name)
|
73
|
+
completed_edges[[source,target,name]]
|
74
|
+
end
|
53
75
|
|
54
76
|
module InstanceMethods
|
55
77
|
def to_node
|
56
78
|
attributes.to_hash.tap do |hash|
|
57
|
-
hash.each { |k,
|
79
|
+
hash.each { |k, v| hash.delete(k) if v.nil? || k.to_s =~ /_id$/ } #remove FKs and nil values
|
58
80
|
hash[:type] = self.class.name
|
59
81
|
end
|
60
82
|
end
|
61
83
|
end
|
62
84
|
|
63
85
|
module ClassMethods
|
64
|
-
def
|
86
|
+
def graph_index_name
|
65
87
|
"#{name.downcase.pluralize}_index"
|
66
88
|
end
|
67
89
|
|
68
|
-
def
|
90
|
+
def graph_indexes(*methods)
|
69
91
|
methods.each do |method|
|
70
92
|
Graphable.register IndexCreator.new(self, method)
|
71
93
|
end
|
@@ -83,6 +105,10 @@ module Graphable
|
|
83
105
|
raise "Invalid Edge type, must be :through or :via"
|
84
106
|
end
|
85
107
|
end
|
108
|
+
|
109
|
+
def graph_with(method)
|
110
|
+
Graphable.register_object_access_method(self, method)
|
111
|
+
end
|
86
112
|
end
|
87
113
|
|
88
114
|
end
|
@@ -35,11 +35,11 @@ module Graphable
|
|
35
35
|
# anyway.
|
36
36
|
metadata.reject! { |_,v| v.nil? }
|
37
37
|
|
38
|
-
|
38
|
+
Graphable.neo.create_relationship(@name, source_node, target_node, metadata)
|
39
39
|
end
|
40
40
|
|
41
41
|
def sources
|
42
|
-
@source
|
42
|
+
Graphable.objects_of(@source)
|
43
43
|
end
|
44
44
|
|
45
45
|
def target_name
|
@@ -49,21 +49,26 @@ module Graphable
|
|
49
49
|
|
50
50
|
class ThroughEdgeCreator < EdgeCreator
|
51
51
|
def call
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
return if Graphable.has_completed_edge?(@source, @target, @name)
|
53
|
+
|
54
|
+
puts "Building #{@name} edges for #{@source.name} -> #{@target.name}"
|
55
|
+
sources.each_slice(250) do |slice|
|
56
|
+
Graphable.neo.batch(*slice.map { |obj|
|
57
|
+
source_node = load_node(obj)
|
58
|
+
relationships = []
|
59
|
+
intermediates_for(obj).each do |intermediate_target|
|
60
|
+
metadata = {}
|
58
61
|
metadata = @metadata_proc.call(intermediate_target) if @metadata_proc
|
59
62
|
metadata = intermediate_target.send(:edge_metadata) if intermediate_target.respond_to?(:edge_metadata)
|
60
|
-
|
61
63
|
target_node = load_node(intermediate_target.send(target_name)) rescue binding.pry
|
62
|
-
|
63
|
-
|
64
|
+
next unless source_node && target_node
|
65
|
+
relationships << [:create_relationship, @name, source_node, target_node, metadata || {}]
|
64
66
|
end
|
65
|
-
|
67
|
+
relationships
|
68
|
+
}.flatten(1))
|
66
69
|
end
|
70
|
+
|
71
|
+
Graphable.completed_edge(@source, @target, @name)
|
67
72
|
end
|
68
73
|
|
69
74
|
def targets_for(source)
|
@@ -79,17 +84,25 @@ module Graphable
|
|
79
84
|
|
80
85
|
class ViaEdgeCreator < EdgeCreator
|
81
86
|
def call
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
return if Graphable.has_completed_edge?(@source, @target, @name)
|
88
|
+
|
89
|
+
puts "Building #{@name} edges for #{@source.name} -> #{@target.name}"
|
90
|
+
sources.each_slice(250) do |slice|
|
91
|
+
Graphable.neo.batch(*slice.map { |obj|
|
92
|
+
source_node = load_node(obj)
|
93
|
+
relationships = []
|
94
|
+
targets_for(obj).each do |target|
|
95
|
+
metadata = {}
|
96
|
+
metadata = @metadata_proc.call(target) if @metadata_proc
|
97
|
+
target_node = load_node(target) rescue binding.pry
|
98
|
+
next unless source_node && target_node
|
99
|
+
relationships << [:create_relationship, @name, source_node, target_node, metadata]
|
100
|
+
end
|
101
|
+
relationships
|
102
|
+
}.flatten(1))
|
92
103
|
end
|
104
|
+
|
105
|
+
Graphable.completed_edge(@source, @target, @name)
|
93
106
|
end
|
94
107
|
|
95
108
|
def targets_for(source)
|
@@ -3,7 +3,7 @@ module Graphable
|
|
3
3
|
extend Forwardable
|
4
4
|
|
5
5
|
attr_reader :klass
|
6
|
-
delegate [:name, :
|
6
|
+
delegate [:name, :graph_index_name] => :@klass
|
7
7
|
|
8
8
|
def initialize(klass, method)
|
9
9
|
@klass = klass
|
@@ -13,11 +13,13 @@ module Graphable
|
|
13
13
|
def call
|
14
14
|
return if Graphable.has_indexed?(@klass, @method)
|
15
15
|
|
16
|
-
puts "Building index for #{name}"
|
17
|
-
Graphable.neo.create_node_index(
|
16
|
+
puts "Building #{@method} index for #{name}"
|
17
|
+
Graphable.neo.create_node_index(graph_index_name, 'exact') # fulltext
|
18
18
|
|
19
|
-
|
20
|
-
Graphable.neo.
|
19
|
+
Graphable.objects_of(@klass).each_slice(250) do |slice|
|
20
|
+
Graphable.neo.batch(*slice.map do |obj|
|
21
|
+
[:add_node_to_index, graph_index_name, @method, obj.send(@method), Graphable.index_cache[obj]]
|
22
|
+
end)
|
21
23
|
end
|
22
24
|
|
23
25
|
Graphable.completed_index(@klass, @method)
|
@@ -5,7 +5,7 @@ module Graphable
|
|
5
5
|
extend Forwardable
|
6
6
|
|
7
7
|
attr_reader :klass
|
8
|
-
delegate [:name
|
8
|
+
delegate [:name] => :@klass
|
9
9
|
|
10
10
|
def initialize(klass)
|
11
11
|
@klass = klass
|
@@ -13,9 +13,12 @@ module Graphable
|
|
13
13
|
|
14
14
|
def call
|
15
15
|
puts "Building nodes for #{name}"
|
16
|
-
|
17
|
-
slice.
|
18
|
-
|
16
|
+
Graphable.objects_of(@klass).each_slice(250) do |slice|
|
17
|
+
nodes = Graphable.neo.batch(*slice.map do |obj|
|
18
|
+
[:create_node, obj.to_node]
|
19
|
+
end)
|
20
|
+
slice.zip(nodes).each do |object, node|
|
21
|
+
Graphable.index_cache[object] = node["body"]
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
data/lib/graphable/version.rb
CHANGED
metadata
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Joe Fredette
|
9
|
+
- Andrew Ross
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2012-
|
13
|
+
date: 2012-08-15 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: activesupport
|
16
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
17
18
|
none: false
|
18
19
|
requirements:
|
19
20
|
- - ~>
|
@@ -21,10 +22,15 @@ dependencies:
|
|
21
22
|
version: '3.1'
|
22
23
|
type: :runtime
|
23
24
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '3.1'
|
25
31
|
- !ruby/object:Gem::Dependency
|
26
32
|
name: neography
|
27
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
28
34
|
none: false
|
29
35
|
requirements:
|
30
36
|
- - ! '>='
|
@@ -32,11 +38,17 @@ dependencies:
|
|
32
38
|
version: '0'
|
33
39
|
type: :runtime
|
34
40
|
prerelease: false
|
35
|
-
version_requirements:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
36
47
|
description: A library for extracting static graph representations of data from rails-y
|
37
48
|
databases
|
38
49
|
email:
|
39
50
|
- jfredett@gmail.com
|
51
|
+
- andrewslavinross@gmail.com
|
40
52
|
executables: []
|
41
53
|
extensions: []
|
42
54
|
extra_rdoc_files: []
|
@@ -72,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
84
|
version: '0'
|
73
85
|
requirements: []
|
74
86
|
rubyforge_project:
|
75
|
-
rubygems_version: 1.8.
|
87
|
+
rubygems_version: 1.8.18
|
76
88
|
signing_key:
|
77
89
|
specification_version: 3
|
78
90
|
summary: A library for extracting static graph representations of data from rails-y
|