neo4j 1.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +141 -0
- data/CONTRIBUTORS +15 -0
- data/Gemfile +3 -0
- data/README.rdoc +2015 -0
- data/lib/neo4j.old/batch_inserter.rb +144 -0
- data/lib/neo4j.old/config.rb +138 -0
- data/lib/neo4j.old/event_handler.rb +73 -0
- data/lib/neo4j.old/extensions/activemodel.rb +158 -0
- data/lib/neo4j.old/extensions/aggregate.rb +12 -0
- data/lib/neo4j.old/extensions/aggregate/aggregate_enum.rb +40 -0
- data/lib/neo4j.old/extensions/aggregate/ext/node_mixin.rb +69 -0
- data/lib/neo4j.old/extensions/aggregate/node_aggregate.rb +8 -0
- data/lib/neo4j.old/extensions/aggregate/node_aggregate_mixin.rb +331 -0
- data/lib/neo4j.old/extensions/aggregate/node_aggregator.rb +216 -0
- data/lib/neo4j.old/extensions/aggregate/node_group.rb +43 -0
- data/lib/neo4j.old/extensions/aggregate/prop_group.rb +30 -0
- data/lib/neo4j.old/extensions/aggregate/property_enum.rb +24 -0
- data/lib/neo4j.old/extensions/aggregate/props_aggregate.rb +8 -0
- data/lib/neo4j.old/extensions/aggregate/props_aggregate_mixin.rb +31 -0
- data/lib/neo4j.old/extensions/aggregate/props_aggregator.rb +80 -0
- data/lib/neo4j.old/extensions/find_path.rb +117 -0
- data/lib/neo4j.old/extensions/graph_algo.rb +1 -0
- data/lib/neo4j.old/extensions/graph_algo/all_simple_paths.rb +133 -0
- data/lib/neo4j.old/extensions/graph_algo/neo4j-graph-algo-0.3.jar +0 -0
- data/lib/neo4j.old/extensions/reindexer.rb +104 -0
- data/lib/neo4j.old/extensions/rest.rb +21 -0
- data/lib/neo4j.old/extensions/rest/rest.rb +336 -0
- data/lib/neo4j.old/extensions/rest/rest_mixin.rb +193 -0
- data/lib/neo4j.old/extensions/rest/server.rb +50 -0
- data/lib/neo4j.old/extensions/rest/stubs.rb +141 -0
- data/lib/neo4j.old/extensions/rest_master.rb +34 -0
- data/lib/neo4j.old/extensions/rest_slave.rb +31 -0
- data/lib/neo4j.old/extensions/tx_tracker.rb +392 -0
- data/lib/neo4j.old/indexer.rb +187 -0
- data/lib/neo4j.old/jars.rb +6 -0
- data/lib/neo4j.old/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
- data/lib/neo4j.old/jars/neo4j-kernel-1.0.jar +0 -0
- data/lib/neo4j.old/mixins/java_list_mixin.rb +139 -0
- data/lib/neo4j.old/mixins/java_node_mixin.rb +205 -0
- data/lib/neo4j.old/mixins/java_property_mixin.rb +169 -0
- data/lib/neo4j.old/mixins/java_relationship_mixin.rb +60 -0
- data/lib/neo4j.old/mixins/migration_mixin.rb +157 -0
- data/lib/neo4j.old/mixins/node_mixin.rb +249 -0
- data/lib/neo4j.old/mixins/property_class_methods.rb +265 -0
- data/lib/neo4j.old/mixins/rel_class_methods.rb +167 -0
- data/lib/neo4j.old/mixins/relationship_mixin.rb +103 -0
- data/lib/neo4j.old/neo.rb +247 -0
- data/lib/neo4j.old/node.rb +49 -0
- data/lib/neo4j.old/reference_node.rb +15 -0
- data/lib/neo4j.old/relationship.rb +85 -0
- data/lib/neo4j.old/relationships/decl_relationship_dsl.rb +164 -0
- data/lib/neo4j.old/relationships/has_list.rb +101 -0
- data/lib/neo4j.old/relationships/has_n.rb +129 -0
- data/lib/neo4j.old/relationships/node_traverser.rb +138 -0
- data/lib/neo4j.old/relationships/relationship_dsl.rb +149 -0
- data/lib/neo4j.old/relationships/traversal_position.rb +50 -0
- data/lib/neo4j.old/relationships/wrappers.rb +51 -0
- data/lib/neo4j.old/search_result.rb +72 -0
- data/lib/neo4j.old/transaction.rb +254 -0
- data/lib/neo4j.old/version.rb +3 -0
- data/lib/neo4j.rb +50 -0
- data/lib/neo4j/config.rb +137 -0
- data/lib/neo4j/database.rb +43 -0
- data/lib/neo4j/equal.rb +22 -0
- data/lib/neo4j/event_handler.rb +91 -0
- data/lib/neo4j/index.rb +157 -0
- data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
- data/lib/neo4j/jars/lucene-core-2.9.2.jar +0 -0
- data/lib/neo4j/jars/lucene-core-3.0.1.jar +0 -0
- data/lib/neo4j/jars/neo4j-index-1.1.jar +0 -0
- data/lib/neo4j/jars/neo4j-kernel-1.1.1.jar +0 -0
- data/lib/neo4j/jars/neo4j-kernel-1.1.jar +0 -0
- data/lib/neo4j/jars/neo4j-lucene-index-0.1-20100916.085626-67.jar +0 -0
- data/lib/neo4j/mapping/class_methods/index.rb +21 -0
- data/lib/neo4j/mapping/class_methods/property.rb +139 -0
- data/lib/neo4j/mapping/class_methods/relationship.rb +96 -0
- data/lib/neo4j/mapping/class_methods/rule.rb +135 -0
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +151 -0
- data/lib/neo4j/mapping/has_n.rb +117 -0
- data/lib/neo4j/mapping/node_mixin.rb +70 -0
- data/lib/neo4j/neo4j.rb +65 -0
- data/lib/neo4j/node.rb +82 -0
- data/lib/neo4j/node_mixin.rb +4 -0
- data/lib/neo4j/node_relationship.rb +60 -0
- data/lib/neo4j/node_traverser.rb +141 -0
- data/lib/neo4j/property.rb +72 -0
- data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
- data/lib/neo4j/rails/model.rb +210 -0
- data/lib/neo4j/rails/railtie.rb +16 -0
- data/lib/neo4j/rails/transaction.rb +29 -0
- data/lib/neo4j/rails/value.rb +43 -0
- data/lib/neo4j/relationship.rb +88 -0
- data/lib/neo4j/relationship_traverser.rb +57 -0
- data/lib/neo4j/to_java.rb +17 -0
- data/lib/neo4j/transaction.rb +69 -0
- data/lib/neo4j/version.rb +3 -0
- data/neo4j.gemspec +30 -0
- metadata +243 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Mapping
|
3
|
+
|
4
|
+
# Enables creating and traversal of nodes.
|
5
|
+
# Includes the Enumerable Mixin.
|
6
|
+
#
|
7
|
+
class HasN
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def initialize(node, dsl) # :nodoc:
|
11
|
+
@node = node
|
12
|
+
@direction = dsl.direction
|
13
|
+
# returns the other DSL if it exists otherwise use this DSL for specifing incoming relationships
|
14
|
+
if @direction == :outgoing
|
15
|
+
@dsl = dsl
|
16
|
+
else
|
17
|
+
# which class specifies the incoming DSL ?
|
18
|
+
clazz = dsl.to_class || node.class
|
19
|
+
@dsl = clazz.decl_relationships[dsl.to_type]
|
20
|
+
raise "Unspecified outgoing relationship '#{dsl.to_type}' for incoming relationship '#{dsl.rel_id}' on class #{clazz}" if @dsl.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
@traverser = Neo4j::NodeTraverser.new(node._java_node, @dsl.namespace_type, @direction)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# Returns the relationships instead of the nodes.
|
28
|
+
#
|
29
|
+
# ==== Example
|
30
|
+
# # return the relationship objects between the folder and file nodes:
|
31
|
+
# folder.files.rels.each {|x| ...}
|
32
|
+
#
|
33
|
+
def rels
|
34
|
+
Neo4j::RelationshipTraverser.new(@node._java_node, [@dsl.namespace_type], @direction)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sets the depth of the traversal.
|
38
|
+
# Default is 1 if not specified.
|
39
|
+
#
|
40
|
+
# ==== Example
|
41
|
+
# morpheus.friends.depth(:all).each { ... }
|
42
|
+
# morpheus.friends.depth(3).each { ... }
|
43
|
+
#
|
44
|
+
# ==== Arguments
|
45
|
+
# d<Fixnum,Symbol>:: the depth or :all if traversing to the end of the network.
|
46
|
+
# ==== Return
|
47
|
+
# self
|
48
|
+
#
|
49
|
+
def depth(d)
|
50
|
+
@traverser.depth(d)
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
# Required by the Enumerable mixin.
|
55
|
+
def each(&block)
|
56
|
+
@traverser.each(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# Returns true if there are no node in this type of relationship
|
61
|
+
def empty?
|
62
|
+
@traverser.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# Creates a relationship instance between this and the other node.
|
67
|
+
def new(other)
|
68
|
+
create_rel(@node, other)
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# Creates a relationship between this and the other node.
|
73
|
+
#
|
74
|
+
# ==== Example
|
75
|
+
#
|
76
|
+
# n1 = Node.new # Node has declared having a friend type of relationship
|
77
|
+
# n2 = Node.new
|
78
|
+
# n3 = Node.new
|
79
|
+
#
|
80
|
+
# n1 << n2 << n3
|
81
|
+
#
|
82
|
+
# This is the same as:
|
83
|
+
#
|
84
|
+
# n1.add_rel(:friends, n2)
|
85
|
+
# n1.add_rel(:friends, n3)
|
86
|
+
#
|
87
|
+
# ==== Returns
|
88
|
+
# self
|
89
|
+
#
|
90
|
+
def <<(other)
|
91
|
+
create_rel(@node, other)
|
92
|
+
self
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def create_rel(node, other) # :nodoc:
|
97
|
+
# If the are creating an incoming relationship we need to swap incoming and outgoing nodes
|
98
|
+
if @direction == :outgoing
|
99
|
+
from, to = node, other
|
100
|
+
else
|
101
|
+
from, to = other, node
|
102
|
+
end
|
103
|
+
|
104
|
+
rel = from.outgoing(@dsl.namespace_type) << to
|
105
|
+
# rel[_classname] = @dsl.relationship_class # TODO
|
106
|
+
|
107
|
+
# the from.neo_id is only used for cascade_delete_incoming since that node will be deleted when all the list items has been deleted.
|
108
|
+
# if cascade_delete_outgoing all nodes will be deleted when the root node is deleted
|
109
|
+
# if cascade_delete_incoming then the root node will be deleted when all root nodes' outgoing nodes are deleted
|
110
|
+
rel[@dsl.cascade_delete_prop_name] = node.neo_id if @dsl.cascade_delete?
|
111
|
+
rel
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Neo4j::Mapping
|
2
|
+
|
3
|
+
module NodeMixin
|
4
|
+
extend Forwardable
|
5
|
+
include Neo4j::Index
|
6
|
+
|
7
|
+
def_delegators :@_java_node, :[]=, :[], :property?, :props, :attributes, :update, :neo_id, :id, :rels, :rel?, :to_param, :getId,
|
8
|
+
:rel, :del, :list?, :print, :print_sub, :outgoing, :incoming, :both,
|
9
|
+
:equal?, :eql?, :==, :exist?
|
10
|
+
|
11
|
+
|
12
|
+
# --------------------------------------------------------------------------
|
13
|
+
# Initialization methods
|
14
|
+
#
|
15
|
+
|
16
|
+
|
17
|
+
# Init this node with the specified java neo node
|
18
|
+
#
|
19
|
+
def init_on_load(java_node) # :nodoc:
|
20
|
+
@_java_node = java_node
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# Creates a new node and initialize with given properties.
|
25
|
+
#
|
26
|
+
def init_on_create(*args) # :nodoc:
|
27
|
+
self[:_classname] = self.class.to_s
|
28
|
+
if args[0].respond_to?(:each_pair)
|
29
|
+
args[0].each_pair { |k, v| @_java_node.set_property(k.to_s, v) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the org.neo4j.graphdb.Node wrapped object
|
34
|
+
def _java_node
|
35
|
+
@_java_node
|
36
|
+
end
|
37
|
+
|
38
|
+
def id
|
39
|
+
@_java_node.id
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.included(c) # :nodoc:
|
43
|
+
c.instance_eval do
|
44
|
+
# these constants are used in the Neo4j::RelClassMethods and Neo4j::PropertyClassMethods
|
45
|
+
# they are defined here since they should only be defined once -
|
46
|
+
# all subclasses share the same index, declared properties and index_updaters
|
47
|
+
unless c.const_defined?(:DECL_RELATIONSHIPS)
|
48
|
+
const_set(:ROOT_CLASS, self)
|
49
|
+
const_set(:DECL_RELATIONSHIPS, {})
|
50
|
+
const_set(:PROPERTIES_INFO, {})
|
51
|
+
end
|
52
|
+
class << self
|
53
|
+
alias_method :orig_new, :new
|
54
|
+
end
|
55
|
+
end
|
56
|
+
c.extend ClassMethods::Property
|
57
|
+
c.extend ClassMethods::Relationship
|
58
|
+
c.extend ClassMethods::Aggregate
|
59
|
+
c.extend Neo4j::Index::ClassMethods
|
60
|
+
def c.inherited(subclass)
|
61
|
+
subclass.indexer subclass
|
62
|
+
super
|
63
|
+
end
|
64
|
+
c.indexer c
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
data/lib/neo4j/neo4j.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Neo4j
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
|
6
|
+
# Start Neo4j using the default database.
|
7
|
+
# This is not required since the database will be started automatically when it is used.
|
8
|
+
#
|
9
|
+
def start
|
10
|
+
default_db
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# sets the default database to use
|
15
|
+
def default_db=(my_db)
|
16
|
+
@db = my_db
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns default database. Creates a new one if it does not exist, but does not start it.
|
20
|
+
def default_db
|
21
|
+
@db ||= Database.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a started db instance
|
25
|
+
def started_db
|
26
|
+
db = default_db
|
27
|
+
db.start unless db.running?
|
28
|
+
db
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# Returns an unstarted db instance
|
33
|
+
# this is typically used for configuring the database, which must sometimes
|
34
|
+
# be done before the database is started
|
35
|
+
# if the database was already started an excetion will be raised
|
36
|
+
def unstarted_db
|
37
|
+
@db ||= Database.new
|
38
|
+
raise "database was already started" if @db.running?
|
39
|
+
@db
|
40
|
+
end
|
41
|
+
|
42
|
+
# returns true if the database is running
|
43
|
+
def running?
|
44
|
+
@db && @db.running?
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def shutdown(this_db = @db)
|
49
|
+
this_db.shutdown if this_db
|
50
|
+
end
|
51
|
+
|
52
|
+
def ref_node(this_db = self.started_db)
|
53
|
+
this_db.graph.reference_node
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns an Enumerable object for all nodes in the database
|
57
|
+
def all_nodes(this_db = self.started_db)
|
58
|
+
Enumerator.new(this_db, :each_node)
|
59
|
+
end
|
60
|
+
|
61
|
+
def event_handler(this_db = default_db)
|
62
|
+
this_db.event_handler
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/neo4j/node.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
module Neo4j
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
org.neo4j.kernel.impl.core.NodeProxy.class_eval do
|
6
|
+
include Neo4j::Property
|
7
|
+
include Neo4j::NodeRelationship
|
8
|
+
include Neo4j::Equal
|
9
|
+
include Neo4j::Index
|
10
|
+
|
11
|
+
# Delete the node and all its relationship
|
12
|
+
def del
|
13
|
+
rels.each {|r| r.del}
|
14
|
+
delete
|
15
|
+
end
|
16
|
+
|
17
|
+
# returns true if the node exists in the database
|
18
|
+
def exist?
|
19
|
+
Neo4j::Node.exist?(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
# provide a hook for ruby class mapping
|
23
|
+
def wrapped_entity
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def class
|
28
|
+
Neo4j::Node
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
class Node
|
34
|
+
extend Neo4j::Index::ClassMethods
|
35
|
+
|
36
|
+
self.indexer self
|
37
|
+
|
38
|
+
class << self
|
39
|
+
|
40
|
+
|
41
|
+
# Creates a new node using the default db instance when given no args
|
42
|
+
# Same as Neo4j::Node#create
|
43
|
+
def new(*args)
|
44
|
+
# the first argument can be an hash of properties to set
|
45
|
+
props = args[0].respond_to?(:each_pair) && args[0]
|
46
|
+
|
47
|
+
# a db instance can be given, is the first argument if that was not a hash, or otherwise the second
|
48
|
+
db = (!props && args[0]) || args[1] || Neo4j.started_db
|
49
|
+
|
50
|
+
node = db.graph.create_node
|
51
|
+
props.each_pair { |k, v| node.set_property(k.to_s, v) } if props
|
52
|
+
node
|
53
|
+
end
|
54
|
+
|
55
|
+
# create is the same as new
|
56
|
+
alias_method :create, :new
|
57
|
+
|
58
|
+
def load(node_id, db = Neo4j.started_db)
|
59
|
+
load_wrapper(db.graph.get_node_by_id(node_id.to_i))
|
60
|
+
rescue java.lang.IllegalStateException
|
61
|
+
nil # the node has been deleted
|
62
|
+
rescue org.neo4j.graphdb.NotFoundException
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_wrapper(node)
|
67
|
+
return node unless node.property?(:_classname)
|
68
|
+
to_class(node[:_classname]).load_wrapper(node)
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_class(class_name)
|
72
|
+
class_name.split("::").inject(Kernel) {|container, name| container.const_get(name.to_s) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def exist?(node_or_node_id, db = Neo4j.started_db)
|
76
|
+
id = node_or_node_id.kind_of?(Fixnum) ? node_or_node_id : node_or_node_id.id
|
77
|
+
load(id, db) != nil
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Neo4j
|
2
|
+
|
3
|
+
|
4
|
+
module NodeRelationship
|
5
|
+
include ToJava
|
6
|
+
|
7
|
+
def outgoing(type=nil)
|
8
|
+
if type
|
9
|
+
NodeTraverser.new(self).outgoing(type)
|
10
|
+
else
|
11
|
+
raise "not implemented yet"
|
12
|
+
NodeTraverser.new(self)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def incoming(type=nil)
|
17
|
+
if type
|
18
|
+
NodeTraverser.new(self).incoming(type)
|
19
|
+
else
|
20
|
+
raise "not implemented yet"
|
21
|
+
NodeTraverser.new(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def both(type=nil)
|
26
|
+
if type
|
27
|
+
NodeTraverser.new(self).both(type)
|
28
|
+
else
|
29
|
+
NodeTraverser.new(self) # default is both
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def rels(*type)
|
34
|
+
RelationshipTraverser.new(self, type, :both)
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# Check if the given relationship exists
|
39
|
+
# Returns true if there are one or more relationships from this node to other nodes
|
40
|
+
# with the given relationship.
|
41
|
+
#
|
42
|
+
# ==== Parameters
|
43
|
+
# type:: the key and value to be set, default any type
|
44
|
+
# dir:: optional default :both (either, :outgoing, :incoming, :both)
|
45
|
+
#
|
46
|
+
# ==== Returns
|
47
|
+
# true if one or more relationships exists for the given type and dir
|
48
|
+
# otherwise false
|
49
|
+
#
|
50
|
+
def rel? (type=nil, dir=:both)
|
51
|
+
if type
|
52
|
+
hasRelationship(type_to_java(type), dir_to_java(dir))
|
53
|
+
else
|
54
|
+
hasRelationship
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,141 @@
|
|
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
|
+
|
55
|
+
def <<(other_node)
|
56
|
+
new(other_node)
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def new(other_node)
|
61
|
+
raise "Only allowed to create outgoing relationships, please add it on the other node if you want to create an incoming relationship" unless @dir == org.neo4j.graphdb.Direction::OUTGOING
|
62
|
+
@from.create_relationship_to(other_node, @type)
|
63
|
+
end
|
64
|
+
|
65
|
+
def both(type)
|
66
|
+
@type = type_to_java(type) if type
|
67
|
+
@dir = dir_to_java(:both)
|
68
|
+
@td = @td.relationships(type_to_java(type), @dir)
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
def outgoing(type)
|
73
|
+
@type = type_to_java(type) if type
|
74
|
+
@dir = dir_to_java(:outgoing)
|
75
|
+
@td = @td.relationships(type_to_java(type), @dir)
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
def incoming(type)
|
80
|
+
@type = type_to_java(type) if type
|
81
|
+
@dir = dir_to_java(:incoming)
|
82
|
+
@td = @td.relationships(type_to_java(type), @dir)
|
83
|
+
self
|
84
|
+
end
|
85
|
+
|
86
|
+
def filter_method(name, &proc)
|
87
|
+
# add method name
|
88
|
+
singelton = class << self; self; end
|
89
|
+
singelton.send(:define_method, name) {filter &proc}
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def prune(&block)
|
94
|
+
@td = @td.prune(PruneEvaluator.new(block))
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
def filter(&block)
|
99
|
+
# we keep a reference to filter predicate since only one filter is allowed and we might want to modify it
|
100
|
+
@filter_predicate ||= FilterPredicate.new
|
101
|
+
@filter_predicate.add(block)
|
102
|
+
@td = @td.filter(@filter_predicate)
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
# Sets depth, if :all then it will traverse any depth
|
107
|
+
def depth(d)
|
108
|
+
@depth = d
|
109
|
+
self
|
110
|
+
end
|
111
|
+
|
112
|
+
def include_start_node
|
113
|
+
@include_start_node = true
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
117
|
+
def size
|
118
|
+
[*self].size
|
119
|
+
end
|
120
|
+
|
121
|
+
def each
|
122
|
+
iter = iterator
|
123
|
+
while (iter.hasNext) do
|
124
|
+
yield Neo4j::Node.load_wrapper(iter.next)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def iterator
|
129
|
+
unless @include_start_node
|
130
|
+
if @filter_predicate
|
131
|
+
@filter_predicate.include_start_node
|
132
|
+
else
|
133
|
+
@td = @td.filter(org.neo4j.kernel.Traversal.return_all_but_start_node)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
@td = @td.prune(org.neo4j.kernel.Traversal.pruneAfterDepth( @depth ) ) unless @depth == :all
|
137
|
+
@td.traverse(@from).nodes.iterator
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|