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.
@@ -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"
@@ -10,7 +10,7 @@ module Graphable
10
10
 
11
11
  included do
12
12
  Graphable.register NodeCreator.new(self)
13
- indexes :id
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, _| hash.delete(k) if k.to_s =~ /_id$/ } #remove FKs
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 index_name
86
+ def graph_index_name
65
87
  "#{name.downcase.pluralize}_index"
66
88
  end
67
89
 
68
- def indexes(*methods)
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
- Neography::Relationship.create(@name, source_node, target_node, metadata)
38
+ Graphable.neo.create_relationship(@name, source_node, target_node, metadata)
39
39
  end
40
40
 
41
41
  def sources
42
- @source.all
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
- puts "Building edges for #{@source.name} -> #{@target.name}"
53
- sources.each_slice(100) do |slice|
54
- slice.each do |source|
55
- source_node = load_node(source)
56
-
57
- intermediates_for(source).each do |intermediate_target|
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
- build_relationship(source_node, target_node, metadata || {})
64
+ next unless source_node && target_node
65
+ relationships << [:create_relationship, @name, source_node, target_node, metadata || {}]
64
66
  end
65
- end
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
- puts "Building edges for #{@source.name} -> #{@target.name}"
83
- sources.each do |source|
84
- source_node = load_node(source)
85
-
86
- targets_for(source).each do |target|
87
- metadata = @metadata_proc.call(target) if @metadata_proc
88
-
89
- target_node = load_node(target) rescue binding.pry
90
- build_relationship(source_node, target_node, metadata || {})
91
- end
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, :all, :index_name] => :@klass
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(index_name, 'fulltext')
16
+ puts "Building #{@method} index for #{name}"
17
+ Graphable.neo.create_node_index(graph_index_name, 'exact') # fulltext
18
18
 
19
- all.to_a.each do |object|
20
- Graphable.neo.add_node_to_index(index_name, @method, object.send(@method), Graphable.index_cache[object])
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, :all] => :@klass
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
- all.each_slice(100) do |slice|
17
- slice.each do |object|
18
- Graphable.index_cache[object] = Neography::Node.create(object.to_node)
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
@@ -1,3 +1,3 @@
1
1
  module Graphable
2
- VERSION = "0.0.5"
2
+ VERSION = "0.1.0"
3
3
  end
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.5
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-04-04 00:00:00.000000000 Z
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: &2156110660 !ruby/object:Gem::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: *2156110660
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: &2156109400 !ruby/object:Gem::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: *2156109400
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.17
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