neo4j 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG +141 -0
  2. data/CONTRIBUTORS +15 -0
  3. data/Gemfile +3 -0
  4. data/README.rdoc +2015 -0
  5. data/lib/neo4j.old/batch_inserter.rb +144 -0
  6. data/lib/neo4j.old/config.rb +138 -0
  7. data/lib/neo4j.old/event_handler.rb +73 -0
  8. data/lib/neo4j.old/extensions/activemodel.rb +158 -0
  9. data/lib/neo4j.old/extensions/aggregate.rb +12 -0
  10. data/lib/neo4j.old/extensions/aggregate/aggregate_enum.rb +40 -0
  11. data/lib/neo4j.old/extensions/aggregate/ext/node_mixin.rb +69 -0
  12. data/lib/neo4j.old/extensions/aggregate/node_aggregate.rb +8 -0
  13. data/lib/neo4j.old/extensions/aggregate/node_aggregate_mixin.rb +331 -0
  14. data/lib/neo4j.old/extensions/aggregate/node_aggregator.rb +216 -0
  15. data/lib/neo4j.old/extensions/aggregate/node_group.rb +43 -0
  16. data/lib/neo4j.old/extensions/aggregate/prop_group.rb +30 -0
  17. data/lib/neo4j.old/extensions/aggregate/property_enum.rb +24 -0
  18. data/lib/neo4j.old/extensions/aggregate/props_aggregate.rb +8 -0
  19. data/lib/neo4j.old/extensions/aggregate/props_aggregate_mixin.rb +31 -0
  20. data/lib/neo4j.old/extensions/aggregate/props_aggregator.rb +80 -0
  21. data/lib/neo4j.old/extensions/find_path.rb +117 -0
  22. data/lib/neo4j.old/extensions/graph_algo.rb +1 -0
  23. data/lib/neo4j.old/extensions/graph_algo/all_simple_paths.rb +133 -0
  24. data/lib/neo4j.old/extensions/graph_algo/neo4j-graph-algo-0.3.jar +0 -0
  25. data/lib/neo4j.old/extensions/reindexer.rb +104 -0
  26. data/lib/neo4j.old/extensions/rest.rb +21 -0
  27. data/lib/neo4j.old/extensions/rest/rest.rb +336 -0
  28. data/lib/neo4j.old/extensions/rest/rest_mixin.rb +193 -0
  29. data/lib/neo4j.old/extensions/rest/server.rb +50 -0
  30. data/lib/neo4j.old/extensions/rest/stubs.rb +141 -0
  31. data/lib/neo4j.old/extensions/rest_master.rb +34 -0
  32. data/lib/neo4j.old/extensions/rest_slave.rb +31 -0
  33. data/lib/neo4j.old/extensions/tx_tracker.rb +392 -0
  34. data/lib/neo4j.old/indexer.rb +187 -0
  35. data/lib/neo4j.old/jars.rb +6 -0
  36. data/lib/neo4j.old/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  37. data/lib/neo4j.old/jars/neo4j-kernel-1.0.jar +0 -0
  38. data/lib/neo4j.old/mixins/java_list_mixin.rb +139 -0
  39. data/lib/neo4j.old/mixins/java_node_mixin.rb +205 -0
  40. data/lib/neo4j.old/mixins/java_property_mixin.rb +169 -0
  41. data/lib/neo4j.old/mixins/java_relationship_mixin.rb +60 -0
  42. data/lib/neo4j.old/mixins/migration_mixin.rb +157 -0
  43. data/lib/neo4j.old/mixins/node_mixin.rb +249 -0
  44. data/lib/neo4j.old/mixins/property_class_methods.rb +265 -0
  45. data/lib/neo4j.old/mixins/rel_class_methods.rb +167 -0
  46. data/lib/neo4j.old/mixins/relationship_mixin.rb +103 -0
  47. data/lib/neo4j.old/neo.rb +247 -0
  48. data/lib/neo4j.old/node.rb +49 -0
  49. data/lib/neo4j.old/reference_node.rb +15 -0
  50. data/lib/neo4j.old/relationship.rb +85 -0
  51. data/lib/neo4j.old/relationships/decl_relationship_dsl.rb +164 -0
  52. data/lib/neo4j.old/relationships/has_list.rb +101 -0
  53. data/lib/neo4j.old/relationships/has_n.rb +129 -0
  54. data/lib/neo4j.old/relationships/node_traverser.rb +138 -0
  55. data/lib/neo4j.old/relationships/relationship_dsl.rb +149 -0
  56. data/lib/neo4j.old/relationships/traversal_position.rb +50 -0
  57. data/lib/neo4j.old/relationships/wrappers.rb +51 -0
  58. data/lib/neo4j.old/search_result.rb +72 -0
  59. data/lib/neo4j.old/transaction.rb +254 -0
  60. data/lib/neo4j.old/version.rb +3 -0
  61. data/lib/neo4j.rb +50 -0
  62. data/lib/neo4j/config.rb +137 -0
  63. data/lib/neo4j/database.rb +43 -0
  64. data/lib/neo4j/equal.rb +22 -0
  65. data/lib/neo4j/event_handler.rb +91 -0
  66. data/lib/neo4j/index.rb +157 -0
  67. data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  68. data/lib/neo4j/jars/lucene-core-2.9.2.jar +0 -0
  69. data/lib/neo4j/jars/lucene-core-3.0.1.jar +0 -0
  70. data/lib/neo4j/jars/neo4j-index-1.1.jar +0 -0
  71. data/lib/neo4j/jars/neo4j-kernel-1.1.1.jar +0 -0
  72. data/lib/neo4j/jars/neo4j-kernel-1.1.jar +0 -0
  73. data/lib/neo4j/jars/neo4j-lucene-index-0.1-20100916.085626-67.jar +0 -0
  74. data/lib/neo4j/mapping/class_methods/index.rb +21 -0
  75. data/lib/neo4j/mapping/class_methods/property.rb +139 -0
  76. data/lib/neo4j/mapping/class_methods/relationship.rb +96 -0
  77. data/lib/neo4j/mapping/class_methods/rule.rb +135 -0
  78. data/lib/neo4j/mapping/decl_relationship_dsl.rb +151 -0
  79. data/lib/neo4j/mapping/has_n.rb +117 -0
  80. data/lib/neo4j/mapping/node_mixin.rb +70 -0
  81. data/lib/neo4j/neo4j.rb +65 -0
  82. data/lib/neo4j/node.rb +82 -0
  83. data/lib/neo4j/node_mixin.rb +4 -0
  84. data/lib/neo4j/node_relationship.rb +60 -0
  85. data/lib/neo4j/node_traverser.rb +141 -0
  86. data/lib/neo4j/property.rb +72 -0
  87. data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
  88. data/lib/neo4j/rails/model.rb +210 -0
  89. data/lib/neo4j/rails/railtie.rb +16 -0
  90. data/lib/neo4j/rails/transaction.rb +29 -0
  91. data/lib/neo4j/rails/value.rb +43 -0
  92. data/lib/neo4j/relationship.rb +88 -0
  93. data/lib/neo4j/relationship_traverser.rb +57 -0
  94. data/lib/neo4j/to_java.rb +17 -0
  95. data/lib/neo4j/transaction.rb +69 -0
  96. data/lib/neo4j/version.rb +3 -0
  97. data/neo4j.gemspec +30 -0
  98. metadata +243 -0
@@ -0,0 +1,101 @@
1
+ module Neo4j
2
+
3
+ module Relationships
4
+
5
+ # Provides appending and traversing nodes that are linked together in a list with
6
+ # relationships to the next list item.
7
+ #
8
+ class HasList
9
+ include Enumerable
10
+ attr_reader :relationship_type
11
+
12
+ def initialize(node, dsl, &filter)
13
+ @node = node
14
+ @relationship_type = "_list_#{dsl.to_type}_#{node.neo_id}"
15
+ if (dsl.counter?)
16
+ @counter_id = "_#{dsl.to_type}_size".to_sym
17
+ end
18
+ @cascade_delete = dsl.cascade_delete_prop_name
19
+ end
20
+
21
+ def size
22
+ @node[@counter_id] || 0
23
+ end
24
+
25
+ # called by the event handler
26
+ def self.on_node_deleted(node) #:nodoc:
27
+ # check if node is member of one or more lists
28
+ node.lists{|list_item| list_item.prev.next = list_item.next if list_item.prev; list_item.size -= 1}
29
+ end
30
+
31
+ # Appends one node to the end of the list
32
+ #
33
+ # :api: public
34
+ def <<(other)
35
+ # does node have a relationship ?
36
+ new_rel = []
37
+ if (@node.rel?(@relationship_type))
38
+ # get that relationship
39
+ first = @node.rels.outgoing(@relationship_type).first
40
+
41
+ # delete this relationship
42
+ first.del
43
+ old_first = first.other_node(@node)
44
+ new_rel << @node.add_rel(@relationship_type, other)
45
+ new_rel << other.add_rel(@relationship_type, old_first)
46
+ else
47
+ # the first node will be set
48
+ new_rel << @node.add_rel(@relationship_type, other)
49
+ end
50
+
51
+ if @cascade_delete
52
+ # the @node.neo_id is only used for cascade_delete_incoming since that node will be deleted when all the list items has been deleted.
53
+ # if cascade_delete_outgoing all nodes will be deleted when the root node is deleted
54
+ # if cascade_delete_incoming then the root node will be deleted when all root nodes' outgoing nodes are deleted
55
+ new_rel.each {|rel| rel[@cascade_delete] = @node.neo_id}
56
+ end
57
+ if @counter_id
58
+ @node[@counter_id] ||= 0
59
+ @node[@counter_id] += 1
60
+ end
61
+
62
+ self
63
+ end
64
+
65
+ # Returns true if the list is empty s
66
+ #
67
+ # :api: public
68
+ def empty?
69
+ !iterator.hasNext
70
+ end
71
+
72
+ def first
73
+ return nil unless @node.rel?(@relationship_type, :outgoing)
74
+ @node.rel(@relationship_type, :outgoing).end_node
75
+ end
76
+
77
+ def each
78
+ iter = iterator
79
+ while (iter.hasNext) do
80
+ n = iter.next
81
+ yield Neo4j.load_node(n.get_id)
82
+ end
83
+ end
84
+
85
+ def iterator
86
+ stop_evaluator = org.neo4j.graphdb.StopEvaluator::END_OF_GRAPH
87
+ traverser_order = org.neo4j.graphdb.Traverser::Order::BREADTH_FIRST
88
+ returnable_evaluator = org.neo4j.graphdb.ReturnableEvaluator::ALL_BUT_START_NODE
89
+ types_and_dirs = []
90
+ types_and_dirs << org.neo4j.graphdb.DynamicRelationshipType.withName(@relationship_type.to_s)
91
+ types_and_dirs << org.neo4j.graphdb.Direction::OUTGOING
92
+ @node._java_node.traverse(traverser_order, stop_evaluator, returnable_evaluator, types_and_dirs.to_java(:object)).iterator
93
+ end
94
+
95
+ end
96
+
97
+
98
+ end
99
+
100
+
101
+ end
@@ -0,0 +1,129 @@
1
+ module Neo4j
2
+ module Relationships
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, &filter) # :nodoc:
11
+ @node = node
12
+ @traverser = NodeTraverser.new(node._java_node)
13
+ @outgoing = dsl.outgoing?
14
+ # returns the other DSL if it exists otherwise use this DSL for specifing incoming relationships
15
+ if @outgoing
16
+ @dsl = dsl
17
+ else
18
+ # which class specifies the incoming DSL ?
19
+ clazz = dsl.to_class || node.class
20
+ @dsl = clazz.decl_relationships[dsl.to_type]
21
+ raise "Unspecified outgoing relationship '#{dsl.to_type}' for incoming relationship '#{dsl.rel_id}' on class #{clazz}" if @dsl.nil?
22
+ end
23
+
24
+ if @outgoing
25
+ @traverser.outgoing(@dsl.namespace_type)
26
+ else
27
+ @traverser.incoming(@dsl.namespace_type)
28
+ end
29
+
30
+ @traverser.filter(&filter) unless filter.nil?
31
+ end
32
+
33
+
34
+ # Returns the relationships instead of the nodes.
35
+ #
36
+ # ==== Example
37
+ # # return the relationship objects between the folder and file nodes:
38
+ # folder.files.rels.each {|x| ...}
39
+ #
40
+ def rels
41
+ Neo4j::Relationships::RelationshipDSL.new(@node._java_node, (@outgoing)? :outgoing : :incoming, @dsl.namespace_type)
42
+ end
43
+
44
+ # Sets the depth of the traversal.
45
+ # Default is 1 if not specified.
46
+ #
47
+ # ==== Example
48
+ # morpheus.friends.depth(:all).each { ... }
49
+ # morpheus.friends.depth(3).each { ... }
50
+ #
51
+ # ==== Arguments
52
+ # d<Fixnum,Symbol>:: the depth or :all if traversing to the end of the network.
53
+ # ==== Return
54
+ # self
55
+ #
56
+ # :api: public
57
+ def depth(d)
58
+ @traverser.depth(d)
59
+ self
60
+ end
61
+
62
+ # Required by the Enumerable mixin.
63
+ def each(&block)
64
+ @traverser.each(&block)
65
+ end
66
+
67
+
68
+ # Returns true if there are no node in this type of relationship
69
+ def empty?
70
+ @traverser.empty?
71
+ end
72
+
73
+ # Return the first relationship or nil
74
+ def first
75
+ @traverser.first
76
+ end
77
+
78
+ # Creates a relationship instance between this and the other node.
79
+ def new(other)
80
+ create_rel(@node, other)
81
+ end
82
+
83
+
84
+ # Creates a relationship between this and the other node.
85
+ #
86
+ # ==== Example
87
+ #
88
+ # n1 = Node.new # Node has declared having a friend type of relationship
89
+ # n2 = Node.new
90
+ # n3 = Node.new
91
+ #
92
+ # n1 << n2 << n3
93
+ #
94
+ # This is the same as:
95
+ #
96
+ # n1.add_rel(:friends, n2)
97
+ # n1.add_rel(:friends, n3)
98
+ #
99
+ # ==== Returns
100
+ # self
101
+ #
102
+ # :api: public
103
+ def <<(other)
104
+ create_rel(@node, other)
105
+ self
106
+ end
107
+
108
+
109
+ def create_rel(node, other) # :nodoc:
110
+ # If the are creating an incoming relationship we need to swap incoming and outgoing nodes
111
+ if @outgoing
112
+ from, to = node, other
113
+ else
114
+ from, to = other, node
115
+ end
116
+
117
+ rel = from.add_rel(@dsl.namespace_type, to, @dsl.relationship_class)
118
+
119
+ # 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.
120
+ # if cascade_delete_outgoing all nodes will be deleted when the root node is deleted
121
+ # if cascade_delete_incoming then the root node will be deleted when all root nodes' outgoing nodes are deleted
122
+ rel[@dsl.cascade_delete_prop_name] = node.neo_id if @dsl.cascade_delete?
123
+ rel
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,138 @@
1
+ module Neo4j
2
+ module Relationships
3
+
4
+ class IllegalTraversalArguments < StandardError;
5
+ end
6
+
7
+ # Enables traversing nodes
8
+ # Contains state about one specific traversal to be performed.
9
+ class NodeTraverser
10
+ include Enumerable
11
+
12
+ attr_accessor :raw
13
+ attr_reader :_java_node
14
+
15
+ def initialize(_java_node, raw = false)
16
+ @_java_node = _java_node
17
+ @raw = raw
18
+ @stop_evaluator = DepthStopEvaluator.new(1)
19
+ @types_and_dirs = [] # what types of relationships and which directions should be traversed
20
+ @traverser_order = org.neo4j.graphdb.Traverser::Order::BREADTH_FIRST
21
+ @returnable_evaluator = org.neo4j.graphdb.ReturnableEvaluator::ALL_BUT_START_NODE
22
+ end
23
+
24
+ # if raw == true then it will return raw Java object instead of wrapped JRuby object which can improve performance.
25
+ def raw(raw = true)
26
+ @raw = raw
27
+ self
28
+ end
29
+
30
+ # Sets the depth of the traversal.
31
+ # Default is 1 if not specified.
32
+ #
33
+ # ==== Example
34
+ # morpheus.outgoing(:friends).depth(:all).each { ... }
35
+ # morpheus.outgoing(:friends).depth(3).each { ... }
36
+ #
37
+ # ==== Arguments
38
+ # d<Fixnum,Symbol>:: the depth or :all if traversing to the end of the network.
39
+ # ==== Return
40
+ # self
41
+ #
42
+ # :api: public
43
+ def depth(d)
44
+ if d == :all
45
+ @stop_evaluator = org.neo4j.graphdb.StopEvaluator::END_OF_GRAPH
46
+ else
47
+ @stop_evaluator = DepthStopEvaluator.new(d)
48
+ end
49
+ self
50
+ end
51
+
52
+ def filter(&proc)
53
+ @returnable_evaluator = ReturnableEvaluator.new(proc, @raw)
54
+ self
55
+ end
56
+
57
+ def outgoing(*types)
58
+ types.each do |type|
59
+ @types_and_dirs << org.neo4j.graphdb.DynamicRelationshipType.withName(type.to_s)
60
+ @types_and_dirs << org.neo4j.graphdb.Direction::OUTGOING
61
+ end
62
+ self
63
+ end
64
+
65
+ def incoming(*types)
66
+ types.each do |type|
67
+ @types_and_dirs << org.neo4j.graphdb.DynamicRelationshipType.withName(type.to_s)
68
+ @types_and_dirs << org.neo4j.graphdb.Direction::INCOMING
69
+ end
70
+ self
71
+ end
72
+
73
+ def both(*types)
74
+ types.each do |type|
75
+ @types_and_dirs << org.neo4j.graphdb.DynamicRelationshipType.withName(type.to_s)
76
+ @types_and_dirs << org.neo4j.graphdb.Direction::BOTH
77
+ end
78
+ self
79
+ end
80
+
81
+ def empty?
82
+ !iterator.hasNext
83
+ end
84
+
85
+ def first
86
+ find {true}
87
+ end
88
+
89
+ def each
90
+ iter = iterator
91
+ if @raw
92
+ while (iter.hasNext) do
93
+ yield iter.next
94
+ end
95
+ else
96
+ while (iter.hasNext) do
97
+ yield iter.next.wrapper
98
+ end
99
+ end
100
+ end
101
+
102
+ # Same as #each method but includes the TraversalPosition argument as a yield argument.
103
+ #
104
+ #
105
+ def each_with_position(&block)
106
+ traverser = create_traverser
107
+ iter = traverser.iterator
108
+ while (iter.hasNext) do
109
+ n = iter.next
110
+ tp = TraversalPosition.new(traverser.currentPosition(), @raw)
111
+ block.call Neo4j.load_node(n.get_id), tp
112
+ end
113
+ end
114
+
115
+
116
+ def create_traverser
117
+ # check that we know which type of relationship should be traversed
118
+ if @types_and_dirs.empty?
119
+ raise IllegalTraversalArguments.new "Unknown type of relationship. Needs to know which type(s) of relationship in order to traverse. Please use the outgoing, incoming or both method."
120
+ end
121
+
122
+ @_java_node.traverse(@traverser_order, @stop_evaluator,
123
+ @returnable_evaluator, @types_and_dirs.to_java(:object))
124
+ end
125
+
126
+ def iterator
127
+ create_traverser.iterator
128
+ end
129
+
130
+ def to_s
131
+ "NodeTraverser [direction=#{@direction}, type=#{@type}]"
132
+ end
133
+
134
+ end
135
+
136
+
137
+ end
138
+ end
@@ -0,0 +1,149 @@
1
+ module Neo4j
2
+ module Relationships
3
+
4
+ # Enables finding relationships for one node
5
+ #
6
+ class RelationshipDSL
7
+ include Enumerable
8
+ attr_reader :node
9
+
10
+ def initialize(node, direction = :outgoing, type = nil)
11
+ @raw = false
12
+ @type = type
13
+ @node = node
14
+
15
+ case direction
16
+ when :outgoing
17
+ outgoing(type)
18
+ when :incoming
19
+ incoming(type)
20
+ when :both
21
+ both(type)
22
+ end
23
+ end
24
+
25
+ # if raw == true then it will return raw Java object instead of wrapped JRuby object which can improve performance.
26
+ def raw(raw = true)
27
+ @raw = raw
28
+ self
29
+ end
30
+
31
+ def outgoing(type = nil)
32
+ @type = type
33
+ @direction = org.neo4j.graphdb.Direction::OUTGOING
34
+ self
35
+ end
36
+
37
+ def incoming(type = nil)
38
+ @type = type
39
+ @direction = org.neo4j.graphdb.Direction::INCOMING
40
+ self
41
+ end
42
+
43
+ def filter(&filter_proc)
44
+ @filter_proc = filter_proc
45
+ self
46
+ end
47
+
48
+ def both(type = nil)
49
+ @type = type
50
+ @direction = org.neo4j.graphdb.Direction::BOTH
51
+ self
52
+ end
53
+
54
+
55
+ # Creates a not declared relationship between this node and the given other_node with the given relationship type
56
+ # Use this method if you do not want to declare the relationship with the class methods has_one or has_n.
57
+ # Can be used at any time on any node.
58
+ #
59
+ # Only supports outgoing relationships.
60
+ #
61
+ # ==== Example
62
+ #
63
+ # node1 = Neo4j::Node.new
64
+ # node2 = Neo4j::Node.new
65
+ # node1.rels.outgoing(:some_relationship_type) << node2 << node3
66
+ #
67
+ # ==== Returns
68
+ # self - so that the << can be chained
69
+ #
70
+ # :api: public
71
+ def <<(other_node)
72
+ source, target = @node, other_node
73
+ source, target = target, source if @direction == org.neo4j.graphdb.Direction::INCOMING
74
+ source.add_rel(@type, target)
75
+ self
76
+ end
77
+
78
+ def empty?
79
+ !iterator.hasNext
80
+ end
81
+
82
+ # Return the first relationship or nil
83
+ def first
84
+ find {true}
85
+ end
86
+
87
+ #
88
+ # Returns the relationship object to the other node.
89
+ #
90
+ def [](other_node)
91
+ find {|r| r.end_node.neo_id == other_node.neo_id}
92
+ end
93
+
94
+
95
+ def each
96
+ iter = iterator
97
+ while (iter.hasNext) do
98
+ rel = @raw ? iter.next : iter.next.wrapper
99
+ next if @filter_proc && !rel.instance_eval(&@filter_proc)
100
+ yield rel
101
+ end
102
+ end
103
+
104
+ def nodes
105
+ RelationshipsEnumeration.new(self, @raw)
106
+ end
107
+
108
+ def iterator
109
+ # if type is nil then we traverse all relationship types of depth one
110
+ return @node.getRelationships(@direction).iterator if @type.nil?
111
+ return @node.getRelationships(org.neo4j.graphdb.DynamicRelationshipType.withName(@type.to_s), @direction).iterator unless @type.nil?
112
+ end
113
+
114
+ def to_s
115
+ "RelationshipDSL [direction=#{@direction}, type=#{@type}]"
116
+ end
117
+
118
+ # Used from RelationshipDSL when traversing nodes instead of relationships.
119
+ #
120
+ class RelationshipsEnumeration #:nodoc:
121
+ include Enumerable
122
+
123
+ def initialize(relationships, raw)
124
+ @relationships = relationships
125
+ @raw = raw
126
+ end
127
+
128
+ def first
129
+ find {true}
130
+ end
131
+
132
+ def empty?
133
+ first.nil?
134
+ end
135
+
136
+ def each
137
+ if @raw
138
+ @relationships.each { |relationship| yield relationship.other_node(@relationships.node) }
139
+ else
140
+ @relationships.each { |relationship| yield relationship.other_node(@relationships.node).wrapper }
141
+ end
142
+ end
143
+
144
+
145
+ end
146
+ end
147
+
148
+ end
149
+ end