hyperactive 0.1.1 → 0.2.2
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.
- data/README +1 -0
- data/lib/hyperactive/list.rb +154 -0
- data/lib/hyperactive/record.rb +322 -297
- data/lib/hyperactive/tree.rb +175 -167
- data/lib/hyperactive.rb +1 -0
- data/tests/list_test.rb +76 -0
- data/tests/record_test.rb +17 -17
- data/tests/tree_benchmark.rb +8 -8
- data/tests/tree_test.rb +13 -13
- metadata +5 -2
data/lib/hyperactive/record.rb
CHANGED
@@ -26,350 +26,375 @@ require 'archipelago'
|
|
26
26
|
module Hyperactive
|
27
27
|
|
28
28
|
#
|
29
|
-
# The
|
29
|
+
# The package containing the base class Bass that simplifies
|
30
|
+
# using archipelago for generic database stuff.
|
30
31
|
#
|
31
|
-
|
32
|
-
|
33
|
-
#
|
34
|
-
# A tiny <b>call</b>able class that saves stuff in
|
35
|
-
# indexes depending on certain attributes.
|
36
|
-
#
|
37
|
-
class IndexBuilder
|
38
|
-
#
|
39
|
-
# Get the first part of the key, that depends on the +attributes+.
|
40
|
-
#
|
41
|
-
def self.get_attribute_key_part(attributes)
|
42
|
-
"Hyperactive::IndexBuilder::#{attributes.join(",")}"
|
43
|
-
end
|
44
|
-
#
|
45
|
-
# Get the last part of the key, that depends on the +values+.
|
46
|
-
#
|
47
|
-
def self.get_value_key_part(values)
|
48
|
-
"#{values.join(",")}"
|
49
|
-
end
|
32
|
+
module Record
|
33
|
+
|
50
34
|
#
|
51
|
-
#
|
52
|
-
# that will be indexed.
|
35
|
+
# The default database connector.
|
53
36
|
#
|
54
|
-
|
55
|
-
|
56
|
-
end
|
37
|
+
CAPTAIN = Archipelago::Pirate::Captain.new
|
38
|
+
|
57
39
|
#
|
58
|
-
#
|
40
|
+
# A tiny <b>call</b>able class that saves stuff in
|
41
|
+
# indexes depending on certain attributes.
|
59
42
|
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
43
|
+
class IndexBuilder
|
44
|
+
#
|
45
|
+
# Get the first part of the key, that depends on the +attributes+.
|
46
|
+
#
|
47
|
+
def self.get_attribute_key_part(attributes)
|
48
|
+
"Hyperactive::IndexBuilder::#{attributes.join(",")}"
|
49
|
+
end
|
50
|
+
#
|
51
|
+
# Get the last part of the key, that depends on the +values+.
|
52
|
+
#
|
53
|
+
def self.get_value_key_part(values)
|
54
|
+
"#{values.join(",")}"
|
55
|
+
end
|
56
|
+
#
|
57
|
+
# Initialize an IndexBuilder giving it an array of +attributes+
|
58
|
+
# that will be indexed.
|
59
|
+
#
|
60
|
+
def initialize(attributes)
|
61
|
+
@attributes = attributes
|
62
|
+
end
|
63
|
+
#
|
64
|
+
# Get the Tree for the given +record+.
|
65
|
+
#
|
66
|
+
def get_key_for(record)
|
67
|
+
values = @attributes.collect do |att|
|
68
|
+
if record.respond_to?(att)
|
69
|
+
record.send(att)
|
70
|
+
else
|
71
|
+
nil
|
72
|
+
end
|
66
73
|
end
|
74
|
+
key = "#{self.class.get_attribute_key_part(@attributes)}::#{self.class.get_value_key_part(values)}"
|
67
75
|
end
|
68
|
-
key = "#{self.class.get_attribute_key_part(@attributes)}::#{self.class.get_value_key_part(values)}"
|
69
|
-
return CAPTAIN[key] ||= Tree.get_instance
|
70
|
-
end
|
71
|
-
#
|
72
|
-
# Call this IndexBuilder and pass it a +block+.
|
73
|
-
#
|
74
|
-
# If the +argument+ is an Array then we know we are a save hook,
|
75
|
-
# otherwise we are a destroy hook.
|
76
|
-
#
|
77
|
-
def call(argument, &block)
|
78
|
-
yield
|
79
|
-
|
80
76
|
#
|
81
|
-
#
|
82
|
-
# then we are a save hook, otherwise a destroy hook.
|
77
|
+
# Call this IndexBuilder and pass it a +block+.
|
83
78
|
#
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
79
|
+
# If the +argument+ is an Array then we know we are a save hook,
|
80
|
+
# otherwise we are a destroy hook.
|
81
|
+
#
|
82
|
+
def call(argument, &block)
|
83
|
+
yield
|
84
|
+
|
85
|
+
#
|
86
|
+
# If the argument is an Array (of old value, new value)
|
87
|
+
# then we are a save hook, otherwise a destroy hook.
|
88
|
+
#
|
89
|
+
if Array === argument
|
90
|
+
record = argument.last
|
91
|
+
old_record = argument.first
|
92
|
+
old_key = get_key_for(old_record)
|
93
|
+
new_key = get_key_for(record)
|
94
|
+
if old_key != new_key
|
95
|
+
(CAPTAIN[old_key] ||= Hyperactive::Tree::Root.get_instance).delete(record.record_id)
|
96
|
+
(CAPTAIN[new_key] ||= Hyperactive::Tree::Root.get_instance)[record.record_id] = record
|
97
|
+
end
|
98
|
+
else
|
99
|
+
record = argument
|
100
|
+
(CAPTAIN[get_key_for(record)] ||= Hyperactive::Tree::Root.get_instance).delete(record.record_id)
|
101
|
+
end
|
92
102
|
end
|
93
103
|
end
|
94
|
-
end
|
95
104
|
|
96
|
-
#
|
97
|
-
# A tiny <b>call</b>able class that saves stuff inside containers
|
98
|
-
# if they match certain criteria.
|
99
|
-
#
|
100
|
-
class MatchSaver
|
101
|
-
#
|
102
|
-
# Initialize this MatchSaver with a +key+, a <b>call</b>able +matcher+
|
103
|
-
# and a +mode+ (:select, :reject, :delete_if_match or :delete_unless_match).
|
104
105
|
#
|
105
|
-
|
106
|
-
|
107
|
-
@matcher = matcher
|
108
|
-
@mode = mode
|
109
|
-
end
|
106
|
+
# A tiny <b>call</b>able class that saves stuff inside containers
|
107
|
+
# if they match certain criteria.
|
110
108
|
#
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
109
|
+
class MatchSaver
|
110
|
+
#
|
111
|
+
# Initialize this MatchSaver with a +key+, a <b>call</b>able +matcher+
|
112
|
+
# and a +mode+ (:select, :reject, :delete_if_match or :delete_unless_match).
|
113
|
+
#
|
114
|
+
def initialize(key, matcher, mode)
|
115
|
+
@key = key
|
116
|
+
@matcher = matcher
|
117
|
+
@mode = mode
|
118
|
+
end
|
119
|
+
#
|
120
|
+
# Depending on <i>@mode</i> and return value of <i>@matcher</i>.call
|
121
|
+
# may save record in the Hash-like container named <i>@key</i> in
|
122
|
+
# the main database after having yielded to +block+.
|
123
|
+
#
|
124
|
+
def call(argument, &block)
|
125
|
+
yield
|
117
126
|
|
118
|
-
|
119
|
-
|
127
|
+
record = argument
|
128
|
+
record = argument.last if Array === argument
|
120
129
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
130
|
+
case @mode
|
131
|
+
when :select
|
132
|
+
if @matcher.call(record)
|
133
|
+
CAPTAIN[@key][record.record_id] = record
|
134
|
+
else
|
135
|
+
CAPTAIN[@key].delete(record.record_id)
|
136
|
+
end
|
137
|
+
when :reject
|
138
|
+
if @matcher.call(record)
|
139
|
+
CAPTAIN[@key].delete(record.record_id)
|
140
|
+
else
|
141
|
+
CAPTAIN[@key][record.record_id] = record
|
142
|
+
end
|
143
|
+
when :delete_if_match
|
144
|
+
if @matcher.call(record)
|
145
|
+
CAPTAIN[@key].delete(record.record_id)
|
146
|
+
end
|
147
|
+
when :delete_unless_match
|
148
|
+
unless @matcher.call(record)
|
149
|
+
CAPTAIN[@key].delete(record.record_id)
|
150
|
+
end
|
141
151
|
end
|
142
152
|
end
|
143
153
|
end
|
144
|
-
end
|
145
154
|
|
146
|
-
#
|
147
|
-
# A convenient base class to inherit when you want the basic utility methods
|
148
|
-
# provided by for example ActiveRecord::Base *hint hint*.
|
149
|
-
#
|
150
|
-
# NB: After an instance is created, it will actually return a copy <b>within your local machine</b>
|
151
|
-
# which is not what is usually the case. Every other time you fetch it using a select or other
|
152
|
-
# method you will instead receive a proxy object to the database. This means that nothing you
|
153
|
-
# do to it at that point will be persistent or even necessarily have a defined result.
|
154
|
-
# Therefore: do not use <b>MyRecordSubclass.new</b> to <b>MyRecordSubclass#initialize</b> objects,
|
155
|
-
# instead use <b>MyRecordSubclass.get_instance</b>, since it will return a fresh proxy object
|
156
|
-
# instead of the devious original:
|
157
|
-
# my_instance = MyRecordSubclass.get_instance(*the_same_arguments_as_to_initialize)
|
158
|
-
#
|
159
|
-
class Record
|
160
|
-
|
161
|
-
@@create_hooks_by_class = {}
|
162
|
-
@@destroy_hooks_by_class = {}
|
163
|
-
@@save_hooks_by_class = {}
|
164
|
-
|
165
|
-
#
|
166
|
-
# The host we are running on.
|
167
155
|
#
|
168
|
-
|
156
|
+
# A convenient base class to inherit when you want the basic utility methods
|
157
|
+
# provided by for example ActiveRecord::Base *hint hint*.
|
158
|
+
#
|
159
|
+
# NB: After an instance is created, it will actually return a copy <b>within your local machine</b>
|
160
|
+
# which is not what is usually the case. Every other time you fetch it using a select or other
|
161
|
+
# method you will instead receive a proxy object to the database. This means that nothing you
|
162
|
+
# do to it at that point will be persistent or even necessarily have a defined result.
|
163
|
+
# Therefore: do not use <b>MyRecordSubclass.new</b> to <b>MyRecordSubclass#initialize</b> objects,
|
164
|
+
# instead use <b>MyRecordSubclass.get_instance</b>, since it will return a fresh proxy object
|
165
|
+
# instead of the devious original:
|
166
|
+
# my_instance = MyRecordSubclass.get_instance(*the_same_arguments_as_to_initialize)
|
167
|
+
#
|
168
|
+
class Bass
|
169
|
+
|
170
|
+
@@create_hooks_by_class = {}
|
171
|
+
@@destroy_hooks_by_class = {}
|
172
|
+
@@save_hooks_by_class = {}
|
169
173
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
def self.setup(options = {})
|
175
|
-
CAPTAIN.setup(options[:pirate_options])
|
176
|
-
end
|
174
|
+
#
|
175
|
+
# The host we are running on.
|
176
|
+
#
|
177
|
+
HOST = "#{Socket::gethostbyname(Socket::gethostname)[0]}" rescue "localhost"
|
177
178
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
# The block argument will be a Proc that actually injects the
|
186
|
-
# instance into the database system.
|
187
|
-
#
|
188
|
-
# Use this to preprocess, validate and/or postprocess your
|
189
|
-
# instances upon creation.
|
190
|
-
#
|
191
|
-
def self.create_hooks
|
192
|
-
self.get_hook_array_by_class(@@create_hooks_by_class)
|
193
|
-
end
|
179
|
+
#
|
180
|
+
# Call this if you want to change the default database connector
|
181
|
+
# to something else.
|
182
|
+
#
|
183
|
+
def self.setup(options = {})
|
184
|
+
CAPTAIN.setup(options[:pirate_options])
|
185
|
+
end
|
194
186
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
187
|
+
#
|
188
|
+
# Return our create_hooks, which can then be treated as any old Array.
|
189
|
+
#
|
190
|
+
# These must be <b>call</b>able objects with an arity of 1
|
191
|
+
# that will be sent the instance about to be created (initial
|
192
|
+
# insertion into the database system) that take a block argument.
|
193
|
+
#
|
194
|
+
# The block argument will be a Proc that actually injects the
|
195
|
+
# instance into the database system.
|
196
|
+
#
|
197
|
+
# Use this to preprocess, validate and/or postprocess your
|
198
|
+
# instances upon creation.
|
199
|
+
#
|
200
|
+
def self.create_hooks
|
201
|
+
self.get_hook_array_by_class(@@create_hooks_by_class)
|
202
|
+
end
|
211
203
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
204
|
+
#
|
205
|
+
# Return our destroy_hooks, which can then be treated as any old Array.
|
206
|
+
#
|
207
|
+
# These must be <b>call</b>able objects with an arity of 1
|
208
|
+
# that will be sent the instance about to be destroyed (removal
|
209
|
+
# from the database system) that take a block argument.
|
210
|
+
#
|
211
|
+
# The block argument will be a Proc that actually removes the
|
212
|
+
# instance from the database system.
|
213
|
+
#
|
214
|
+
# Use this to preprocess, validate and/or postprocess your
|
215
|
+
# instances upon destruction.
|
216
|
+
#
|
217
|
+
def self.destroy_hooks
|
218
|
+
self.get_hook_array_by_class(@@destroy_hooks_by_class)
|
219
|
+
end
|
220
|
+
|
221
|
+
#
|
222
|
+
# Return our save_hooks, which can then be treated as any old Array.
|
223
|
+
#
|
224
|
+
# These must be <b>call</b>able objects with an arity of 1
|
225
|
+
# that will be sent [the old version, the new version] of the
|
226
|
+
# instance about to be saved (storage into the database system)
|
227
|
+
# along with a block argument.
|
228
|
+
#
|
229
|
+
# The block argument will be a Proc that actually saves the
|
230
|
+
# instance into the database system.
|
231
|
+
#
|
232
|
+
# Use this to preprocess, validate and/or postprocess your
|
233
|
+
# instances upon saving.
|
234
|
+
#
|
235
|
+
def self.save_hooks
|
236
|
+
self.get_hook_array_by_class(@@save_hooks_by_class)
|
237
|
+
end
|
229
238
|
|
230
|
-
|
231
|
-
|
232
|
-
|
239
|
+
#
|
240
|
+
# Create an index for this class.
|
241
|
+
#
|
242
|
+
# Will create a method find_by_#{attributes.join("_and_")} for this
|
243
|
+
# class that will return what you expect.
|
244
|
+
#
|
245
|
+
def self.index_by(*attributes)
|
246
|
+
attribute_key_part = IndexBuilder.get_attribute_key_part(attributes)
|
247
|
+
self.class_eval <<END
|
233
248
|
def self.find_by_#{attributes.join("_and_")}(*args)
|
234
|
-
|
235
|
-
|
249
|
+
key = "#{attribute_key_part}::" + IndexBuilder.get_value_key_part(args)
|
250
|
+
CAPTAIN[key]
|
236
251
|
end
|
237
252
|
END
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
253
|
+
index_builder = IndexBuilder.new(attributes)
|
254
|
+
self.save_hooks << index_builder
|
255
|
+
self.destroy_hooks << index_builder
|
256
|
+
end
|
242
257
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
258
|
+
#
|
259
|
+
# Will define a method called +name+ that will include all
|
260
|
+
# existing instances of this class that when sent to +matcher+.call
|
261
|
+
# return true. Will only return instances saved after this selector
|
262
|
+
# is defined.
|
263
|
+
#
|
264
|
+
def self.select(name, &block)
|
265
|
+
key = self.collection_key(name)
|
266
|
+
CAPTAIN[key] ||= Hyperactive::Tree::Root.get_instance
|
267
|
+
self.class_eval <<END
|
253
268
|
def self.#{name}
|
254
269
|
CAPTAIN["#{key}"]
|
255
270
|
end
|
256
271
|
END
|
257
|
-
|
258
|
-
|
259
|
-
|
272
|
+
self.save_hooks << MatchSaver.new(key, Proc.new do |arg|
|
273
|
+
yield(arg)
|
274
|
+
end, :select)
|
275
|
+
self.destroy_hooks << MatchSaver.new(key, Proc.new do |arg|
|
276
|
+
yield(arg)
|
277
|
+
end, :delete_if_match)
|
278
|
+
end
|
260
279
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
def self.reject(name,
|
268
|
-
|
269
|
-
|
270
|
-
|
280
|
+
#
|
281
|
+
# Will define a method called +name+ that will include all
|
282
|
+
# existing instances of this class that when sent to +matcher+.call
|
283
|
+
# does not return true. Will only return instances saved after this
|
284
|
+
# rejector is defined.
|
285
|
+
#
|
286
|
+
def self.reject(name, &block)
|
287
|
+
key = self.collection_key(name)
|
288
|
+
CAPTAIN[key] ||= Hyperactive::Tree::Root.get_instance
|
289
|
+
self.class_eval <<END
|
271
290
|
def self.#{name}
|
272
291
|
CAPTAIN["#{key}"]
|
273
292
|
end
|
274
293
|
END
|
275
|
-
|
276
|
-
|
277
|
-
|
294
|
+
self.save_hooks << MatchSaver.new(key, Proc.new do |arg|
|
295
|
+
yield(arg)
|
296
|
+
end, :reject)
|
297
|
+
self.destroy_hooks << MatchSaver.new(key, Proc.new do |arg|
|
298
|
+
yield(arg)
|
299
|
+
end, :delete_unless_match)
|
300
|
+
end
|
278
301
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
302
|
+
#
|
303
|
+
# Return the record with +record_id+.
|
304
|
+
#
|
305
|
+
def self.find(record_id)
|
306
|
+
CAPTAIN[record_id]
|
307
|
+
end
|
285
308
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
end
|
292
|
-
|
293
|
-
#
|
294
|
-
# Use this method to get new instances of this class, since it will actually
|
295
|
-
# make sure it both resides in the database and return a proxy to the remote
|
296
|
-
# object.
|
297
|
-
#
|
298
|
-
def self.get_instance(*arguments)
|
299
|
-
instance = self.new(*arguments)
|
300
|
-
instance.instance_eval do
|
301
|
-
@record_id = Digest::SHA1.hexdigest("#{HOST}:#{Time.new.to_f}:#{self.object_id}:#{rand(1 << 32)}")
|
309
|
+
#
|
310
|
+
# Will execute +block+ within a transaction.
|
311
|
+
#
|
312
|
+
def self.transaction(&block)
|
313
|
+
CAPTAIN.transaction(&block)
|
302
314
|
end
|
303
315
|
|
304
|
-
|
305
|
-
|
316
|
+
#
|
317
|
+
# Use this method to get new instances of this class, since it will actually
|
318
|
+
# make sure it both resides in the database and return a proxy to the remote
|
319
|
+
# object.
|
320
|
+
#
|
321
|
+
def self.get_instance(*arguments)
|
322
|
+
instance = self.new(*arguments)
|
323
|
+
instance.instance_eval do
|
324
|
+
@record_id = Digest::SHA1.hexdigest("#{HOST}:#{Time.new.to_f}:#{self.object_id}:#{rand(1 << 32)}")
|
325
|
+
end
|
326
|
+
|
327
|
+
Hyperactive::Hooker.call_with_hooks(instance, *self.create_hooks) do
|
328
|
+
CAPTAIN[instance.record_id] = instance
|
329
|
+
end
|
330
|
+
|
331
|
+
proxy = CAPTAIN[instance.record_id]
|
332
|
+
|
333
|
+
return proxy
|
306
334
|
end
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
#
|
324
|
-
def save_hook(old_value, &block)
|
325
|
-
Hyperactive::Hooker.call_with_hooks([old_value, self], *self.class.save_hooks) do
|
326
|
-
yield
|
335
|
+
|
336
|
+
#
|
337
|
+
# Our semi-unique id.
|
338
|
+
#
|
339
|
+
attr_reader :record_id
|
340
|
+
|
341
|
+
#
|
342
|
+
# This will allow us to wrap any write of us to persistent storage
|
343
|
+
# in the @@save_hooks as long as the Archipelago::Hashish provider
|
344
|
+
# supports it. See Archipelago::Hashish::BerkeleyHashish for an example
|
345
|
+
# of Hashish providers that do this.
|
346
|
+
#
|
347
|
+
def save_hook(old_value, &block)
|
348
|
+
Hyperactive::Hooker.call_with_hooks([old_value, self], *self.class.save_hooks) do
|
349
|
+
yield
|
350
|
+
end
|
327
351
|
end
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
352
|
+
|
353
|
+
#
|
354
|
+
# Remove this instance from the database calling all the right hooks.
|
355
|
+
#
|
356
|
+
# Freezes this instance after having deleted it.
|
357
|
+
#
|
358
|
+
# Returns false without destroying anything if any of the @@pre_destroy_hooks
|
359
|
+
# returns false.
|
360
|
+
#
|
361
|
+
# Returns true otherwise.
|
362
|
+
#
|
363
|
+
def destroy
|
364
|
+
Hyperactive::Hooker.call_with_hooks(self, *self.class.destroy_hooks) do
|
365
|
+
CAPTAIN.delete(@record_id)
|
366
|
+
self.freeze
|
367
|
+
end
|
344
368
|
end
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
"Hyperactive::Record::collection_key::#{sym}"
|
354
|
-
end
|
355
|
-
|
356
|
-
#
|
357
|
-
# Get an Array from +hash+ using <i>self</i> as
|
358
|
-
# key. If <i>self</i> doesnt exist in the +hash+
|
359
|
-
# it will recurse by calling the same method in the
|
360
|
-
# superclass until it has been called in Hyperactive::Record.
|
361
|
-
#
|
362
|
-
def self.get_hook_array_by_class(hash)
|
363
|
-
return hash[self] if hash.include?(self)
|
364
|
-
|
365
|
-
if self == Record
|
366
|
-
hash[self] = []
|
367
|
-
return self.get_hook_array_by_class(hash)
|
368
|
-
else
|
369
|
-
hash[self] = self.superclass.get_hook_array_by_class(hash).clone
|
370
|
-
return self.get_hook_array_by_class(hash)
|
369
|
+
|
370
|
+
private
|
371
|
+
|
372
|
+
#
|
373
|
+
# The key used to store the collection with the given +sym+ as name.
|
374
|
+
#
|
375
|
+
def self.collection_key(sym)
|
376
|
+
"Hyperactive::Record::Bass::collection_key::#{sym}"
|
371
377
|
end
|
378
|
+
|
379
|
+
#
|
380
|
+
# Get an Array from +hash+ using <i>self</i> as
|
381
|
+
# key. If <i>self</i> doesnt exist in the +hash+
|
382
|
+
# it will recurse by calling the same method in the
|
383
|
+
# superclass until it has been called in Hyperactive::Record::Base.
|
384
|
+
#
|
385
|
+
def self.get_hook_array_by_class(hash)
|
386
|
+
return hash[self] if hash.include?(self)
|
387
|
+
|
388
|
+
if self == Bass
|
389
|
+
hash[self] = []
|
390
|
+
return self.get_hook_array_by_class(hash)
|
391
|
+
else
|
392
|
+
hash[self] = self.superclass.get_hook_array_by_class(hash).clone
|
393
|
+
return self.get_hook_array_by_class(hash)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
372
397
|
end
|
373
|
-
|
374
398
|
end
|
375
399
|
end
|
400
|
+
|