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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
-