neoid 0.1.2 → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  module Neoid
2
2
  class NeoDatabaseCleaner
3
- def self.clean_db(start_node = Neoid.db.get_root)
3
+ def self.clean_db()
4
4
  Neoid.db.execute_script <<-GREMLIN
5
5
  g.V.toList().each { if (it.id != 0) g.removeVertex(it) }
6
6
  g.indices.each { g.dropIndex(it.indexName); }
@@ -1,4 +1,4 @@
1
- module Ndoid
1
+ module Neoid
2
2
  class Middleware
3
3
  def initialize(app)
4
4
  @app = app
@@ -2,11 +2,11 @@ module Neoid
2
2
  module ModelAdditions
3
3
  module ClassMethods
4
4
  attr_reader :neoid_config
5
-
5
+
6
6
  def neoid_config
7
7
  @neoid_config ||= Neoid::ModelConfig.new(self)
8
8
  end
9
-
9
+
10
10
  def neoidable(options = {})
11
11
  # defaults
12
12
  neoid_config.auto_index = true
@@ -15,17 +15,17 @@ module Neoid
15
15
  yield(neoid_config) if block_given?
16
16
 
17
17
  options.each do |key, value|
18
- raise "Neoid #{self.name} model options: No such option #{key}" unless neoid_config.respond_to?("#{key}=")
18
+ raise "Neoid #{name} model options: No such option #{key}" unless neoid_config.respond_to?("#{key}=")
19
19
  neoid_config.send("#{key}=", value)
20
20
  end
21
21
  end
22
22
 
23
23
  def neo_model_index_name
24
- raise "Per Model index is not enabled. Nodes/Relationships are auto indexed with node_auto_index/relationship_auto_index" unless Neoid.config.enable_per_model_indexes || neoid_config.enable_model_index
25
- @index_name ||= "#{self.name.tableize}_index"
24
+ raise 'Per Model index is not enabled. Nodes/Relationships are auto indexed with node_auto_index/relationship_auto_index' unless Neoid.config.enable_per_model_indexes || neoid_config.enable_model_index
25
+ @index_name ||= "#{name.tableize}_index"
26
26
  end
27
27
  end
28
-
28
+
29
29
  module InstanceMethods
30
30
  def to_neo
31
31
  if self.class.neoid_config.stored_fields
@@ -33,9 +33,9 @@ module Neoid
33
33
  all[field] = if block
34
34
  instance_eval(&block)
35
35
  else
36
- self.send(field) rescue (raise "No field #{field} for #{self.class.name}")
36
+ send(field) rescue (raise "No field #{field} for #{self.class.name}")
37
37
  end
38
-
38
+
39
39
  all
40
40
  end
41
41
 
@@ -69,7 +69,7 @@ module Neoid
69
69
  begin
70
70
  neo_representation.del
71
71
  rescue Neography::NodeNotFoundException => e
72
- Neoid::logger.info "Neoid#neo_destroy entity not found #{self.class.name} #{self.id}"
72
+ Neoid::logger.info "Neoid#neo_destroy entity not found #{self.class.name} #{id}"
73
73
  end
74
74
 
75
75
  # Not working yet because Neography can't delete a node and all of its realtionships in a batch, and deleting a node with relationships results an error
@@ -89,18 +89,20 @@ module Neoid
89
89
  end
90
90
 
91
91
  def neo_unique_id
92
- "#{self.class.name}:#{self.id}"
92
+ "#{self.class.name}:#{id}"
93
93
  end
94
94
 
95
95
  protected
96
+
96
97
  def neo_properties_to_hash(*attribute_list)
97
98
  attribute_list.flatten.inject({}) { |all, property|
98
- all[property] = self.send(property)
99
+ all[property] = send(property)
99
100
  all
100
101
  }
101
102
  end
102
103
 
103
104
  private
105
+
104
106
  def _neo_representation
105
107
  @_neo_representation ||= neo_find_by_id || neo_save
106
108
  end
@@ -5,34 +5,34 @@ module Neoid
5
5
  attr_reader :relationship_options
6
6
  attr_accessor :enable_model_index
7
7
  attr_accessor :auto_index
8
-
8
+
9
9
  def initialize(klass)
10
10
  @klass = klass
11
11
  end
12
-
12
+
13
13
  def stored_fields
14
14
  @stored_fields ||= {}
15
15
  end
16
-
16
+
17
17
  def field(name, &block)
18
- self.stored_fields[name] = block
18
+ stored_fields[name] = block
19
19
  end
20
-
20
+
21
21
  def relationship(options)
22
22
  @relationship_options = options
23
23
  end
24
-
24
+
25
25
  def search(&block)
26
- raise "search needs a block" unless block_given?
26
+ raise 'search needs a block' unless block_given?
27
27
  @search_options = SearchConfig.new
28
- block.(@search_options)
28
+ block.call(@search_options)
29
29
  end
30
-
30
+
31
31
  def inspect
32
32
  "#<Neoid::ModelConfig @properties=#{properties.inspect} @search_options=#{@search_options.inspect}>"
33
33
  end
34
34
  end
35
-
35
+
36
36
  class SearchConfig
37
37
  def index_fields
38
38
  @index_fields ||= {}
@@ -41,15 +41,15 @@ module Neoid
41
41
  def fulltext_fields
42
42
  @fulltext_fields ||= {}
43
43
  end
44
-
44
+
45
45
  def index(field, options = {}, &block)
46
46
  index_fields[field] = options.merge(block: block)
47
47
  end
48
-
48
+
49
49
  def fulltext(field, options = {}, &block)
50
50
  fulltext_fields[field] = options.merge(block: block)
51
51
  end
52
-
52
+
53
53
  def inspect
54
54
  "#<Neoid::SearchConfig @index_fields=#{index_fields.inspect} @fulltext_fields=#{fulltext_fields.inspect}>"
55
55
  end
@@ -6,15 +6,22 @@ module Neoid
6
6
  node
7
7
  end
8
8
 
9
+ def self.included(receiver)
10
+ receiver.send :include, Neoid::ModelAdditions
11
+ receiver.extend ClassMethods
12
+ receiver.send :include, InstanceMethods
13
+ Neoid.node_models << receiver
14
+ end
15
+
9
16
  module ClassMethods
10
17
  attr_accessor :neo_subref_node
11
18
 
12
19
  def neo_subref_rel_type
13
- @_neo_subref_rel_type ||= "#{self.name.tableize}_subref"
20
+ @_neo_subref_rel_type ||= "#{name.tableize}_subref"
14
21
  end
15
22
 
16
23
  def neo_subref_node_rel_type
17
- @_neo_subref_node_rel_type ||= self.name.tableize
24
+ @_neo_subref_node_rel_type ||= name.tableize
18
25
  end
19
26
 
20
27
  def delete_command
@@ -60,7 +67,7 @@ module Neoid
60
67
 
61
68
  script_vars = {
62
69
  neo_subref_rel_type: neo_subref_rel_type,
63
- name: self.name
70
+ name: name
64
71
  }
65
72
 
66
73
  Neoid.execute_script_or_add_to_batch gremlin_query, script_vars do |value|
@@ -77,18 +84,18 @@ module Neoid
77
84
  Neoid.search(self, term, options)
78
85
  end
79
86
  end
80
-
87
+
81
88
  module InstanceMethods
82
89
  def neo_find_by_id
83
90
  # Neoid::logger.info "Node#neo_find_by_id #{self.class.neo_index_name} #{self.id}"
84
- node = Neoid.db.get_node_auto_index(Neoid::UNIQUE_ID_KEY, self.neo_unique_id)
91
+ node = Neoid.db.get_node_auto_index(Neoid::UNIQUE_ID_KEY, neo_unique_id)
85
92
  node.present? ? Neoid::Node.from_hash(node[0]) : nil
86
93
  end
87
-
94
+
88
95
  def _neo_save
89
96
  return unless Neoid.enabled?
90
97
 
91
- data = self.to_neo.merge(ar_type: self.class.name, ar_id: self.id, Neoid::UNIQUE_ID_KEY => self.neo_unique_id)
98
+ data = to_neo.merge(ar_type: self.class.name, ar_id: id, Neoid::UNIQUE_ID_KEY => neo_unique_id)
92
99
  data.reject! { |k, v| v.nil? }
93
100
 
94
101
  gremlin_query = <<-GREMLIN
@@ -114,10 +121,10 @@ module Neoid
114
121
  node
115
122
  GREMLIN
116
123
 
117
- script_vars = {
124
+ script_vars = {
118
125
  unique_id_key: Neoid::UNIQUE_ID_KEY,
119
126
  node_data: data,
120
- unique_id: self.neo_unique_id,
127
+ unique_id: neo_unique_id,
121
128
  enable_subrefs: Neoid.config.enable_subrefs,
122
129
  enable_model_index: Neoid.config.enable_per_model_indexes && self.class.neoid_config.enable_model_index
123
130
  }
@@ -135,7 +142,7 @@ module Neoid
135
142
  )
136
143
  end
137
144
 
138
- Neoid::logger.info "Node#neo_save #{self.class.name} #{self.id}"
145
+ Neoid::logger.info "Node#neo_save #{self.class.name} #{id}"
139
146
 
140
147
  node = Neoid.execute_script_or_add_to_batch(gremlin_query, script_vars) do |value|
141
148
  @_neo_representation = Neoid::Node.from_hash(value)
@@ -171,14 +178,14 @@ module Neoid
171
178
  if options[:block]
172
179
  options[:block].call
173
180
  else
174
- self.send(field) rescue (raise "No field #{field} for #{self.class.name}")
181
+ send(field) rescue (raise "No field #{field} for #{self.class.name}")
175
182
  end
176
183
  end
177
-
184
+
178
185
  def neo_load(hash)
179
186
  Neoid::Node.from_hash(hash)
180
187
  end
181
-
188
+
182
189
  def neo_node
183
190
  _neo_representation
184
191
  end
@@ -191,7 +198,7 @@ module Neoid
191
198
  rel_model, foreign_key_of_owner, foreign_key_of_record = Neoid::Relationship.meta_data[self.class.name.to_s][record.class.name.to_s]
192
199
  rel_model = rel_model.to_s.constantize
193
200
  @__neo_temp_rels ||= {}
194
- @__neo_temp_rels[record] = rel_model.where(foreign_key_of_owner => self.id, foreign_key_of_record => record.id).first
201
+ @__neo_temp_rels[record] = rel_model.where(foreign_key_of_owner => id, foreign_key_of_record => record.id).first
195
202
  end
196
203
 
197
204
  def neo_after_relationship_through_remove(record)
@@ -199,12 +206,5 @@ module Neoid
199
206
  @__neo_temp_rels.delete(record)
200
207
  end
201
208
  end
202
-
203
- def self.included(receiver)
204
- receiver.send :include, Neoid::ModelAdditions
205
- receiver.extend ClassMethods
206
- receiver.send :include, InstanceMethods
207
- Neoid.node_models << receiver
208
- end
209
209
  end
210
210
  end
@@ -2,7 +2,7 @@ require 'neoid/middleware'
2
2
 
3
3
  module Neoid
4
4
  class Railtie < Rails::Railtie
5
- initializer "neoid.configure_rails_initialization" do
5
+ initializer 'neoid.configure_rails_initialization' do
6
6
  config.after_initialize do
7
7
  Neoid.initialize_all
8
8
  end
@@ -1,5 +1,70 @@
1
1
  module Neoid
2
2
  module Relationship
3
+ class << self
4
+ def from_hash(hash)
5
+ relationship = RelationshipLazyProxy.new(hash)
6
+
7
+ relationship
8
+ end
9
+
10
+ def included(receiver)
11
+ receiver.send :include, Neoid::ModelAdditions
12
+ receiver.send :include, InstanceMethods
13
+ receiver.extend ClassMethods
14
+
15
+ initialize_relationship receiver if Neoid.env_loaded
16
+
17
+ Neoid.relationship_models << receiver
18
+ end
19
+
20
+ def meta_data
21
+ @meta_data ||= {}
22
+ end
23
+
24
+ def initialize_relationship(rel_model)
25
+ rel_model.reflect_on_all_associations(:belongs_to).each do |belongs_to|
26
+ return if belongs_to.options[:polymorphic]
27
+
28
+ # e.g. all has_many on User class
29
+ all_has_many = belongs_to.klass.reflect_on_all_associations(:has_many)
30
+
31
+ # has_many (without through) on the side of the relationship that removes a relationship. e.g. User has_many :likes
32
+ this_has_many = all_has_many.find { |o| o.klass == rel_model }
33
+ next unless this_has_many
34
+
35
+ # e.g. User has_many :likes, after_remove: ...
36
+ full_callback_name = "after_remove_for_#{this_has_many.name}"
37
+ belongs_to.klass.send(full_callback_name) << :neo_after_relationship_remove if belongs_to.klass.method_defined?(full_callback_name)
38
+
39
+ # has_many (with through) on the side of the relationship that removes a relationship. e.g. User has_many :movies, through :likes
40
+ many_to_many = all_has_many.find { |o| o.options[:through] == this_has_many.name }
41
+ next unless many_to_many
42
+
43
+ return if many_to_many.options[:as] # polymorphic are not supported here yet
44
+
45
+ # user_id
46
+ foreign_key_of_owner = many_to_many.through_reflection.foreign_key
47
+
48
+ # movie_id
49
+ foreign_key_of_record = many_to_many.source_reflection.foreign_key
50
+
51
+ (Neoid::Relationship.meta_data ||= {}).tap do |data|
52
+ (data[belongs_to.klass.name.to_s] ||= {}).tap do |model_data|
53
+ model_data[many_to_many.klass.name.to_s] = [rel_model.name.to_s, foreign_key_of_owner, foreign_key_of_record]
54
+ end
55
+ end
56
+
57
+ # e.g. User has_many :movies, through: :likes, before_remove: ...
58
+ full_callback_name = "before_remove_for_#{many_to_many.name}"
59
+ belongs_to.klass.send(full_callback_name) << :neo_before_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)
60
+
61
+ # e.g. User has_many :movies, through: :likes, after_remove: ...
62
+ full_callback_name = "after_remove_for_#{many_to_many.name}"
63
+ belongs_to.klass.send(full_callback_name) << :neo_after_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)
64
+ end
65
+ end
66
+ end
67
+
3
68
  # this is a proxy that delays loading of start_node and end_node from Neo4j until accessed.
4
69
  # the original Neography Relatioship loaded them on initialization
5
70
  class RelationshipLazyProxy < ::Neography::Relationship
@@ -12,13 +77,6 @@ module Neoid
12
77
  end
13
78
  end
14
79
 
15
- def self.from_hash(hash)
16
- relationship = RelationshipLazyProxy.new(hash)
17
-
18
- relationship
19
- end
20
-
21
-
22
80
  module ClassMethods
23
81
  def delete_command
24
82
  :delete_relationship
@@ -27,26 +85,26 @@ module Neoid
27
85
 
28
86
  module InstanceMethods
29
87
  def neo_find_by_id
30
- results = Neoid.db.get_relationship_auto_index(Neoid::UNIQUE_ID_KEY, self.neo_unique_id)
88
+ results = Neoid.db.get_relationship_auto_index(Neoid::UNIQUE_ID_KEY, neo_unique_id)
31
89
  relationship = results.present? ? Neoid::Relationship.from_hash(results[0]) : nil
32
90
  relationship
33
91
  end
34
-
92
+
35
93
  def _neo_save
36
94
  return unless Neoid.enabled?
37
-
95
+
38
96
  options = self.class.neoid_config.relationship_options
39
-
40
- start_item = self.send(options[:start_node])
41
- end_item = self.send(options[:end_node])
42
-
97
+
98
+ start_item = send(options[:start_node])
99
+ end_item = send(options[:end_node])
100
+
43
101
  return unless start_item && end_item
44
102
 
45
103
  # initialize nodes
46
104
  start_item.neo_node
47
105
  end_item.neo_node
48
106
 
49
- data = self.to_neo.merge(ar_type: self.class.name, ar_id: self.id, Neoid::UNIQUE_ID_KEY => self.neo_unique_id)
107
+ data = to_neo.merge(ar_type: self.class.name, ar_id: id, Neoid::UNIQUE_ID_KEY => neo_unique_id)
50
108
  data.reject! { |k, v| v.nil? }
51
109
 
52
110
  rel_type = options[:type].is_a?(Proc) ? options[:type].call(self) : options[:type]
@@ -75,24 +133,24 @@ module Neoid
75
133
  relationship
76
134
  GREMLIN
77
135
 
78
- script_vars = {
136
+ script_vars = {
79
137
  unique_id_key: Neoid::UNIQUE_ID_KEY,
80
138
  relationship_data: data,
81
- unique_id: self.neo_unique_id,
139
+ unique_id: neo_unique_id,
82
140
  start_node_unique_id: start_item.neo_unique_id,
83
141
  end_node_unique_id: end_item.neo_unique_id,
84
142
  rel_type: rel_type
85
143
  }
86
144
 
87
- Neoid::logger.info "Relationship#neo_save #{self.class.name} #{self.id}"
88
-
145
+ Neoid::logger.info "Relationship#neo_save #{self.class.name} #{id}"
146
+
89
147
  relationship = Neoid.execute_script_or_add_to_batch gremlin_query, script_vars do |value|
90
148
  Neoid::Relationship.from_hash(value)
91
149
  end
92
150
 
93
151
  relationship
94
152
  end
95
-
153
+
96
154
  def neo_load(hash)
97
155
  Neoid::Relationship.from_hash(hash)
98
156
  end
@@ -101,63 +159,5 @@ module Neoid
101
159
  _neo_representation
102
160
  end
103
161
  end
104
-
105
- def self.included(receiver)
106
- receiver.send :include, Neoid::ModelAdditions
107
- receiver.send :include, InstanceMethods
108
- receiver.extend ClassMethods
109
-
110
- initialize_relationship receiver if Neoid.env_loaded
111
-
112
- Neoid.relationship_models << receiver
113
- end
114
-
115
- def self.meta_data
116
- @meta_data ||= {}
117
- end
118
-
119
- def self.initialize_relationship(rel_model)
120
- rel_model.reflect_on_all_associations(:belongs_to).each do |belongs_to|
121
- return if belongs_to.options[:polymorphic]
122
-
123
- # e.g. all has_many on User class
124
- all_has_many = belongs_to.klass.reflect_on_all_associations(:has_many)
125
-
126
- # has_many (without through) on the side of the relationship that removes a relationship. e.g. User has_many :likes
127
- this_has_many = all_has_many.find { |o| o.klass == rel_model }
128
- next unless this_has_many
129
-
130
- # e.g. User has_many :likes, after_remove: ...
131
- full_callback_name = "after_remove_for_#{this_has_many.name}"
132
- belongs_to.klass.send(full_callback_name) << :neo_after_relationship_remove if belongs_to.klass.method_defined?(full_callback_name)
133
-
134
- # has_many (with through) on the side of the relationship that removes a relationship. e.g. User has_many :movies, through :likes
135
- many_to_many = all_has_many.find { |o| o.options[:through] == this_has_many.name }
136
- next unless many_to_many
137
-
138
- return if many_to_many.options[:as] # polymorphic are not supported here yet
139
-
140
- # user_id
141
- foreign_key_of_owner = many_to_many.through_reflection.foreign_key
142
-
143
- # movie_id
144
- foreign_key_of_record = many_to_many.source_reflection.foreign_key
145
-
146
- (Neoid::Relationship.meta_data ||= {}).tap do |data|
147
- (data[belongs_to.klass.name.to_s] ||= {}).tap do |model_data|
148
- model_data[many_to_many.klass.name.to_s] = [rel_model.name.to_s, foreign_key_of_owner, foreign_key_of_record]
149
- end
150
- end
151
-
152
- # e.g. User has_many :movies, through: :likes, before_remove: ...
153
- full_callback_name = "before_remove_for_#{many_to_many.name}"
154
- belongs_to.klass.send(full_callback_name) << :neo_before_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)
155
-
156
-
157
- # e.g. User has_many :movies, through: :likes, after_remove: ...
158
- full_callback_name = "after_remove_for_#{many_to_many.name}"
159
- belongs_to.klass.send(full_callback_name) << :neo_after_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)
160
- end
161
- end
162
162
  end
163
163
  end