neo4j 2.0.0.alpha.6-java → 2.0.0.alpha.7-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|