redis_storage 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -4,6 +4,7 @@ RedisStorage
4
4
  This is a little gem which provides a redis interface for models. It works out of the box with rails or can be used standalone.
5
5
 
6
6
  Basically I just got sick rewriting the same logic over and over again for each model of my little sinatra apps so this evolved. Then I wanted to write a new rails app an thought having this in a gem would be really nice, and a generator would be awesome.
7
+ Now I will add new Feature as I need them. You also can let me know what to add.
7
8
 
8
9
  Features
9
10
  ---
@@ -13,20 +14,21 @@ Features
13
14
  * compatible with the default rails controller
14
15
  * uses ActiveModel to provide things like validations
15
16
  * provides a Rails 3 Generator
17
+ * indexing of choosen attributes and find_by
16
18
 
17
19
  Roadmap aka. ToDo
18
20
  ---
19
21
 
22
+ * perhaps use some stuff from redis-scripting to make more methods atomic (like find_by or update_attributes)
20
23
  * some wrappers for searching in a model(probably will need some indexes)
21
- * add something to make it easy to add an index(but there will be the update problematic)
22
24
  * perhaps some kind of dirty flag - or the ActiveModel::Dirty module, but that will make some things way more complicated
23
25
  * more tests/specs are always good
24
26
 
25
27
  Newest Stuff
26
28
  ---
27
29
 
28
- * the generator now calls the test_framework generator for models
29
- * added a random method which returns a random item from the collection
30
+ * indexing for choosen attributes
31
+ * new find_by :attr
30
32
 
31
33
  Installation
32
34
  ---
@@ -77,6 +79,22 @@ Minimal Example
77
79
  attr_accessor *attrs
78
80
  end
79
81
 
82
+ Indexing and find_by
83
+ ---
84
+
85
+ If you want or need to find records based on a attribute you have to add it to the index_for array like this.
86
+
87
+ def self.index_for
88
+ [:some, :attributes, :to, :index]
89
+ end
90
+
91
+ The elements should be symbols and have to also be element of attrs.
92
+ After that you can use the following to get the the instance.
93
+
94
+ MyModel.find_by :key, "search"
95
+
96
+ Also I should mention that you should update record only via the update_attributes method, otherwise the indexes will become corrupt.
97
+
80
98
  Rails 3 Integration
81
99
  ---
82
100
 
data/lib/redis_storage.rb CHANGED
@@ -19,6 +19,9 @@ module RedisStorage
19
19
  attr_accessor :id
20
20
  attr_reader :errors
21
21
 
22
+ def self.index_for
23
+ []
24
+ end
22
25
  def self.build(params)
23
26
  new params
24
27
  end
@@ -31,25 +34,27 @@ module RedisStorage
31
34
 
32
35
  def self.random
33
36
  i = $db.srandmember(persisted_key)
34
- find_by_id(i) unless i.nil?
37
+ load(i) unless i.nil?
35
38
  end
36
39
  def self.find(params=nil)
37
40
  if params.nil?
38
41
  all
39
42
  else
40
- find_by_id(params) #TODO perhaps make this at some point more generic
43
+ load(params) #TODO perhaps make this at some point more generic
41
44
  end
42
45
  end
43
- def self.find_by_id(entry_id)
44
- return nil if entry_id.nil?
45
- r = $db.get("#{db_key}:#{entry_id}")
46
- new(JSON.parse(r)) unless r.nil?
46
+ def self.find_by(key, value)
47
+ if key == :id
48
+ load "#{db_key}:#{value}"
49
+ elsif index_for.include? key
50
+ load($db.get("#{db_key}:#{key}:#{value.hash}"))
51
+ else
52
+ nil
53
+ end
47
54
  end
48
55
 
49
56
  def self.all
50
- keys = $db.smembers(persisted_key).map do |i|
51
- "#{db_key}:#{i}"
52
- end
57
+ keys = $db.smembers(persisted_key)
53
58
 
54
59
  if keys.empty?
55
60
  []
@@ -64,10 +69,10 @@ module RedisStorage
64
69
  $db.scard(persisted_key)
65
70
  end
66
71
  def self.first
67
- find_by_id $db.smembers(persisted_key).sort.first
72
+ load $db.smembers(persisted_key).sort.first
68
73
  end
69
74
  def self.last
70
- find_by_id $db.smembers(persisted_key).sort.last
75
+ load $db.smembers(persisted_key).sort.last
71
76
  end
72
77
  def serializable_hash
73
78
  self.class.attrs.inject({:id => @id}) do |a,key|
@@ -80,19 +85,23 @@ module RedisStorage
80
85
  end
81
86
 
82
87
  def update_attributes(params)
88
+ delete!
83
89
  params.each do |key, value|
84
90
  send("#{key}=", value) unless key.to_sym == :id
85
91
  end
86
92
  save
87
93
  end
88
94
  def save
89
- unless persisted?
95
+ if @id.nil?
90
96
  @id = $db.incr(self.class.next_id_key)
91
97
  end
92
98
  if valid?
93
99
  $db.multi do
94
100
  $db.set db_key, to_json
95
- $db.sadd self.class.persisted_key, id
101
+ $db.sadd self.class.persisted_key, db_key
102
+ for key in self.class.index_for do
103
+ $db.set "#{self.class.db_key}:#{key}:#{send(key).hash}", db_key
104
+ end
96
105
  end
97
106
  @id
98
107
  else
@@ -107,7 +116,10 @@ module RedisStorage
107
116
  if persisted?
108
117
  $db.multi do
109
118
  $db.del db_key
110
- $db.srem self.class.persisted_key, id
119
+ $db.srem self.class.persisted_key, db_key
120
+ for key in self.class.index_for do
121
+ $db.del "#{self.class.db_key}:#{key}:#{send(key).hash}"
122
+ end
111
123
  end
112
124
  true
113
125
  else
@@ -119,7 +131,7 @@ module RedisStorage
119
131
  if id.nil?
120
132
  false
121
133
  else
122
- $db.sismember(self.class.persisted_key, id)
134
+ $db.sismember(self.class.persisted_key, db_key)
123
135
  end
124
136
  end
125
137
 
@@ -141,6 +153,11 @@ module RedisStorage
141
153
  end
142
154
  end
143
155
  private
156
+ def self.load(key)
157
+ return nil if key.nil?
158
+ r = $db.get(key)
159
+ new(JSON.parse(r)) unless r.nil?
160
+ end
144
161
  def self.next_id_key
145
162
  "#{db_key}:next_id"
146
163
  end
@@ -1,3 +1,3 @@
1
1
  module RedisStorage
2
- VERSION = "0.2.6"
2
+ VERSION = "0.2.7"
3
3
  end
data/spec/model_spec.rb CHANGED
@@ -4,6 +4,9 @@ class MockModel < RedisStorage::Model
4
4
  [:body, :title]
5
5
  end
6
6
  attr_accessor *attrs
7
+ def self.index_for
8
+ [:title]
9
+ end
7
10
  end
8
11
 
9
12
  describe RedisStorage::Model do
@@ -57,19 +60,42 @@ describe RedisStorage::Model do
57
60
  MockModel.expects(:all)
58
61
  MockModel.find
59
62
  end
60
- it 'should push the given Params from .find to .find_by_id' do
61
- MockModel.expects(:find_by_id).with(3)
63
+ it 'should push the given params from .find to .load' do
64
+ MockModel.expects(:load).with(3)
62
65
  MockModel.find(3)
63
66
  end
64
- context '#find_by_id' do
67
+ context '#find_by' do
68
+ it "should call load if called find_by :id" do
69
+ MockModel.expects(:load)
70
+ MockModel.find_by(:id,3)
71
+ end
65
72
  1.upto(4) do |i|
66
- it "should find record #{i} and create a new instance" do
67
- record = MockModel.find_by_id(i)
73
+ it "should find record #{i} by id, load it and create a new instance" do
74
+ record = MockModel.find_by :id, i
68
75
  record.id.should == i
69
76
  record.body.should == h[i-1]['body']
70
77
  record.title.should == h[i-1]['title']
71
78
  end
72
79
  end
80
+ it 'should find instances based on their title' do
81
+ model = MockModel.find_by :title, "second test"
82
+ model.title.should eq("second test")
83
+ model.body.should eq("Dolor Sit")
84
+ end
85
+ it 'should still find by title after updating the title' do
86
+ m = MockModel.first
87
+ m.update_attributes({'title' => "f**k that title"})
88
+ n = MockModel.find_by :title, "f**k that title"
89
+ n.title.should == "f**k that title"
90
+ n.id.should == m.id
91
+ end
92
+ it 'should no longer find by the old title after updating the title' do
93
+ m = MockModel.first
94
+ t = m.title
95
+ m.update_attributes({'title' => "f**k that title"})
96
+ n = MockModel.find_by :title, t
97
+ n.should be_nil
98
+ end
73
99
  end
74
100
  context '#all' do
75
101
  it 'should return an empty array if there are no entries' do
@@ -136,7 +162,7 @@ describe RedisStorage::Model do
136
162
  end
137
163
  it 'should add the id to the persisted set in redis' do
138
164
  id = model.save
139
- $db.sismember("MockModel:persisted", id).should be_true
165
+ $db.sismember("MockModel:persisted", "MockModel:#{id}").should be_true
140
166
  end
141
167
  end
142
168
  context '#update_attributes' do
@@ -166,7 +192,7 @@ describe RedisStorage::Model do
166
192
  it 'should remove the id from the persisted set in redis' do
167
193
  id=model.save
168
194
  model.delete!
169
- $db.sismember("MockModel:persisted", id).should be_false
195
+ $db.sismember("MockModel:persisted", "MockModel:#{id}").should be_false
170
196
  end
171
197
  end
172
198
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-27 00:00:00.000000000 +02:00
12
+ date: 2011-06-30 00:00:00.000000000 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: redis
17
- requirement: &193730080 !ruby/object:Gem::Requirement
17
+ requirement: &13617920 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 2.2.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *193730080
25
+ version_requirements: *13617920
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: json
28
- requirement: &193729660 !ruby/object:Gem::Requirement
28
+ requirement: &13655520 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *193729660
36
+ version_requirements: *13655520
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: activemodel
39
- requirement: &193729120 !ruby/object:Gem::Requirement
39
+ requirement: &13654980 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 3.0.0
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *193729120
47
+ version_requirements: *13654980
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rspec
50
- requirement: &193728620 !ruby/object:Gem::Requirement
50
+ requirement: &13654480 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 2.0.0
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *193728620
58
+ version_requirements: *13654480
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: mocha
61
- requirement: &193728160 !ruby/object:Gem::Requirement
61
+ requirement: &13654020 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 0.9.10
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *193728160
69
+ version_requirements: *13654020
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rails
72
- requirement: &193727700 !ruby/object:Gem::Requirement
72
+ requirement: &13653560 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,7 +77,7 @@ dependencies:
77
77
  version: 3.0.0
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *193727700
80
+ version_requirements: *13653560
81
81
  description: Provides a data backend for a Redis in Rails, will also provide a Rails
82
82
  3 Generator
83
83
  email: