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
@@ -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