neo4j 1.0.0.beta.9 → 1.0.0.beta.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/README.rdoc +5 -1971
  2. data/lib/neo4j/mapping/class_methods/relationship.rb +2 -2
  3. data/lib/neo4j/mapping/decl_relationship_dsl.rb +6 -1
  4. data/lib/neo4j/mapping/has_n.rb +17 -1
  5. data/lib/neo4j/node_traverser.rb +14 -1
  6. data/lib/neo4j/rails/model.rb +127 -31
  7. data/lib/neo4j/rails/tx_methods.rb +11 -0
  8. data/lib/neo4j/rails/value.rb +44 -1
  9. data/lib/neo4j/version.rb +1 -1
  10. data/lib/neo4j.rb +1 -0
  11. metadata +4 -59
  12. data/lib/neo4j.old/batch_inserter.rb +0 -144
  13. data/lib/neo4j.old/config.rb +0 -138
  14. data/lib/neo4j.old/event_handler.rb +0 -73
  15. data/lib/neo4j.old/extensions/activemodel.rb +0 -158
  16. data/lib/neo4j.old/extensions/aggregate/aggregate_enum.rb +0 -40
  17. data/lib/neo4j.old/extensions/aggregate/ext/node_mixin.rb +0 -69
  18. data/lib/neo4j.old/extensions/aggregate/node_aggregate.rb +0 -8
  19. data/lib/neo4j.old/extensions/aggregate/node_aggregate_mixin.rb +0 -331
  20. data/lib/neo4j.old/extensions/aggregate/node_aggregator.rb +0 -216
  21. data/lib/neo4j.old/extensions/aggregate/node_group.rb +0 -43
  22. data/lib/neo4j.old/extensions/aggregate/prop_group.rb +0 -30
  23. data/lib/neo4j.old/extensions/aggregate/property_enum.rb +0 -24
  24. data/lib/neo4j.old/extensions/aggregate/props_aggregate.rb +0 -8
  25. data/lib/neo4j.old/extensions/aggregate/props_aggregate_mixin.rb +0 -31
  26. data/lib/neo4j.old/extensions/aggregate/props_aggregator.rb +0 -80
  27. data/lib/neo4j.old/extensions/aggregate.rb +0 -12
  28. data/lib/neo4j.old/extensions/find_path.rb +0 -117
  29. data/lib/neo4j.old/extensions/graph_algo/all_simple_paths.rb +0 -133
  30. data/lib/neo4j.old/extensions/graph_algo/neo4j-graph-algo-0.3.jar +0 -0
  31. data/lib/neo4j.old/extensions/graph_algo.rb +0 -1
  32. data/lib/neo4j.old/extensions/reindexer.rb +0 -104
  33. data/lib/neo4j.old/extensions/rest/rest.rb +0 -336
  34. data/lib/neo4j.old/extensions/rest/rest_mixin.rb +0 -193
  35. data/lib/neo4j.old/extensions/rest/server.rb +0 -50
  36. data/lib/neo4j.old/extensions/rest/stubs.rb +0 -141
  37. data/lib/neo4j.old/extensions/rest.rb +0 -21
  38. data/lib/neo4j.old/extensions/rest_master.rb +0 -34
  39. data/lib/neo4j.old/extensions/rest_slave.rb +0 -31
  40. data/lib/neo4j.old/extensions/tx_tracker.rb +0 -392
  41. data/lib/neo4j.old/indexer.rb +0 -187
  42. data/lib/neo4j.old/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  43. data/lib/neo4j.old/jars/neo4j-kernel-1.0.jar +0 -0
  44. data/lib/neo4j.old/jars.rb +0 -6
  45. data/lib/neo4j.old/mixins/java_list_mixin.rb +0 -139
  46. data/lib/neo4j.old/mixins/java_node_mixin.rb +0 -205
  47. data/lib/neo4j.old/mixins/java_property_mixin.rb +0 -169
  48. data/lib/neo4j.old/mixins/java_relationship_mixin.rb +0 -60
  49. data/lib/neo4j.old/mixins/migration_mixin.rb +0 -157
  50. data/lib/neo4j.old/mixins/node_mixin.rb +0 -249
  51. data/lib/neo4j.old/mixins/property_class_methods.rb +0 -265
  52. data/lib/neo4j.old/mixins/rel_class_methods.rb +0 -167
  53. data/lib/neo4j.old/mixins/relationship_mixin.rb +0 -103
  54. data/lib/neo4j.old/neo.rb +0 -247
  55. data/lib/neo4j.old/node.rb +0 -49
  56. data/lib/neo4j.old/reference_node.rb +0 -15
  57. data/lib/neo4j.old/relationship.rb +0 -85
  58. data/lib/neo4j.old/relationships/decl_relationship_dsl.rb +0 -164
  59. data/lib/neo4j.old/relationships/has_list.rb +0 -101
  60. data/lib/neo4j.old/relationships/has_n.rb +0 -129
  61. data/lib/neo4j.old/relationships/node_traverser.rb +0 -138
  62. data/lib/neo4j.old/relationships/relationship_dsl.rb +0 -149
  63. data/lib/neo4j.old/relationships/traversal_position.rb +0 -50
  64. data/lib/neo4j.old/relationships/wrappers.rb +0 -51
  65. data/lib/neo4j.old/search_result.rb +0 -72
  66. data/lib/neo4j.old/transaction.rb +0 -254
  67. data/lib/neo4j.old/version.rb +0 -3
@@ -1,187 +0,0 @@
1
- module Neo4j
2
-
3
- # This class is responsible for both knowing which nodes that needs to be reindexed
4
- # and how to perform the reindex operation (the document_updaters attribute).
5
- #
6
- # There is one Indexer per Node root class.
7
- #
8
- class Indexer #:nodoc:
9
- attr_reader :document_updaters, :index_id
10
- attr_reader :property_indexer # for testing purpose
11
-
12
- def initialize(indexed_class, query_for_nodes)
13
- @relationship_indexers = {}
14
- @query_for_nodes = query_for_nodes
15
- @property_indexer = PropertyIndexer.new
16
- @document_updaters = [@property_indexer]
17
- # the file name of the lucene index if kept on disk
18
- @index_id = "/" + indexed_class.to_s.gsub('::', '/')
19
- end
20
-
21
- # Returns the Indexer for the given Neo4j::NodeMixin class
22
- def self.instance(clazz, query_for_nodes = true)
23
- @instances ||= {}
24
- @instances[clazz.root_class] ||= Indexer.new(clazz.root_class, query_for_nodes)
25
- @instances[clazz.root_class]
26
- end
27
-
28
- # only for testing purpose, e.g we need to redefine an existing class
29
- def self.remove_instance(clazz)
30
- @instances.delete(clazz.root_class) if !@instances.nil? && clazz.respond_to?(:root_class)
31
- end
32
-
33
-
34
- # (Re)index the given node
35
- def self.index(node)
36
- indexer = instance(node.class)
37
- indexer.index(node)
38
- end
39
-
40
- def find(query,block)
41
- SearchResult.new lucene_index, query, @query_for_nodes, &block
42
- end
43
-
44
- def add_index_on_property(prop)
45
- @property_indexer.properties << prop.to_sym
46
- end
47
-
48
- def remove_index_on_property(prop)
49
- @property_indexer.properties.delete prop.to_sym
50
- end
51
-
52
- def add_index_in_relationship_on_property(updater_clazz, rel_name, rel_type, prop, namespace_type)
53
- unless relationship_indexer_for?(namespace_type)
54
- indexer = new_relationship_indexer_for(namespace_type, rel_name.to_sym)
55
- self.class.instance(updater_clazz).document_updaters << indexer
56
- end
57
-
58
- # TODO make sure the same index is not added twice
59
- relationship_indexer_for(namespace_type).properties << prop.to_sym
60
- end
61
-
62
- def index(node)
63
- document = {:id => node.neo_id }
64
-
65
- @document_updaters.each do |updater|
66
- updater.update_document(document, node)
67
- end
68
-
69
- lucene_index << document
70
- end
71
-
72
- def delete_index(node)
73
- lucene_index.delete(node.neo_id)
74
- end
75
-
76
-
77
- def lucene_index
78
- Lucene::Index.new(@index_id)
79
- end
80
-
81
- def field_infos
82
- lucene_index.field_infos
83
- end
84
-
85
- def on_property_changed(node, prop)
86
- @relationship_indexers.values.each {|indexer| indexer.on_property_changed(node, prop.to_sym)}
87
- @property_indexer.on_property_changed(node,prop.to_sym)
88
- end
89
-
90
- def on_relationship_created(node, rel_type)
91
- @relationship_indexers.values.each {|indexer| indexer.on_relationship_created(node, rel_type.to_sym)}
92
- end
93
-
94
- def on_relationship_deleted(node, rel_type)
95
- @relationship_indexers.values.each {|indexer| indexer.on_relationship_deleted(node, rel_type.to_sym)}
96
- end
97
-
98
- def relationship_indexer_for(rel_type)
99
- @relationship_indexers[rel_type.to_sym]
100
- end
101
-
102
- def relationship_indexer_for?(rel_type)
103
- !relationship_indexer_for(rel_type.to_sym).nil?
104
- end
105
-
106
- def new_relationship_indexer_for(rel_type, rel_name)
107
- @relationship_indexers[rel_type.to_sym] = RelationshipIndexer.new(rel_name.to_sym, rel_type.to_sym)
108
- end
109
-
110
- end
111
-
112
-
113
- class PropertyIndexer #:nodoc:
114
- attr_reader :properties
115
-
116
- def initialize
117
- @properties = []
118
- end
119
-
120
- def on_property_changed(node, prop)
121
- Indexer.index(node) if @properties.include?(prop)
122
- end
123
-
124
- def update_document(document, node)
125
- # we have to check that the property exists since the index can be defined in a subclass
126
- @properties.each {|prop| document[prop.to_sym] = node.send(prop) if node.respond_to?(prop)}
127
- end
128
- end
129
-
130
-
131
- # If node class A has a relationship with type 'd' to node class B
132
- # A.x -d-> B.y A.index d.y
133
- # If property y on a B node changes then all its nodes in the relationship 'd' will
134
- # be reindexed. Those nodes (which will be of type node class A) will use the same RelationshipIndexer to update the
135
- # index document with key field 'd.y' and values of property y of all nodes in the
136
- # relationship 'd'
137
- #
138
- class RelationshipIndexer #:nodoc:
139
- attr_reader :rel_type, :properties
140
-
141
- def initialize(rel_name, rel_type)
142
- @properties = []
143
- @rel_type = rel_type
144
- @rel_name = rel_name
145
- end
146
-
147
- def on_property_changed(node, prop)
148
- # make sure we're interested in indexing this property
149
- reindex_related_nodes(node) if @properties.include?(prop)
150
- end
151
-
152
- def on_relationship_deleted(node, rel_type)
153
- Indexer.index(node) if @rel_type == rel_type
154
- end
155
-
156
- def on_relationship_created(node, rel_type)
157
- # make sure we're interested in indexing this relationship
158
- if @rel_type == rel_type
159
- reindex_related_nodes(node)
160
- Indexer.index(node)
161
- end
162
- end
163
-
164
- def reindex_related_nodes(node)
165
- related_nodes = node.rels.both(@rel_type).nodes
166
- related_nodes.each do |related_node|
167
- Indexer.index(related_node)
168
- end
169
- end
170
-
171
- def index_key(property)
172
- "#@rel_name.#{property}".to_sym
173
- end
174
-
175
- def update_document(document, node)
176
- relationships = node.rels.both(@rel_type).nodes
177
- relationships.each do |other_node|
178
- @properties.each do |p|
179
- index_key = index_key(p)
180
- document[index_key] ||= []
181
- document[index_key] << other_node.send(p)
182
- end
183
- end
184
- end
185
- end
186
-
187
- end
@@ -1,6 +0,0 @@
1
- include Java
2
-
3
- module Neo4j
4
- require 'neo4j/jars/neo4j-kernel-1.0.jar'
5
- require 'neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar'
6
- end
@@ -1,139 +0,0 @@
1
- module Neo4j::JavaListMixin
2
-
3
- # --------------------------------------------------------------------------
4
- # List methods
5
- #
6
-
7
-
8
- # Returns true if this nodes belongs to a list of the given name
9
- #
10
- def list?(list_name)
11
- regexp = Regexp.new "_list_#{list_name}"
12
- rels.both.find { |rel| regexp.match(rel.relationship_type.to_s) } != nil
13
- end
14
-
15
- # Returns one or more list of the given list_name and list_node.
16
- # If the optional list_node parameter is given the specific list belonging to that list node will be returned (or nil)
17
- # If only the list_name parameter is given the first list matching the given list_name will be returned.
18
- # (There might be several list of the same name but from different list nodes.)
19
- #
20
- # ==== Returns
21
- #
22
- # The node but with the extra instance methods
23
- # * next - the next node in the list
24
- # * prev - the previous node in the list
25
- # * head - the head node (the node that has the has_list method)
26
- # * size (if the size optional parameter is given in the has_list class method)
27
- #
28
- # ==== Example
29
- # class Foo
30
- # include Neo4j::NodeMixin
31
- # has_list :baar
32
- # end
33
- #
34
- # f = Foo.new
35
- # n1 = Neo4j::Node.new
36
- # n2 = Neo4j::Node.new
37
- # f.baar << n1 << n2
38
- #
39
- # n2.list(:baar).next # => n1
40
- # n2.list(:baar).prev # => f
41
- # n2.list(:baar).head # => f
42
- #
43
- def list(list_name, list_node = nil)
44
- if list_node
45
- list_id = "_list_#{list_name}_#{list_node.neo_id}"
46
- add_list_item_methods(list_id, list_name, list_node)
47
- else
48
- list_items = []
49
- lists(list_name) {|list_item| list_items << list_item}
50
- list_items[0]
51
- end
52
- end
53
-
54
-
55
- # Returns an array of lists with the given names that this nodes belongs to.
56
- # Expects a block to yield for each found list
57
- # That block will be given one parameter - the node with the extra method (see #list method)
58
- #
59
- def lists(*list_names)
60
- list_names.collect! {|n| n.to_sym}
61
-
62
- rels.both.inject({}) do |res, rel|
63
- rel_type = rel.relationship_type.to_s
64
- md = /_list_(\w*)_(\d*)/.match(rel_type)
65
- next res if md.nil?
66
- next res unless list_names.empty? || list_names.include?(md[1].to_sym)
67
- res[rel_type] = [md[1], Neo4j.load_node(md[2])]
68
- res
69
- end.each_pair do |rel_id, list_name_and_head_node|
70
- yield self.add_list_item_methods(rel_id, list_name_and_head_node[0], list_name_and_head_node[1]) # clone ?
71
- end
72
- end
73
-
74
-
75
- def add_list_item_methods(list_id, list_name, head_node) #:no_doc:
76
- mod = Module.new do
77
- define_method :head do
78
- head_node
79
- end
80
-
81
- define_method :size do
82
- head_node["_#{list_name}_size"] || 0
83
- end
84
-
85
- define_method :size= do |new_size|
86
- head_node["_#{list_name}_size"] = new_size
87
- end
88
-
89
- define_method :next do
90
- next_node = rels.outgoing(list_id).nodes.first
91
- return nil if next_node.nil?
92
- next_node.add_list_item_methods(list_id, list_name, head_node)
93
- next_node
94
- end
95
-
96
- define_method :next= do |new_next|
97
- # does it have a next pointer ?
98
- next_rel = rels.outgoing(list_id).first
99
- # delete the relationship if exists
100
- next_rel.delete if (next_rel.nil?)
101
- rels.outgoing(list_id) << new_next unless new_next.nil?
102
- nil
103
- end
104
-
105
- define_method :prev do
106
- prev_node = rels.incoming(list_id).nodes.first
107
- return nil if prev_node.nil?
108
- prev_node.add_list_item_methods(list_id, list_name, head_node)
109
- prev_node
110
- end
111
-
112
- define_method :prev= do |new_prev|
113
- # does it have a next pointer ?
114
- prev_rel = rels.incoming(list_id).first
115
- # delete the relationship if exists
116
- prev_rel.delete if (prev_rel.nil?)
117
- rels.outgoing(list_id) << new_prev unless new_prev.nil?
118
- nil
119
- end
120
- end
121
-
122
- self.extend mod
123
- end
124
-
125
- def add_list_head_methods(list_name) # :nodoc:
126
- prop_name = "_#{list_name}_size".to_sym
127
- mod = Module.new do
128
- define_method :size do
129
- self[prop_name] || 0
130
- end
131
-
132
- define_method :size= do |new_size|
133
- self[prop_name]=new_size
134
- end
135
- end
136
- self.extend mod
137
- end
138
-
139
- end
@@ -1,205 +0,0 @@
1
- module Neo4j::JavaNodeMixin
2
-
3
-
4
- # Check if the given relationship exists
5
- # Returns true if there are one or more relationships from this node to other nodes
6
- # with the given relationship.
7
- # It will not return true only because the relationship is defined.
8
- #
9
- # ==== Parameters
10
- # rel_name<#to_s>:: the key and value to be set
11
- # dir:: optional default :outgoing (either, :outgoing, :incoming, :both)
12
- #
13
- # ==== Returns
14
- # true if one or more relationships exists for the given rel_name and dir
15
- # otherwise false
16
- #
17
- def rel? (rel_name, dir=:outgoing)
18
- type = org.neo4j.graphdb.DynamicRelationshipType.withName(rel_name.to_s)
19
- java_dir = _to_java_direction(dir)
20
- hasRelationship(type, java_dir)
21
- end
22
-
23
-
24
- # Returns a Neo4j::Relationships::RelationshipDSL object for accessing relationships from and to this node.
25
- # The Neo4j::Relationships::RelationshipDSL is an Enumerable that returns Neo4j::RelationshipMixin objects.
26
- #
27
- # ==== Returns
28
- # A Neo4j::Relationships::RelationshipDSL object
29
- #
30
- # ==== See Also
31
- # * Neo4j::Relationships::RelationshipDSL
32
- # * Neo4j::RelationshipMixin
33
- #
34
- # ==== Example
35
- #
36
- # person_node.rels.outgoing(:friends).each { ... }
37
- #
38
- def rels(direction = :outgoing)
39
- Neo4j::Relationships::RelationshipDSL.new(self, direction)
40
- end
41
-
42
- # Returns a single relationship or nil if none available.
43
- # If there are more then one relationship of the given type it will raise an exception.
44
- #
45
- # ==== Parameters
46
- # type<#to_s>:: the key and value to be set
47
- # dir:: optional, default :outgoing (either, :outgoing, :incoming, :both)
48
- # raw:: optional, true|false (false default). If false return the ruby wrapped relationship object instead of the raw java neo4j obejct.
49
-
50
- #
51
- # ==== Returns
52
- # An object that mixins the Neo4j::RelationshipMixin representing the given relationship type or nil if there are no relationships.
53
- # If there are more then one relationship it will raise an Exception (java exception of type org.neo4j.graphdb.NotFoundException)
54
- #
55
- # ==== See Also
56
- # * JavaDoc for http://api.neo4j.org/current/org/neo4j/api/core/Node.html#getSingleRelationship(org.neo4j.graphdb.RelationshipType,%20org.neo4j.graphdb.Direction)
57
- # * Neo4j::RelationshipMixin
58
- #
59
- # ==== Example
60
- #
61
- # person_node.rel(:address).end_node[:street]
62
- #
63
- def rel(rel_name, dir=:outgoing, raw=false)
64
- java_dir = _to_java_direction(dir)
65
- rel_type = org.neo4j.graphdb.DynamicRelationshipType.withName(rel_name.to_s)
66
- rel = getSingleRelationship(rel_type, java_dir)
67
- return nil if rel.nil?
68
- return rel.wrapper unless raw
69
- rel
70
- end
71
-
72
-
73
- # Adds an outgoing relationship from this node to another node.
74
- # Will trigger a relationship_created event.
75
- #
76
- # ==== Parameters
77
- # type:: the relationship type between the nodes (respond_to :to_s)
78
- # to:: the other node (Neo4j::Node || kind_of?(Neo4j::NodeMixin)
79
- #
80
- # ==== Returns
81
- # a Neo4j::Relationship object
82
- #
83
- # === Example
84
- # nodeA = Neo4j::Node.new
85
- # nodeB = Neo4j::Node.new
86
- # nodeA.add_rel(:friend, nodeB)
87
- #
88
-
89
- # all creation of relationships uses this method
90
- def add_rel (type, to, rel_clazz = nil) # :nodoc:
91
- java_type = org.neo4j.graphdb.DynamicRelationshipType.withName(type.to_s)
92
- java_rel = createRelationshipTo(to._java_node, java_type)
93
- # check if we should create a wrapped Ruby Relationship class or use the raw java one.
94
- rel = (rel_clazz.nil?) ? java_rel : rel_clazz.new(java_rel)
95
- Neo4j.event_handler.relationship_created(rel)
96
- @_wrapper.class.indexer.on_relationship_created(@_wrapper, type) if @_wrapper
97
- rel
98
- end
99
-
100
- def _to_java_direction(dir) # :nodoc:
101
- case dir
102
- when :outgoing
103
- org.neo4j.graphdb.Direction::OUTGOING
104
- when :incoming
105
- org.neo4j.graphdb.Direction::INCOMING
106
- when :both
107
- org.neo4j.graphdb.Direction::BOTH
108
- else
109
- raise "Unknown parameter: '#{dir}', only accept :outgoing, :incoming or :both"
110
- end
111
- end
112
-
113
-
114
- # Returns a Neo4j::Relationships::NodeTraverser object for traversing outgoing nodes from and to this node.
115
- # The Neo4j::Relationships::NodeTraverser is an Enumerable that returns Neo4j::NodeMixin objects.
116
- #
117
- # ==== See Also
118
- # Neo4j::Relationships::NodeTraverser
119
- #
120
- # ==== Example
121
- #
122
- # person_node.outgoing(:friends).each { ... }
123
- # person_node.outgoing(:friends).raw(true).each { }
124
- #
125
- # The raw false parameter means that the ruby wrapper object will not be loaded, instead the raw Java Neo4j object will be used,
126
- # it might improve the performance.
127
- #
128
- def outgoing(*args)
129
- Neo4j::Relationships::NodeTraverser.new(self).outgoing(*args)
130
- end
131
-
132
- # Returns a Neo4j::Relationships::NodeTraverser object for traversing outgoing nodes from and to this node.
133
- # The Neo4j::Relationships::NodeTraverser is an Enumerable that returns Neo4j::NodeMixin objects.
134
- #
135
- # ==== See Also
136
- # Neo4j::Relationships::NodeTraverser
137
- #
138
- # ==== Example
139
- #
140
- # person_node.incoming(:friends).each { ... }
141
- # person_node.incoming(:friends).raw(true).each { }
142
- #
143
- # The raw false parameter means that the ruby wrapper object will not be loaded, instead the raw Java Neo4j object will be used,
144
- # it might improve the performance.
145
- #
146
- def incoming(*args)
147
- Neo4j::Relationships::NodeTraverser.new(self).incoming(*args)
148
- end
149
-
150
-
151
- # Deletes this node.
152
- # Deletes all relationships as well.
153
- # Invoking any methods on this node after delete() has returned is invalid and may lead to unspecified behavior.
154
- #
155
- # :api: public
156
- def del
157
- Neo4j.event_handler.node_deleted(wrapper)
158
-
159
- # delete outgoing relationships, and check for cascade delete
160
- rels.outgoing.each { |r| r.del; r.end_node.del if r[:_cascade_delete_outgoing]}
161
-
162
- rels.incoming.each do |r|
163
- r.del
164
- if r[:_cascade_delete_incoming]
165
- node_id = r[:_cascade_delete_incoming]
166
- node = Neo4j.load_node(node_id)
167
- # check node has no outgoing relationships
168
- no_outgoing = node.rels.outgoing.empty?
169
- # check node has only incoming relationship with cascade_delete_incoming
170
- no_incoming = node.rels.incoming.find{|r| !node.ignore_incoming_cascade_delete?(r)}.nil?
171
- # only cascade delete incoming if no outgoing and no incoming (exception cascade_delete_incoming) relationships
172
- node.del if no_outgoing and no_incoming
173
- end
174
- end
175
- delete
176
- @_wrapper.class.indexer.delete_index(self) if @_wrapper
177
- end
178
-
179
- # --------------------------------------------------------------------------
180
- # Debug
181
- #
182
-
183
- # Used for debugging purpose, traverse the graph of given depth and direction and prints nodes and relationship information.
184
- def print(levels = 0, dir = :outgoing)
185
- print_sub(0, levels, dir)
186
- end
187
-
188
- def print_sub(level, max_level, dir) # :nodoc:
189
- spaces = " " * level
190
- node_class = (self[:_classname].nil?) ? Neo4j::Node.to_s : self[:_classname]
191
- node_desc = "#{spaces}neo_id=#{neo_id} #{node_class}"
192
- props.each_pair {|key, value| next if %w[id].include?(key) or key.match(/^_/) ; node_desc << " #{key}='#{value}'"}
193
- puts node_desc
194
-
195
- if (level != max_level)
196
- rels(dir).each do |rel|
197
- cascade_desc = ""
198
- cascade_desc << "cascade in: #{rel[:_cascade_delete_incoming]}" if rel.property?(:_cascade_delete_incoming)
199
- cascade_desc << "cascade out: #{rel[:_cascade_delete_outgoing]}" if rel.property?(:_cascade_delete_outgoing)
200
- rel.other_node(self).print_sub(level + 1, max_level, dir)
201
- end
202
- end
203
- end
204
-
205
- end
@@ -1,169 +0,0 @@
1
- module Neo4j::JavaPropertyMixin
2
-
3
- # This is the property to use to map ruby classes to Neo4j Nodes
4
- CLASSNAME_PROPERTY = "_classname"
5
-
6
- # Returns the unique id of this node.
7
- # Ids are garbage collected over time so are only guaranteed to be unique at a specific set of time: if the node is deleted,
8
- # it's likely that a new node at some point will get the old id. Note: this make node ids brittle as public APIs.
9
- def neo_id
10
- getId
11
- end
12
-
13
- def _wrapper=(wrapper) # :nodoc:
14
- @_wrapper = wrapper
15
- end
16
-
17
- def _java_node
18
- self
19
- end
20
-
21
- # Returns true if this property container has a property accessible through the given key, false otherwise.
22
- def property?(key)
23
- has_property?(key.to_s)
24
- end
25
-
26
- # Returns the given property if it exist or nil if it does not exist.
27
- def [](key)
28
- return unless property?(key)
29
- if @_wrapper and @_wrapper.class.marshal?(key)
30
- Marshal.load(String.from_java_bytes(get_property(key.to_s)))
31
- else
32
- get_property(key.to_s)
33
- end
34
- end
35
-
36
- # Sets the given property to given value.
37
- # Will generate an event if the property does not start with '_' (which could be an internal property, like _classname)
38
- #
39
- def []=(key, value)
40
- k = key.to_s
41
- old_value = self[key]
42
-
43
- if value.nil?
44
- delete_property(k)
45
- elsif @_wrapper and @_wrapper.class.marshal?(key)
46
- setProperty(k, Marshal.dump(value).to_java_bytes)
47
- else
48
- value = java.lang.Double.new(value) if value.is_a? Float
49
- setProperty(k, value)
50
- end
51
-
52
- if (@_wrapper and k[0, 1] != '_') # do not want events on internal properties
53
- @_wrapper.class.indexer.on_property_changed(@_wrapper, k) if @_wrapper.class.respond_to? :indexer
54
- Neo4j.event_handler.property_changed(@_wrapper, k, old_value, value)
55
- end
56
-
57
- end
58
-
59
-
60
- # Removes the property from this node.
61
- # This is same as setting a property value to nil.
62
- #
63
- # For more information see JavaDoc PropertyContainer#removeProperty
64
- #
65
- # ==== Example
66
- # a = Node.new
67
- # a[:foo] = 2
68
- # a.delete_property('foo')
69
- # a[:foo] # => nil
70
- #
71
- # ==== Returns
72
- # <tt>true</tt> if the property was removed, <tt>false</tt> otherwise
73
- #
74
- def delete_property (name)
75
- removed = !removeProperty(name).nil?
76
- if (removed and @_wrapper and name[0] != '_') # do not want events on internal properties
77
- @_wrapper.class.indexer.on_property_changed(self, name)
78
- end
79
- removed
80
- end
81
-
82
- # Returns a hash of all properties.
83
- #
84
- # === Returns
85
- # Hash:: property key and property value with the '_neo_id' as the neo_id
86
- #
87
- def props
88
- ret = {"_neo_id" => getId()}
89
- iter = getPropertyKeys.iterator
90
- while (iter.hasNext) do
91
- key = iter.next
92
- ret[key] = getProperty(key)
93
- end
94
- ret
95
- end
96
-
97
- # Updates this node/relationship's properties by using the provided struct/hash.
98
- # If the option <code>{:strict => true}</code> is given, any properties present on
99
- # the node but not present in the hash will be removed from the node.
100
- #
101
- # === Parameters
102
- # struct_or_hash<#each_pair>:: the key and value to be set, should respond to 'each_pair'
103
- # options:: further options defining the context of the update, should be a Hash
104
- #
105
- # === Returns
106
- # self
107
- #
108
- def update(struct_or_hash, options={})
109
- strict = options[:strict]
110
- keys_to_delete = props.keys - %w(_neo_id _classname) if strict
111
- struct_or_hash.each_pair do |key, value|
112
- next if %w(_neo_id _classname).include? key.to_s # do not allow special properties to be mass assigned
113
- keys_to_delete.delete(key) if strict
114
- setter_meth = "#{key}=".to_sym
115
- if @_wrapper && @_wrapper.respond_to?(setter_meth)
116
- @_wrapper.send(setter_meth, value)
117
- else
118
- self[key] = value
119
- end
120
- end
121
- keys_to_delete.each{|key| delete_property(key) } if strict
122
- self
123
- end
124
-
125
-
126
- def equal?(o)
127
- eql?(o)
128
- end
129
-
130
- def eql?(o)
131
- return false unless o.respond_to?(:neo_id)
132
- o.neo_id == neo_id
133
- end
134
-
135
- def ==(o)
136
- eql?(o)
137
- end
138
-
139
-
140
- # Same as neo_id but returns a String instead of a Fixnum.
141
- # Used by Ruby on Rails.
142
- #
143
- def to_param
144
- neo_id.to_s
145
- end
146
-
147
- # Loads a Neo node wrapper if possible
148
- # If the neo property '_classname' does not exist then it will map the neo node to the ruby class Neo4j::Node
149
- def wrapper
150
- return self unless wrapper?
151
- @_wrapper ||= wrapper_class.new(self)
152
- @_wrapper
153
- end
154
-
155
- def wrapper?
156
- property?(CLASSNAME_PROPERTY)
157
- end
158
-
159
- def wrapper_class # :nodoc:
160
- return nil unless wrapper?
161
- classname = get_property(CLASSNAME_PROPERTY)
162
- classname.split("::").inject(Kernel) do |container, name|
163
- container.const_get(name.to_s)
164
- end
165
- end
166
-
167
-
168
- end
169
-