neo4j 1.0.0.beta.21-java

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 (99) hide show
  1. data/CHANGELOG +141 -0
  2. data/CONTRIBUTORS +17 -0
  3. data/Gemfile +16 -0
  4. data/README.rdoc +135 -0
  5. data/lib/generators/neo4j.rb +65 -0
  6. data/lib/generators/neo4j/model/model_generator.rb +39 -0
  7. data/lib/generators/neo4j/model/templates/model.erb +7 -0
  8. data/lib/neo4j.rb +77 -0
  9. data/lib/neo4j/config.rb +153 -0
  10. data/lib/neo4j/database.rb +56 -0
  11. data/lib/neo4j/equal.rb +21 -0
  12. data/lib/neo4j/event_handler.rb +116 -0
  13. data/lib/neo4j/index/class_methods.rb +62 -0
  14. data/lib/neo4j/index/index.rb +33 -0
  15. data/lib/neo4j/index/indexer.rb +312 -0
  16. data/lib/neo4j/index/indexer_registry.rb +68 -0
  17. data/lib/neo4j/index/lucene_query.rb +191 -0
  18. data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
  19. data/lib/neo4j/jars/lucene-core-3.0.2.jar +0 -0
  20. data/lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar +0 -0
  21. data/lib/neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar +0 -0
  22. data/lib/neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar +0 -0
  23. data/lib/neo4j/load.rb +21 -0
  24. data/lib/neo4j/mapping/class_methods/init_node.rb +50 -0
  25. data/lib/neo4j/mapping/class_methods/init_rel.rb +35 -0
  26. data/lib/neo4j/mapping/class_methods/list.rb +13 -0
  27. data/lib/neo4j/mapping/class_methods/property.rb +82 -0
  28. data/lib/neo4j/mapping/class_methods/relationship.rb +91 -0
  29. data/lib/neo4j/mapping/class_methods/rule.rb +295 -0
  30. data/lib/neo4j/mapping/decl_relationship_dsl.rb +214 -0
  31. data/lib/neo4j/mapping/has_list.rb +134 -0
  32. data/lib/neo4j/mapping/has_n.rb +83 -0
  33. data/lib/neo4j/mapping/node_mixin.rb +112 -0
  34. data/lib/neo4j/mapping/relationship_mixin.rb +120 -0
  35. data/lib/neo4j/model.rb +4 -0
  36. data/lib/neo4j/neo4j.rb +95 -0
  37. data/lib/neo4j/node.rb +131 -0
  38. data/lib/neo4j/node_mixin.rb +4 -0
  39. data/lib/neo4j/node_relationship.rb +149 -0
  40. data/lib/neo4j/node_traverser.rb +157 -0
  41. data/lib/neo4j/property.rb +111 -0
  42. data/lib/neo4j/rails/attributes.rb +155 -0
  43. data/lib/neo4j/rails/callbacks.rb +34 -0
  44. data/lib/neo4j/rails/finders.rb +134 -0
  45. data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
  46. data/lib/neo4j/rails/mapping/property.rb +60 -0
  47. data/lib/neo4j/rails/model.rb +105 -0
  48. data/lib/neo4j/rails/persistence.rb +260 -0
  49. data/lib/neo4j/rails/railtie.rb +21 -0
  50. data/lib/neo4j/rails/relationships/mapper.rb +96 -0
  51. data/lib/neo4j/rails/relationships/relationship.rb +30 -0
  52. data/lib/neo4j/rails/relationships/relationships.rb +60 -0
  53. data/lib/neo4j/rails/serialization.rb +25 -0
  54. data/lib/neo4j/rails/timestamps.rb +65 -0
  55. data/lib/neo4j/rails/transaction.rb +67 -0
  56. data/lib/neo4j/rails/tx_methods.rb +15 -0
  57. data/lib/neo4j/rails/validations.rb +38 -0
  58. data/lib/neo4j/rails/validations/non_nil.rb +11 -0
  59. data/lib/neo4j/rails/validations/uniqueness.rb +37 -0
  60. data/lib/neo4j/relationship.rb +169 -0
  61. data/lib/neo4j/relationship_mixin.rb +4 -0
  62. data/lib/neo4j/relationship_traverser.rb +92 -0
  63. data/lib/neo4j/to_java.rb +31 -0
  64. data/lib/neo4j/transaction.rb +68 -0
  65. data/lib/neo4j/type_converters.rb +117 -0
  66. data/lib/neo4j/version.rb +3 -0
  67. data/lib/orm_adapter/adapters/neo4j.rb +55 -0
  68. data/lib/tmp/neo4j/active_tx_log +1 -0
  69. data/lib/tmp/neo4j/index/lucene-store.db +0 -0
  70. data/lib/tmp/neo4j/index/lucene.log.active +0 -0
  71. data/lib/tmp/neo4j/lucene-fulltext/lucene-store.db +0 -0
  72. data/lib/tmp/neo4j/lucene-fulltext/lucene.log.active +0 -0
  73. data/lib/tmp/neo4j/lucene/lucene-store.db +0 -0
  74. data/lib/tmp/neo4j/lucene/lucene.log.active +0 -0
  75. data/lib/tmp/neo4j/messages.log +85 -0
  76. data/lib/tmp/neo4j/neostore +0 -0
  77. data/lib/tmp/neo4j/neostore.id +0 -0
  78. data/lib/tmp/neo4j/neostore.nodestore.db +0 -0
  79. data/lib/tmp/neo4j/neostore.nodestore.db.id +0 -0
  80. data/lib/tmp/neo4j/neostore.propertystore.db +0 -0
  81. data/lib/tmp/neo4j/neostore.propertystore.db.arrays +0 -0
  82. data/lib/tmp/neo4j/neostore.propertystore.db.arrays.id +0 -0
  83. data/lib/tmp/neo4j/neostore.propertystore.db.id +0 -0
  84. data/lib/tmp/neo4j/neostore.propertystore.db.index +0 -0
  85. data/lib/tmp/neo4j/neostore.propertystore.db.index.id +0 -0
  86. data/lib/tmp/neo4j/neostore.propertystore.db.index.keys +0 -0
  87. data/lib/tmp/neo4j/neostore.propertystore.db.index.keys.id +0 -0
  88. data/lib/tmp/neo4j/neostore.propertystore.db.strings +0 -0
  89. data/lib/tmp/neo4j/neostore.propertystore.db.strings.id +0 -0
  90. data/lib/tmp/neo4j/neostore.relationshipstore.db +0 -0
  91. data/lib/tmp/neo4j/neostore.relationshipstore.db.id +0 -0
  92. data/lib/tmp/neo4j/neostore.relationshiptypestore.db +0 -0
  93. data/lib/tmp/neo4j/neostore.relationshiptypestore.db.id +0 -0
  94. data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names +0 -0
  95. data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names.id +0 -0
  96. data/lib/tmp/neo4j/nioneo_logical.log.active +0 -0
  97. data/lib/tmp/neo4j/tm_tx_log.1 +0 -0
  98. data/neo4j.gemspec +31 -0
  99. metadata +216 -0
@@ -0,0 +1,214 @@
1
+ module Neo4j::Mapping
2
+
3
+
4
+ # A DSL for declared relationships has_n and has_one
5
+ # This DSL will be used to create accessor methods for relationships.
6
+ # Instead of using the 'raw' Neo4j::NodeMixin#rels method where one needs to know
7
+ # the name of relationship and direction one can use the generated accessor methods.
8
+ #
9
+ # The DSL can also be used to specify a mapping to a Ruby class for a relationship, see Neo4j::Relationships::DeclRelationshipDsl#relationship
10
+ #
11
+ # ==== Example
12
+ #
13
+ # class Folder
14
+ # include Neo4j::NodeMixin
15
+ # property :name
16
+ # # Declaring a Many relationship to any other node
17
+ # has_n(:files)
18
+ # end
19
+ #
20
+ # class File
21
+ # include Neo4j::NodeMixin
22
+ # # declaring a incoming relationship from Folder's relationship files
23
+ # has_one(:folder).from(Folder, :files)
24
+ # end
25
+ #
26
+ # The following methods will be generated:
27
+ # <b>Folder#files</b> :: returns an Enumerable of outgoing nodes for relationship 'files'
28
+ # <b>Folder#files_rels</b> :: returns an Enumerable of outgoing relationships for relationship 'files'
29
+ # <b>File#folder</b> :: for adding one node for the relationship 'files' from the outgoing Folder node
30
+ # <b>File#folder_rel</b> :: for accessing relationship 'files' from the outgoing Folder node
31
+ # <b>File#folder</b> :: for accessing nodes from relationship 'files' from the outgoing Folder node
32
+ #
33
+ class DeclRelationshipDsl
34
+ include Neo4j::ToJava
35
+
36
+ attr_reader :target_class, :direction, :rel_type
37
+
38
+ def initialize(method_id, has_one, target_class, params)
39
+ @direction = :outgoing
40
+ @method_id = method_id
41
+ @has_one = has_one
42
+ @rel_type = method_id
43
+ @target_class = target_class
44
+ end
45
+
46
+ def to_s
47
+ "DeclRelationshipDsl #{object_id} dir: #{@direction} rel_id: #{@method_id}, rel_type: #{@rel_type}, target_class:#{@target_class} rel_class:#{@relationship}"
48
+ end
49
+
50
+ def has_one?
51
+ @has_one
52
+ end
53
+
54
+ def each_node(node, direction, &block) #:nodoc:
55
+ type = type_to_java(rel_type)
56
+ dir = dir_to_java(direction)
57
+ node._java_node.getRelationships(type, dir).each do |rel|
58
+ other = rel.getOtherNode(node).wrapper
59
+ block.call other
60
+ end
61
+ end
62
+
63
+ def incoming? #:nodoc:
64
+ @direction == :incoming
65
+ end
66
+
67
+ def single_node(node) #:nodoc:
68
+ rel = single_relationship(node)
69
+ rel && rel.other_node(node).wrapper
70
+ end
71
+
72
+ def single_relationship(node) #:nodoc:
73
+ node._java_node.rel(direction, rel_type)
74
+ end
75
+
76
+ def _all_relationships(node) #:nodoc:
77
+ type = type_to_java(rel_type)
78
+ dir = dir_to_java(direction)
79
+ node._java_node.getRelationships(type, dir)
80
+ end
81
+
82
+ def all_relationships(node) #:nodoc:
83
+ Neo4j::RelationshipTraverser.new(node._java_node, [rel_type], direction)
84
+ end
85
+
86
+ def create_relationship_to(node, other) # :nodoc:
87
+ from, to = incoming? ? [other, node] : [node, other]
88
+ java_type = type_to_java(rel_type)
89
+
90
+ rel = from._java_node.create_relationship_to(to._java_node, java_type)
91
+ rel[:_classname] = relationship_class.to_s if relationship_class
92
+ rel.wrapper
93
+ end
94
+
95
+ # Specifies an outgoing relationship.
96
+ # The name of the outgoing class will be used as a prefix for the relationship used.
97
+ #
98
+ # ==== Arguments
99
+ # clazz:: to which class this relationship goes
100
+ # relationship:: optional, the relationship to use
101
+ #
102
+ # ==== Example
103
+ # class FolderNode
104
+ # include Neo4j::NodeMixin
105
+ # has_n(:files).to(FileNode)
106
+ # end
107
+ #
108
+ # folder = FolderNode.new
109
+ # # generate a relationship between folder and file of type 'FileNode#files'
110
+ # folder.files << FileNode.new
111
+ #
112
+ def to(*args)
113
+ @direction = :outgoing
114
+
115
+ if (args.size > 1)
116
+ raise "only one argument expected - the class of the node this relationship points to, got #{args.inspect}"
117
+ elsif (Class === args[0])
118
+ # handle e.g. has_n(:friends).to(class)
119
+ @target_class = args[0]
120
+ @rel_type = "#{@target_class}##{@method_id}"
121
+ else
122
+ raise "Expected a class for, got #{args[0]}"
123
+ end
124
+ self
125
+ end
126
+
127
+ # Specifies an incoming relationship.
128
+ # Will use the outgoing relationship given by the from class.
129
+ #
130
+ # ==== Example, with prefix FileNode
131
+ # class FolderNode
132
+ # include Neo4j::NodeMixin
133
+ # has_n(:files).to(FileNode)
134
+ # end
135
+ #
136
+ # class FileNode
137
+ # include Neo4j::NodeMixin
138
+ # # will only traverse any incoming relationship of type files from node FileNode
139
+ # has_one(:folder).from(FileNode, :files)
140
+ # end
141
+ #
142
+ # file = FileNode.new
143
+ # # create an outgoing relationship of type 'FileNode#files' from folder node to file (FileNode is the prefix).
144
+ # file.folder = FolderNode.new
145
+ #
146
+ # ==== Example, without prefix
147
+ #
148
+ # class FolderNode
149
+ # include Neo4j::NodeMixin
150
+ # has_n(:files)
151
+ # end
152
+ #
153
+ # class FileNode
154
+ # include Neo4j::NodeMixin
155
+ # has_one(:folder).from(:files) # will traverse any incoming relationship of type files
156
+ # end
157
+ #
158
+ # file = FileNode.new
159
+ # # create an outgoing relationship of type 'FileNode#files' from folder node to file
160
+ # file.folder = FolderNode.new
161
+ #
162
+ #
163
+ def from(*args)
164
+ @direction = :incoming
165
+
166
+ if (args.size > 1)
167
+ # handle specified (prefixed) relationship, e.g. has_n(:known_by).from(clazz, :type)
168
+ @rel_type = "#{@target_class}##{args[1]}"
169
+ @target_class = args[0]
170
+ other_class_dsl = @target_class._decl_rels[args[1]]
171
+ if other_class_dsl
172
+ @relationship = other_class_dsl.relationship_class
173
+ else
174
+ puts "WARNING: Unknown outgoing relationship #{args[1]} on #{@target_class}"
175
+ end
176
+ elsif (Symbol === args[0])
177
+ # handle unspecified (unprefixed) relationship, e.g. has_n(:known_by).from(:type)
178
+ @rel_type = args[0]
179
+ else
180
+ raise "Expected a symbol for, got #{args[0]}"
181
+ end
182
+ self
183
+ end
184
+
185
+ # Specifies which relationship ruby class to use for the relationship
186
+ #
187
+ # ==== Example
188
+ #
189
+ # class OrderLine
190
+ # include Neo4j::RelationshipMixin
191
+ # property :units
192
+ # property :unit_price
193
+ # end
194
+ #
195
+ # class Order
196
+ # property :total_cost
197
+ # property :dispatched
198
+ # has_n(:products).to(Product).relationship(OrderLine)
199
+ # end
200
+ #
201
+ # order = Order.new
202
+ # order.products << Product.new
203
+ # order.products_rels.first # => OrderLine
204
+ #
205
+ def relationship(rel_class)
206
+ @relationship = rel_class
207
+ self
208
+ end
209
+
210
+ def relationship_class # :nodoc:
211
+ @relationship
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,134 @@
1
+ module Neo4j
2
+ module Mapping
3
+
4
+ # Enables creating and traversal of nodes in a list.
5
+ #
6
+ # It uses the TimeLine http://api.neo4j.org/current/org/neo4j/index/timeline/Timeline.html,
7
+ #
8
+ # Includes the Enumerable Mixin.
9
+ # The Neo4j::Mapping::ClassMethods::List#has_list methods returns an object of this type.
10
+ #
11
+ # === Example, index same as size of list
12
+ #
13
+ # class Person
14
+ # include Neo4j::NodeMixin
15
+ # has_list :feeds
16
+ # end
17
+ #
18
+ # person = Person.new
19
+ # person.feeds << Neo4j::Node:new << Neo4j::Node.new
20
+ #
21
+ # === Example, using a custom index
22
+ #
23
+ # class Person
24
+ # include Neo4j::NodeMixin
25
+ # has_list :feeds
26
+ # end
27
+ #
28
+ # person = Person.new
29
+ # person.feeds[42] = (a = Neo4j::Node:new)
30
+ # person.feeds[1251] = Neo4j::Node.new
31
+ #
32
+ # person.feeds[42] # => a
33
+ #
34
+ class HasList
35
+ include Enumerable
36
+ include ToJava
37
+
38
+ def initialize(node, name)
39
+ @time_line = org.neo4j.index.timeline.Timeline.new(name, node._java_node, true, Neo4j.started_db.graph)
40
+ @node = node
41
+ @name = name
42
+ self.size = 0 unless size
43
+ end
44
+
45
+ # returns the size of this list
46
+ # notice in order to get correct result you must call the #remove method when an item is removed from the list
47
+ def size
48
+ @node["_list_size_#{@name}"]
49
+ end
50
+
51
+ # same as #size == 0
52
+ def empty?
53
+ size == 0
54
+ end
55
+
56
+ # returns the first node with index n
57
+ def [](n)
58
+ @time_line.getAllNodesBetween(n-1, n+1).first
59
+ end
60
+
61
+ # returns all nodes with the given index n
62
+ def all(n)
63
+ @time_line.getAllNodesBetween(n-1, n+1)
64
+ end
65
+
66
+ # returns the first node in the list or nil
67
+ def first
68
+ @time_line.first_node
69
+ end
70
+
71
+ # returns the last node in the list or nil
72
+ def last
73
+ @time_line.last_node
74
+ end
75
+
76
+ # adds a node to the list with the given index n
77
+ def []=(n, other_node)
78
+ @time_line.add_node(other_node, n)
79
+ self.size = self.size + 1
80
+ end
81
+
82
+ # returns all the nodes between the given Range
83
+ def between(range)
84
+ @time_line.getAllNodesBetween(range.first-1, range.end+1)
85
+ end
86
+
87
+ # removes one node from the list and decrases the size of the list,
88
+ def remove(node)
89
+ @time_line.remove_node(node)
90
+ self.size = self.size - 1
91
+ end
92
+
93
+ # Required by the Enumerable mixin so that we can
94
+ #
95
+ # ==== Example
96
+ #
97
+ # class Person
98
+ # include Neo4j::NodeMixin
99
+ # has_list :feeds
100
+ # end
101
+ #
102
+ # person.feeds.each {|node| node}
103
+ #
104
+ def each
105
+ @time_line.all_nodes.iterator.each { |node|
106
+ if @raw then
107
+ yield node
108
+ else
109
+ yield node.wrapper
110
+ end }
111
+ end
112
+
113
+ # If called then it will only return the raw java nodes and not the Ruby wrappers using the Neo4j::NodeMixin
114
+ def raw
115
+ @raw = true
116
+ end
117
+
118
+ def <<(other)
119
+ @time_line.add_node(other, size)
120
+ self.size = self.size + 1
121
+ self
122
+ end
123
+
124
+
125
+ private
126
+ def size=(size)
127
+ @node["_list_size_#{@name}"] = size
128
+ end
129
+
130
+
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,83 @@
1
+ module Neo4j
2
+ module Mapping
3
+
4
+ # Enables creating and traversal of nodes.
5
+ #
6
+ # Includes the Enumerable Mixin.
7
+ # The Neo4j::Mapping::ClassMethods::Relationship#has_n and Neo4j::Mapping::ClassMethods::Relationship#one
8
+ # methods returns an object of this type.
9
+ #
10
+ # ==== See Also
11
+ # Neo4j::Mapping::ClassMethods::Relationship
12
+ #
13
+ class HasN
14
+ include Enumerable
15
+ include ToJava
16
+
17
+ def initialize(node, dsl) # :nodoc:
18
+ @node = node
19
+ @direction = dsl.direction
20
+ @dsl = dsl
21
+ end
22
+
23
+ def to_s
24
+ "HasN [#@direction, id: #{@node.neo_id} type: #{@dsl && @dsl.rel_type} dsl:#{@dsl}]"
25
+ end
26
+
27
+ def size
28
+ [*self].size
29
+ end
30
+
31
+ alias_method :length, :size
32
+
33
+ def [](index)
34
+ each_with_index {|node,i| break node if index == i}
35
+ end
36
+
37
+ # Pretend we are an array - this is neccessarly for Rails actionpack/actionview/formhelper to work with this
38
+ def is_a?(type)
39
+ # ActionView requires this for nested attributes to work
40
+ return true if Array == type
41
+ super
42
+ end
43
+
44
+ # Required by the Enumerable mixin.
45
+ def each(&block)
46
+ @dsl.each_node(@node, @direction, &block)
47
+ end
48
+
49
+
50
+ # Returns true if there are no node in this type of relationship
51
+ def empty?
52
+ first == nil
53
+ end
54
+
55
+
56
+ # Creates a relationship instance between this and the other node.
57
+ # Returns the relationship object
58
+ def new(other)
59
+ @dsl.create_relationship_to(@node, other)
60
+ end
61
+
62
+
63
+ # Creates a relationship between this and the other node.
64
+ #
65
+ # ==== Example
66
+ #
67
+ # n1 = Node.new # Node has declared having a friend type of relationship
68
+ # n2 = Node.new
69
+ # n3 = Node.new
70
+ #
71
+ # n1 << n2 << n3
72
+ #
73
+ # ==== Returns
74
+ # self
75
+ #
76
+ def <<(other)
77
+ @dsl.create_relationship_to(@node, other)
78
+ self
79
+ end
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,112 @@
1
+ require "active_support/core_ext/module/delegation"
2
+
3
+ module Neo4j::Mapping
4
+
5
+ # This Mixin is used to wrap Neo4j Java Nodes in Ruby objects.
6
+ #
7
+ # It includes a number of mixins and forwards some methods to the raw Java node which in term includes a number of mixins, see below.
8
+ #
9
+ # === Instance Methods
10
+ #
11
+ # Mixins:
12
+ # * Neo4j::Index
13
+ # * Neo4j::Property
14
+ # * Neo4j::NodeRelationship
15
+ # * Neo4j::Equal
16
+ # * Neo4j::Index
17
+ #
18
+ # === Class Methods
19
+ #
20
+ # Mixins:
21
+ # * Neo4j::Mapping::ClassMethods::Root
22
+ # * Neo4j::Mapping::ClassMethods::Property
23
+ # * Neo4j::Mapping::ClassMethods::InitNode
24
+ # * Neo4j::Mapping::ClassMethods::Relationship
25
+ # * Neo4j::Mapping::ClassMethods::Rule
26
+ # * Neo4j::Mapping::ClassMethods::List
27
+ # * Neo4j::Index::ClassMethods
28
+ #
29
+ module NodeMixin
30
+ include Neo4j::Index
31
+
32
+ delegate :[]=, :[], :property?, :props, :attributes, :update, :neo_id, :id, :rels, :rel?, :to_param, :getId,
33
+ :rel, :del, :list?, :print, :print_sub, :outgoing, :incoming, :both,
34
+ :equal?, :eql?, :==, :exist?, :getRelationships, :getSingleRelationship, :_rels, :rel,
35
+ :to => :@_java_node, :allow_nil => true
36
+
37
+
38
+ # --------------------------------------------------------------------------
39
+ # Initialization methods
40
+ #
41
+
42
+
43
+ # Init this node with the specified java neo node
44
+ #
45
+ def init_on_load(java_node) # :nodoc:
46
+ @_java_node = java_node
47
+ end
48
+
49
+
50
+ # Creates a new node and initialize with given properties.
51
+ # You can override this to provide your own initialization.
52
+ #
53
+ def init_on_create(*args) # :nodoc:
54
+ self[:_classname] = self.class.to_s
55
+ if args[0].respond_to?(:each_pair)
56
+ args[0].each_pair { |k, v| respond_to?("#{k}=")? self.send("#{k}=", v) : @_java_node[k] = v }
57
+ end
58
+ end
59
+
60
+ # Returns the org.neo4j.graphdb.Node wrapped object
61
+ def _java_node
62
+ @_java_node
63
+ end
64
+
65
+ def trigger_rules
66
+ self.class.trigger_rules(self)
67
+ end
68
+
69
+
70
+ def _decl_rels_for(rel_type)
71
+ self.class._decl_rels[rel_type]
72
+ end
73
+
74
+ def wrapper
75
+ self
76
+ end
77
+
78
+
79
+ def self.included(c) # :nodoc:
80
+ c.instance_eval do
81
+ class << self
82
+ alias_method :orig_new, :new
83
+ end
84
+ end unless c.respond_to?(:orig_new)
85
+
86
+ c.class_inheritable_hash :_decl_props
87
+ c._decl_props ||= {}
88
+
89
+ c.class_inheritable_hash :_decl_rels
90
+ c._decl_rels ||= {}
91
+
92
+ c.extend ClassMethods::Property
93
+ c.extend ClassMethods::InitNode
94
+ c.extend ClassMethods::Relationship
95
+ c.extend ClassMethods::Rule
96
+ c.extend ClassMethods::List
97
+ c.extend Neo4j::Index::ClassMethods
98
+
99
+ def c.inherited(subclass)
100
+ # inherit the index properties
101
+ subclass.node_indexer self
102
+
103
+ # inherit the rules too
104
+ subclass.inherit_rules_from self
105
+
106
+ super
107
+ end
108
+
109
+ c.node_indexer c
110
+ end
111
+ end
112
+ end