neo4j 1.0.0.beta.20 → 3.0.0.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +243 -0
- data/CONTRIBUTORS +12 -0
- data/Gemfile +10 -11
- data/README.md +23 -0
- data/bin/neo4j-jars +33 -0
- data/config/locales/en.yml +5 -0
- data/config/neo4j/config.yml +98 -0
- data/lib/neo4j.rb +28 -68
- data/lib/neo4j/active_node.rb +60 -0
- data/lib/neo4j/active_node/callbacks.rb +41 -0
- data/lib/neo4j/active_node/has_n.rb +138 -0
- data/lib/neo4j/active_node/has_n/decl_rel.rb +236 -0
- data/lib/neo4j/active_node/has_n/nodes.rb +82 -0
- data/lib/neo4j/active_node/identity.rb +28 -0
- data/lib/neo4j/active_node/initialize.rb +24 -0
- data/lib/neo4j/active_node/labels.rb +142 -0
- data/lib/neo4j/active_node/persistence.rb +193 -0
- data/lib/neo4j/active_node/property.rb +41 -0
- data/lib/neo4j/active_node/rels.rb +11 -0
- data/lib/neo4j/active_node/validations.rb +51 -0
- data/lib/neo4j/railtie.rb +40 -0
- data/lib/neo4j/version.rb +1 -1
- data/lib/neo4j/wrapper.rb +25 -0
- data/neo4j.gemspec +25 -15
- metadata +136 -149
- data/README.rdoc +0 -135
- data/lib/generators/neo4j.rb +0 -65
- data/lib/generators/neo4j/model/model_generator.rb +0 -39
- data/lib/generators/neo4j/model/templates/model.erb +0 -7
- data/lib/neo4j/config.rb +0 -153
- data/lib/neo4j/database.rb +0 -56
- data/lib/neo4j/equal.rb +0 -21
- data/lib/neo4j/event_handler.rb +0 -116
- data/lib/neo4j/index/class_methods.rb +0 -62
- data/lib/neo4j/index/index.rb +0 -33
- data/lib/neo4j/index/indexer.rb +0 -312
- data/lib/neo4j/index/indexer_registry.rb +0 -68
- data/lib/neo4j/index/lucene_query.rb +0 -191
- data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
- data/lib/neo4j/jars/lucene-core-3.0.2.jar +0 -0
- data/lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar +0 -0
- data/lib/neo4j/load.rb +0 -21
- data/lib/neo4j/mapping/class_methods/init_node.rb +0 -50
- data/lib/neo4j/mapping/class_methods/init_rel.rb +0 -35
- data/lib/neo4j/mapping/class_methods/property.rb +0 -80
- data/lib/neo4j/mapping/class_methods/relationship.rb +0 -90
- data/lib/neo4j/mapping/class_methods/root.rb +0 -31
- data/lib/neo4j/mapping/class_methods/rule.rb +0 -295
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +0 -214
- data/lib/neo4j/mapping/has_n.rb +0 -83
- data/lib/neo4j/mapping/node_mixin.rb +0 -97
- data/lib/neo4j/mapping/relationship_mixin.rb +0 -117
- data/lib/neo4j/model.rb +0 -4
- data/lib/neo4j/neo4j.rb +0 -95
- data/lib/neo4j/node.rb +0 -131
- data/lib/neo4j/node_mixin.rb +0 -4
- data/lib/neo4j/node_relationship.rb +0 -149
- data/lib/neo4j/node_traverser.rb +0 -157
- data/lib/neo4j/property.rb +0 -111
- data/lib/neo4j/rails/finders.rb +0 -121
- data/lib/neo4j/rails/lucene_connection_closer.rb +0 -19
- data/lib/neo4j/rails/mapping/property.rb +0 -35
- data/lib/neo4j/rails/model.rb +0 -324
- data/lib/neo4j/rails/railtie.rb +0 -16
- data/lib/neo4j/rails/transaction.rb +0 -67
- data/lib/neo4j/rails/tx_methods.rb +0 -15
- data/lib/neo4j/rails/validations/non_nil.rb +0 -11
- data/lib/neo4j/rails/validations/uniqueness.rb +0 -31
- data/lib/neo4j/rails/value.rb +0 -124
- data/lib/neo4j/rails/value_properties.rb +0 -29
- data/lib/neo4j/relationship.rb +0 -169
- data/lib/neo4j/relationship_mixin.rb +0 -4
- data/lib/neo4j/relationship_traverser.rb +0 -92
- data/lib/neo4j/to_java.rb +0 -31
- data/lib/neo4j/transaction.rb +0 -68
- data/lib/neo4j/type_converters.rb +0 -98
data/lib/neo4j/node_mixin.rb
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
3
|
-
|
4
|
-
module NodeRelationship
|
5
|
-
include ToJava
|
6
|
-
|
7
|
-
|
8
|
-
# Returns the outgoing nodes for this node.
|
9
|
-
#
|
10
|
-
# ==== Returns
|
11
|
-
# a Neo4j::NodeTraverser which can be used to further specify which nodes should be included
|
12
|
-
# in traversal by using the <tt>depth</tt>, <tt>filter</tt> and <tt>prune</tt> methods.
|
13
|
-
#
|
14
|
-
# ==== Examples
|
15
|
-
# # Find all my friends (nodes of depth 1 of type <tt>friends</tt>)
|
16
|
-
# me.outgoing(:friends).each {|friend| puts friend[:name]}
|
17
|
-
#
|
18
|
-
# # Find all my friends and their friends (nodes of depth 1 of type <tt>friends</tt>)
|
19
|
-
# # me.outgoing(:friends).depth(2).each {|friend| puts friend[:name]}
|
20
|
-
#
|
21
|
-
# # Find all my friends and include my self in the result
|
22
|
-
# me.outgoing(:friends).depth(4).include_start_node.each {...}
|
23
|
-
#
|
24
|
-
# # Find all my friends friends friends, etc. at any depth
|
25
|
-
# me.outgoing(:friends).depth(:all).each {...}
|
26
|
-
#
|
27
|
-
# # Find all my friends friends but do not include my friends (only depth == 2)
|
28
|
-
# me.outgoing(:friends).depth(2).filter{|path| path.length == 2}
|
29
|
-
#
|
30
|
-
# # Find all my friends but 'cut off' some parts of the traversal path
|
31
|
-
# me.outgoing(:friends).depth(42).prune(|path| an_expression_using_path_returning_true_false }
|
32
|
-
#
|
33
|
-
# # Find all my friends and work colleges
|
34
|
-
# me.outgoing(:friends).outgoing(:work).each {...}
|
35
|
-
#
|
36
|
-
# Of course all the methods <tt>outgoing</tt>, <tt>incoming</tt>, <tt>both</tt>, <tt>depth</tt>, <tt>include_start_node</tt>, <tt>filter</tt>, and <tt>prune</tt> can be combined.
|
37
|
-
#
|
38
|
-
def outgoing(type)
|
39
|
-
if type
|
40
|
-
NodeTraverser.new(self).outgoing(type)
|
41
|
-
else
|
42
|
-
raise "not implemented yet"
|
43
|
-
NodeTraverser.new(self)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
# Returns the incoming nodes of given type(s).
|
49
|
-
#
|
50
|
-
# See #outgoing
|
51
|
-
#
|
52
|
-
def incoming(type)
|
53
|
-
if type
|
54
|
-
NodeTraverser.new(self).incoming(type)
|
55
|
-
else
|
56
|
-
raise "not implemented yet"
|
57
|
-
NodeTraverser.new(self)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns both incoming and outgoing nodes of given types(s)
|
62
|
-
#
|
63
|
-
# If a type is not given then it will return all types of relationships.
|
64
|
-
#
|
65
|
-
# See #outgoing
|
66
|
-
#
|
67
|
-
def both(type=nil)
|
68
|
-
if type
|
69
|
-
NodeTraverser.new(self).both(type)
|
70
|
-
else
|
71
|
-
NodeTraverser.new(self) # default is both
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
# Returns an enumeration of relationship objects.
|
77
|
-
# It always returns relationship of depth one.
|
78
|
-
#
|
79
|
-
# See Neo4j::Relationship
|
80
|
-
#
|
81
|
-
# ==== Examples
|
82
|
-
# # Return both incoming and outgoing relationships
|
83
|
-
# me.rels(:friends, :work).each {|relationship|...}
|
84
|
-
#
|
85
|
-
# # Only return outgoing relationship of given type
|
86
|
-
# me.rels(:friends).outgoing.first.end_node # => my friend node
|
87
|
-
#
|
88
|
-
def rels(*type)
|
89
|
-
RelationshipTraverser.new(self, type, :both)
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
# Returns the only relationship of a given type and direction that is attached to this node, or null.
|
94
|
-
# This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or
|
95
|
-
# one relationships of a given type and direction to another node.
|
96
|
-
# Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships
|
97
|
-
# exist, it is a fatal error that should generate an unchecked exception. This method reflects that semantics and
|
98
|
-
# returns either:
|
99
|
-
#
|
100
|
-
# * nil if there are zero relationships of the given type and direction,
|
101
|
-
# * the relationship if there's exactly one, or
|
102
|
-
# * raise an exception in all other cases.
|
103
|
-
def rel(dir, type)
|
104
|
-
result = _rel(dir, type)
|
105
|
-
result && result.wrapper
|
106
|
-
end
|
107
|
-
|
108
|
-
# Same as rel but does not return a ruby wrapped object but instead returns the Java object.
|
109
|
-
def _rel(dir, type)
|
110
|
-
get_single_relationship(type_to_java(type), dir_to_java(dir))
|
111
|
-
end
|
112
|
-
|
113
|
-
# Returns the raw java neo4j relationship object.
|
114
|
-
def _rels(dir=:both, *types)
|
115
|
-
if types.size > 1
|
116
|
-
java_types = types.inject([]) { |result, type| result << type_to_java(type) }.to_java(:'org.neo4j.graphdb.RelationshipType')
|
117
|
-
get_relationships(java_types)
|
118
|
-
elsif types.size == 1
|
119
|
-
get_relationships(type_to_java(types[0], dir_to_java(dir)))
|
120
|
-
elsif dir == :both
|
121
|
-
get_relationships(dir_to_java(dir))
|
122
|
-
else
|
123
|
-
raise "illegal argument, does not accept #{dir} #{types.join(',')} - only dir=:both for any relationship types"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Check if the given relationship exists
|
128
|
-
# Returns true if there are one or more relationships from this node to other nodes
|
129
|
-
# with the given relationship.
|
130
|
-
#
|
131
|
-
# ==== Parameters
|
132
|
-
# type:: the key and value to be set, default any type
|
133
|
-
# dir:: optional default :both (either, :outgoing, :incoming, :both)
|
134
|
-
#
|
135
|
-
# ==== Returns
|
136
|
-
# true if one or more relationships exists for the given type and dir
|
137
|
-
# otherwise false
|
138
|
-
#
|
139
|
-
def rel? (type=nil, dir=:both)
|
140
|
-
if type
|
141
|
-
hasRelationship(type_to_java(type), dir_to_java(dir))
|
142
|
-
else
|
143
|
-
hasRelationship
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|
data/lib/neo4j/node_traverser.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
3
|
-
class PruneEvaluator # :nodoc:
|
4
|
-
include org.neo4j.graphdb.traversal.PruneEvaluator
|
5
|
-
def initialize(proc)
|
6
|
-
@proc = proc
|
7
|
-
end
|
8
|
-
|
9
|
-
def prune_after(path)
|
10
|
-
@proc.call(path)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class FilterPredicate # :nodoc:
|
15
|
-
include org.neo4j.helpers.Predicate
|
16
|
-
def initialize
|
17
|
-
@procs = []
|
18
|
-
end
|
19
|
-
|
20
|
-
def add(proc)
|
21
|
-
@procs << proc
|
22
|
-
end
|
23
|
-
|
24
|
-
def include_start_node
|
25
|
-
@include_start_node = true
|
26
|
-
end
|
27
|
-
|
28
|
-
def accept(path)
|
29
|
-
return false if @include_start_node && path.length == 0
|
30
|
-
# find the first filter which returns false
|
31
|
-
# if not found then we will accept this path
|
32
|
-
@procs.find {|p| !p.call(path)}.nil?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
class NodeTraverser
|
38
|
-
include Enumerable
|
39
|
-
include ToJava
|
40
|
-
|
41
|
-
def initialize(from, type = nil, dir=nil)
|
42
|
-
@from = from
|
43
|
-
@depth = 1
|
44
|
-
if type.nil? || dir.nil?
|
45
|
-
@td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first()
|
46
|
-
else
|
47
|
-
@type = type_to_java(type)
|
48
|
-
@dir = dir_to_java(dir)
|
49
|
-
@td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first().relationships(@type, @dir)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
def to_s
|
55
|
-
"NodeTraverser [from: #{@from.neo_id} depth: #{@depth} type: #{@type} dir:#{@dir}"
|
56
|
-
end
|
57
|
-
|
58
|
-
def <<(other_node)
|
59
|
-
new(other_node)
|
60
|
-
self
|
61
|
-
end
|
62
|
-
|
63
|
-
def new(other_node)
|
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
|
72
|
-
end
|
73
|
-
|
74
|
-
def both(type)
|
75
|
-
@type = type_to_java(type) if type
|
76
|
-
@dir = dir_to_java(:both)
|
77
|
-
@td = @td.relationships(type_to_java(type), @dir)
|
78
|
-
self
|
79
|
-
end
|
80
|
-
|
81
|
-
def outgoing(type)
|
82
|
-
@type = type_to_java(type) if type
|
83
|
-
@dir = dir_to_java(:outgoing)
|
84
|
-
@td = @td.relationships(type_to_java(type), @dir)
|
85
|
-
self
|
86
|
-
end
|
87
|
-
|
88
|
-
def incoming(type)
|
89
|
-
@type = type_to_java(type) if type
|
90
|
-
@dir = dir_to_java(:incoming)
|
91
|
-
@td = @td.relationships(type_to_java(type), @dir)
|
92
|
-
self
|
93
|
-
end
|
94
|
-
|
95
|
-
def filter_method(name, &proc)
|
96
|
-
# add method name
|
97
|
-
singelton = class << self; self; end
|
98
|
-
singelton.send(:define_method, name) {filter &proc}
|
99
|
-
self
|
100
|
-
end
|
101
|
-
|
102
|
-
def prune(&block)
|
103
|
-
@td = @td.prune(PruneEvaluator.new(block))
|
104
|
-
self
|
105
|
-
end
|
106
|
-
|
107
|
-
def filter(&block)
|
108
|
-
# we keep a reference to filter predicate since only one filter is allowed and we might want to modify it
|
109
|
-
@filter_predicate ||= FilterPredicate.new
|
110
|
-
@filter_predicate.add(block)
|
111
|
-
@td = @td.filter(@filter_predicate)
|
112
|
-
self
|
113
|
-
end
|
114
|
-
|
115
|
-
# Sets depth, if :all then it will traverse any depth
|
116
|
-
def depth(d)
|
117
|
-
@depth = d
|
118
|
-
self
|
119
|
-
end
|
120
|
-
|
121
|
-
def include_start_node
|
122
|
-
@include_start_node = true
|
123
|
-
self
|
124
|
-
end
|
125
|
-
|
126
|
-
def size
|
127
|
-
[*self].size
|
128
|
-
end
|
129
|
-
|
130
|
-
alias_method :length, :size
|
131
|
-
|
132
|
-
def [](index)
|
133
|
-
each_with_index {|node,i| break node if index == i}
|
134
|
-
end
|
135
|
-
|
136
|
-
def empty?
|
137
|
-
first == nil
|
138
|
-
end
|
139
|
-
|
140
|
-
def each
|
141
|
-
iterator.each {|i| yield i.wrapper}
|
142
|
-
end
|
143
|
-
|
144
|
-
def iterator
|
145
|
-
unless @include_start_node
|
146
|
-
if @filter_predicate
|
147
|
-
@filter_predicate.include_start_node
|
148
|
-
else
|
149
|
-
@td = @td.filter(org.neo4j.kernel.Traversal.return_all_but_start_node)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
@td = @td.prune(org.neo4j.kernel.Traversal.pruneAfterDepth( @depth ) ) unless @depth == :all
|
153
|
-
@td.traverse(@from).nodes
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
data/lib/neo4j/property.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module Property
|
3
|
-
|
4
|
-
# Returns a hash of all properties
|
5
|
-
# It also include the id of the node with the key <tt>_neo_id</tt>
|
6
|
-
#
|
7
|
-
def props
|
8
|
-
ret = {"_neo_id" => neo_id}
|
9
|
-
iter = getPropertyKeys.iterator
|
10
|
-
while (iter.hasNext) do
|
11
|
-
key = iter.next
|
12
|
-
ret[key] = get_property(key)
|
13
|
-
end
|
14
|
-
ret
|
15
|
-
end
|
16
|
-
|
17
|
-
# Returns the unique id of this node.
|
18
|
-
# Ids are garbage collected over time so they are only guaranteed to be unique during a specific time span:
|
19
|
-
# if the node is deleted, it's likely that a new node at some point will get the old id. Note:
|
20
|
-
# this makes node ids brittle as public APIs.
|
21
|
-
def neo_id
|
22
|
-
getId
|
23
|
-
end
|
24
|
-
|
25
|
-
# Returns a hash of properties with keys not starting with <tt>_</tt>
|
26
|
-
# That means that the neo_id will not be included in the returned hash.
|
27
|
-
#
|
28
|
-
def attributes
|
29
|
-
attr = props
|
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
|
33
|
-
end
|
34
|
-
|
35
|
-
# Checks if the given key exist as a property.
|
36
|
-
def property?(key)
|
37
|
-
has_property?(key.to_s)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Updates this node/relationship's properties by using the provided struct/hash.
|
41
|
-
# If the option <code>{:strict => true}</code> is given, any properties present on
|
42
|
-
# the node but not present in the hash will be removed from the node.
|
43
|
-
#
|
44
|
-
# ==== Parameters
|
45
|
-
# struct_or_hash:: the key and value to be set, should respond to <tt>each_pair</tt>
|
46
|
-
# options:: further options defining the context of the update, should be a Hash
|
47
|
-
#
|
48
|
-
# ==== Returns
|
49
|
-
# self
|
50
|
-
#
|
51
|
-
def update(struct_or_hash, options={})
|
52
|
-
strict = options[:strict]
|
53
|
-
keys_to_delete = props.keys - %w(_neo_id _classname) if strict
|
54
|
-
struct_or_hash.each_pair do |key, value|
|
55
|
-
next if %w(_neo_id _classname).include? key.to_s
|
56
|
-
# do not allow special properties to be mass assigned
|
57
|
-
keys_to_delete.delete(key) if strict
|
58
|
-
setter_meth = "#{key}=".to_sym
|
59
|
-
if @_wrapper && @_wrapper.respond_to?(setter_meth)
|
60
|
-
@_wrapper.send(setter_meth, value)
|
61
|
-
else
|
62
|
-
self[key] = value
|
63
|
-
end
|
64
|
-
end
|
65
|
-
keys_to_delete.each { |key| delete_property(key) } if strict
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
|
-
# Returns the value of the given key or nil if the property does not exist.
|
71
|
-
def [](key)
|
72
|
-
return unless property?(key)
|
73
|
-
val = get_property(key.to_s)
|
74
|
-
val.class.superclass == ArrayJavaProxy ? val.to_a : val
|
75
|
-
end
|
76
|
-
|
77
|
-
# Sets the property of this node.
|
78
|
-
# Property keys are always strings. Valid property value types are the primitives(<tt>String</tt>, <tt>Fixnum</tt>, <tt>Float</tt>, <tt>FalseClass</tt>, <tt>TrueClass</tt>) or array of those primitives.
|
79
|
-
#
|
80
|
-
# ==== Gotchas
|
81
|
-
# * Values in the array must be of the same type.
|
82
|
-
# * You can *not* delete or add one item in the array (e.g. person.phones.delete('123')) but instead you must create a new array instead.
|
83
|
-
#
|
84
|
-
def []=(key, value)
|
85
|
-
k = key.to_s
|
86
|
-
if value.nil?
|
87
|
-
remove_property(k)
|
88
|
-
elsif (Array === value)
|
89
|
-
case value[0]
|
90
|
-
when NilClass
|
91
|
-
set_property(k, [].to_java(:string))
|
92
|
-
when String
|
93
|
-
set_property(k, value.to_java(:string))
|
94
|
-
when Float
|
95
|
-
set_property(k, value.to_java(:double))
|
96
|
-
when FalseClass, TrueClass
|
97
|
-
set_property(k, value.to_java(:boolean))
|
98
|
-
when Fixnum
|
99
|
-
set_property(k, value.to_java(:long))
|
100
|
-
when Boolean
|
101
|
-
set_property(k, value.to_java(:boolean))
|
102
|
-
else
|
103
|
-
raise "Not allowed to store array with value #{value[0]} type #{value[0].class}"
|
104
|
-
end
|
105
|
-
else
|
106
|
-
set_property(k, value)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
data/lib/neo4j/rails/finders.rb
DELETED
@@ -1,121 +0,0 @@
|
|
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
|
-
|