redis_storage 0.2.6 → 0.2.7

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.
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: