redis_object 1.0 → 1.1

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/.coveralls.yml +1 -0
  2. data/.gitignore +2 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +4 -0
  5. data/README.markdown +24 -15
  6. data/Rakefile +8 -0
  7. data/lib/redis_object.rb +11 -1
  8. data/lib/redis_object/base.rb +210 -60
  9. data/lib/redis_object/collection.rb +130 -100
  10. data/lib/redis_object/defaults.rb +21 -8
  11. data/lib/redis_object/{history.rb → experimental/history.rb} +0 -0
  12. data/lib/redis_object/ext/filters.rb +34 -16
  13. data/lib/redis_object/ext/script_cache.rb +92 -0
  14. data/lib/redis_object/ext/shardable.rb +18 -0
  15. data/lib/redis_object/ext/triggers.rb +75 -13
  16. data/lib/redis_object/ext/view_caching.rb +258 -0
  17. data/lib/redis_object/ext/views.rb +102 -0
  18. data/lib/redis_object/indices.rb +44 -39
  19. data/lib/redis_object/inheritance_tracking.rb +23 -0
  20. data/lib/redis_object/keys.rb +4 -4
  21. data/lib/redis_object/storage.rb +30 -1
  22. data/lib/redis_object/storage/adapter.rb +6 -3
  23. data/lib/redis_object/storage/redis.rb +98 -3
  24. data/lib/redis_object/timestamps.rb +42 -21
  25. data/lib/redis_object/types.rb +172 -30
  26. data/lib/redis_object/version.rb +1 -1
  27. data/redis_object.gemspec +1 -0
  28. data/spec/adapter_spec.rb +43 -0
  29. data/spec/base_spec.rb +41 -6
  30. data/spec/benchmark_spec.rb +46 -0
  31. data/spec/collections_spec.rb +144 -0
  32. data/spec/defaults_spec.rb +56 -0
  33. data/spec/filters_spec.rb +29 -0
  34. data/spec/indices_spec.rb +45 -0
  35. data/spec/rename_class_spec.rb +96 -0
  36. data/spec/spec_helper.rb +32 -1
  37. data/spec/timestamp_spec.rb +28 -0
  38. data/spec/trigger_spec.rb +51 -0
  39. data/spec/types_spec.rb +103 -0
  40. data/spec/view_caching_spec.rb +130 -0
  41. data/spec/views_spec.rb +72 -0
  42. metadata +111 -116
  43. data/doc/Object.html +0 -185
  44. data/doc/Seabright.html +0 -181
  45. data/doc/Seabright/Adapter.html +0 -442
  46. data/doc/Seabright/Collection.html +0 -797
  47. data/doc/Seabright/Collections.html +0 -635
  48. data/doc/Seabright/Collections/ClassMethods.html +0 -212
  49. data/doc/Seabright/ExternalIndex.html +0 -217
  50. data/doc/Seabright/History.html +0 -382
  51. data/doc/Seabright/History/ClassMethods.html +0 -276
  52. data/doc/Seabright/Indices.html +0 -324
  53. data/doc/Seabright/Indices/ClassMethods.html +0 -348
  54. data/doc/Seabright/Keys.html +0 -314
  55. data/doc/Seabright/Keys/ClassMethods.html +0 -276
  56. data/doc/Seabright/ObjectBase.html +0 -852
  57. data/doc/Seabright/ObjectBase/ClassMethods.html +0 -677
  58. data/doc/Seabright/RedisObject.html +0 -230
  59. data/doc/Seabright/References.html +0 -280
  60. data/doc/Seabright/Storage.html +0 -252
  61. data/doc/Seabright/Storage/ClassMethods.html +0 -276
  62. data/doc/Seabright/Storage/MySQL.html +0 -442
  63. data/doc/Seabright/Storage/Redis.html +0 -218
  64. data/doc/Seabright/Template.html +0 -212
  65. data/doc/Seabright/Template/ClassMethods.html +0 -166
  66. data/doc/Seabright/Timestamps.html +0 -292
  67. data/doc/Seabright/Timestamps/ClassMethods.html +0 -214
  68. data/doc/Seabright/Types.html +0 -410
  69. data/doc/Seabright/Types/ClassMethods.html +0 -308
  70. data/doc/created.rid +0 -17
  71. data/doc/images/add.png +0 -0
  72. data/doc/images/brick.png +0 -0
  73. data/doc/images/brick_link.png +0 -0
  74. data/doc/images/bug.png +0 -0
  75. data/doc/images/bullet_black.png +0 -0
  76. data/doc/images/bullet_toggle_minus.png +0 -0
  77. data/doc/images/bullet_toggle_plus.png +0 -0
  78. data/doc/images/date.png +0 -0
  79. data/doc/images/delete.png +0 -0
  80. data/doc/images/find.png +0 -0
  81. data/doc/images/loadingAnimation.gif +0 -0
  82. data/doc/images/macFFBgHack.png +0 -0
  83. data/doc/images/package.png +0 -0
  84. data/doc/images/page_green.png +0 -0
  85. data/doc/images/page_white_text.png +0 -0
  86. data/doc/images/page_white_width.png +0 -0
  87. data/doc/images/plugin.png +0 -0
  88. data/doc/images/ruby.png +0 -0
  89. data/doc/images/tag_blue.png +0 -0
  90. data/doc/images/tag_green.png +0 -0
  91. data/doc/images/transparent.png +0 -0
  92. data/doc/images/wrench.png +0 -0
  93. data/doc/images/wrench_orange.png +0 -0
  94. data/doc/images/zoom.png +0 -0
  95. data/doc/index.html +0 -125
  96. data/doc/js/darkfish.js +0 -153
  97. data/doc/js/jquery.js +0 -18
  98. data/doc/js/navigation.js +0 -142
  99. data/doc/js/search.js +0 -94
  100. data/doc/js/search_index.js +0 -1
  101. data/doc/js/searcher.js +0 -228
  102. data/doc/rdoc.css +0 -543
  103. data/doc/table_of_contents.html +0 -394
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module BenchmarkSpec
4
+
5
+ TestValues = {
6
+ date: Date.today,
7
+ number: 27,
8
+ int: 356192,
9
+ float: 72.362517,
10
+ bool: true,
11
+ # boolean: false,
12
+ # array: [:test1,:test2],
13
+ json: {test1: true, test2: "false"}
14
+ }
15
+
16
+ TestData = TestValues.inject({}){|acc,(k,v)| acc["a_#{k}".to_sym] = v; acc }
17
+
18
+ class BenchmarkedObject < RedisObject
19
+
20
+ TestValues.keys.each do |type|
21
+ send(type.to_sym,"a_#{type}".to_sym)
22
+ end
23
+
24
+ def aggregate
25
+ sleep 0.1
26
+ 42.7
27
+ end
28
+ benchmark :aggregate
29
+
30
+ end
31
+
32
+ describe Seabright::Benchmark do
33
+ before do
34
+ RedisObject.store.flushdb
35
+ end
36
+
37
+ it "benchmarks a call" do
38
+
39
+ obj = BenchmarkedObject.create(TestData)
40
+
41
+ obj.aggregate.should eq(42.7)
42
+
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,144 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module CollectionSpec
4
+
5
+ class GrandDad < RedisObject; end
6
+ class Daddy < RedisObject; end
7
+ class Son < RedisObject; end
8
+ class GrandSon < RedisObject; end
9
+
10
+ describe Seabright::Collections do
11
+ before do
12
+
13
+ RedisObject.store.flushdb
14
+ @granddad = GrandDad.create("gramps")
15
+ @dad = Daddy.create("dad")
16
+ @son = Son.create("sun")
17
+ @sonny = Son.create("sonny")
18
+ @grandson = GrandSon.create("baby")
19
+ GrandDad << @dad
20
+ @granddad << @dad
21
+ @granddad << @son
22
+ @dad << @son
23
+ @dad.push @sonny
24
+ @son.reference @grandson
25
+
26
+ end
27
+
28
+ it "can reference other objects" do
29
+
30
+ @granddad.daddies.count.should eq(1)
31
+ @granddad.sons.count.should eq(1)
32
+ @dad.sons.count.should eq(2)
33
+
34
+ end
35
+
36
+ it "should have appropriate collections" do
37
+
38
+ @granddad.has_collection?(:daddies).should eq(true)
39
+ @granddad.has_collection?(:sons).should eq(true)
40
+ @granddad.has_collection?(:grand_sons).should eq(false)
41
+
42
+ end
43
+
44
+ it "should cache collection accessors" do
45
+
46
+ @granddad.daddies.should be_a(Seabright::Collection)
47
+ @granddad.daddy.should be_a(Daddy)
48
+
49
+ end
50
+
51
+ it "should be able to iterate over collected items" do
52
+
53
+ @dad.sons.count.should eq(2)
54
+ @dad.sons.each do |s|
55
+ s.should be_a(Son)
56
+ end
57
+
58
+ end
59
+
60
+ it "can find items in a collection" do
61
+
62
+ @dad = Daddy.find("dad")
63
+ @dad.sons.find(son_id: "sonny").first.should be_a(Son)
64
+
65
+ end
66
+
67
+ it "can get one collection item" do
68
+
69
+ @dad = Daddy.find("dad")
70
+ @dad.son.should be_a(Son)
71
+
72
+ end
73
+
74
+ it "can get one collection item" do
75
+
76
+ @dad = Daddy.find("dad")
77
+ @dad.get(:son).should be_a(Son)
78
+
79
+ end
80
+
81
+ it "can get backreferences of a type" do
82
+
83
+ @son.backreferences(GrandDad).each do |s|
84
+ s.should be_a(GrandDad)
85
+ end
86
+
87
+ end
88
+
89
+ it "can dereference itself" do
90
+
91
+ @dad.dereference_from_backreferences
92
+ GrandDad.find("gramps").daddies.count.should eq(0)
93
+
94
+ end
95
+
96
+ it "can delete items from a collection" do
97
+
98
+ @dad.sons.delete(@sonny)
99
+ @dad.sons.find(son_id: "sonny").first.should be_a(NilClass)
100
+ @dad.sons.count.should eq(1)
101
+
102
+ @dad.delete_child(@son)
103
+ @dad.get(:sons).count.should eq(0)
104
+
105
+ end
106
+
107
+ it "can delete a collection" do
108
+
109
+ @dad.sons.remove!
110
+ @dad.collections.keys.should_not include(:sons)
111
+ @son.remove_collection!(:grand_sons)
112
+ @son.collections.keys.should_not include(:grand_sons)
113
+
114
+ end
115
+
116
+ it "retrieves via index" do
117
+
118
+ 5.times do
119
+ @dad << Son.create
120
+ end
121
+
122
+ # @dad.sons.indexed(:created_at,3,true).count.should eq(3)
123
+
124
+ Son.indexed(:created_at,3,true).count.should eq(3)
125
+
126
+ end
127
+
128
+ it "can collect on classes themselves" do
129
+
130
+ 5.times do
131
+ Daddy << Son.create
132
+ end
133
+
134
+ Daddy.get(:sons).should be_a(Seabright::Collection)
135
+ Daddy.get(:sons).count.should eq(5)
136
+ Daddy.get(:son).should be_a(Son)
137
+ Daddy.delete_child(Daddy.get(:son))
138
+ Daddy.get(:sons).count.should eq(4)
139
+ # Daddy.get(:sons).indexed(:created_at,3,true).count.should eq(3)
140
+
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,56 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module DefaultSpec
4
+
5
+ TestValues = {
6
+ date: Date.today,
7
+ number: 27,
8
+ int: 356192,
9
+ float: 72.362517,
10
+ bool: true,
11
+ # boolean: false,
12
+ # array: [:test1,:test2],
13
+ json: {test1: true, test2: "false"}
14
+ }
15
+
16
+ TestData = TestValues.inject({}){|acc,(k,v)| acc["a_#{k}".to_sym] = v; acc }
17
+
18
+ # Delicious pizza!
19
+ class DefaultedObject < RedisObject
20
+
21
+ TestValues.keys.each do |type|
22
+ send(type.to_sym,"a_#{type}".to_sym)
23
+ end
24
+ default_for :testy, "test"
25
+ default_for :a_number, 42
26
+
27
+ end
28
+
29
+ describe Seabright::DefaultValues do
30
+ before do
31
+ RedisObject.store.flushdb
32
+ end
33
+
34
+ it "returns default value" do
35
+
36
+ obj = DefaultedObject.create(TestData)
37
+
38
+ obj.testy.should eq("test")
39
+ obj.get(:a_number).should eq(27)
40
+ obj.unset(:a_number)
41
+ obj.get(:a_number).should eq(42)
42
+
43
+ end
44
+
45
+ it "returns default value after unset" do
46
+
47
+ obj = DefaultedObject.create(TestData)
48
+
49
+ obj.get(:a_number).should eq(27)
50
+ obj.unset(:a_number)
51
+ obj.get(:a_number).should eq(42)
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module FilterSpec
4
+
5
+ class FilteredObject < RedisObject
6
+
7
+ def double(k,v)
8
+ (k == :testy) && v ? [:testy,v*2] : [k,v]
9
+ end
10
+ set_filter :double
11
+
12
+ end
13
+
14
+ describe Seabright::Filters do
15
+ before do
16
+ RedisObject.store.flushdb
17
+ end
18
+
19
+ it "modifies set and gets correctly" do
20
+
21
+ obj = FilteredObject.create("test")
22
+
23
+ obj.set(:testy,"test")
24
+ obj.get(:testy).should eq("testtest")
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module IndexSpec
4
+
5
+ TestValues = {
6
+ date: Date.today,
7
+ number: 27,
8
+ int: 356192,
9
+ float: 72.362517,
10
+ bool: true,
11
+ # boolean: false,
12
+ # array: [:test1,:test2],
13
+ json: {test1: true, test2: "false"}
14
+ }
15
+
16
+ TestData = TestValues.inject({}){|acc,(k,v)| acc["a_#{k}".to_sym] = v; acc }
17
+
18
+ # Delicious pizza!
19
+ class IndexedObject < RedisObject
20
+
21
+ TestValues.keys.each do |type|
22
+ send(type.to_sym,"a_#{type}".to_sym)
23
+ end
24
+
25
+ sort_by :a_number
26
+
27
+ end
28
+
29
+ describe Seabright::Indices do
30
+ before do
31
+ RedisObject.store.flushdb
32
+ end
33
+
34
+ it "indexes on integer field" do
35
+
36
+ 5.times do
37
+ obj = IndexedObject.create(a_number: Random.rand(100))
38
+ end
39
+
40
+ IndexedObject.indexed(:a_number,3,true).count.should eq(3)
41
+
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,96 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module RenameClassSpec
4
+ # Delicious pizza!
5
+ class Pizza < RedisObject; end
6
+ # We love toppings but our current name Topping is too ambiguous!
7
+ class Topping < RedisObject; end
8
+ # Let's change the class name to PizzaTopping!
9
+ class PizzaTopping < RedisObject; end
10
+
11
+ describe Seabright::Storage::Redis, "#rename_class" do
12
+ before do
13
+ RedisObject.store.flushdb
14
+
15
+ mozzarella = Topping.create(:mozzarella)
16
+ basil = Topping.create(:basil)
17
+ tomato = Topping.create(:tomato)
18
+ garlic = Topping.create(:garlic)
19
+ oregano = Topping.create(:oregano)
20
+ olive_oil = Topping.create(:olive_oil)
21
+
22
+ marinara = Pizza.create(:marinara)
23
+ [ tomato, garlic, oregano, olive_oil ].each{|topping| marinara << topping }
24
+
25
+ margherita = Pizza.create(:margherita)
26
+ [ tomato, mozzarella, basil, olive_oil ].each{|topping| margherita << topping }
27
+ end
28
+
29
+ it "setup works" do
30
+ margherita = Pizza.find(:margherita)
31
+ marinara = Pizza.find(:marinara)
32
+ mozzarella = Topping.find(:mozzarella)
33
+ basil = Topping.find(:basil)
34
+ tomato = Topping.find(:tomato)
35
+ garlic = Topping.find(:garlic)
36
+ oregano = Topping.find(:oregano)
37
+ olive_oil = Topping.find(:olive_oil)
38
+
39
+ [ mozzarella, basil, tomato, garlic, oregano, olive_oil ].each do |topping|
40
+ topping.get(:class).should == Topping.name
41
+ topping.get(:key).should == "RenameClassSpec::Topping:#{topping.id}"
42
+ topping.get(:topping_id).should == topping.id
43
+ end
44
+
45
+ Topping.indexed(:created_at).first.should_not be_nil
46
+ Topping.indexed(:created_at).count.should == 5
47
+
48
+ [margherita, marinara].each do |pizza|
49
+ pizza.pizza_toppings.should be_nil
50
+ pizza.toppings.count.should == 4
51
+ pizza.toppings.should include(tomato.hkey)
52
+ pizza.toppings.should include(olive_oil.hkey)
53
+ end
54
+
55
+ margherita.toppings.should include(basil.hkey)
56
+ margherita.toppings.should include(mozzarella.hkey)
57
+ marinara.toppings.should include(oregano.hkey)
58
+ marinara.toppings.should include(garlic.hkey)
59
+ end
60
+
61
+ it "renames a class" do
62
+ RedisObject.store.rename_class(:"RenameClassSpec::Topping", :"RenameClassSpec::PizzaTopping")
63
+
64
+ margherita = Pizza.find(:margherita)
65
+ marinara = Pizza.find(:marinara)
66
+ mozzarella = PizzaTopping.find(:mozzarella)
67
+ basil = PizzaTopping.find(:basil)
68
+ tomato = PizzaTopping.find(:tomato)
69
+ garlic = PizzaTopping.find(:garlic)
70
+ oregano = PizzaTopping.find(:oregano)
71
+ olive_oil = PizzaTopping.find(:olive_oil)
72
+
73
+ [ mozzarella, basil, tomato, garlic, oregano, olive_oil ].each do |topping|
74
+ topping.get(:class).should == PizzaTopping.name
75
+ topping.get(:key).should == "RenameClassSpec::PizzaTopping:#{topping.id}"
76
+ topping.get(:"renameclassspec::pizzatopping_id").should == topping.id
77
+ # topping.get(:topping_id).should == nil
78
+ end
79
+
80
+ [margherita, marinara].each do |pizza|
81
+ pizza.toppings.should be_nil
82
+ pizza.pizza_toppings.count.should == 4
83
+ pizza.pizza_toppings.should include(tomato.hkey)
84
+ pizza.pizza_toppings.should include(olive_oil.hkey)
85
+ end
86
+
87
+ margherita.pizza_toppings.should include(basil.hkey)
88
+ margherita.pizza_toppings.should include(mozzarella.hkey)
89
+ marinara.pizza_toppings.should include(oregano.hkey)
90
+ marinara.pizza_toppings.should include(garlic.hkey)
91
+
92
+ PizzaTopping.indexed(:created_at).first.should_not be_nil
93
+ PizzaTopping.indexed(:created_at).count.should == 5
94
+ end
95
+ end
96
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,4 +4,35 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
4
4
  require 'rubygems'
5
5
  require 'test/unit'
6
6
  require 'rspec'
7
- require 'redis_object'
7
+
8
+ require 'simplecov'
9
+ require 'coveralls'
10
+
11
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
12
+ SimpleCov::Formatter::HTMLFormatter,
13
+ Coveralls::SimpleCov::Formatter
14
+ ]
15
+ SimpleCov.start do
16
+ add_filter "_spec.rb"
17
+ add_filter "/experimental/"
18
+ add_group "Extensions", "lib/redis_object/ext/"
19
+ end
20
+
21
+ require 'redis_object'
22
+
23
+ class DebugMode
24
+ def initialize(o=nil); @opts = o; end
25
+ def verbose?; debug? && !!@opts[:verbose]; end
26
+ def debug?; !!@opts; end
27
+ end
28
+ Debug = if ENV['DEBUG']
29
+ require 'debugger'
30
+ DEBUG = true
31
+ DebugMode.new(verbose:true)
32
+ else
33
+ DEBUG = false
34
+ DebugMode.new
35
+ end
36
+
37
+ raise 'must specify TEST_DB' unless ENV['TEST_DB']
38
+ RedisObject.configure_store({adapter:'Redis', db:ENV['TEST_DB']},:global,:alias)