redis_object 0.5.0 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
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