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
@@ -1,72 +1,20 @@
1
1
  module Seabright
2
2
  module Triggers
3
3
 
4
+ def set(k,v)
5
+ super(k,v)
6
+ if self.class.field_triggers[k.to_sym]
7
+ send(self.class.field_triggers[k.to_sym],k,v)
8
+ end
9
+ self.class.update_triggers.each do |actn|
10
+ send(actn.to_sym,k,v)
11
+ end
12
+ end
13
+
4
14
  module ClassMethods
5
15
 
6
16
  def trigger_on_set(fld,actn)
7
17
  field_triggers[fld.to_sym] = actn.to_sym
8
- intercept_sets_for_triggers!
9
- end
10
-
11
- def intercept_sets_for_triggers!
12
- return if @intercepted_sets_for_triggers
13
- self.class_eval do
14
- alias_method :untriggered_set, :set unless method_defined?(:untriggered_set)
15
- def set(k,v)
16
- untriggered_set(k,v)
17
- unless self.class.untriggerables.include?(k)
18
- begin
19
- self.class.untriggerables << k
20
- if self.class.field_triggers[k.to_sym]
21
- send(self.class.field_triggers[k.to_sym],k,v)
22
- end
23
- self.class.update_triggers.each do |actn|
24
- send(actn.to_sym,k,v)
25
- end
26
- ensure
27
- self.class.untriggerables.delete k
28
- end
29
- end
30
- end
31
- alias_method :untriggered_setnx, :setnx unless method_defined?(:untriggered_setnx)
32
- def setnx(k,v)
33
- ret = untriggered_setnx(k,v)
34
- unless self.class.untriggerables.include?(k)
35
- begin
36
- self.class.untriggerables << k
37
- if self.class.field_triggers[k.to_sym]
38
- send(self.class.field_triggers[k.to_sym],k,v)
39
- end
40
- self.class.update_triggers.each do |actn|
41
- send(actn.to_sym,k,v)
42
- end
43
- ensure
44
- self.class.untriggerables.delete k
45
- end
46
- end
47
- ret
48
- end
49
-
50
- end
51
- @intercepted_sets_for_triggers = true
52
- end
53
-
54
- def intercept_reference_for_triggers!
55
- return if @intercepted_reference_for_triggers
56
- self.class_eval do
57
- alias_method :untriggered_reference, :reference unless method_defined?(:untriggered_reference)
58
- def reference(obj)
59
- untriggered_reference(obj)
60
- self.class.reference_triggers.each do |actn|
61
- send(actn.to_sym,obj)
62
- end
63
- end
64
- end
65
- @intercepted_reference_for_triggers = true
66
- end
67
-
68
- def untriggerables
69
- @untriggerables ||= [:updated_at,:created_at]
70
18
  end
71
19
 
72
20
  def field_triggers
@@ -74,21 +22,11 @@ module Seabright
74
22
  end
75
23
 
76
24
  def trigger_on_update(actn)
77
- update_triggers << actn.to_sym
78
- intercept_sets_for_triggers!
25
+ update_triggers.push actn.to_sym
79
26
  end
80
27
 
81
28
  def update_triggers
82
- @update_triggers ||= Set.new
83
- end
84
-
85
- def trigger_on_reference(actn)
86
- reference_triggers << actn.to_sym
87
- intercept_reference_for_triggers!
88
- end
89
-
90
- def reference_triggers
91
- @reference_triggers ||= Set.new
29
+ @update_triggers ||= []
92
30
  end
93
31
 
94
32
  end
@@ -98,4 +36,4 @@ module Seabright
98
36
  end
99
37
 
100
38
  end
101
- end
39
+ end
@@ -1,50 +1,45 @@
1
1
  module Seabright
2
2
  module Indices
3
3
 
4
+ # def save_indices
5
+ # # self.class.indices.each do |indx|
6
+ # # indx.each do |key,idx|
7
+ # #
8
+ # # end
9
+ # # end
10
+ # self.class.sort_indices.each do |idx|
11
+ # store.zadd(index_key(idx), send(idx).to_i, hkey)
12
+ # end
13
+ # end
14
+
4
15
  def index_key(idx)
5
16
  self.class.index_key(idx)
6
17
  end
7
18
 
8
- module ClassMethods
9
-
10
- def intercept_sets_for_indices!
11
- return if @intercepted_sets_for_indices
12
- self.class_eval do
13
- alias_method :unindexed_set, :set unless method_defined?(:unindexed_set)
14
- def set(k,v)
15
- ret = unindexed_set(k,v)
16
- if self.class.has_sort_index?(k)
17
- store.zrem(index_key(k), hkey)
18
- store.zadd(index_key(k), score_format(k,v), hkey)
19
- end
20
- ret
21
- end
22
- alias_method :unindexed_mset, :mset unless method_defined?(:unindexed_mset)
23
- def mset(dat)
24
- ret = unindexed_mset(dat)
25
- dat.select {|k,v| self.class.has_sort_index?(k) }.each do |k,v|
26
- store.zrem(index_key(k), hkey)
27
- store.zadd(index_key(k), score_format(k,v), hkey)
28
- end
29
- ret
30
- end
31
- alias_method :unindexed_setnx, :setnx unless method_defined?(:unindexed_setnx)
32
- def setnx(k,v)
33
- ret = unindexed_setnx(k,v)
34
- if self.class.has_sort_index?(k)
35
- store.zrem(index_key(k), hkey)
36
- store.zadd(index_key(k), score_format(k,v), hkey)
37
- end
38
- ret
39
- end
40
-
41
- end
42
- @intercepted_sets_for_indices = true
19
+ # def save
20
+ # super
21
+ # save_indices
22
+ # end
23
+
24
+ def mset(dat)
25
+ super(dat)
26
+ dat.select {|k,v| self.class.has_sort_index?(k) }.each do |k,v|
27
+ store.zadd(index_key(k), score_format(k,v), hkey)
43
28
  end
29
+ end
30
+
31
+ def set(k,v)
32
+ super(k,v)
33
+ if self.class.has_sort_index?(k)
34
+ store.zadd(index_key(k), score_format(k,v), hkey)
35
+ end
36
+ end
37
+
38
+ module ClassMethods
44
39
 
45
40
  def indexed(idx,num=-1,reverse=false)
46
41
  out = Enumerator.new do |yielder|
47
- store.send(reverse ? :zrevrange : :zrange, index_key(idx), 0, num-1).each do |member|
42
+ store.send(reverse ? :zrevrange : :zrange, index_key(idx), 0, num).each do |member|
48
43
  if a = self.find_by_key(member)
49
44
  yielder << a
50
45
  end
@@ -63,20 +58,20 @@ module Seabright
63
58
  "#{self.plname}::#{idx}"
64
59
  end
65
60
 
61
+ # def index(opts)
62
+ # indices << opts
63
+ # end
64
+ #
65
+ # def indices
66
+ # @@indices ||= []
67
+ # end
68
+
66
69
  def sort_indices
67
70
  @@sort_indices ||= []
68
71
  end
69
72
 
70
73
  def sort_by(k)
71
74
  sort_indices << k.to_sym
72
- intercept_sets_for_indices!
73
- end
74
-
75
- def reindex(k)
76
- store.del index_key(k)
77
- all.each do |obj|
78
- obj.set(k,obj.get(k))
79
- end
80
75
  end
81
76
 
82
77
  def has_sort_index?(k)
@@ -15,15 +15,15 @@ module Seabright
15
15
 
16
16
  module ClassMethods
17
17
 
18
- def key(ident=nil)
19
- "#{cname}#{ident ? ":#{ident.gsub(/^.*:/,'')}" : ""}"
18
+ def key(ident)
19
+ "#{cname}:#{ident.gsub(/^.*:/,'')}"
20
20
  end
21
21
 
22
- def reserve_key(ident=nil)
22
+ def reserve_key(ident)
23
23
  "#{key(ident)}_reserve"
24
24
  end
25
25
 
26
- def hkey(ident = nil)
26
+ def hkey(ident = id)
27
27
  "#{key(ident)}_h"
28
28
  end
29
29
 
@@ -19,12 +19,8 @@ module Seabright
19
19
  adapters[id] ||= const_get(adapter).new(config(id))
20
20
  end
21
21
 
22
- def configure_store(conf,id=store_name,*ids)
22
+ def configure_store(conf,id=store_name)
23
23
  configs[id] = conf
24
- ids.each do |i|
25
- configs[i] = conf
26
- end
27
- store(id)
28
24
  end
29
25
 
30
26
  def use_store(id)
@@ -58,31 +54,6 @@ module Seabright
58
54
  configs[id]
59
55
  end
60
56
 
61
- def stores
62
- adapters
63
- end
64
-
65
- def dump_stores_to_files(path)
66
- raise "Directory does not exist!" unless Dir.exists?(File.dirname(path))
67
- adapters.each do |name,adptr|
68
- if adptr.respond_to? :dump_to_file
69
- puts "Dumping #{name} into #{path}/#{name.to_s}.dump"
70
- adptr.dump_to_file("#{path}/#{name.to_s}.dump")
71
- end
72
- end
73
- end
74
-
75
- def restore_stores_from_files(path)
76
- raise "Directory does not exist!" unless Dir.exists?(File.dirname(path))
77
- Dir.glob(path + "/*.dump").each do |file|
78
- name = file.gsub(/\.[^\.]+$/,'').gsub(/.*\//,'').to_sym
79
- if (stor = store(name)) && stor.respond_to?(:restore_from_file)
80
- puts "Restoring #{name} from #{file}"
81
- stor.restore_from_file(file)
82
- end
83
- end
84
- end
85
-
86
57
  end
87
58
 
88
59
  def self.included(base)
@@ -23,18 +23,15 @@ module Seabright
23
23
  end
24
24
 
25
25
  def reset
26
- connections.each_index do |i|
27
- connections[i] = nil
26
+ @connections.each_index do |i|
27
+ @connections[i] = nil
28
28
  end
29
29
  end
30
30
  alias_method :reconnect!, :reset
31
31
 
32
32
  def connection(num=0)
33
- connections[num] ||= new_connection
34
- end
35
-
36
- def connections
37
33
  @connections ||= []
34
+ @connections[num] ||= new_connection
38
35
  end
39
36
 
40
37
  def new_connection
@@ -3,7 +3,6 @@ module Seabright
3
3
  class Redis < Adapter
4
4
 
5
5
  def method_missing(sym, *args, &block)
6
- return super unless connection.respond_to?(sym)
7
6
  puts "[Storage::Redis] #{sym}(#{args.inspect.gsub(/\[|\]/m,'')})" if Debug.verbose?
8
7
  begin
9
8
  connection.send(sym,*args, &block)
@@ -11,109 +10,15 @@ module Seabright
11
10
  puts "Rescued: #{err.inspect}" if DEBUG
12
11
  reset
13
12
  connection.send(sym,*args, &block)
14
- rescue ::Redis::TimeoutError => err
15
- puts "Rescued connection timeout: #{err.inspect}" if DEBUG
16
- reset
17
- connection.send(sym,*args, &block)
18
13
  end
19
14
  end
20
15
 
21
16
  def new_connection
22
17
  require 'redis'
23
- puts "Connecting to Redis with: #{config_opts(:path, :db, :password, :host, :port, :timeout, :tcp_keepalive).inspect}" if DEBUG
24
- ::Redis.new(config_opts(:path, :db, :password, :host, :port, :timeout, :tcp_keepalive))
25
- end
26
-
27
- DUMP_SEPARATOR = "---:::RedisObject::DUMP_SEPARATOR:::---"
28
- REC_SEPARATOR = "---:::RedisObject::REC_SEPARATOR:::---"
29
-
30
- def dump_to_file(file)
31
- File.open(file,'wb') do |f|
32
- keys = connection.send(:keys,"*")
33
- f.write keys.map {|k|
34
- v = connection.dump(k)
35
- v.force_encoding(Encoding::BINARY)
36
- [k,v].join(DUMP_SEPARATOR)
37
- }.join(REC_SEPARATOR)
38
- end
39
- end
40
-
41
- def restore_from_file(file)
42
- str = File.read(file)
43
- str.force_encoding(Encoding::BINARY)
44
- str.split(REC_SEPARATOR).each do |line|
45
- line.force_encoding(Encoding::BINARY)
46
- key, val = line.split(DUMP_SEPARATOR)
47
- connection.multi do
48
- connection.del key
49
- connection.restore key, 0, val
50
- end
51
- end
52
- end
53
-
54
- def rename_class old_name, new_name
55
- old_name = old_name.to_s#.split('::').last
56
- new_name = new_name.to_s#.split('::').last
57
- old_collection_name = old_name.split('::').last.underscore.pluralize
58
- new_collection_name = new_name.split('::').last.underscore.pluralize
59
-
60
- # references to type in collection data
61
- keys("#{old_name}:*:backreferences").each do |backref_key|
62
- smembers(backref_key).each do |hashref|
63
- # there are two referenes we need to fix: individual references to items
64
- # and lists of collection names.
65
- #
66
- # this updates the item references in collections
67
- backref = hashref.sub(/_h$/,'');
68
- old_collection = "#{backref}:COLLECTION:#{old_collection_name}"
69
- new_collection = "#{backref}:COLLECTION:#{new_collection_name}"
70
- zrange(old_collection, 0, 99999, withscores:true).each do |key, score|
71
- zadd(new_collection, score, key.sub(/^#{old_name}/, new_name))
72
- end
73
- del(old_collection)
74
-
75
- # this updates the lists of collection names
76
- collection_names = "#{hashref}:collections"
77
- smembers(collection_names).each do |collection_name|
78
- if collection_name == old_collection_name
79
- sadd(collection_names, new_collection_name)
80
- srem(collection_names, old_collection_name)
81
- end
82
- end
83
- end
84
- rename(backref_key, backref_key.sub(/^#{old_name}/, new_name))
85
- end
86
-
87
- # type-wide id index
88
- smembers(old_name.pluralize).each do |key|
89
- sadd(new_name.pluralize, key.sub(/^#{old_name}/, new_name))
90
- old_class = hget("#{key}_h", :class)
91
- old_key = hget("#{key}_h", :key)
92
- hset("#{key}_h", :class, old_class.sub(/#{old_name}$/, new_name))
93
- hset("#{key}_h", :key, old_key.sub(/^#{old_name}/, new_name))
94
- hset("#{key}_h", "#{new_name.downcase}_id", key.sub(/^#{old_name}:/,''))
95
- hdel("#{key}_h", "#{old_name.downcase}_id")
96
- end
97
- del(old_name.pluralize)
98
-
99
- # column indexes
100
- keys("#{old_name.pluralize}::*").each do |old_index|
101
- new_index = old_index.sub(/^#{old_name.pluralize}/, new_name.pluralize)
102
- zrange(old_index, 0, 99999, withscores:true).each do |key, score|
103
- zadd(new_index, score, key.sub(/^#{old_name}/, new_name))
104
- end
105
- del(old_index)
106
- end
107
-
108
- # top-level keys
109
- keys("#{old_name}:*").each do |key|
110
- rename(key, key.sub(/^#{old_name}/, new_name))
111
- end
112
- keys("#{old_name.pluralize}:*").each do |key|
113
- rename(key, key.sub(/^#{old_name.pluralize}/, new_name.pluralize))
114
- end
18
+ # puts "Connecting to Redis with: #{config_opts(:path, :db, :password).inspect}" if DEBUG
19
+ ::Redis.new(config_opts(:path, :db, :password))
115
20
  end
116
21
 
117
22
  end
118
23
  end
119
- end
24
+ end
@@ -2,54 +2,34 @@ module Seabright
2
2
  module Timestamps
3
3
 
4
4
  def update_timestamps
5
- # return unless self.class.time_matters?
5
+ return if @@time_irrelevant
6
6
  set(:created_at, Time.now) if !is_set?(:created_at)
7
7
  set(:updated_at, Time.now)
8
8
  end
9
9
 
10
+ def mset(dat)
11
+ super(dat)
12
+ set(:updated_at, Time.now)
13
+ end
14
+
15
+ def set(k,v)
16
+ super(k,v)
17
+ set(:updated_at, Time.now) unless k.to_sym == :updated_at
18
+ end
19
+
20
+ def save
21
+ super
22
+ update_timestamps
23
+ end
24
+
10
25
  module ClassMethods
11
26
 
12
- def intercept_sets_for_timestamps!
13
- return if @intercepted_sets_for_timestamps
14
- self.class_eval do
15
- alias_method :untimestamped_set, :set unless method_defined?(:untimestamped_set)
16
- def set(k,v)
17
- ret = untimestamped_set(k,v)
18
- set(:updated_at, Time.now) unless k.to_sym == :updated_at
19
- ret
20
- end
21
- alias_method :untimestamped_mset, :mset unless method_defined?(:untimestamped_mset)
22
- def mset(dat)
23
- ret = untimestamped_mset(dat)
24
- set(:updated_at, Time.now)
25
- ret
26
- end
27
- alias_method :untimestamped_setnx, :setnx unless method_defined?(:untimestamped_setnx)
28
- def setnx(k,v)
29
- ret = untimestamped_setnx(k,v)
30
- set(:updated_at, Time.now) unless k.to_sym == :updated_at
31
- ret
32
- end
33
- alias_method :untimestamped_save, :save unless method_defined?(:untimestamped_save)
34
- def save
35
- ret = untimestamped_save()
36
- update_timestamps
37
- ret
38
- end
39
- end
40
- @intercepted_sets_for_timestamps = true
27
+ def time_matters_not!
28
+ @@time_irrelevant = true
29
+ @@sort_indices.delete(:created_at)
30
+ @@sort_indices.delete(:updated_at)
41
31
  end
42
32
 
43
- # def time_matters?
44
- # @time_irrelevant != true
45
- # end
46
- #
47
- # def time_matters_not!
48
- # @time_irrelevant = true
49
- # sort_indices.delete(:created_at)
50
- # sort_indices.delete(:updated_at)
51
- # end
52
- #
53
33
  def recently_created(num=5)
54
34
  self.indexed(:created_at,num,true)
55
35
  end
@@ -61,13 +41,12 @@ module Seabright
61
41
  end
62
42
 
63
43
  def self.included(base)
64
- # @time_irrelevant = false
44
+ @@time_irrelevant = false
65
45
  base.send(:sort_by,:created_at)
66
46
  base.send(:sort_by,:updated_at)
67
47
  base.send(:register_format,:created_at, :date)
68
48
  base.send(:register_format,:updated_at, :date)
69
49
  base.extend(ClassMethods)
70
- base.intercept_sets_for_timestamps!
71
50
  end
72
51
 
73
52
  end