neo4j-core 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
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