neo4j 1.0.0.beta.20 → 3.0.0.alpha.2
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.
- 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
|
-
|