neo4j 1.0.0.beta.19 → 1.0.0.beta.20
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTORS +1 -0
- data/Gemfile +3 -3
- data/README.rdoc +28 -6
- data/lib/generators/neo4j/model/model_generator.rb +5 -5
- data/lib/generators/neo4j/model/templates/{model.rb → model.erb} +1 -1
- data/lib/neo4j.rb +5 -2
- data/lib/neo4j/config.rb +7 -0
- data/lib/neo4j/index/indexer.rb +7 -7
- data/lib/neo4j/index/{index_registry.rb → indexer_registry.rb} +0 -0
- data/lib/neo4j/mapping/class_methods/property.rb +0 -1
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +80 -76
- data/lib/neo4j/mapping/has_n.rb +3 -7
- data/lib/neo4j/neo4j.rb +5 -0
- data/lib/neo4j/node_traverser.rb +8 -2
- data/lib/neo4j/property.rb +4 -3
- data/lib/neo4j/rails/finders.rb +121 -0
- data/lib/neo4j/rails/mapping/property.rb +35 -0
- data/lib/neo4j/rails/model.rb +43 -81
- data/lib/neo4j/rails/transaction.rb +2 -2
- data/lib/neo4j/rails/validations/non_nil.rb +11 -0
- data/lib/neo4j/rails/validations/uniqueness.rb +29 -27
- data/lib/neo4j/rails/value.rb +2 -2
- data/lib/neo4j/rails/{properties.rb → value_properties.rb} +2 -2
- data/lib/neo4j/relationship_traverser.rb +4 -0
- data/lib/neo4j/type_converters.rb +19 -5
- data/lib/neo4j/version.rb +1 -1
- metadata +9 -6
data/CONTRIBUTORS
CHANGED
data/Gemfile
CHANGED
@@ -11,6 +11,6 @@ group 'test' do
|
|
11
11
|
gem "test-unit"
|
12
12
|
end
|
13
13
|
|
14
|
-
gem 'ruby-debug-base19' if RUBY_VERSION.include? "1.9"
|
15
|
-
gem 'ruby-debug-base' if RUBY_VERSION.include? "1.8"
|
16
|
-
gem "ruby-debug-ide"
|
14
|
+
#gem 'ruby-debug-base19' if RUBY_VERSION.include? "1.9"
|
15
|
+
#gem 'ruby-debug-base' if RUBY_VERSION.include? "1.8"
|
16
|
+
#gem "ruby-debug-ide"
|
data/README.rdoc
CHANGED
@@ -26,8 +26,8 @@ Here are some of the major benefits of Neo4j.rb
|
|
26
26
|
|
27
27
|
=== Documentation
|
28
28
|
|
29
|
-
* {Documentation
|
30
|
-
* {
|
29
|
+
* {API Documentation}[http://neo4j.rubyforge.org]
|
30
|
+
* {Documentation and Getting Started with Neo4j}[http://neo4j.rubyforge.org/guides/index.html]
|
31
31
|
|
32
32
|
=== Some Examples
|
33
33
|
|
@@ -39,8 +39,8 @@ Example of creating a Neo4j::Node
|
|
39
39
|
require 'neo4j'
|
40
40
|
|
41
41
|
Neo4j::Transaction.run do
|
42
|
-
node = Neo4j::Node.new :name => 'andreas'
|
43
|
-
node.outgoing(:friends) << Neo4j::Node.new :name => 'peter'
|
42
|
+
node = Neo4j::Node.new (:name => 'andreas')
|
43
|
+
node.outgoing(:friends) << Neo4j::Node.new (:name => 'peter')
|
44
44
|
node.outgoing(:friends).each {|node| puts "name #{node[:name]}"}
|
45
45
|
end
|
46
46
|
|
@@ -59,8 +59,8 @@ Example of mapping a ruby class to a node and delaring properties and relationsh
|
|
59
59
|
end
|
60
60
|
|
61
61
|
# assume we have an transaction already running
|
62
|
-
andreas = Person.new :name => 'andreas'
|
63
|
-
andreas.friends << Person.new :name => 'peter'
|
62
|
+
andreas = Person.new (:name => 'andreas')
|
63
|
+
andreas.friends << Person.new (:name => 'peter')
|
64
64
|
andreas.friends.each {|person| puts "name #{person.name}" }
|
65
65
|
Person.find("name: andreas").first.name # => 'andreas'
|
66
66
|
|
@@ -88,6 +88,28 @@ Example of using Neo4j with Rails 3 (ActiveModel)
|
|
88
88
|
...
|
89
89
|
end
|
90
90
|
|
91
|
+
==== Generate a Rails Application
|
92
|
+
|
93
|
+
Example of creating an Neo4j Application from scratch:
|
94
|
+
|
95
|
+
gem install rails
|
96
|
+
rails new myapp -m http://andreasronge.github.com/rails3.rb
|
97
|
+
cd myapp
|
98
|
+
bundle
|
99
|
+
rails generate scaffold User name:string email:string
|
100
|
+
rails s
|
101
|
+
open a webbrowser: http://localhost:3000/users
|
102
|
+
|
103
|
+
You may get an error message "ERROR IOError: Connection reset by peer"
|
104
|
+
using WEBrick (it still works). This error message is not shown when running
|
105
|
+
the application with {Tomcat/Trinidad}[https://github.com/calavera/trinidad]
|
106
|
+
|
107
|
+
To run it with Tomcat
|
108
|
+
|
109
|
+
gem install trinidad
|
110
|
+
trinidad
|
111
|
+
|
112
|
+
|
91
113
|
=== Presentation Materials and other URLs
|
92
114
|
* {Intoduction to Neo4j.rb}[http://www.slideshare.net/andreasronge/neo4jrb]
|
93
115
|
* {Nordic Ruby 2010 May 21-23}[http://nordicruby.org/speakers#user_29]
|
@@ -9,7 +9,7 @@ class Neo4j::Generators::ModelGenerator < Neo4j::Generators::Base
|
|
9
9
|
class_option :parent, :type => :string, :desc => "The parent class for the generated model"
|
10
10
|
|
11
11
|
def create_model_file
|
12
|
-
template "model.
|
12
|
+
template "model.erb", File.join('app/models', "#{singular_name}.rb")
|
13
13
|
end
|
14
14
|
|
15
15
|
protected
|
@@ -27,11 +27,11 @@ class Neo4j::Generators::ModelGenerator < Neo4j::Generators::Base
|
|
27
27
|
|
28
28
|
def timestamp_statements
|
29
29
|
%q{
|
30
|
-
property :created_at, DateTime
|
31
|
-
# property :created_on, Date
|
30
|
+
property :created_at, DateTime
|
31
|
+
# property :created_on, Date
|
32
32
|
|
33
|
-
property :updated_at, DateTime
|
34
|
-
# property :updated_on, Date
|
33
|
+
property :updated_at, DateTime
|
34
|
+
# property :updated_on, Date
|
35
35
|
}
|
36
36
|
end
|
37
37
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class <%= class_name %> < <%= parent? ? options[:parent].classify : "Neo4j::Rails::Model" %>
|
2
2
|
<% attributes.each do |attribute| -%>
|
3
|
-
|
3
|
+
property :<%= attribute.name %><%= ", :type => #{attribute.type_class}" %>
|
4
4
|
<% end -%>
|
5
5
|
|
6
6
|
<%= timestamp_statements if timestamps? -%>
|
data/lib/neo4j.rb
CHANGED
@@ -20,7 +20,7 @@ require 'neo4j/neo4j'
|
|
20
20
|
|
21
21
|
require 'neo4j/index/index'
|
22
22
|
require 'neo4j/index/class_methods'
|
23
|
-
require 'neo4j/index/
|
23
|
+
require 'neo4j/index/indexer_registry'
|
24
24
|
require 'neo4j/index/indexer'
|
25
25
|
require 'neo4j/index/lucene_query'
|
26
26
|
require 'neo4j/relationship_traverser'
|
@@ -53,8 +53,11 @@ require 'neo4j/rails/tx_methods'
|
|
53
53
|
require 'neo4j/rails/transaction'
|
54
54
|
require 'neo4j/rails/railtie'
|
55
55
|
require 'neo4j/rails/validations/uniqueness'
|
56
|
+
require 'neo4j/rails/validations/non_nil'
|
57
|
+
require 'neo4j/rails/finders'
|
58
|
+
require 'neo4j/rails/mapping/property'
|
56
59
|
require 'neo4j/rails/model'
|
57
|
-
require 'neo4j/rails/
|
60
|
+
require 'neo4j/rails/value_properties'
|
58
61
|
require 'neo4j/rails/value'
|
59
62
|
require 'neo4j/rails/lucene_connection_closer'
|
60
63
|
|
data/lib/neo4j/config.rb
CHANGED
@@ -26,6 +26,13 @@ module Neo4j
|
|
26
26
|
@defaults ||= {
|
27
27
|
:storage_path => 'tmp/neo4j',
|
28
28
|
:timestamps => true,
|
29
|
+
|
30
|
+
# TODO: Just pickup all converter classes that are in the Neo4j::TypeConverters module?
|
31
|
+
:converters => { Date => Neo4j::TypeConverters::DateConverter,
|
32
|
+
DateTime => Neo4j::TypeConverters::DateTimeConverter,
|
33
|
+
Time => Neo4j::TypeConverters::TimeConverter
|
34
|
+
},
|
35
|
+
|
29
36
|
:lucene => {
|
30
37
|
:fulltext => {"provider" => "lucene", "type" => "fulltext" },
|
31
38
|
:exact => {"provider" => "lucene", "type" => "exact" }}
|
data/lib/neo4j/index/indexer.rb
CHANGED
@@ -83,7 +83,7 @@ module Neo4j
|
|
83
83
|
rel_dsl = @indexer_for._decl_rels[conf[:via]]
|
84
84
|
raise "No relationship defined for '#{conf[:via]}'. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]} <-- error. Define it with a has_one or has_n" unless rel_dsl
|
85
85
|
raise "Only incoming relationship are possible to define index on. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]}" unless rel_dsl.incoming?
|
86
|
-
via_indexer = rel_dsl.
|
86
|
+
via_indexer = rel_dsl.target_class._indexer
|
87
87
|
|
88
88
|
field = field.to_s
|
89
89
|
@via_relationships[field] = rel_dsl
|
@@ -99,7 +99,7 @@ module Neo4j
|
|
99
99
|
@field_types.keys.each { |field| rm_index(node, field, props[field]) if props[field] }
|
100
100
|
# remove all via indexed fields
|
101
101
|
@via_relationships.each_value do |dsl|
|
102
|
-
indexer = dsl.
|
102
|
+
indexer = dsl.target_class._indexer
|
103
103
|
tx_data.deleted_relationships.each do |rel|
|
104
104
|
start_node = rel._start_node
|
105
105
|
next if node != rel._end_node
|
@@ -122,14 +122,14 @@ module Neo4j
|
|
122
122
|
# find which via relationship match rel_type
|
123
123
|
@via_relationships.each_pair do |field, dsl|
|
124
124
|
# have we declared an index on this changed relationship ?
|
125
|
-
next unless dsl.
|
125
|
+
next unless dsl.rel_type == rel_type
|
126
126
|
|
127
127
|
# yes, so find the node and value we should update the index on
|
128
128
|
val = end_node[field]
|
129
129
|
start_node = relationship._start_node
|
130
130
|
|
131
131
|
# find the indexer to use
|
132
|
-
indexer = dsl.
|
132
|
+
indexer = dsl.target_class._indexer
|
133
133
|
|
134
134
|
# is the relationship created or deleted ?
|
135
135
|
if is_created
|
@@ -143,11 +143,11 @@ module Neo4j
|
|
143
143
|
def update_index_on(node, field, old_val, new_val) #:nodoc:
|
144
144
|
if @via_relationships.include?(field)
|
145
145
|
dsl = @via_relationships[field]
|
146
|
-
|
146
|
+
target_class = dsl.target_class
|
147
147
|
|
148
148
|
dsl._all_relationships(node).each do |rel|
|
149
149
|
other = rel._start_node
|
150
|
-
|
150
|
+
target_class._indexer.update_single_index_on(other, field, old_val, new_val)
|
151
151
|
end
|
152
152
|
end
|
153
153
|
update_single_index_on(node, field, old_val, new_val)
|
@@ -309,4 +309,4 @@ module Neo4j
|
|
309
309
|
|
310
310
|
end
|
311
311
|
|
312
|
-
end
|
312
|
+
end
|
File without changes
|
@@ -33,39 +33,26 @@ module Neo4j::Mapping
|
|
33
33
|
class DeclRelationshipDsl
|
34
34
|
include Neo4j::ToJava
|
35
35
|
|
36
|
-
attr_reader :
|
36
|
+
attr_reader :target_class, :direction, :rel_type
|
37
37
|
|
38
|
-
def initialize(
|
39
|
-
@direction
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@to_class = to_class
|
45
|
-
end
|
46
|
-
|
47
|
-
def has_one?
|
48
|
-
@has_one
|
38
|
+
def initialize(method_id, has_one, target_class, params)
|
39
|
+
@direction = :outgoing
|
40
|
+
@method_id = method_id
|
41
|
+
@has_one = has_one
|
42
|
+
@rel_type = method_id
|
43
|
+
@target_class = target_class
|
49
44
|
end
|
50
45
|
|
51
|
-
def
|
52
|
-
|
53
|
-
return args[0], args[1]
|
54
|
-
elsif (Symbol === args[0])
|
55
|
-
return @to_class, args[0]
|
56
|
-
else
|
57
|
-
return args[0], @rel_id
|
58
|
-
end
|
46
|
+
def to_s
|
47
|
+
"DeclRelationshipDsl #{object_id} dir: #{@direction} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_class} rel_class:#{@relationship}"
|
59
48
|
end
|
60
49
|
|
61
|
-
|
62
|
-
|
63
|
-
def namespace_type
|
64
|
-
@namespace_type
|
50
|
+
def has_one?
|
51
|
+
@has_one
|
65
52
|
end
|
66
53
|
|
67
|
-
def each_node(node, direction, &block)
|
68
|
-
type = type_to_java(
|
54
|
+
def each_node(node, direction, &block) #:nodoc:
|
55
|
+
type = type_to_java(rel_type)
|
69
56
|
dir = dir_to_java(direction)
|
70
57
|
node._java_node.getRelationships(type, dir).each do |rel|
|
71
58
|
other = rel.getOtherNode(node).wrapper
|
@@ -73,59 +60,35 @@ module Neo4j::Mapping
|
|
73
60
|
end
|
74
61
|
end
|
75
62
|
|
76
|
-
def incoming?
|
63
|
+
def incoming? #:nodoc:
|
77
64
|
@direction == :incoming
|
78
65
|
end
|
79
66
|
|
80
|
-
def
|
81
|
-
dsl = @to_class._decl_rels[to_type]
|
82
|
-
raise "Unspecified outgoing relationship '#{to_type}' for incoming relationship '#{rel_id}' on class #{to_class}" if dsl.nil?
|
83
|
-
dsl
|
84
|
-
end
|
85
|
-
|
86
|
-
def single_node(node)
|
67
|
+
def single_node(node) #:nodoc:
|
87
68
|
rel = single_relationship(node)
|
88
69
|
rel && rel.other_node(node).wrapper
|
89
70
|
end
|
90
71
|
|
91
|
-
def single_relationship(node)
|
92
|
-
|
93
|
-
dsl = incoming? ? incoming_dsl : self
|
94
|
-
node._java_node.rel(dir, dsl.namespace_type)
|
72
|
+
def single_relationship(node) #:nodoc:
|
73
|
+
node._java_node.rel(direction, rel_type)
|
95
74
|
end
|
96
75
|
|
97
|
-
def _all_relationships(node)
|
98
|
-
|
99
|
-
type = type_to_java(dsl.namespace_type)
|
76
|
+
def _all_relationships(node) #:nodoc:
|
77
|
+
type = type_to_java(rel_type)
|
100
78
|
dir = dir_to_java(direction)
|
101
79
|
node._java_node.getRelationships(type, dir)
|
102
80
|
end
|
103
81
|
|
104
|
-
def all_relationships(node)
|
105
|
-
|
106
|
-
Neo4j::RelationshipTraverser.new(node._java_node, [dsl.namespace_type], direction)
|
82
|
+
def all_relationships(node) #:nodoc:
|
83
|
+
Neo4j::RelationshipTraverser.new(node._java_node, [rel_type], direction)
|
107
84
|
end
|
108
85
|
|
109
|
-
def create_relationship_to(node, other)
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
dsl = self
|
116
|
-
from, to = node, other
|
117
|
-
end
|
118
|
-
|
119
|
-
java_type = type_to_java(dsl.namespace_type)
|
120
|
-
|
121
|
-
rel = from._java_node.create_relationship_to(to._java_node, java_type)
|
122
|
-
rel[:_classname] = dsl.relationship_class.to_s if dsl.relationship_class
|
123
|
-
|
124
|
-
# TODO - not implemented yet
|
125
|
-
# the from.neo_id is only used for cascade_delete_incoming since that node will be deleted when all the list items has been deleted.
|
126
|
-
# if cascade_delete_outgoing all nodes will be deleted when the root node is deleted
|
127
|
-
# if cascade_delete_incoming then the root node will be deleted when all root nodes' outgoing nodes are deleted
|
128
|
-
#rel[@dsl.cascade_delete_prop_name] = node.neo_id if @dsl.cascade_delete?
|
86
|
+
def create_relationship_to(node, other) # :nodoc:
|
87
|
+
from, to = incoming? ? [other, node] : [node, other]
|
88
|
+
java_type = type_to_java(rel_type)
|
89
|
+
|
90
|
+
rel = from._java_node.create_relationship_to(to._java_node, java_type)
|
91
|
+
rel[:_classname] = relationship_class.to_s if relationship_class
|
129
92
|
rel.wrapper
|
130
93
|
end
|
131
94
|
|
@@ -148,33 +111,74 @@ module Neo4j::Mapping
|
|
148
111
|
#
|
149
112
|
def to(*args)
|
150
113
|
@direction = :outgoing
|
151
|
-
|
152
|
-
|
114
|
+
|
115
|
+
if (args.size > 1)
|
116
|
+
raise "only one argument expected - the class of the node this relationship points to, got #{args.inspect}"
|
117
|
+
elsif (Class === args[0])
|
118
|
+
# handle e.g. has_n(:friends).to(class)
|
119
|
+
@target_class = args[0]
|
120
|
+
@rel_type = "#{@target_class}##{@method_id}"
|
121
|
+
else
|
122
|
+
raise "Expected a class for, got #{args[0]}"
|
123
|
+
end
|
153
124
|
self
|
154
125
|
end
|
155
126
|
|
156
127
|
# Specifies an incoming relationship.
|
157
128
|
# Will use the outgoing relationship given by the from class.
|
158
129
|
#
|
159
|
-
# ==== Example
|
130
|
+
# ==== Example, with prefix FileNode
|
160
131
|
# class FolderNode
|
161
132
|
# include Neo4j::NodeMixin
|
162
133
|
# has_n(:files).to(FileNode)
|
163
134
|
# end
|
164
135
|
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
136
|
+
# class FileNode
|
137
|
+
# include Neo4j::NodeMixin
|
138
|
+
# # will only traverse any incoming relationship of type files from node FileNode
|
139
|
+
# has_one(:folder).from(FileNode, :files)
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# file = FileNode.new
|
143
|
+
# # create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
|
144
|
+
# file.folder = FolderNode.new
|
145
|
+
#
|
146
|
+
# ==== Example, without prefix
|
147
|
+
#
|
148
|
+
# class FolderNode
|
149
|
+
# include Neo4j::NodeMixin
|
150
|
+
# has_n(:files)
|
151
|
+
# end
|
152
|
+
#
|
153
|
+
# class FileNode
|
154
|
+
# include Neo4j::NodeMixin
|
155
|
+
# has_one(:folder).from(:files) # will traverse any incoming relationship of type files
|
156
|
+
# end
|
157
|
+
#
|
158
|
+
# file = FileNode.new
|
159
|
+
# # create an outgoing relationship of type 'FileNode#files' from folder node to file
|
160
|
+
# file.folder = FolderNode.new
|
169
161
|
#
|
170
|
-
# file = FileNode.new
|
171
|
-
# # create an outgoing relationship of type 'FileNode#files' from folder node to file
|
172
|
-
# file.folder = FolderNode.new
|
173
162
|
#
|
174
163
|
def from(*args)
|
175
|
-
#(clazz, type)
|
176
164
|
@direction = :incoming
|
177
|
-
|
165
|
+
|
166
|
+
if (args.size > 1)
|
167
|
+
# handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
|
168
|
+
@rel_type = "#{@target_class}##{args[1]}"
|
169
|
+
@target_class = args[0]
|
170
|
+
other_class_dsl = @target_class._decl_rels[args[1]]
|
171
|
+
if other_class_dsl
|
172
|
+
@relationship = other_class_dsl.relationship_class
|
173
|
+
else
|
174
|
+
puts "WARNING: Unknown outgoing relationship #{args[1]} on #{@target_class}"
|
175
|
+
end
|
176
|
+
elsif (Symbol === args[0])
|
177
|
+
# handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
|
178
|
+
@rel_type = args[0]
|
179
|
+
else
|
180
|
+
raise "Expected a symbol for, got #{args[0]}"
|
181
|
+
end
|
178
182
|
self
|
179
183
|
end
|
180
184
|
|
data/lib/neo4j/mapping/has_n.rb
CHANGED
@@ -17,11 +17,11 @@ module Neo4j
|
|
17
17
|
def initialize(node, dsl) # :nodoc:
|
18
18
|
@node = node
|
19
19
|
@direction = dsl.direction
|
20
|
-
@dsl =
|
20
|
+
@dsl = dsl
|
21
21
|
end
|
22
22
|
|
23
23
|
def to_s
|
24
|
-
"HasN [#@direction, #{@node.neo_id} #{@dsl.
|
24
|
+
"HasN [#@direction, id: #{@node.neo_id} type: #{@dsl.rel_type} dsl:#{@dsl}]"
|
25
25
|
end
|
26
26
|
|
27
27
|
def size
|
@@ -74,11 +74,7 @@ module Neo4j
|
|
74
74
|
# self
|
75
75
|
#
|
76
76
|
def <<(other)
|
77
|
-
|
78
|
-
@dsl.create_relationship_to(other, @node)
|
79
|
-
else
|
80
|
-
@dsl.create_relationship_to(@node, other)
|
81
|
-
end
|
77
|
+
@dsl.create_relationship_to(@node, other)
|
82
78
|
self
|
83
79
|
end
|
84
80
|
end
|
data/lib/neo4j/neo4j.rb
CHANGED
data/lib/neo4j/node_traverser.rb
CHANGED
@@ -61,8 +61,14 @@ module Neo4j
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def new(other_node)
|
64
|
-
|
65
|
-
|
64
|
+
case @dir
|
65
|
+
when org.neo4j.graphdb.Direction::OUTGOING
|
66
|
+
@from.create_relationship_to(other_node, @type)
|
67
|
+
when org.neo4j.graphdb.Direction::INCOMING
|
68
|
+
other_node._java_node.create_relationship_to(@from, @type)
|
69
|
+
else
|
70
|
+
raise "Only allowed to create outgoing or incoming relationships (not #@dir)"
|
71
|
+
end
|
66
72
|
end
|
67
73
|
|
68
74
|
def both(type)
|
data/lib/neo4j/property.rb
CHANGED
@@ -27,8 +27,9 @@ module Neo4j
|
|
27
27
|
#
|
28
28
|
def attributes
|
29
29
|
attr = props
|
30
|
-
|
31
|
-
attr
|
30
|
+
ret = {}
|
31
|
+
attr.each_pair { |k, v| ret[k] = wrapper.respond_to?(k) ? wrapper.send(k) : v unless k.to_s[0] == ?_ }
|
32
|
+
ret
|
32
33
|
end
|
33
34
|
|
34
35
|
# Checks if the given key exist as a property.
|
@@ -107,4 +108,4 @@ module Neo4j
|
|
107
108
|
end
|
108
109
|
|
109
110
|
end
|
110
|
-
end
|
111
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Rails
|
3
|
+
module Finders
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
rule :_all
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# overwrite the index method to add find_by_xxx class methods
|
12
|
+
def index(*args)
|
13
|
+
field = args.first
|
14
|
+
module_eval <<-RUBY, __FILE__, __LINE__
|
15
|
+
def self.all_by_#{field}(value)
|
16
|
+
find_with_indexer("#{field}: \\"\#{value}\\"")
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.find_by_#{field}(value)
|
20
|
+
all_by_#{field}(value).first
|
21
|
+
end
|
22
|
+
RUBY
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
# load an id or array of ids from the database
|
28
|
+
def load(*ids)
|
29
|
+
result = ids.map { |id| Neo4j::Node.load(id) }
|
30
|
+
if ids.length == 1
|
31
|
+
result.first
|
32
|
+
else
|
33
|
+
result
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Behave like the ActiveRecord query interface
|
38
|
+
|
39
|
+
# Handle Model.find(params[:id])
|
40
|
+
|
41
|
+
# Model.find
|
42
|
+
# Model.find(:first)
|
43
|
+
|
44
|
+
# Model.find("1")
|
45
|
+
# Model.find(1)
|
46
|
+
|
47
|
+
# Model.find("name: test")
|
48
|
+
# Model.find(:name => "test")
|
49
|
+
|
50
|
+
# Model.find(:first, "name: test")
|
51
|
+
# Model.find(:first, { :name => "test" })
|
52
|
+
|
53
|
+
# Model.find(:first, :conditions => "name: test")
|
54
|
+
# Model.find(:first, :conditions => { :name => "test" })
|
55
|
+
|
56
|
+
# Model.find(:all, "name: test")
|
57
|
+
# Model.find(:all, { :name => "test" })
|
58
|
+
|
59
|
+
# Model.find(:all, :conditions => "name: test")
|
60
|
+
# Model.find(:all, :conditions => { :name => "test" })
|
61
|
+
def find(*args)
|
62
|
+
case args.first
|
63
|
+
when :all, :first
|
64
|
+
kind = args.shift
|
65
|
+
send(kind, *args)
|
66
|
+
else
|
67
|
+
find_with_ids(*args) or first(*args)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def all(*args)
|
72
|
+
if args.empty?
|
73
|
+
# use the _all rule to recover all the stored instances of this node
|
74
|
+
_all
|
75
|
+
else
|
76
|
+
args = normalize_args(*args)
|
77
|
+
# handle the special case of a search by id
|
78
|
+
if args.first.is_a?(Hash) && args.first[:id]
|
79
|
+
[find_with_ids(args.first[:id])].flatten
|
80
|
+
else
|
81
|
+
find_with_indexer(*args)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def first(*args)
|
87
|
+
all(*args).first
|
88
|
+
end
|
89
|
+
|
90
|
+
protected
|
91
|
+
def find_with_ids(*args)
|
92
|
+
if ((args.first.is_a?(String) || args.first.is_a?(Integer)) && args.first.to_i > 0)
|
93
|
+
load(*args.map { |p| p.to_i })
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def find_with_indexer(*args)
|
98
|
+
hits = _indexer.find(*args)
|
99
|
+
# We need to save this so that the Rack Neo4j::Rails:LuceneConnection::Closer can close it
|
100
|
+
Thread.current[:neo4j_lucene_connection] ||= []
|
101
|
+
Thread.current[:neo4j_lucene_connection] << hits
|
102
|
+
hits
|
103
|
+
end
|
104
|
+
|
105
|
+
def normalize_args(*args)
|
106
|
+
options = args.extract_options!
|
107
|
+
|
108
|
+
if options.present?
|
109
|
+
if options[:conditions]
|
110
|
+
args << options[:conditions]
|
111
|
+
else
|
112
|
+
args << options
|
113
|
+
end
|
114
|
+
end
|
115
|
+
args
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Rails
|
3
|
+
module Mapping
|
4
|
+
module Property
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def []=(key, value)
|
8
|
+
attribute_will_change!(key.to_s) if self[key.to_s] != value
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
# Handle some additional options for the property
|
14
|
+
#
|
15
|
+
# Set a default - :default => "default"
|
16
|
+
# Prpoerty must be there - :null => false
|
17
|
+
# Property has a length limit - :limit => 128
|
18
|
+
def property(*args)
|
19
|
+
super
|
20
|
+
handle_property_options_for(args.first)
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
def handle_property_options_for(property)
|
25
|
+
options = _decl_props[property.to_sym]
|
26
|
+
|
27
|
+
write_inheritable_attribute(:attribute_defaults, property => options[:default]) if options[:default]
|
28
|
+
validates(property, :non_nil => true) if options.has_key?(:null) && options[:null] == false
|
29
|
+
validates(property, :length => { :maximum => options[:limit] }) if options[:limit]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/neo4j/rails/model.rb
CHANGED
@@ -2,6 +2,7 @@ module Neo4j
|
|
2
2
|
module Rails
|
3
3
|
class Model
|
4
4
|
include Neo4j::NodeMixin
|
5
|
+
|
5
6
|
include ActiveModel::Serializers::Xml
|
6
7
|
include ActiveModel::Validations
|
7
8
|
include ActiveModel::Dirty
|
@@ -9,14 +10,19 @@ module Neo4j
|
|
9
10
|
|
10
11
|
extend ActiveModel::Naming
|
11
12
|
extend ActiveModel::Callbacks
|
12
|
-
|
13
|
+
|
14
|
+
include Neo4j::Rails::Validations
|
15
|
+
extend Neo4j::Rails::Validations::ClassMethods
|
16
|
+
|
17
|
+
include Finders # ActiveRecord style find
|
18
|
+
include Mapping::Property # allows some additional options on the #property class method
|
19
|
+
|
13
20
|
extend TxMethods
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
rule :all
|
22
|
+
class_inheritable_hash :attribute_defaults
|
23
|
+
self.attribute_defaults = {}
|
18
24
|
|
19
|
-
|
25
|
+
define_model_callbacks :create, :save, :update, :destroy
|
20
26
|
|
21
27
|
class RecordInvalidError < RuntimeError
|
22
28
|
attr_reader :record
|
@@ -63,31 +69,15 @@ module Neo4j
|
|
63
69
|
self.class.define_attribute_methods(self.class._decl_props.keys)
|
64
70
|
# try again
|
65
71
|
send(method_id, *args, &block)
|
72
|
+
elsif property?(method_id)
|
73
|
+
send(:[], method_id)
|
74
|
+
else
|
75
|
+
super
|
66
76
|
end
|
67
77
|
end
|
68
78
|
|
69
|
-
# redefine this methods so that ActiveModel::Dirty will work
|
70
|
-
def []=(key, new_value)
|
71
|
-
key = key.to_s
|
72
|
-
unless key[0] == ?_
|
73
|
-
old_value = self.send(:[], key)
|
74
|
-
attribute_will_change!(key) unless old_value == new_value
|
75
|
-
end
|
76
|
-
Neo4j::Rails::Transaction.running? ? super : Neo4j::Rails::Transaction.run { super }
|
77
|
-
end
|
78
|
-
|
79
|
-
def attribute_will_change!(attr)
|
80
|
-
begin
|
81
|
-
value = __send__(:[], attr)
|
82
|
-
value = value.duplicable? ? value.clone : value
|
83
|
-
rescue TypeError, NoMethodError
|
84
|
-
end
|
85
|
-
changed_attributes[attr] = value
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
79
|
def read_attribute_for_validation(key)
|
90
|
-
|
80
|
+
send(key)
|
91
81
|
end
|
92
82
|
|
93
83
|
def attributes=(values)
|
@@ -159,9 +149,9 @@ module Neo4j
|
|
159
149
|
end
|
160
150
|
end
|
161
151
|
|
162
|
-
def save
|
152
|
+
def save(*args)
|
163
153
|
_run_save_callbacks do
|
164
|
-
if create_or_update_node
|
154
|
+
if create_or_update_node(*args)
|
165
155
|
true
|
166
156
|
else
|
167
157
|
# if not valid we should rollback the transaction so that the changes does not take place.
|
@@ -172,11 +162,13 @@ module Neo4j
|
|
172
162
|
end
|
173
163
|
end
|
174
164
|
|
175
|
-
def create_or_update_node
|
176
|
-
|
165
|
+
def create_or_update_node(options = {})
|
166
|
+
options.reverse_merge!({ :validate => true })
|
167
|
+
|
168
|
+
if options[:validate] == false || valid?(:save)
|
177
169
|
if new_record?
|
178
170
|
_run_create_callbacks do
|
179
|
-
if valid?(:create)
|
171
|
+
if options[:validate] == false || valid?(:create)
|
180
172
|
node = Neo4j::Node.new(props)
|
181
173
|
return false unless _java_node.save_nested(node)
|
182
174
|
init_on_load(node)
|
@@ -188,7 +180,7 @@ module Neo4j
|
|
188
180
|
end
|
189
181
|
else
|
190
182
|
_run_update_callbacks do
|
191
|
-
if valid?(:update)
|
183
|
+
if options[:validate] == false || valid?(:update)
|
192
184
|
clear_changes
|
193
185
|
self.updated_at = DateTime.now if Neo4j::Config[:timestamps] && respond_to?(:updated_at)
|
194
186
|
true
|
@@ -208,8 +200,8 @@ module Neo4j
|
|
208
200
|
reload_from_database or set_deleted_properties and return self
|
209
201
|
end
|
210
202
|
|
211
|
-
def save!
|
212
|
-
raise RecordInvalidError.new(self) unless save
|
203
|
+
def save!(*args)
|
204
|
+
raise RecordInvalidError.new(self) unless save(*args)
|
213
205
|
end
|
214
206
|
|
215
207
|
# Returns if the record is persisted, i.e. it’s not a new record and it was not destroyed
|
@@ -245,7 +237,8 @@ module Neo4j
|
|
245
237
|
@_deleted
|
246
238
|
end
|
247
239
|
|
248
|
-
|
240
|
+
# TODO: []= shouldn't need to be in a transaction because it shouldn't update the DB. Need to refactor the @_java_node handling stuff if we want that to be the case though
|
241
|
+
tx_methods :destroy, :create_or_update_node, :[]=, :update_attributes, :update_attributes!, :update_nested_attributes
|
249
242
|
|
250
243
|
# --------------------------------------
|
251
244
|
# Class Methods
|
@@ -259,45 +252,10 @@ module Neo4j
|
|
259
252
|
wrapped = self.orig_new
|
260
253
|
value = Neo4j::Rails::Value.new(wrapped)
|
261
254
|
wrapped.init_on_load(value)
|
262
|
-
wrapped.attributes=
|
255
|
+
wrapped.attributes = initial_attributes(*args)
|
263
256
|
wrapped
|
264
257
|
end
|
265
258
|
|
266
|
-
# Behave like ActiveModel
|
267
|
-
def all_with_args(*args)
|
268
|
-
if args.empty?
|
269
|
-
all_without_args
|
270
|
-
else
|
271
|
-
hits = find_without_checking_for_id(*args)
|
272
|
-
# We need to save this so that the Rack Neo4j::Rails:LuceneConnection::Closer can close it
|
273
|
-
Thread.current[:neo4j_lucene_connection] ||= []
|
274
|
-
Thread.current[:neo4j_lucene_connection] << hits
|
275
|
-
hits
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
alias_method_chain :all, :args
|
280
|
-
|
281
|
-
# Handle Model.find(params[:id])
|
282
|
-
def find_with_checking_for_id(*args)
|
283
|
-
if args.length == 1 && String === args[0] && args[0].to_i != 0
|
284
|
-
load(*args)
|
285
|
-
else
|
286
|
-
all_with_args(*args).first
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
alias_method_chain :find, :checking_for_id
|
291
|
-
|
292
|
-
def load(*ids)
|
293
|
-
result = ids.map { |id| Neo4j::Node.load(id) }
|
294
|
-
if ids.length == 1
|
295
|
-
result.first
|
296
|
-
else
|
297
|
-
result
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
259
|
alias_method :_orig_create, :create
|
302
260
|
|
303
261
|
def create(*args)
|
@@ -308,10 +266,10 @@ module Neo4j
|
|
308
266
|
new(*args).tap { |o| o.save! }
|
309
267
|
end
|
310
268
|
|
311
|
-
tx_methods :create, :create!
|
312
|
-
|
313
269
|
def transaction(&block)
|
314
|
-
Neo4j::Rails::Transaction.run
|
270
|
+
Neo4j::Rails::Transaction.run do |tx|
|
271
|
+
block.call(tx)
|
272
|
+
end
|
315
273
|
end
|
316
274
|
|
317
275
|
def accepts_nested_attributes_for(*attr_names)
|
@@ -320,29 +278,33 @@ module Neo4j
|
|
320
278
|
attr_names.each do |association_name|
|
321
279
|
rel = self._decl_rels[association_name.to_sym]
|
322
280
|
raise "No relationship declared with has_n or has_one with type #{association_name}" unless rel
|
323
|
-
|
324
|
-
raise "Can't use accepts_nested_attributes_for(#{association_name}) since it has not defined which class it has a relationship to, use has_n(#{association_name}).to(MyOtherClass)" unless
|
325
|
-
type = rel.
|
281
|
+
target_class = rel.target_class
|
282
|
+
raise "Can't use accepts_nested_attributes_for(#{association_name}) since it has not defined which class it has a relationship to, use has_n(#{association_name}).to(MyOtherClass)" unless target_class
|
283
|
+
type = rel.rel_type
|
326
284
|
has_one = rel.has_one?
|
327
285
|
|
328
286
|
send(:define_method, "#{association_name}_attributes=") do |attributes|
|
329
287
|
if has_one
|
330
|
-
update_nested_attributes(type,
|
288
|
+
update_nested_attributes(type, target_class, true, attributes, options)
|
331
289
|
else
|
332
290
|
if attributes.is_a?(Array)
|
333
291
|
attributes.each do |attr|
|
334
|
-
update_nested_attributes(type,
|
292
|
+
update_nested_attributes(type, target_class, false, attr, options)
|
335
293
|
end
|
336
294
|
else
|
337
295
|
attributes.each_value do |attr|
|
338
|
-
update_nested_attributes(type,
|
296
|
+
update_nested_attributes(type, target_class, false, attr, options)
|
339
297
|
end
|
340
298
|
end
|
341
299
|
end
|
342
300
|
end
|
343
|
-
tx_methods("#{association_name}_attributes=")
|
344
301
|
end
|
345
302
|
end
|
303
|
+
|
304
|
+
protected
|
305
|
+
def initial_attributes(*args)
|
306
|
+
args.first.is_a?(Hash) ? args.first.reverse_merge(attribute_defaults) : attribute_defaults
|
307
|
+
end
|
346
308
|
end
|
347
309
|
|
348
310
|
private
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Rails
|
3
|
+
module Validations
|
4
|
+
class NonNilValidator < ActiveModel::EachValidator
|
5
|
+
def validate_each(record, attribute, value)
|
6
|
+
record.errors.add(attribute, :nil, options.merge(:value => value)) if value.nil?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -1,29 +1,31 @@
|
|
1
1
|
module Neo4j
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
2
|
+
module Rails
|
3
|
+
module Validations
|
4
|
+
class UniquenessValidator < ActiveModel::EachValidator
|
5
|
+
def initialize(options)
|
6
|
+
super(options.reverse_merge(:case_sensitive => true))
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup(klass)
|
10
|
+
@attributes.each do |attribute|
|
11
|
+
if klass.index_type_for(attribute) != :exact
|
12
|
+
raise "Can't validate property #{attribute} on class #{klass} since there is no :exact lucene index on that property or the index declaration #{attribute} comes after the validation declaration in #{klass} (try to move it before the validation rules)"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_each(record, attribute, value)
|
18
|
+
if record.class.find("#{attribute}: \"#{value}\"")
|
19
|
+
record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
def validates_uniqueness_of(*attr_names)
|
26
|
+
validates_with UniquenessValidator, _merge_attributes(attr_names)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
29
31
|
end
|
data/lib/neo4j/rails/value.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Neo4j::Rails
|
2
2
|
|
3
3
|
class Value
|
4
|
-
include
|
4
|
+
include ValueProperties
|
5
5
|
include org.neo4j.graphdb.Node
|
6
6
|
|
7
7
|
def initialize(wrapper)
|
@@ -60,7 +60,7 @@ module Neo4j::Rails
|
|
60
60
|
|
61
61
|
class Relationship
|
62
62
|
include org.neo4j.graphdb.Relationship
|
63
|
-
include
|
63
|
+
include ValueProperties
|
64
64
|
|
65
65
|
attr_reader :end_node, :start_node
|
66
66
|
|
@@ -1,7 +1,7 @@
|
|
1
|
+
# provide some properties before we have a real node or relationship
|
1
2
|
module Neo4j
|
2
3
|
module Rails
|
3
|
-
|
4
|
-
module Properties # :nodoc:
|
4
|
+
module ValueProperties
|
5
5
|
include Neo4j::Property
|
6
6
|
|
7
7
|
# override Neo4j::Property#props
|
@@ -40,13 +40,29 @@ module Neo4j
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
class TimeConverter
|
45
|
+
class << self
|
46
|
+
# Converts the given DateTime (UTC) value to an Fixnum.
|
47
|
+
# Only utc times are supported !
|
48
|
+
def to_java(value)
|
49
|
+
return nil if value.nil?
|
50
|
+
value.utc.to_i
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_ruby(value)
|
54
|
+
return nil if value.nil?
|
55
|
+
Time.at(value).utc
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
43
59
|
|
44
60
|
# Converts the given value to a Java type by using the registered converters.
|
45
61
|
# It just looks at the class of the given value and will convert it if there is a converter
|
46
62
|
# registered (in Neo4j::Config) for this value.
|
47
63
|
def self.convert(value)
|
48
64
|
type = value.class
|
49
|
-
converter = Neo4j
|
65
|
+
converter = Neo4j.converters[type]
|
50
66
|
return value unless converter
|
51
67
|
converter.to_java(value)
|
52
68
|
end
|
@@ -56,7 +72,7 @@ module Neo4j
|
|
56
72
|
def self.to_java(clazz, key, value)
|
57
73
|
type = clazz._decl_props[key] && clazz._decl_props[key][:type]
|
58
74
|
if type
|
59
|
-
converter = Neo4j
|
75
|
+
converter = Neo4j.converters[type]
|
60
76
|
converter ? converter.to_java(value) : value
|
61
77
|
elsif clazz.superclass != Object
|
62
78
|
to_java(clazz.superclass, key, value)
|
@@ -70,7 +86,7 @@ module Neo4j
|
|
70
86
|
def self.to_ruby(clazz, key, value)
|
71
87
|
type = clazz._decl_props[key] && clazz._decl_props[key][:type]
|
72
88
|
if type
|
73
|
-
converter = Neo4j
|
89
|
+
converter = Neo4j.converters[type]
|
74
90
|
converter ? converter.to_ruby(value) : value
|
75
91
|
elsif clazz.superclass != Object
|
76
92
|
to_ruby(clazz.superclass, key, value)
|
@@ -78,7 +94,5 @@ module Neo4j
|
|
78
94
|
value
|
79
95
|
end
|
80
96
|
end
|
81
|
-
|
82
|
-
Neo4j::Config[:converters] = {Date => DateConverter, DateTime => DateTimeConverter}
|
83
97
|
end
|
84
98
|
end
|
data/lib/neo4j/version.rb
CHANGED
metadata
CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
|
|
7
7
|
- 0
|
8
8
|
- 0
|
9
9
|
- beta
|
10
|
-
-
|
11
|
-
version: 1.0.0.beta.
|
10
|
+
- 20
|
11
|
+
version: 1.0.0.beta.20
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Andreas Ronge
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-11-
|
19
|
+
date: 2010-11-16 00:00:00 +01:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -61,7 +61,7 @@ files:
|
|
61
61
|
- lib/neo4j.rb
|
62
62
|
- lib/generators/neo4j.rb
|
63
63
|
- lib/generators/neo4j/model/model_generator.rb
|
64
|
-
- lib/generators/neo4j/model/templates/model.
|
64
|
+
- lib/generators/neo4j/model/templates/model.erb
|
65
65
|
- lib/neo4j/event_handler.rb
|
66
66
|
- lib/neo4j/model.rb
|
67
67
|
- lib/neo4j/type_converters.rb
|
@@ -86,9 +86,12 @@ files:
|
|
86
86
|
- lib/neo4j/rails/lucene_connection_closer.rb
|
87
87
|
- lib/neo4j/rails/transaction.rb
|
88
88
|
- lib/neo4j/rails/tx_methods.rb
|
89
|
-
- lib/neo4j/rails/
|
89
|
+
- lib/neo4j/rails/value_properties.rb
|
90
|
+
- lib/neo4j/rails/finders.rb
|
90
91
|
- lib/neo4j/rails/value.rb
|
92
|
+
- lib/neo4j/rails/mapping/property.rb
|
91
93
|
- lib/neo4j/rails/validations/uniqueness.rb
|
94
|
+
- lib/neo4j/rails/validations/non_nil.rb
|
92
95
|
- lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar
|
93
96
|
- lib/neo4j/jars/lucene-core-3.0.2.jar
|
94
97
|
- lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar
|
@@ -104,9 +107,9 @@ files:
|
|
104
107
|
- lib/neo4j/mapping/class_methods/root.rb
|
105
108
|
- lib/neo4j/mapping/class_methods/init_rel.rb
|
106
109
|
- lib/neo4j/mapping/class_methods/relationship.rb
|
107
|
-
- lib/neo4j/index/index_registry.rb
|
108
110
|
- lib/neo4j/index/indexer.rb
|
109
111
|
- lib/neo4j/index/lucene_query.rb
|
112
|
+
- lib/neo4j/index/indexer_registry.rb
|
110
113
|
- lib/neo4j/index/class_methods.rb
|
111
114
|
- lib/neo4j/index/index.rb
|
112
115
|
- README.rdoc
|