redis_object 0.5.0 → 1.0

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 (103) hide show
  1. data/.gitignore +0 -2
  2. data/Gemfile +0 -4
  3. data/README.markdown +15 -24
  4. data/Rakefile +0 -8
  5. data/doc/Object.html +185 -0
  6. data/doc/Seabright.html +181 -0
  7. data/doc/Seabright/Adapter.html +442 -0
  8. data/doc/Seabright/Collection.html +797 -0
  9. data/doc/Seabright/Collections.html +635 -0
  10. data/doc/Seabright/Collections/ClassMethods.html +212 -0
  11. data/doc/Seabright/ExternalIndex.html +217 -0
  12. data/doc/Seabright/History.html +382 -0
  13. data/doc/Seabright/History/ClassMethods.html +276 -0
  14. data/doc/Seabright/Indices.html +324 -0
  15. data/doc/Seabright/Indices/ClassMethods.html +348 -0
  16. data/doc/Seabright/Keys.html +314 -0
  17. data/doc/Seabright/Keys/ClassMethods.html +276 -0
  18. data/doc/Seabright/ObjectBase.html +852 -0
  19. data/doc/Seabright/ObjectBase/ClassMethods.html +677 -0
  20. data/doc/Seabright/RedisObject.html +230 -0
  21. data/doc/Seabright/References.html +280 -0
  22. data/doc/Seabright/Storage.html +252 -0
  23. data/doc/Seabright/Storage/ClassMethods.html +276 -0
  24. data/doc/Seabright/Storage/MySQL.html +442 -0
  25. data/doc/Seabright/Storage/Redis.html +218 -0
  26. data/doc/Seabright/Template.html +212 -0
  27. data/doc/Seabright/Template/ClassMethods.html +166 -0
  28. data/doc/Seabright/Timestamps.html +292 -0
  29. data/doc/Seabright/Timestamps/ClassMethods.html +214 -0
  30. data/doc/Seabright/Types.html +410 -0
  31. data/doc/Seabright/Types/ClassMethods.html +308 -0
  32. data/doc/created.rid +17 -0
  33. data/doc/images/add.png +0 -0
  34. data/doc/images/brick.png +0 -0
  35. data/doc/images/brick_link.png +0 -0
  36. data/doc/images/bug.png +0 -0
  37. data/doc/images/bullet_black.png +0 -0
  38. data/doc/images/bullet_toggle_minus.png +0 -0
  39. data/doc/images/bullet_toggle_plus.png +0 -0
  40. data/doc/images/date.png +0 -0
  41. data/doc/images/delete.png +0 -0
  42. data/doc/images/find.png +0 -0
  43. data/doc/images/loadingAnimation.gif +0 -0
  44. data/doc/images/macFFBgHack.png +0 -0
  45. data/doc/images/package.png +0 -0
  46. data/doc/images/page_green.png +0 -0
  47. data/doc/images/page_white_text.png +0 -0
  48. data/doc/images/page_white_width.png +0 -0
  49. data/doc/images/plugin.png +0 -0
  50. data/doc/images/ruby.png +0 -0
  51. data/doc/images/tag_blue.png +0 -0
  52. data/doc/images/tag_green.png +0 -0
  53. data/doc/images/transparent.png +0 -0
  54. data/doc/images/wrench.png +0 -0
  55. data/doc/images/wrench_orange.png +0 -0
  56. data/doc/images/zoom.png +0 -0
  57. data/doc/index.html +125 -0
  58. data/doc/js/darkfish.js +153 -0
  59. data/doc/js/jquery.js +18 -0
  60. data/doc/js/navigation.js +142 -0
  61. data/doc/js/search.js +94 -0
  62. data/doc/js/search_index.js +1 -0
  63. data/doc/js/searcher.js +228 -0
  64. data/doc/rdoc.css +543 -0
  65. data/doc/table_of_contents.html +394 -0
  66. data/lib/redis_object.rb +1 -11
  67. data/lib/redis_object/base.rb +60 -210
  68. data/lib/redis_object/collection.rb +100 -130
  69. data/lib/redis_object/defaults.rb +8 -21
  70. data/lib/redis_object/ext/filters.rb +16 -34
  71. data/lib/redis_object/ext/triggers.rb +13 -75
  72. data/lib/redis_object/{experimental/history.rb → history.rb} +0 -0
  73. data/lib/redis_object/indices.rb +39 -44
  74. data/lib/redis_object/keys.rb +4 -4
  75. data/lib/redis_object/storage.rb +1 -30
  76. data/lib/redis_object/storage/adapter.rb +3 -6
  77. data/lib/redis_object/storage/redis.rb +3 -98
  78. data/lib/redis_object/timestamps.rb +21 -42
  79. data/lib/redis_object/types.rb +30 -172
  80. data/lib/redis_object/version.rb +1 -1
  81. data/redis_object.gemspec +0 -1
  82. data/spec/base_spec.rb +6 -41
  83. data/spec/spec_helper.rb +1 -32
  84. metadata +116 -111
  85. data/.coveralls.yml +0 -1
  86. data/.travis.yml +0 -5
  87. data/lib/redis_object/ext/script_cache.rb +0 -92
  88. data/lib/redis_object/ext/shardable.rb +0 -18
  89. data/lib/redis_object/ext/view_caching.rb +0 -258
  90. data/lib/redis_object/ext/views.rb +0 -102
  91. data/lib/redis_object/inheritance_tracking.rb +0 -23
  92. data/spec/adapter_spec.rb +0 -43
  93. data/spec/benchmark_spec.rb +0 -46
  94. data/spec/collections_spec.rb +0 -144
  95. data/spec/defaults_spec.rb +0 -56
  96. data/spec/filters_spec.rb +0 -29
  97. data/spec/indices_spec.rb +0 -45
  98. data/spec/rename_class_spec.rb +0 -96
  99. data/spec/timestamp_spec.rb +0 -28
  100. data/spec/trigger_spec.rb +0 -51
  101. data/spec/types_spec.rb +0 -103
  102. data/spec/view_caching_spec.rb +0 -130
  103. data/spec/views_spec.rb +0 -72
@@ -2,6 +2,20 @@ module Seabright
2
2
 
3
3
  module Collections
4
4
 
5
+ def dump
6
+ require "utf8_utils"
7
+ out = ["puts \"Creating: #{id}\""]
8
+ s_id = id.gsub(/\W/,"_")
9
+ out << "a#{s_id} = #{self.class.cname}.new(#{actual.to_s.tidy_bytes})"
10
+ collections.each do |col|
11
+ col.each do |sobj|
12
+ out << sobj.dump(self)
13
+ end
14
+ end
15
+ out << "a#{s_id}.save"
16
+ out.join("\n")
17
+ end
18
+
5
19
  def hkey_col(ident = nil)
6
20
  "#{hkey}:collections"
7
21
  end
@@ -10,24 +24,49 @@ module Seabright
10
24
  super(o_id)
11
25
  store.smembers(hkey_col).each do |name|
12
26
  collections[name] = Seabright::Collection.load(name,self)
13
- define_access(name) do
14
- get_collection(name)
15
- end
16
- define_access(name.to_s.singularize) do
17
- get_collection(name).latest
18
- end
19
27
  end
28
+ # TODO: Here's an example of dynamic method creation - should do this instead of method_missing + module intercepts...
29
+ # %w[report alert error summary].each do |kind|
30
+ # class_eval <<-END
31
+ # if "#{kind}" == "summary"
32
+ # def summaries
33
+ # data_for_server[:summaries]
34
+ # end
35
+ # else
36
+ # def #{kind}s
37
+ # data_for_server[:#{kind}s]
38
+ # end
39
+ # end
40
+ #
41
+ # if "#{kind}" == "report"
42
+ # def report(new_entry)
43
+ # reports << new_entry
44
+ # end
45
+ # elsif "#{kind}" == "summary"
46
+ # def summary(new_entry)
47
+ # summaries << new_entry
48
+ # end
49
+ # else
50
+ # def #{kind}(*fields)
51
+ # #{kind}s << ( fields.first.is_a?(Hash) ?
52
+ # fields.first :
53
+ # {:subject => fields.first, :body => fields.last} )
54
+ # end
55
+ # end
56
+ # alias_method :add_#{kind}, :#{kind}
57
+ # END
58
+ # end
20
59
  true
21
60
  end
22
61
 
23
62
  def delete_child(obj)
24
- if col = get_collection(obj.collection_name)
25
- col.delete obj
63
+ if col = collections[obj.collection_name]
64
+ col.delete obj.hkey
26
65
  end
27
66
  end
28
67
 
29
68
  def collection_name
30
- self.class.collection_name
69
+ self.class.plname.underscore.to_sym
31
70
  end
32
71
 
33
72
  def ref_key(ident = nil)
@@ -35,18 +74,14 @@ module Seabright
35
74
  end
36
75
 
37
76
  def reference(obj)
38
- raise "Not an object." unless obj.is_a?(RedisObject)
39
- get_collection(obj.collection_name) << obj.hkey
77
+ name = obj.collection_name
78
+ store.sadd hkey_col, name
79
+ collections[name.to_s] ||= Seabright::Collection.load(name,self)
80
+ collections[name.to_s] << obj.hkey
40
81
  obj.referenced_by self
41
82
  end
42
-
43
- def <<(obj)
44
- reference obj
45
- end
46
-
47
- def push(obj)
48
- reference obj
49
- end
83
+ alias_method :<<, :reference
84
+ alias_method :push, :reference
50
85
 
51
86
  def remove_collection!(name)
52
87
  store.srem hkey_col, name
@@ -89,23 +124,11 @@ module Seabright
89
124
  end
90
125
 
91
126
  def has_collection?(name)
92
- collection_names.include?(name.to_s)
127
+ store.sismember(hkey_col,name.to_s)
93
128
  end
94
129
 
95
130
  def get_collection(name)
96
- if has_collection?(name)
97
- collections[name.to_s] ||= Collection.load(name,self)
98
- else
99
- store.sadd hkey_col, name
100
- @collection_names << name.to_s
101
- collections[name.to_s] ||= Collection.load(name,self)
102
- define_access(name.to_s.pluralize) do
103
- get_collection(name)
104
- end
105
- define_access(name.to_s.singularize) do
106
- get_collection(name).latest
107
- end
108
- end
131
+ collections[name.to_s] ||= Collection.load(name,self)
109
132
  collections[name.to_s]
110
133
  end
111
134
 
@@ -113,77 +136,22 @@ module Seabright
113
136
  @collections ||= {}
114
137
  end
115
138
 
116
- def collection_names
117
- @collection_names ||= store.smembers(hkey_col)
118
- end
119
-
120
139
  def mset(dat)
121
140
  dat.select! {|k,v| !collections[k.to_s] }
122
141
  super(dat)
123
142
  end
124
143
 
125
144
  def set(k,v)
126
- @data ? super(k,v) : has_collection?(k) ? get_collection(k.to_s).replace(v) : super(k,v)
145
+ @data ? super(k,v) : collections[k.to_s] ? get_collection(k.to_s).replace(v) : super(k,v)
127
146
  v
128
147
  end
129
148
 
130
149
  module ClassMethods
131
150
 
132
- def hkey_col(ident = nil)
151
+ def hkey_col(ident = id)
133
152
  "#{hkey(ident)}:collections"
134
153
  end
135
154
 
136
- def delete_child(obj)
137
- if col = get_collection(obj.collection_name)
138
- col.delete obj
139
- end
140
- end
141
-
142
- def collection_name
143
- self.name.split('::').last.pluralize.underscore.to_sym
144
- end
145
-
146
- def reference(obj)
147
- name = obj.collection_name
148
- store.sadd hkey_col, name
149
- get_collection(name) << obj.hkey
150
- end
151
-
152
- def <<(obj)
153
- reference obj
154
- end
155
-
156
- def push(obj)
157
- reference obj
158
- end
159
-
160
- def remove_collection!(name)
161
- store.srem hkey_col, name
162
- end
163
-
164
- def get(k)
165
- if has_collection?(k)
166
- get_collection(k)
167
- elsif has_collection?(pk = k.to_s.pluralize)
168
- get_collection(pk).first
169
- else
170
- super(k)
171
- end
172
- end
173
-
174
- def has_collection?(name)
175
- store.sismember(hkey_col,name.to_s)
176
- end
177
-
178
- def get_collection(name)
179
- collections[name.to_s] ||= Collection.load(name,self)
180
- collections[name.to_s]
181
- end
182
-
183
- def collections
184
- @collections ||= {}
185
- end
186
-
187
155
  end
188
156
 
189
157
  def self.included(base)
@@ -194,26 +162,24 @@ module Seabright
194
162
 
195
163
  class Collection < Array
196
164
 
197
- include Seabright::CachedScripts
198
-
199
- def initialize(name,owner)
165
+ def initialize(name,parent)
200
166
  @name = name.to_s
201
- @owner = owner
167
+ @parent = parent
202
168
  end
203
169
 
204
170
  def remove!
205
- @owner.remove_collection! @name
171
+ @parent.remove_collection! @name
206
172
  end
207
173
 
208
174
  def latest
209
- indexed(:created_at,5,true).first || first
175
+ indexed(:created_at,5,true).first
210
176
  end
211
177
 
212
178
  def indexed(idx,num=-1,reverse=false)
213
179
  keys = keys_by_index(idx,num,reverse)
214
180
  out = Enumerator.new do |y|
215
181
  keys.each do |member|
216
- if a = class_const.find_by_key(member)
182
+ if a = RedisObject.find_by_key(member)
217
183
  y << a
218
184
  end
219
185
  end
@@ -228,16 +194,18 @@ module Seabright
228
194
  end
229
195
 
230
196
  def temp_key
231
- "#{key}::zintersect_temp::#{RedisObject.new_id(4)}"
197
+ "zintersect_temp"
232
198
  end
233
199
 
234
- RedisObject::ScriptSources::FwdScript = "redis.call('ZINTERSTORE', KEYS[1], 2, KEYS[2], KEYS[3], 'WEIGHTS', 1, 0)\nlocal keys = redis.call('ZRANGE', KEYS[1], 0, KEYS[4])\nredis.call('DEL', KEYS[1])\nreturn keys".freeze
235
- RedisObject::ScriptSources::RevScript = "redis.call('ZINTERSTORE', KEYS[1], 2, KEYS[2], KEYS[3], 'WEIGHTS', 1, 0)\nlocal keys = redis.call('ZREVRANGE', KEYS[1], 0, KEYS[4])\nredis.call('DEL', KEYS[1])\nreturn keys".freeze
236
-
237
200
  def keys_by_index(idx,num=-1,reverse=false)
238
- keys = run_script(reverse ? :RevScript : :FwdScript, [temp_key, index_key(idx), key, num])
201
+ keys = nil
202
+ store.multi do
203
+ store.zinterstore(temp_key, [index_key(idx), key], {:weights => ["1","0"]})
204
+ keys = store.send(reverse ? :zrevrange : :zrange, temp_key, 0, num)
205
+ store.del temp_key
206
+ end
239
207
  Enumerator.new do |y|
240
- keys.each do |member|
208
+ keys.value.each do |member|
241
209
  y << member
242
210
  end
243
211
  end
@@ -256,15 +224,12 @@ module Seabright
256
224
  return real_at(item_key(k))
257
225
  elsif k.is_a? Hash
258
226
  return match(k)
259
- elsif k.is_a? Integer
227
+ elsif k.is_a? Number
260
228
  return real_at(at(k))
261
229
  end
262
230
  return nil
263
231
  end
264
-
265
- def [](k)
266
- find k
267
- end
232
+ alias_method :[], :find
268
233
 
269
234
  def match(pkt)
270
235
  Enumerator.new do |y|
@@ -277,25 +242,29 @@ module Seabright
277
242
  end
278
243
 
279
244
  def real_at(key)
280
- class_const.find_by_key(key)
245
+ RedisObject.find_by_key(key)
281
246
  end
282
247
 
248
+ # def [](idx)
249
+ # class_const.find_by_key(at(idx))
250
+ # end
251
+
283
252
  def objects
284
253
  each.to_a
285
254
  end
286
255
 
287
256
  def first
288
- class_const.find_by_key(super)
257
+ RedisObject.find_by_key(super)
289
258
  end
290
259
 
291
260
  def last
292
- class_const.find_by_key(super)
261
+ RedisObject.find_by_key(super)
293
262
  end
294
263
 
295
264
  def each
296
265
  out = Enumerator.new do |y|
297
266
  each_index do |key|
298
- if a = class_const.find_by_key(at(key))
267
+ if a = RedisObject.find_by_key(at(key))
299
268
  y << a
300
269
  end
301
270
  end
@@ -311,7 +280,7 @@ module Seabright
311
280
 
312
281
  def cleanup!
313
282
  each_index do |key|
314
- unless a = class_const.find_by_key(at(key))
283
+ unless a = RedisObject.find_by_key(at(key))
315
284
  puts "Deleting #{key} because not #{a.inspect}" if DEBUG
316
285
  delete at(key)
317
286
  end
@@ -330,7 +299,7 @@ module Seabright
330
299
  return nil unless block_given?
331
300
  Enumerator.new do |y|
332
301
  each_index do |key|
333
- if (a = class_const.find_by_key(at(key))) && block.call(a)
302
+ if (a = RedisObject.find_by_key(at(key))) && block.call(a)
334
303
  y << a
335
304
  end
336
305
  end
@@ -352,35 +321,36 @@ module Seabright
352
321
  store.zadd(key,store.zcount(key,"-inf", "+inf"),k)
353
322
  super(k)
354
323
  end
355
-
356
- def push(obj)
357
- self << obj
358
- end
324
+ alias_method :push, :<<
359
325
 
360
326
  def class_const
361
- self.class.class_const_for(@name)
362
- end
363
-
364
- def store
365
- class_const.store
327
+ Object.const_get(@name.to_s.classify.to_sym)
366
328
  end
367
329
 
368
330
  def key
369
- "#{@owner ? "#{@owner.key}:" : ""}COLLECTION:#{@name}"
331
+ "#{@parent ? "#{@parent.key}:" : ""}COLLECTION:#{@name}"
370
332
  end
371
333
 
372
334
  class << self
373
335
 
374
- def load(name,owner)
375
- out = new(name,owner)
376
- out.replace class_const_for(name).store.zrange(out.key,0,-1)
336
+ def load(name,parent)
337
+ out = new(name,parent)
338
+ out.replace store.zrange(out.key,0,-1)
377
339
  out
378
340
  end
379
341
 
380
- def class_const_for(name)
381
- Object.const_get(name.to_s.classify.to_sym) rescue RedisObject
342
+ private
343
+
344
+ def store
345
+ @@store ||= RedisObject.store
382
346
  end
383
-
347
+
348
+ end
349
+
350
+ private
351
+
352
+ def store
353
+ @@store ||= RedisObject.store
384
354
  end
385
355
 
386
356
  end
@@ -1,36 +1,23 @@
1
1
  module Seabright
2
2
  module DefaultValues
3
3
 
4
+ def get(k)
5
+ if (d = self.class.default_vals[k.to_sym]) && !d.nil?
6
+ return d unless is_set?(k)
7
+ end
8
+ super(k)
9
+ end
10
+
4
11
  module ClassMethods
5
12
 
6
13
  def default_vals
7
14
  @default_vals ||= {}
8
15
  end
9
16
 
10
- def intercept_for_defaults!
11
- return if @intercepted_for_defaults
12
- self.class_eval do
13
-
14
- alias_method :undefaulted_get, :get unless method_defined?(:undefaulted_get)
15
- def get(k)
16
- if !is_set?(k) && (d = self.class.default_vals[k.to_sym]) && !d.nil?
17
- return d
18
- end
19
- undefaulted_get(k)
20
- end
21
-
22
- end
23
- @intercepted_for_defaults = true
24
- end
25
-
26
17
  def register_default(k,vl)
27
18
  default_vals[k.to_sym] = vl
28
- intercept_for_defaults!
29
- end
30
-
31
- def default_for(k,vl)
32
- register_default k, vl
33
19
  end
20
+ alias_method :default_for, :register_default
34
21
 
35
22
  end
36
23
 
@@ -1,43 +1,19 @@
1
1
  module Seabright
2
2
  module Filters
3
3
 
4
- module ClassMethods
5
-
6
- def intercept_for_filters!
7
- return if @intercept_for_filters
8
- self.class_eval do
9
-
10
- def filtered_method_call(method,*args)
11
- if filters = self.class.filters_for(method)
12
- filters.each do |f|
13
- args = send(f,*args)
14
- end
15
- end
16
- send("unfiltered_#{method.to_s}".to_sym,*args)
17
- end
18
-
19
- alias_method :unfiltered_get, :get unless method_defined?(:unfiltered_get)
20
- def get(k)
21
- filtered_method_call(:get,k)
22
- end
23
-
24
- alias_method :unfiltered_set, :set unless method_defined?(:unfiltered_set)
25
- def set(k,v)
26
- filtered_method_call(:set,k,v)
27
- end
28
-
29
- alias_method :unfiltered_setnx, :setnx unless method_defined?(:unfiltered_setnx)
30
- def setnx(k,v)
31
- filtered_method_call(:setnx,k,v)
32
- end
33
-
4
+ def filtered(method,*args)
5
+ if filters = self.class.filters_for(method)
6
+ filters.each do |f|
7
+ args = send(f,*args)
34
8
  end
35
- @intercept_for_filters = true
36
9
  end
10
+ method(*args)
11
+ end
12
+
13
+ module ClassMethods
37
14
 
38
15
  def set_filter(filter)
39
16
  filter_method(:set,filter)
40
- filter_method(:setnx,filter)
41
17
  end
42
18
 
43
19
  def get_filter(filter)
@@ -45,9 +21,15 @@ module Seabright
45
21
  end
46
22
 
47
23
  def filter_method(method, filter)
48
- method_filters[method.to_sym] ||= []
24
+ unless method_filters[method.to_sym]
25
+ method_filters[method.to_sym] ||= []
26
+ filter!(method.to_sym)
27
+ end
49
28
  method_filters[method.to_sym] << filter.to_sym unless method_filters[method.to_sym].include?(filter.to_sym)
50
- intercept_for_filters!
29
+ end
30
+
31
+ def filter!(method)
32
+ self.class.instance_exec("")
51
33
  end
52
34
 
53
35
  def method_filters