neo4j 2.0.0.alpha.6-java → 2.0.0.alpha.7-java
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/CHANGELOG +7 -0
- data/lib/neo4j/rails/attributes.rb +12 -2
- data/lib/neo4j/rails/finders.rb +24 -0
- data/lib/neo4j/rails/has_n.rb +21 -7
- data/lib/neo4j/rails/model.rb +53 -9
- data/lib/neo4j/rails/persistence.rb +26 -16
- data/lib/neo4j/rails/relationship_persistence.rb +33 -26
- data/lib/neo4j/rails/relationships/node_dsl.rb +2 -1
- data/lib/neo4j/rails/relationships/relationships.rb +2 -1
- data/lib/neo4j/rails/validations.rb +7 -0
- data/lib/neo4j/version.rb +1 -1
- data/neo4j.gemspec +1 -1
- metadata +3 -4
- data/lib/neo4j/performance.rb +0 -43
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== 2.0.0.alpha.7 / 2012-04-19
|
2
|
+
* fix for Neo4j::Config bug - did not work from rails to set the db location, closes #191
|
3
|
+
* has_n and has_one method generate class method returning the name of the relationship as a Symbol, closes #170
|
4
|
+
* Raise exception if trying to index boolean property, closes #180
|
5
|
+
* Made start_node= and end_node= protected closes 186
|
6
|
+
* Support for things like @dungeon.monsters.dangerous { |m| m[:weapon?] == 'sword' } closes #181
|
7
|
+
|
1
8
|
== 2.0.0.alpha.6 / 2012-04-15
|
2
9
|
* Complete rewrite and smaller change of API + lots of refactoring and better RSpecs
|
3
10
|
* Moved code to the neo4j-core and neo4j-wrapper gems
|
@@ -4,10 +4,13 @@ module Neo4j
|
|
4
4
|
# in a Railsy way. This typically means not writing anything to the DB until the
|
5
5
|
# object is saved (after validation).
|
6
6
|
#
|
7
|
-
# Externally, when we talk about properties (e.g. #property
|
7
|
+
# Externally, when we talk about properties (e.g. {#property?}, {#property_names}),
|
8
8
|
# we mean all of the stored properties for this object include the 'hidden' props
|
9
9
|
# with underscores at the beginning such as _neo_id and _classname. When we talk
|
10
10
|
# about attributes, we mean all the properties apart from those hidden ones.
|
11
|
+
#
|
12
|
+
# This mixin defines a number of class methods, see #{ClassMethods}.
|
13
|
+
#
|
11
14
|
module Attributes
|
12
15
|
extend ActiveSupport::Concern
|
13
16
|
extend TxMethods
|
@@ -47,6 +50,8 @@ module Neo4j
|
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
53
|
+
# Is called when a node neo4j entity is created and we need to save attributes
|
54
|
+
# @private
|
50
55
|
def init_on_create(*)
|
51
56
|
self._classname = self.class.to_s
|
52
57
|
write_default_attributes
|
@@ -54,6 +59,8 @@ module Neo4j
|
|
54
59
|
clear_changes
|
55
60
|
end
|
56
61
|
|
62
|
+
# Setup this mixins instance variables
|
63
|
+
# @private
|
57
64
|
def initialize_attributes(attributes)
|
58
65
|
@_properties = {}
|
59
66
|
@_properties_before_type_cast={}
|
@@ -88,13 +95,14 @@ module Neo4j
|
|
88
95
|
end
|
89
96
|
tx_methods :update_attributes
|
90
97
|
|
91
|
-
# Same as #update_attributes, but raises an exception if saving fails.
|
98
|
+
# Same as {#update_attributes}, but raises an exception if saving fails.
|
92
99
|
def update_attributes!(attributes)
|
93
100
|
self.attributes = attributes
|
94
101
|
save!
|
95
102
|
end
|
96
103
|
tx_methods :update_attributes!
|
97
104
|
|
105
|
+
# @private
|
98
106
|
def reset_attributes
|
99
107
|
@_properties = {}
|
100
108
|
end
|
@@ -309,6 +317,8 @@ module Neo4j
|
|
309
317
|
_decl_props[property][:converter] = converter
|
310
318
|
|
311
319
|
if options.include?(:index)
|
320
|
+
_decl_props[property][:index] = options[:index]
|
321
|
+
raise "Indexing boolean property is not allowed" if options[:type] && options[:type] == :boolean
|
312
322
|
index(property, :type => options[:index], :field_type => converter.index_as)
|
313
323
|
end
|
314
324
|
|
data/lib/neo4j/rails/finders.rb
CHANGED
@@ -3,10 +3,12 @@ module Neo4j
|
|
3
3
|
class RecordNotFoundError < StandardError
|
4
4
|
end
|
5
5
|
|
6
|
+
# Defines {ClassMethods}
|
6
7
|
module Finders
|
7
8
|
extend ActiveSupport::Concern
|
8
9
|
|
9
10
|
|
11
|
+
# @private
|
10
12
|
def reachable_from_ref_node?
|
11
13
|
# All relationships are reachable
|
12
14
|
respond_to?(:_java_rel) || Neo4j::Algo.all_path(self.class.ref_node_for_class, self).outgoing(self.class).outgoing(:_all).first != nil
|
@@ -16,8 +18,29 @@ module Neo4j
|
|
16
18
|
rule(:_all, :functions => Neo4j::Wrapper::Rule::Functions::Size.new) if respond_to?(:rule)
|
17
19
|
end
|
18
20
|
|
21
|
+
# Defines the #{#find} method. When declaring properties with index a number of finder methods will be generated,
|
22
|
+
# similar to active record, example +find_by_<property_name>+, +find_or_create_by_<property_name>. +all_by_<property_name>+
|
23
|
+
#
|
24
|
+
# @example find_or_create_by
|
25
|
+
# class Person < Neo4j::Rails::Model
|
26
|
+
# property :age, :type => Fixnum
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Person.find_by_age(42)
|
30
|
+
# Person.find_or_create_by
|
31
|
+
# Person.find_or_create_by!(:age => 'bla')
|
32
|
+
#
|
33
|
+
# @example find all
|
34
|
+
# Person.all_by_age
|
35
|
+
# Person.all(:name => 'bla')
|
36
|
+
# Person.all('name: "bla"') # lucene query syntax
|
37
|
+
#
|
38
|
+
# @see Neo4j::Rails::Attributes::ClassMethods#property
|
39
|
+
# @see #find
|
40
|
+
#
|
19
41
|
module ClassMethods
|
20
42
|
|
43
|
+
# @private
|
21
44
|
def index_prefix
|
22
45
|
return "" unless Neo4j.running?
|
23
46
|
return "" unless respond_to?(:ref_node_for_class)
|
@@ -26,6 +49,7 @@ module Neo4j
|
|
26
49
|
prefix ? prefix + "_" : ""
|
27
50
|
end
|
28
51
|
|
52
|
+
# @private
|
29
53
|
# overwrite the index method to add find_by_xxx class methods
|
30
54
|
def index(*args)
|
31
55
|
field = args.first
|
data/lib/neo4j/rails/has_n.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
|
+
# Defines class methods, see {ClassMethods}
|
3
4
|
module HasN
|
4
5
|
extend ActiveSupport::Concern
|
5
6
|
|
6
7
|
module ClassMethods
|
7
8
|
|
8
9
|
# Create a number of methods similar to active record has_many.
|
9
|
-
# The first one returns an Neo4j::Rails::Relationships::NodesDSL
|
10
|
+
# The first one returns an {Neo4j::Rails::Relationships::NodesDSL}
|
10
11
|
# the second generate method (with the _rels postfix) returns a
|
11
|
-
# Neo4j::Rails::Relationships::RelsDSL
|
12
|
+
# {Neo4j::Rails::Relationships::RelsDSL}
|
12
13
|
#
|
13
14
|
# See also Neo4j::NodeMixin#has_n which only work with persisted relationships.
|
14
15
|
#
|
@@ -101,7 +102,7 @@ module Neo4j
|
|
101
102
|
RUBY
|
102
103
|
end
|
103
104
|
|
104
|
-
unless method_defined?("#{rel_type}="
|
105
|
+
unless method_defined?("#{rel_type}=")
|
105
106
|
class_eval <<-RUBY, __FILE__, __LINE__
|
106
107
|
def #{rel_type}=(other)
|
107
108
|
dsl = _decl_rels_for(:'#{rel_type}')
|
@@ -142,16 +143,29 @@ module Neo4j
|
|
142
143
|
RUBY
|
143
144
|
end
|
144
145
|
|
146
|
+
instance_eval <<-RUBY, __FILE__, __LINE__
|
147
|
+
def #{rel_type}
|
148
|
+
_decl_rels[:'#{rel_type}'].rel_type.to_sym
|
149
|
+
end
|
150
|
+
RUBY
|
151
|
+
|
145
152
|
_decl_rels[rel_type.to_sym] = Neo4j::Wrapper::HasN::DeclRel.new(rel_type, true, self)
|
146
153
|
end
|
147
154
|
|
148
155
|
def define_has_n_methods_for(rel_type, options) #:nodoc:
|
149
156
|
unless method_defined?(rel_type)
|
150
157
|
class_eval <<-RUBY, __FILE__, __LINE__
|
151
|
-
def #{rel_type}
|
158
|
+
def #{rel_type}(cypher_hash_query = nil, &cypher_block)
|
152
159
|
dsl = _decl_rels_for(:'#{rel_type}')
|
153
|
-
|
154
|
-
|
160
|
+
if cypher_hash_query || cypher_block
|
161
|
+
raise "Expected a hash, can't translated to cypher where statements" if cypher_hash_query && !cypher_hash_query.is_a?(Hash)
|
162
|
+
Neo4j::Wrapper::HasN::Nodes.new(self, dsl, cypher_hash_query, &cypher_block)
|
163
|
+
else
|
164
|
+
storage = _create_or_get_storage_for_decl_rels(dsl)
|
165
|
+
NodesDSL.new(storage, dsl.dir).tap do |n|
|
166
|
+
Neo4j::Wrapper::HasN::Nodes.define_rule_methods_on(n, dsl)
|
167
|
+
end
|
168
|
+
end
|
155
169
|
end
|
156
170
|
RUBY
|
157
171
|
end
|
@@ -190,7 +204,7 @@ module Neo4j
|
|
190
204
|
|
191
205
|
instance_eval <<-RUBY, __FILE__, __LINE__
|
192
206
|
def #{rel_type}
|
193
|
-
_decl_rels[:'#{rel_type}'].rel_type.
|
207
|
+
_decl_rels[:'#{rel_type}'].rel_type.to_sym
|
194
208
|
end
|
195
209
|
RUBY
|
196
210
|
|
data/lib/neo4j/rails/model.rb
CHANGED
@@ -1,20 +1,39 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
3
|
# Makes Neo4j nodes and relationships behave like active record objects.
|
4
|
-
# That means for example that you don't have to care about transactions since they will be
|
5
|
-
# automatically be created when needed. Validation, Callbacks etc. are also supported.
|
4
|
+
# That means for example that you don't (normally) have to care about transactions since they will be
|
5
|
+
# automatically be created when needed. {Neo4j::Rails::Validation}, {Neo4j::Rails::Callbacks} etc. are also supported.
|
6
6
|
#
|
7
|
-
# @example
|
7
|
+
# @example Create a node (learn more - see {Neo4j::Rails::Persistence})
|
8
|
+
# class Company < Neo4j::Rails::Model
|
9
|
+
# end
|
10
|
+
# Company.new.save
|
11
|
+
# Company.save
|
12
|
+
# Company.save(:name => 'Foo Ab')
|
13
|
+
#
|
14
|
+
# @example Declare properties (learn more - see {Neo4j::Rails::Attributes})
|
15
|
+
#
|
16
|
+
# class Company < Neo4j::Rails::Model
|
17
|
+
# property :data
|
18
|
+
# property :revenue, :type => :Float
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# c = Company.new(:data => false, :type => '2123123.23')
|
22
|
+
# c.data = "changed type"
|
23
|
+
# c.revenue = 123124 # will always be converted
|
24
|
+
#
|
25
|
+
# @example Creating and Navigating Relationships (learn more - see {Neo4j::Rails::Relationships})
|
8
26
|
# class Person < Neo4j::Rails::Model
|
9
27
|
# end
|
10
28
|
#
|
11
|
-
# person = Person.
|
12
|
-
# person.outgoing(:foo) << Person.
|
29
|
+
# person = Person.new
|
30
|
+
# person.outgoing(:foo) << Person.new
|
13
31
|
# person.save!
|
14
32
|
# person.outgoing(:foo).depth(:all)...
|
15
33
|
# person.outgoing(:friends).map{|f| f.outgoing(:knows).to_a}.flatten
|
34
|
+
# person.rels(:outgoing, :foo).first.end_node #=> the other node
|
16
35
|
#
|
17
|
-
# @example Declared Relationships
|
36
|
+
# @example Declared Relationships (learn more - see {Neo4j::Rails::HasN::ClassMethods})
|
18
37
|
#
|
19
38
|
# class Person < Neo4j::Rails::Model
|
20
39
|
# end
|
@@ -25,9 +44,9 @@ module Neo4j
|
|
25
44
|
# end
|
26
45
|
#
|
27
46
|
# Person.new.foo << other_node
|
28
|
-
# Person.friends.build(:name => 'kalle')
|
47
|
+
# Person.friends.build(:name => 'kalle').save
|
29
48
|
#
|
30
|
-
# @example
|
49
|
+
# @example Searching with Lucene Index (learn more - see {Neo4j::Rails::Finders::ClassMethods})
|
31
50
|
#
|
32
51
|
# class Person < Neo4j::Rails::Model
|
33
52
|
# property :name
|
@@ -37,7 +56,32 @@ module Neo4j
|
|
37
56
|
# Person.create(:name => 'kalle', :age => 42, :undeclared_prop => 3.14)
|
38
57
|
# Person.find_by_age(42)
|
39
58
|
#
|
40
|
-
# @example
|
59
|
+
# @example Searching with Cypher (learn more - {Neo4j-core}[http://rdoc.info/github/andreasronge/neo4j-core/file/README.rdoc])
|
60
|
+
#
|
61
|
+
# Monster.all.query(:strength => 17).first #=> a node/Neo4j::Rails::Model
|
62
|
+
# Monster.all.query(:strength => 17).to_s #=> "START n0=node(42) MATCH ..."
|
63
|
+
# Neo4j.query{Neo4j.rb cypher DSL}
|
64
|
+
# dungeon.monsters.query(:name => 'Ghost', :strength => 10) # all monsters with those properties
|
65
|
+
# dungeon.monsters(:name => 'Ghost', :strength => 10) # same as above
|
66
|
+
# dungeon.monsters { |m| m[:name] == 'Ghost'] & m[:strength] == 16} # same as above
|
67
|
+
#
|
68
|
+
# @example Rules and Cypher (learn more {Neoj::Wrapper::Rule::ClassMethods}[http://rdoc.info/github/andreasronge/neo4j-wrapper/Neo4j/Wrapper/Rule/ClassMethods] )
|
69
|
+
# class Dungeon < Neo4j::Rails::Model
|
70
|
+
# has_n(:monsters).to(Monster)
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# class Monster < Neo4j::Rails::Model
|
74
|
+
# rule(:dangerous) { |m| m[:strength] > 15 }
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# class Room < Neo4j::Rails::Model
|
78
|
+
# has_n(:monsters).to(Monster)
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# @dungeon.monsters.dangerous { |m| rooms = m.incoming(Room.monsters); rooms } # returns rooms we should avoid
|
82
|
+
# @dungeon.monsters{|m| ret(m).asc(m[:strength])} # return the monsters nodes sorted by strength
|
83
|
+
#
|
84
|
+
# @example Callbacks (learn more - see #{Neo4j::Rails::Callbacks})
|
41
85
|
#
|
42
86
|
# class Person < Neo4j::Rails::Model
|
43
87
|
# before_save :do_something
|
@@ -1,13 +1,19 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
|
+
# Defines the create, delete and update methods.
|
4
|
+
# @see ClassMethods class methods when including this module
|
3
5
|
module Persistence
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
extend TxMethods
|
6
8
|
|
7
9
|
|
8
10
|
# Persist the object to the database. Validations and Callbacks are included
|
9
|
-
# by default but validation can be disabled by passing
|
10
|
-
# to
|
11
|
+
# by default but validation can be disabled by passing <tt>:validate => false</tt>
|
12
|
+
# to <tt>save</tt>. Creates a new transaction.
|
13
|
+
# @param (see Neo4j::Rails::Validations#save)
|
14
|
+
# @return [Boolean] true if it was persisted
|
15
|
+
# @see Neo4j::Rails::Validations Neo4j::Rails::Validations - for the :validate parameter
|
16
|
+
# @see Neo4j::Rails::Callbacks Neo4j::Rails::Callbacks - for callbacks
|
11
17
|
def save(*)
|
12
18
|
create_or_update
|
13
19
|
end
|
@@ -15,23 +21,20 @@ module Neo4j
|
|
15
21
|
|
16
22
|
# Persist the object to the database. Validations and Callbacks are included
|
17
23
|
# by default but validation can be disabled by passing :validate => false
|
18
|
-
# to #save
|
24
|
+
# to #save! Creates a new transaction.
|
19
25
|
#
|
20
|
-
#
|
26
|
+
# @raise a RecordInvalidError if there is a problem during save.
|
27
|
+
# @param (see Neo4j::Rails::Validations#save)
|
28
|
+
# @return nil
|
29
|
+
# @see #save
|
30
|
+
# @see Neo4j::Rails::Validations Neo4j::Rails::Validations - for the :validate parameter
|
31
|
+
# @see Neo4j::Rails::Callbacks Neo4j::Rails::Callbacks - for callbacks
|
21
32
|
def save!(*args)
|
22
33
|
unless save(*args)
|
23
34
|
raise RecordInvalidError.new(self)
|
24
35
|
end
|
25
36
|
end
|
26
37
|
|
27
|
-
def update
|
28
|
-
write_changed_attributes
|
29
|
-
clear_changes
|
30
|
-
true
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
38
|
# Removes the node from Neo4j and freezes the object.
|
36
39
|
def destroy
|
37
40
|
delete
|
@@ -39,24 +42,24 @@ module Neo4j
|
|
39
42
|
end
|
40
43
|
|
41
44
|
# Same as #destroy but doesn't run destroy callbacks and doesn't freeze
|
42
|
-
# the object
|
45
|
+
# the object. Creates a new transaction
|
43
46
|
def delete
|
44
47
|
del unless new_record? || destroyed?
|
45
48
|
set_deleted_properties
|
46
49
|
end
|
47
50
|
tx_methods :delete
|
48
51
|
|
49
|
-
# Returns true if the object was destroyed.
|
52
|
+
# Returns +true+ if the object was destroyed.
|
50
53
|
def destroyed?
|
51
54
|
@_deleted || (!new_record? && !self.class.load_entity(neo_id))
|
52
55
|
end
|
53
56
|
|
54
|
-
# Returns if the record is persisted, i.e. it’s not a new record and it was not destroyed
|
57
|
+
# Returns +true+ if the record is persisted, i.e. it’s not a new record and it was not destroyed
|
55
58
|
def persisted?
|
56
59
|
!new_record? && !destroyed?
|
57
60
|
end
|
58
61
|
|
59
|
-
# Returns true if the record hasn't been saved to Neo4j yet.
|
62
|
+
# Returns +true+ if the record hasn't been saved to Neo4j yet.
|
60
63
|
def new_record?
|
61
64
|
_java_entity.nil?
|
62
65
|
end
|
@@ -117,6 +120,13 @@ module Neo4j
|
|
117
120
|
end
|
118
121
|
|
119
122
|
protected
|
123
|
+
|
124
|
+
def update
|
125
|
+
write_changed_attributes
|
126
|
+
clear_changes
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
120
130
|
def create_or_update
|
121
131
|
result = persisted? ? update : create
|
122
132
|
unless result != false
|
@@ -34,10 +34,12 @@ module Neo4j
|
|
34
34
|
true
|
35
35
|
end
|
36
36
|
|
37
|
+
# @return [Symbol] the relationship type
|
37
38
|
def rel_type
|
38
39
|
new_record? ? @_rel_type : _java_entity.rel_type.to_sym
|
39
40
|
end
|
40
41
|
|
42
|
+
# @see http://rdoc.info/github/andreasronge/neo4j-core/Neo4j/Core/Relationship#other_node-instance_method
|
41
43
|
def other_node(node)
|
42
44
|
if persisted?
|
43
45
|
_java_rel._other_node(node._java_node)
|
@@ -46,40 +48,18 @@ module Neo4j
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
|
-
|
51
|
+
# Returns the start node which can be unpersisted
|
52
|
+
# @see http://rdoc.info/github/andreasronge/neo4j-core/Neo4j/Core/Relationship#start_node-instance_method
|
50
53
|
def start_node
|
51
54
|
@_start_node ||= _java_rel && _java_rel.start_node.wrapper
|
52
55
|
end
|
53
56
|
|
54
|
-
|
55
|
-
|
56
|
-
@_start_node = node
|
57
|
-
# TODO should raise exception if not persisted and changed
|
58
|
-
if old != @_start_node
|
59
|
-
old && old.rm_outgoing_rel(rel_type, self)
|
60
|
-
@_start_node.class != Neo4j::Node && @_start_node.add_outgoing_rel(rel_type, self)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
57
|
+
# Returns the end node which can be unpersisted
|
58
|
+
# @see http://rdoc.info/github/andreasronge/neo4j-core/Neo4j/Core/Relationship#end_node-instance_method
|
64
59
|
def end_node
|
65
60
|
@_end_node ||= _java_rel && _java_rel.end_node.wrapper
|
66
61
|
end
|
67
62
|
|
68
|
-
def end_node=(node)
|
69
|
-
old = @_end_node
|
70
|
-
@_end_node = node
|
71
|
-
# TODO should raise exception if not persisted and changed
|
72
|
-
if old != @_end_node
|
73
|
-
old && old.rm_incoming_rel(rel_type, self)
|
74
|
-
@_end_node.class != Neo4j::Node && @_end_node.add_incoming_rel(rel_type, self)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
def _persist_node(start_or_end_node)
|
80
|
-
(start_or_end_node.new_record? || start_or_end_node.relationships_changed?) ? start_or_end_node.save : true
|
81
|
-
end
|
82
|
-
|
83
63
|
# Reload the object from the DB
|
84
64
|
def reload(options = nil)
|
85
65
|
raise "Can't reload a none persisted node" if new_record?
|
@@ -100,6 +80,33 @@ module Neo4j
|
|
100
80
|
end
|
101
81
|
reloaded
|
102
82
|
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
|
86
|
+
def start_node=(node)
|
87
|
+
old = @_start_node
|
88
|
+
@_start_node = node
|
89
|
+
# TODO should raise exception if not persisted and changed
|
90
|
+
if old != @_start_node
|
91
|
+
old && old.rm_outgoing_rel(rel_type, self)
|
92
|
+
@_start_node.class != Neo4j::Node && @_start_node.add_outgoing_rel(rel_type, self)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def end_node=(node)
|
97
|
+
old = @_end_node
|
98
|
+
@_end_node = node
|
99
|
+
# TODO should raise exception if not persisted and changed
|
100
|
+
if old != @_end_node
|
101
|
+
old && old.rm_incoming_rel(rel_type, self)
|
102
|
+
@_end_node.class != Neo4j::Node && @_end_node.add_incoming_rel(rel_type, self)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def _persist_node(start_or_end_node)
|
107
|
+
(start_or_end_node.new_record? || start_or_end_node.relationships_changed?) ? start_or_end_node.save : true
|
108
|
+
end
|
109
|
+
|
103
110
|
end
|
104
111
|
|
105
112
|
end
|
@@ -142,6 +142,7 @@ module Neo4j
|
|
142
142
|
#
|
143
143
|
def all(*args)
|
144
144
|
unless args.empty?
|
145
|
+
raise "Illegal argument, expected a node" unless args.first.kind_of?(Neo4j::NodeMixin)
|
145
146
|
enum = Enumerator.new(@storage, :each_node, @dir).find { |n| n == args.first }
|
146
147
|
else
|
147
148
|
enum = Enumerator.new(@storage, :each_node, @dir)
|
@@ -208,7 +209,7 @@ module Neo4j
|
|
208
209
|
|
209
210
|
# These methods are using the Neo4j::Core::Traversal::Traverser which means that only persisted relationship will be seen
|
210
211
|
# but more advanced traversal can be performed.
|
211
|
-
CORE_TRAVERSAL_METHODS = [:depth, :outgoing, :incoming, :both, :expand, :depth_first, :breadth_first, :eval_paths, :unique, :expander, :prune, :filter, :include_start_node, :rels, :eval_paths]
|
212
|
+
CORE_TRAVERSAL_METHODS = [:depth, :outgoing, :incoming, :both, :expand, :depth_first, :breadth_first, :eval_paths, :unique, :expander, :prune, :filter, :include_start_node, :rels, :eval_paths, :query]
|
212
213
|
|
213
214
|
|
214
215
|
protected
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
3
|
|
4
|
-
# This module overrides the Neo4j::Core::Rels
|
4
|
+
# This module overrides the {Neo4j::Core::Rels}[http://rdoc.info/github/andreasronge/neo4j-core/Neo4j/Core/Rels] and {Neo4j::Core::Traversal}[http://rdoc.info/github/andreasronge/neo4j-core/Neo4j/Core/Traversal]
|
5
|
+
# modules so that it can handle unpersisted relationships of depth one.
|
5
6
|
#
|
6
7
|
module Relationships
|
7
8
|
extend ActiveSupport::Concern
|
@@ -1,14 +1,20 @@
|
|
1
1
|
module Neo4j
|
2
2
|
module Rails
|
3
|
+
# This mixin replace the original save method and performs validation before the save.
|
3
4
|
module Validations
|
4
5
|
include ActiveModel::Validations
|
5
6
|
|
7
|
+
# Implements the ActiveModel::Validation hook method.
|
8
|
+
# @see http://rubydoc.info/docs/rails/ActiveModel/Validations:read_attribute_for_validation
|
6
9
|
def read_attribute_for_validation(key)
|
7
10
|
respond_to?(key) ? send(key) : self[key]
|
8
11
|
end
|
9
12
|
|
10
13
|
# The validation process on save can be skipped by passing false. The regular Model#save method is
|
11
14
|
# replaced with this when the validations module is mixed in, which it is by default.
|
15
|
+
# @param [Hash] options the options to create a message with.
|
16
|
+
# @option options [true, false] :validate if false no validation will take place
|
17
|
+
# @return [Boolean] true if it saved it successfully
|
12
18
|
def save(options={})
|
13
19
|
result = perform_validations(options) ? super : false
|
14
20
|
if !result
|
@@ -17,6 +23,7 @@ module Neo4j
|
|
17
23
|
result
|
18
24
|
end
|
19
25
|
|
26
|
+
# @return [Boolean] true if valid
|
20
27
|
def valid?(context = nil)
|
21
28
|
context ||= (new_record? ? :create : :update)
|
22
29
|
super(context)
|
data/lib/neo4j/version.rb
CHANGED
data/neo4j.gemspec
CHANGED
@@ -32,5 +32,5 @@ It comes included with the Apache Lucene document database.
|
|
32
32
|
s.add_dependency('orm_adapter', ">= 0.0.3")
|
33
33
|
s.add_dependency("activemodel", ">= 3.0.0", "< 3.3")
|
34
34
|
s.add_dependency("railties", ">= 3.0.0", "< 3.3")
|
35
|
-
s.add_dependency("neo4j-wrapper", '0.0.
|
35
|
+
s.add_dependency("neo4j-wrapper", '0.0.8')
|
36
36
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: neo4j
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 2.0.0.alpha.
|
5
|
+
version: 2.0.0.alpha.7
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Andreas Ronge
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-04-
|
13
|
+
date: 2012-04-19 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: orm_adapter
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
requirements:
|
60
60
|
- - "="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0.0.
|
62
|
+
version: 0.0.8
|
63
63
|
type: :runtime
|
64
64
|
version_requirements: *id004
|
65
65
|
description: |
|
@@ -93,7 +93,6 @@ files:
|
|
93
93
|
- lib/tasks/upgrade_v2/upgrade_v2.rake
|
94
94
|
- lib/tasks/upgrade_v2/lib/upgrade_v2.rb
|
95
95
|
- lib/orm_adapter/adapters/neo4j.rb
|
96
|
-
- lib/neo4j/performance.rb
|
97
96
|
- lib/neo4j/version.rb
|
98
97
|
- lib/neo4j/rails/attributes.rb
|
99
98
|
- lib/neo4j/rails/rack_middleware.rb
|
data/lib/neo4j/performance.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'neo4j'
|
3
|
-
|
4
|
-
class MyIndex
|
5
|
-
include Neo4j::NodeMixin
|
6
|
-
index(:name) # default :exact
|
7
|
-
index(:things)
|
8
|
-
index(:age, :field_type => Fixnum) # default :exact
|
9
|
-
index(:wheels, :field_type => Fixnum)
|
10
|
-
index(:description, :type => :fulltext)
|
11
|
-
end
|
12
|
-
|
13
|
-
def rm_db_storage
|
14
|
-
FileUtils.rm_rf Neo4j::Config[:storage_path]
|
15
|
-
raise "Can't delete db" if File.exist?(Neo4j::Config[:storage_path])
|
16
|
-
end
|
17
|
-
|
18
|
-
def finish_tx
|
19
|
-
return unless @tx
|
20
|
-
@tx.success
|
21
|
-
@tx.finish
|
22
|
-
@tx = nil
|
23
|
-
end
|
24
|
-
|
25
|
-
def new_tx
|
26
|
-
finish_tx if @tx
|
27
|
-
@tx = Neo4j::Transaction.new
|
28
|
-
end
|
29
|
-
|
30
|
-
rm_db_storage
|
31
|
-
|
32
|
-
10.times do
|
33
|
-
t = Time.now
|
34
|
-
new_tx
|
35
|
-
(0..1000).each do
|
36
|
-
MyIndex.new :things => 'bla', :name => 'foo', :age => 42, :wheels => 53, :description => "Bla bla"
|
37
|
-
end
|
38
|
-
d1 = Time.now - t
|
39
|
-
t = Time.now
|
40
|
-
finish_tx
|
41
|
-
d2 = Time.now - t
|
42
|
-
puts "Index #{d2}, create #{d1} tot #{d1 + d2} - #{d2/(d1 + d2).round(2)}"
|
43
|
-
end
|