neo4j-core 0.0.1-java

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.
Files changed (71) hide show
  1. data/Gemfile +27 -0
  2. data/README.rdoc +27 -0
  3. data/config/neo4j/config.yml +102 -0
  4. data/lib/db/active_tx_log +1 -0
  5. data/lib/db/index/lucene-store.db +0 -0
  6. data/lib/db/index/lucene.log.1 +0 -0
  7. data/lib/db/index/lucene.log.active +0 -0
  8. data/lib/db/lock +0 -0
  9. data/lib/db/messages.log +530 -0
  10. data/lib/db/neostore +0 -0
  11. data/lib/db/neostore.id +0 -0
  12. data/lib/db/neostore.nodestore.db +0 -0
  13. data/lib/db/neostore.nodestore.db.id +0 -0
  14. data/lib/db/neostore.propertystore.db +0 -0
  15. data/lib/db/neostore.propertystore.db.arrays +0 -0
  16. data/lib/db/neostore.propertystore.db.arrays.id +0 -0
  17. data/lib/db/neostore.propertystore.db.id +0 -0
  18. data/lib/db/neostore.propertystore.db.index +0 -0
  19. data/lib/db/neostore.propertystore.db.index.id +0 -0
  20. data/lib/db/neostore.propertystore.db.index.keys +0 -0
  21. data/lib/db/neostore.propertystore.db.index.keys.id +0 -0
  22. data/lib/db/neostore.propertystore.db.strings +0 -0
  23. data/lib/db/neostore.propertystore.db.strings.id +0 -0
  24. data/lib/db/neostore.relationshipstore.db +0 -0
  25. data/lib/db/neostore.relationshipstore.db.id +0 -0
  26. data/lib/db/neostore.relationshiptypestore.db +0 -0
  27. data/lib/db/neostore.relationshiptypestore.db.id +0 -0
  28. data/lib/db/neostore.relationshiptypestore.db.names +0 -0
  29. data/lib/db/neostore.relationshiptypestore.db.names.id +0 -0
  30. data/lib/db/nioneo_logical.log.2 +0 -0
  31. data/lib/db/nioneo_logical.log.active +0 -0
  32. data/lib/db/tm_tx_log.1 +0 -0
  33. data/lib/neo4j/config.rb +139 -0
  34. data/lib/neo4j/cypher.rb +156 -0
  35. data/lib/neo4j/neo4j.rb +244 -0
  36. data/lib/neo4j/neo4j.rb~ +214 -0
  37. data/lib/neo4j/node.rb +39 -0
  38. data/lib/neo4j/relationship.rb +61 -0
  39. data/lib/neo4j/transaction.rb +86 -0
  40. data/lib/neo4j/type_converters/type_converters.rb +287 -0
  41. data/lib/neo4j-core/cypher/cypher.rb +867 -0
  42. data/lib/neo4j-core/cypher/result_wrapper.rb +39 -0
  43. data/lib/neo4j-core/database.rb +191 -0
  44. data/lib/neo4j-core/equal/equal.rb +23 -0
  45. data/lib/neo4j-core/event_handler.rb +265 -0
  46. data/lib/neo4j-core/index/class_methods.rb +117 -0
  47. data/lib/neo4j-core/index/index.rb +36 -0
  48. data/lib/neo4j-core/index/index_config.rb +112 -0
  49. data/lib/neo4j-core/index/indexer.rb +243 -0
  50. data/lib/neo4j-core/index/indexer_registry.rb +55 -0
  51. data/lib/neo4j-core/index/lucene_query.rb +264 -0
  52. data/lib/neo4j-core/lazy_map.rb +21 -0
  53. data/lib/neo4j-core/node/class_methods.rb +77 -0
  54. data/lib/neo4j-core/node/node.rb +47 -0
  55. data/lib/neo4j-core/property/property.rb +94 -0
  56. data/lib/neo4j-core/relationship/class_methods.rb +80 -0
  57. data/lib/neo4j-core/relationship/relationship.rb +97 -0
  58. data/lib/neo4j-core/relationship_set.rb +61 -0
  59. data/lib/neo4j-core/rels/rels.rb +147 -0
  60. data/lib/neo4j-core/rels/traverser.rb +99 -0
  61. data/lib/neo4j-core/to_java.rb +51 -0
  62. data/lib/neo4j-core/traversal/evaluator.rb +36 -0
  63. data/lib/neo4j-core/traversal/filter_predicate.rb +30 -0
  64. data/lib/neo4j-core/traversal/prune_evaluator.rb +20 -0
  65. data/lib/neo4j-core/traversal/rel_expander.rb +35 -0
  66. data/lib/neo4j-core/traversal/traversal.rb +130 -0
  67. data/lib/neo4j-core/traversal/traverser.rb +295 -0
  68. data/lib/neo4j-core/version.rb +5 -0
  69. data/lib/neo4j-core.rb +64 -0
  70. data/neo4j-core.gemspec +31 -0
  71. metadata +145 -0
@@ -0,0 +1,77 @@
1
+ module Neo4j
2
+ module Core
3
+ module Node
4
+ module ClassMethods
5
+ # Returns a new neo4j Node.
6
+ # The return node is actually an Java object of type Java::OrgNeo4jGraphdb::Node java object
7
+ # which has been extended (see the included mixins for Neo4j::Node).
8
+ #
9
+ #
10
+ # The created node will have a unique id - Neo4j::Property#neo_id
11
+ #
12
+ # @param [Hash, Array] args either an hash of properties or an array where the first item is the database to be used and the second item is the properties
13
+ # @return [Java::OrgNeo4jGraphdb::Node] the java node which implements the Neo4j::Node mixins
14
+ #
15
+ # @example using default database
16
+ #
17
+ # Neo4j::Transaction.run do
18
+ # Neo4j::Node.new
19
+ # Neo4j::Node.new :name => 'foo', :age => 100
20
+ # end
21
+ #
22
+ # @example using a different database
23
+ #
24
+ # Neo4j::Node.new({:name => 'foo', :age => 100}, my_db)
25
+ def new(*args)
26
+ # the first argument can be an hash of properties to set
27
+ props = args[0].respond_to?(:each_pair) && args[0]
28
+
29
+ # a db instance can be given, is the first argument if that was not a hash, or otherwise the second
30
+ db = (!props && args[0]) || args[1] || Neo4j.started_db
31
+
32
+ node = db.graph.create_node
33
+ props.each_pair { |k, v| node[k]= v } if props
34
+ node
35
+ end
36
+
37
+ # create is the same as new
38
+ alias_method :create, :new
39
+
40
+
41
+ # Same as load but does not return the node as a wrapped Ruby object.
42
+ #
43
+ def _load(node_id, db = Neo4j.started_db)
44
+ return nil if node_id.nil?
45
+ db.graph.get_node_by_id(node_id.to_i)
46
+ rescue Java::OrgNeo4jGraphdb.NotFoundException
47
+ nil
48
+ end
49
+
50
+
51
+ # Checks if the given entity node or entity id (Neo4j::Node#neo_id) exists in the database.
52
+ # @return [true, false] if exist
53
+ def exist?(entity_or_entity_id, db = Neo4j.started_db)
54
+ id = entity_or_entity_id.kind_of?(Fixnum) ? entity_or_entity_id : entity_or_entity_id.id
55
+ node = _load(id, db)
56
+ return false unless node
57
+ node.has_property?('a')
58
+ true
59
+ rescue java.lang.IllegalStateException
60
+ nil # the node has been deleted
61
+ end
62
+
63
+ # Loads a node or wrapped node given a native java node or an id.
64
+ # If there is a Ruby wrapper for the node then it will create a Ruby object that will
65
+ # wrap the java node (see Neo4j::NodeMixin).
66
+ # To implement a wrapper you must implement a wrapper class method in the Neo4j::Node or Neo4j::Relationship.
67
+ #
68
+ # @return [Object, nil] If the node does not exist it will return nil otherwise the loaded node or wrapped node.
69
+ def load(node_id, db = Neo4j.started_db)
70
+ node = _load(node_id, db)
71
+ node && node.wrapper
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,47 @@
1
+ module Neo4j
2
+
3
+ module Core
4
+ module Node
5
+
6
+ # Delete the node and all its relationship.
7
+ #
8
+ # It might raise an exception if this method was called without a Transaction,
9
+ # or if it failed to delete the node (it maybe was already deleted).
10
+ #
11
+ # If this method raise an exception you may also get an exception when the transaction finish.
12
+ # This method is defined in the Java::OrgNeo4jKernel::impl.core.NodeProxy which is return by Neo4j::Node.new
13
+ #
14
+ # @return nil or raise an exception
15
+ def del
16
+ _rels.each { |r| r.del }
17
+ delete
18
+ nil
19
+ end
20
+
21
+ # This method can be used to access the none wrapped neo4j node/relationship java object.
22
+ # Notice that this method is defined in the Java::OrgNeo4jKernel::impl.core.NodeProxy or RelationshipProxy which is return by Neo4j::Node.new
23
+ # @return the java node/relationship object representing this object unless it is already the java object.
24
+ def _java_node
25
+ self
26
+ end
27
+
28
+ # Same as Neo4j::Node#exist? or Neo4j::Relationship#exist?
29
+ # @return [true, false] if the node exists in the database
30
+ def exist?
31
+ Neo4j::Node.exist?(self)
32
+ end
33
+
34
+ # Tries to load the wrapper object for this node by calling the class #wrapper method.
35
+ # This allows you to create a custom Ruby wrapper class around the Neo4j::Node.
36
+ # This is for example done in the <tt>neo4j<//t> ruby gem <tt>Neo4j::NodeMixin</tt>
37
+ # @return a wrapper object or self
38
+ def wrapper
39
+ self.class.respond_to?(:wrapper) ? self.class.wrapper(node) : self
40
+ end
41
+
42
+ def class
43
+ Neo4j::Node
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,94 @@
1
+ module Neo4j
2
+ module Core
3
+ module Property
4
+
5
+ # @return [Hash] all properties plus the id of the node with the key <tt>_neo_id</tt>
6
+ def props
7
+ ret = {"_neo_id" => neo_id}
8
+ iter = get_property_keys.iterator
9
+ while (iter.hasNext) do
10
+ key = iter.next
11
+ ret[key] = get_property(key)
12
+ end
13
+ ret
14
+ end
15
+
16
+ # Ids are garbage collected over time so they are only guaranteed to be unique during a specific time span:
17
+ # if the node is deleted, it's likely that a new node at some point will get the old id. Note:
18
+ # this makes node ids brittle as public APIs.
19
+ # @return [Fixnum] the unique id of this node.
20
+ def neo_id
21
+ getId
22
+ end
23
+
24
+ # @param [#to_s] the property we want to check if it exist.
25
+ # @return [true false] true if the given key exist as a property.
26
+ def property?(key)
27
+ has_property?(key.to_s)
28
+ end
29
+
30
+ # Updates this node/relationship's properties by using the provided struct/hash.
31
+ # If the option <code>{:strict => true}</code> is given, any properties present on
32
+ # the node but not present in the hash will be removed from the node.
33
+ #
34
+ # @param [Hash, :each_pair] struct_or_hash the key and value to be set
35
+ # @param [Hash] options further options defining the context of the update
36
+ # @option options [Boolean] :strict any properties present on the node but not present in the hash will be removed from the node if true
37
+ # @return self
38
+ def update(struct_or_hash, options={})
39
+ strict = options[:strict]
40
+ keys_to_delete = props.keys - %w(_neo_id _classname) if strict
41
+ struct_or_hash.each_pair do |key, value|
42
+ next if key.to_s[0..0] == '_'
43
+ # do not allow special properties to be mass assigned
44
+ keys_to_delete.delete(key.to_s) if strict
45
+ self[key] = value
46
+ end
47
+ keys_to_delete.each { |key| remove_property(key) } if strict
48
+ self
49
+ end
50
+
51
+
52
+ # @return the value of the given key or nil if the property does not exist.
53
+ def [](key)
54
+ return unless property?(key)
55
+ val = get_property(key.to_s)
56
+ val.class.superclass == ArrayJavaProxy ? val.to_a : val
57
+ end
58
+
59
+ # Sets the property of this node.
60
+ # 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.
61
+ #
62
+ # ==== Gotchas
63
+ # * Values in the array must be of the same type.
64
+ # * 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.
65
+ #
66
+ # @param [String, Symbol] key of the property to set
67
+ # @param [String,Fixnum,Float,true,false, Array] value to set
68
+ def []=(key, value)
69
+ k = key.to_s
70
+ if value.nil?
71
+ remove_property(k)
72
+ elsif (Array === value)
73
+ case value[0]
74
+ when NilClass
75
+ set_property(k, [].to_java(:string))
76
+ when String
77
+ set_property(k, value.to_java(:string))
78
+ when Float
79
+ set_property(k, value.to_java(:double))
80
+ when FalseClass, TrueClass
81
+ set_property(k, value.to_java(:boolean))
82
+ when Fixnum
83
+ set_property(k, value.to_java(:long))
84
+ else
85
+ raise "Not allowed to store array with value #{value[0]} type #{value[0].class}"
86
+ end
87
+ else
88
+ set_property(k, value)
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,80 @@
1
+ module Neo4j
2
+ module Core
3
+ module Relationship
4
+ module ClassMethods
5
+
6
+ # Returns a Java::OrgNeo4jGraphdb::Relationship java object which include the Neo4j::Relationship mixins.
7
+ # Will trigger a event that the relationship was created.
8
+ #
9
+ # @param [String, Symbol] type of relationship
10
+ # @param [#_java_node] from_node the start node of this relationship
11
+ # @param [#_java_node] end_node the end node of this relationship
12
+ # @param [Hash] props optional properties for the created relationship
13
+ #
14
+ # @return [Neo4j::Relationship] which is really a Java::OrgNeo4jGraphdb::Relationship java object including the Neo4j::Relationship mixins
15
+ #
16
+ # @example
17
+ #
18
+ # Neo4j::Relationship.new :friend, node1, node2, :since => '2001-01-02', :status => 'okey'
19
+ #
20
+ def new(type, start_node, end_node, props=nil)
21
+ java_type = ToJava.type_to_java(type)
22
+ rel = start_node._java_node.create_relationship_to(end_node._java_node, java_type)
23
+ props.each_pair { |k, v| rel[k] = v } if props
24
+ rel
25
+ end
26
+
27
+ # create is the same as new
28
+ alias_method :create, :new
29
+
30
+ # Loads a relationship or wrapped relationship given a native java relationship or an id.
31
+ # If there is a Ruby wrapper for the node then it will create a Ruby object that will
32
+ # wrap the java node (see Neo4j::RelationshipMixin).
33
+ # Notice that it can load the node even if it has been deleted in the same transaction, see #exist?
34
+ #
35
+ # @see #_load
36
+ # @see #exist?
37
+ # @return the wrapper for the relationship or nil
38
+ def load(rel_id, db = Neo4j.started_db)
39
+ rel = _load(rel_id, db)
40
+ return nil if rel.nil?
41
+ rel.wrapper
42
+ end
43
+
44
+ # Same as load but does not return the node as a wrapped Ruby object.
45
+ # @see #load
46
+ def _load(rel_id, db = Neo4j.started_db)
47
+ return nil if rel_id.nil?
48
+ rel = db.graph.get_relationship_by_id(rel_id.to_i)
49
+ # TODO
50
+ rel
51
+ rescue Java::OrgNeo4jGraphdb::NotFoundException
52
+ nil
53
+ end
54
+
55
+ # Checks if the given node or entity id (Neo4j::Relationship#neo_id) exists in the database.
56
+ # @return [true, false] if exist
57
+ def exist?(entity_or_entity_id, db = Neo4j.started_db)
58
+ id = entity_or_entity_id.kind_of?(Fixnum) ? entity_or_entity_id : entity_or_entity_id.id
59
+ entity = _load(id, db)
60
+ return false unless entity
61
+ entity.hasProperty('_classname') # since we want a IllegalStateException which is otherwise not triggered
62
+ true
63
+ rescue java.lang.IllegalStateException
64
+ nil # the node has been deleted
65
+ end
66
+
67
+ # Loads a relationship or wrapped relationship given a native java relationship or an id.
68
+ # If there is a Ruby wrapper for the relationship then it will create a Ruby object that will
69
+ # wrap the java node (see Neo4j::RelationshipMixin).
70
+ # To implement a wrapper you must implement a wrapper class method in the Neo4j::Node or Neo4j::Relationship.
71
+ #
72
+ # @return [Object, nil] If the node does not exist it will return nil otherwise the loaded node or wrapped node.
73
+ def load(node_id, db = Neo4j.started_db)
74
+ node = _load(node_id, db)
75
+ node && node.wrapper
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,97 @@
1
+ module Neo4j
2
+ module Core
3
+ module Relationship
4
+
5
+ # Same as Java::OrgNeo4jGraphdb::Relationship#getEndNode
6
+ def _end_node
7
+ get_end_node
8
+ end
9
+
10
+ # Same as Java::OrgNeo4jGraphdb::Relationship#getStartNode
11
+ def _start_node
12
+ get_start_node
13
+ end
14
+
15
+ # Same as Java::OrgNeo4jGraphdb::Relationship#getOtherNode
16
+ def _other_node(node)
17
+ get_other_node(node)
18
+ end
19
+
20
+ # Deletes the relationship between the start and end node
21
+ # May raise an exception if delete was unsuccessful.
22
+ #
23
+ # @return [nil]
24
+ def del
25
+ delete
26
+ end
27
+
28
+ # Same as Java::OrgNeo4jGraphdb::Relationship#getEndNode but returns the wrapper for it (if it exist)
29
+ # @see Neo4j::Node#wrapper
30
+ def end_node
31
+ _end_node.wrapper
32
+ end
33
+
34
+ # Same as Java::OrgNeo4jGraphdb::Relationship#getStartNode but returns the wrapper for it (if it exist)
35
+ # @see Neo4j::Node#wrapper
36
+ def start_node
37
+ _start_node.wrapper
38
+ end
39
+
40
+ # A convenience operation that, given a node that is attached to this relationship, returns the other node.
41
+ # For example if node is a start node, the end node will be returned, and vice versa.
42
+ # This is a very convenient operation when you're manually traversing the node space by invoking one of the #rels
43
+ # method on a node. For example, to get the node "at the other end" of a relationship, use the following:
44
+ #
45
+ # @example
46
+ # end_node = node.rels.first.other_node(node)
47
+ #
48
+ # @raise This operation will throw a runtime exception if node is neither this relationship's start node nor its end node.
49
+ #
50
+ # @param [Neo4j::Node] node the node that we don't want to return
51
+ # @return [Neo4j::Node] the other node wrapper
52
+ def other_node(node)
53
+ _other_node(node._java_node).wrapper
54
+ end
55
+
56
+
57
+ # same as #_java_rel
58
+ # Used so that we have same method for both relationship and nodes
59
+ def wrapped_entity
60
+ self
61
+ end
62
+
63
+ # @return self
64
+ def _java_rel
65
+ self
66
+ end
67
+
68
+ # @return [true, false] if the relationship exists
69
+ def exist?
70
+ Neo4j::Relationship.exist?(self)
71
+ end
72
+
73
+ # Loads the wrapper using the #wrapper class method if it exists, otherwise return self.
74
+ def wrapper
75
+ self.class.respond_to?(:wrapper) ? self.class.wrapper(node) : self
76
+ end
77
+
78
+
79
+ # Returns the relationship name
80
+ #
81
+ # @example
82
+ # a = Neo4j::Node.new
83
+ # a.outgoing(:friends) << Neo4j::Node.new
84
+ # a.rels.first.rel_type # => 'friends'
85
+ # @return [String] the type of the relationship
86
+ def rel_type
87
+ getType().name()
88
+ end
89
+
90
+ def class
91
+ Neo4j::Relationship
92
+ end
93
+
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,61 @@
1
+ module Neo4j
2
+ module Core
3
+ # == Represents a set of relationships.
4
+ # See Neo4j::EventHandler
5
+ class RelationshipSet
6
+ def initialize(size=0)
7
+ @relationship_type_set = java.util.HashSet.new(size)
8
+ @relationship_set = java.util.HashSet.new(size)
9
+ @relationship_map = java.util.HashMap.new(size)
10
+ end
11
+
12
+ # Adds a relationship to the set
13
+ def add(rel)
14
+ @relationship_type_set.add(RelationshipSetEntry.new(rel.getEndNode().getId(), rel.rel_type))
15
+ relationships(rel.getEndNode().getId()) << rel
16
+ @relationship_set.add(rel.getId)
17
+ end
18
+
19
+ # Returns a collection of relationships where the node with the specified end node id is the end node.
20
+ def relationships(end_node_id)
21
+ @relationship_map.get(end_node_id) || add_list(end_node_id)
22
+ end
23
+
24
+ # Returns true if the specified relationship is in the set
25
+ def contains_rel?(rel)
26
+ @relationship_set.contains(rel.getId)
27
+ end
28
+
29
+ # Returns true if a relationship with the specified end_node_id and relationship_type is present in the set.
30
+ def contains?(end_node_id, relationship_type)
31
+ @relationship_type_set.contains(RelationshipSetEntry.new(end_node_id, relationship_type))
32
+ end
33
+
34
+ protected
35
+ def add_list(node_id)
36
+ @relationship_map.put(node_id, [])
37
+ @relationship_map.get(node_id)
38
+ end
39
+ end
40
+
41
+ class RelationshipSetEntry
42
+ attr_accessor :nodeid, :relationship_type
43
+
44
+ def initialize(nodeid, relationship_type)
45
+ @nodeid, @relationship_type = nodeid.to_s, relationship_type.to_s
46
+ end
47
+
48
+ def ==(o)
49
+ eql?(o)
50
+ end
51
+
52
+ def eql?(other)
53
+ @nodeid == other.nodeid && @relationship_type == other.relationship_type
54
+ end
55
+
56
+ def hash
57
+ 3 * @nodeid.hash + @relationship_type.hash
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,147 @@
1
+ module Neo4j
2
+ module Core
3
+ # Contains methods for traversing relationship object of depth one from one node.
4
+ module Rels
5
+ # Returns the only node of a given type and direction that is attached to this node, or nil.
6
+ # This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or one relationships of a given type and direction to another node.
7
+ # Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships exist, it is a fatal error that should generate an exception.
8
+
9
+ # This method reflects that semantics and returns either:
10
+ # * nil if there are zero relationships of the given type and direction,
11
+ # * the relationship if there's exactly one, or
12
+ # * throws an unchecked exception in all other cases.
13
+ #
14
+ # This method should be used only in situations with an invariant as described above. In those situations, a "state-checking" method (e.g. #rel?) is not required,
15
+ # because this method behaves correctly "out of the box."
16
+ #
17
+ # @param (see #rel)
18
+ # @see Neo4j::Core::Node#wrapper #wrapper - The method used to wrap the node in a Ruby object if the node was found
19
+ def node(dir, type)
20
+ n = _node(dir, type)
21
+ n && n.wrapper
22
+ end
23
+
24
+ # Same as #node but instead returns an unwrapped native java node.
25
+ # @param (see #rel)
26
+ def _node(dir, type)
27
+ r = _rel(dir, type)
28
+ r && r._other_node(self._java_node)
29
+ end
30
+
31
+ # Works like #rels method but instead returns the nodes.
32
+ # @param (see #rels)
33
+ # @see #rels
34
+ # @return [Enumerable<Neo4j::Node>]
35
+ def _nodes(dir, *types)
36
+ r = _rels(dir, *types)
37
+ case dir
38
+ when :outgoing then
39
+ Neo4j::Core::LazyMap.new(r, &:_end_node)
40
+ when :incoming then
41
+ Neo4j::Core::LazyMap.new(r, &:_start_node)
42
+ when :both then
43
+ Neo4j::Core::LazyMap.new(r) { |x| x._other_node(self) }
44
+ end
45
+ end
46
+
47
+ # Works like #rels method but instead returns the nodes.
48
+ # It does try to load a Ruby wrapper around each node
49
+ # @param (see #rels)
50
+ # @see Neo4j::Core::Node#wrapper #wrapper - The method used wrap to the node in a Ruby object if the node was found
51
+ # @return [Enumerable] an Enumeration of either Neo4j::Node objects or wrapped Neo4j::Node objects
52
+ # @notice it's possible that the same node is returned more then once because of several relationship reaching to the same node, see #outgoing for alternative
53
+ def nodes(dir, *types)
54
+ Neo4j::Core::LazyMap.new(_nodes(dir, *types), &:wrapper)
55
+ end
56
+
57
+
58
+ # Returns an enumeration of relationship objects using the builder DSL pattern.
59
+ # It always returns relationships of depth one.
60
+ #
61
+ # @param [:both, :incoming, :outgoing] dir the direction of the relationship
62
+ # @param [String, Symbol] types the requested relationship types we want look for, if none it gets relationships of any type
63
+ # @return [Neo4j::Core::Rels::Traverser] an object which included the Ruby Enumerable mixin
64
+ #
65
+ # @example Return both incoming and outgoing relationships
66
+ # me.rels(:both, :friends, :work).each {|relationship|...}
67
+ #
68
+ # @example Only return outgoing relationship of given type
69
+ # me.rels(:outgoing, :friends).first.end_node # => my friend node
70
+ #
71
+ # @example All the relationships between me and another node of given dir & type
72
+ # me.rels(:outgoing, :friends).to_other(node)
73
+ #
74
+ # @example Delete all relationships between me and another node of given dir & type
75
+ # me.rels(:outgoing, :friends).to_other(node).del
76
+ #
77
+ # @see Neo4j::Core::Node#wrapper #wrapper - The method used wrap to the node in a Ruby object if the node was found
78
+ # @see Neo4j::Relationship#rel_type
79
+ # @raise an exception if the first parameter is not <tt>:both</tt>, <tt>;outgoing</tt> or <tt>:incoming</tt>
80
+ def rels(dir=:both, *types)
81
+ raise "Illegal argument, first argument must be :both, :incoming or :outgoing, got #{dir.inspect}" unless [:incoming, :outgoing, :both].include?(dir)
82
+ Neo4j::Core::Rels::Traverser.new(self, types, dir)
83
+ end
84
+
85
+
86
+ # Returns the only relationship of a given type and direction that is attached to this node, or null.
87
+ # This is a convenience method that is used in the commonly occuring situation where a node has exactly zero or
88
+ # one relationships of a given type and direction to another node.
89
+ # Typically this invariant is maintained by the rest of the code: if at any time more than one such relationships
90
+ # exist, it is a fatal error that should generate an unchecked exception. This method reflects that semantics and
91
+ # returns either:
92
+ #
93
+ # * nil if there are zero relationships of the given type and direction,
94
+ # * the relationship if there's exactly one, or
95
+ # * raise an exception in all other cases.
96
+ # @param [:both, :incoming, :outgoing] dir the direction of the relationship
97
+ # @param [Symbol, String] type the type of relationship, see Neo4j::Core::Relationship#rel_type
98
+ # @return [Neo4j::Relationship, nil, Object] the Relationship or wrapper for the Relationship or nil
99
+ # @see Neo4j::Core::Relationship#rel_type
100
+ # @see Neo4j::Core::Node#wrapper #wrapper - The method used to wrap the node in a Ruby object if the node was found
101
+ def rel(dir, type)
102
+ result = _rel(dir, type)
103
+ result && result.wrapper
104
+ end
105
+
106
+ # Same as rel but does not return a ruby wrapped object but instead returns the Java object.
107
+ # @param (see #rel)
108
+ # @return [Neo4j::Relationship, nil]
109
+ # @see #rel
110
+ def _rel(dir, type)
111
+ get_single_relationship(ToJava.type_to_java(type), ToJava.dir_to_java(dir))
112
+ end
113
+
114
+ # Finds relationship starting from this node given a direction and/or relationship type(s).
115
+ # @param (see #rels)
116
+ # @return [Enumerable] of Neo4j::Relationship objects
117
+ def _rels(dir=:both, *types)
118
+ if types.size > 1
119
+ get_relationships(ToJava.dir_to_java(dir), ToJava.types_to_java(types))
120
+ elsif types.size == 1
121
+ get_relationships(ToJava.type_to_java(types[0]), ToJava.dir_to_java(dir))
122
+ else
123
+ get_relationships(ToJava.dir_to_java(dir))
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
+ # @param [:both, :incoming, :outgoing] dir optional default :both (either, :outgoing, :incoming, :both)
132
+ # @param [String,Symbol] type the key and value to be set, default any type
133
+ # @return [Boolean] true if one or more relationships exists for the given type and dir otherwise false
134
+ def rel?(dir=:both, type=nil)
135
+ if type
136
+ has_relationship(ToJava.type_to_java(type), ToJava.dir_to_java(dir))
137
+ else
138
+ has_relationship(ToJava.dir_to_java(dir))
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+
146
+
147
+ end