neo4j 1.0.0.beta.19 → 1.0.0.beta.20
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/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
|