nono-redis-store 1.0.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.
- data/.gitignore +11 -0
- data/CHANGELOG +262 -0
- data/Gemfile +33 -0
- data/Gemfile.lock +194 -0
- data/MIT-LICENSE +20 -0
- data/README.md +191 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/lib/action_controller/session/redis_session_store.rb +74 -0
- data/lib/active_support/cache/redis_store.rb +228 -0
- data/lib/cache/merb/redis_store.rb +75 -0
- data/lib/cache/sinatra/redis_store.rb +126 -0
- data/lib/i18n/backend/redis.rb +67 -0
- data/lib/rack/cache/redis_entitystore.rb +51 -0
- data/lib/rack/cache/redis_metastore.rb +42 -0
- data/lib/rack/session/merb.rb +32 -0
- data/lib/rack/session/redis.rb +81 -0
- data/lib/redis-store.rb +44 -0
- data/lib/redis/distributed_store.rb +35 -0
- data/lib/redis/factory.rb +46 -0
- data/lib/redis/store.rb +30 -0
- data/lib/redis/store/interface.rb +17 -0
- data/lib/redis/store/marshalling.rb +41 -0
- data/lib/redis/store/namespace.rb +54 -0
- data/lib/redis/store/ttl.rb +37 -0
- data/lib/redis/store/version.rb +11 -0
- data/redis-store.gemspec +103 -0
- data/spec/action_controller/session/redis_session_store_spec.rb +121 -0
- data/spec/active_support/cache/redis_store_spec.rb +405 -0
- data/spec/cache/merb/redis_store_spec.rb +143 -0
- data/spec/cache/sinatra/redis_store_spec.rb +192 -0
- data/spec/config/master.conf +312 -0
- data/spec/config/single.conf +312 -0
- data/spec/config/slave.conf +312 -0
- data/spec/i18n/backend/redis_spec.rb +56 -0
- data/spec/rack/cache/entitystore/pony.jpg +0 -0
- data/spec/rack/cache/entitystore/redis_spec.rb +120 -0
- data/spec/rack/cache/metastore/redis_spec.rb +255 -0
- data/spec/rack/session/redis_spec.rb +234 -0
- data/spec/redis/distributed_store_spec.rb +47 -0
- data/spec/redis/factory_spec.rb +110 -0
- data/spec/redis/store/interface_spec.rb +23 -0
- data/spec/redis/store/marshalling_spec.rb +83 -0
- data/spec/redis/store/namespace_spec.rb +76 -0
- data/spec/redis/store/version_spec.rb +7 -0
- data/spec/spec_helper.rb +43 -0
- data/tasks/redis.tasks.rb +220 -0
- metadata +141 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 - 2010 Luca Guidi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
# Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Download and install Redis from [http://code.google.com/p/redis/](http://code.google.com/p/redis/)
|
6
|
+
|
7
|
+
wget http://redis.googlecode.com/files/redis-2.0.0.tar.gz
|
8
|
+
tar -zxf redis-2.0.0.tar.gz
|
9
|
+
mv redis-2.0.0 redis
|
10
|
+
cd redis
|
11
|
+
make
|
12
|
+
|
13
|
+
Install the gem
|
14
|
+
|
15
|
+
sudo gem install redis-store
|
16
|
+
|
17
|
+
## Options
|
18
|
+
There are two ways to configure the Redis server options: by an URI string and by an hash.
|
19
|
+
By default each store try to connect on `localhost` with the port `6379` and the db `0`.
|
20
|
+
|
21
|
+
### String
|
22
|
+
|
23
|
+
"redis://:secret@192.168.1.100:23682/13/theplaylist"
|
24
|
+
|
25
|
+
host: 192.168.1.100
|
26
|
+
port: 23682
|
27
|
+
db: 13
|
28
|
+
namespace: theplaylist
|
29
|
+
password: secret
|
30
|
+
|
31
|
+
If you want to specify the `namespace` optional, you have to pass the `db` param too.
|
32
|
+
#### __Important__: for now (beta3) `namespace` is only supported for single, non-distributed stores.
|
33
|
+
|
34
|
+
### Hash
|
35
|
+
|
36
|
+
{ :host => 192.168.1.100, :port => 23682, :db => 13, :namespace => "theplaylist", :password => "secret" }
|
37
|
+
|
38
|
+
#### __Important__: for now (beta3) `namespace` is only supported for single, non-distributed stores.
|
39
|
+
|
40
|
+
## Cache store
|
41
|
+
|
42
|
+
Provides a cache store for your Ruby web framework of choice.
|
43
|
+
|
44
|
+
### Rails 2.x
|
45
|
+
|
46
|
+
config.gem "redis-store"
|
47
|
+
config.cache_store = :redis_store
|
48
|
+
|
49
|
+
### Rails 2.x (with Bundler)
|
50
|
+
|
51
|
+
# Gemfile
|
52
|
+
gem "redis-store"
|
53
|
+
|
54
|
+
# in your configuration
|
55
|
+
config.gem "redis-store"
|
56
|
+
config.cache_store = :redis_store
|
57
|
+
|
58
|
+
### Rails 3.x
|
59
|
+
|
60
|
+
# Gemfile
|
61
|
+
gem 'rails', '3.0.0'
|
62
|
+
gem 'redis'
|
63
|
+
gem 'redis-store', '1.0.0.beta3'
|
64
|
+
|
65
|
+
# config/environments/production.rb
|
66
|
+
config.cache_store = :redis_store
|
67
|
+
|
68
|
+
For advanced configurations scenarios please visit [the wiki](http://wiki.github.com/jodosha/redis-store/rails).
|
69
|
+
|
70
|
+
### Merb
|
71
|
+
|
72
|
+
dependency "redis-store", "1.0.0.beta3"
|
73
|
+
dependency("merb-cache", merb_gems_version) do
|
74
|
+
Merb::Cache.setup do
|
75
|
+
register(:redis, Merb::Cache::RedisStore, :servers => ["127.0.0.1:6379"])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
### Sinatra
|
80
|
+
|
81
|
+
require "sinatra"
|
82
|
+
require "redis-store"
|
83
|
+
class MyApp < Sinatra::Base
|
84
|
+
register Sinatra::Cache
|
85
|
+
get "/hi" do
|
86
|
+
cache.fetch("greet") { "Hello, World!" }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
## Rack::Session
|
91
|
+
|
92
|
+
Provides a Redis store for Rack::Session. See [http://rack.rubyforge.org/doc/Rack/Session.html](http://rack.rubyforge.org/doc/Rack/Session.html)
|
93
|
+
|
94
|
+
### Rack application
|
95
|
+
|
96
|
+
require "rack"
|
97
|
+
require "redis-store"
|
98
|
+
require "application"
|
99
|
+
use Rack::Session::Redis
|
100
|
+
run Application.new
|
101
|
+
|
102
|
+
### Rails 2.x
|
103
|
+
|
104
|
+
config.gem "redis-store"
|
105
|
+
ActionController::Base.session_store = :redis_session_store
|
106
|
+
|
107
|
+
### Rails 2.x (with Bundler)
|
108
|
+
|
109
|
+
# Gemfile
|
110
|
+
gem "redis-store"
|
111
|
+
|
112
|
+
# in your configuration
|
113
|
+
config.gem "redis-store"
|
114
|
+
|
115
|
+
# config/initializers/session_store.rb
|
116
|
+
ActionController::Base.session_store = :redis_session_store
|
117
|
+
|
118
|
+
### Rails 3.x
|
119
|
+
|
120
|
+
# Gemfile
|
121
|
+
gem 'rails', '3.0.0'
|
122
|
+
gem 'redis'
|
123
|
+
gem 'redis-store', '1.0.0.beta3'
|
124
|
+
|
125
|
+
# config/initializers/session_store.rb
|
126
|
+
MyApp::Application.config.session_store :redis_session_store
|
127
|
+
|
128
|
+
For advanced configurations scenarios please visit [the wiki](http://wiki.github.com/jodosha/redis-store/rails).
|
129
|
+
|
130
|
+
### Merb
|
131
|
+
|
132
|
+
dependency "redis-store", "1.0.0.beta3"
|
133
|
+
Merb::Config.use do |c|
|
134
|
+
c[:session_store] = "redis"
|
135
|
+
end
|
136
|
+
Merb::BootLoader.before_app_loads do
|
137
|
+
Merb::SessionContainer.subclasses << "Merb::RedisSession"
|
138
|
+
end
|
139
|
+
|
140
|
+
### Sinatra
|
141
|
+
|
142
|
+
require "sinatra"
|
143
|
+
require "redis-store"
|
144
|
+
|
145
|
+
class MyApp < Sinatra::Base
|
146
|
+
use Rack::Session::Redis
|
147
|
+
|
148
|
+
get "/" do
|
149
|
+
session[:visited_at] = DateTime.now.to_s # This is stored in Redis
|
150
|
+
"Hello, visitor."
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
## Rack::Cache
|
155
|
+
|
156
|
+
Provides a Redis store for HTTP caching. See [http://github.com/rtomayko/rack-cache](http://github.com/rtomayko/rack-cache)
|
157
|
+
|
158
|
+
require "rack"
|
159
|
+
require "rack/cache"
|
160
|
+
require "redis-store"
|
161
|
+
require "application"
|
162
|
+
use Rack::Cache,
|
163
|
+
:metastore => 'redis://localhost:6379/0',
|
164
|
+
:entitystore => 'redis://localhost:6380/1'
|
165
|
+
run Application.new
|
166
|
+
|
167
|
+
## I18n
|
168
|
+
|
169
|
+
require "i18n"
|
170
|
+
require "redis-store"
|
171
|
+
I18n.backend = I18n::Backend::Redis.new
|
172
|
+
|
173
|
+
The backend accepts the uri string and hash options.
|
174
|
+
|
175
|
+
## Running specs
|
176
|
+
|
177
|
+
gem install jeweler bundler
|
178
|
+
git clone git://github.com/jodosha/redis-store.git
|
179
|
+
cd redis-store
|
180
|
+
bundle install
|
181
|
+
REDIS_STORE_ENV=rails3 bundle install # to install Rails 3 gems
|
182
|
+
rake dtach:install
|
183
|
+
rake redis:install
|
184
|
+
rake
|
185
|
+
REDIS_STORE_ENV=rails3 rake # to test against Rails 3
|
186
|
+
|
187
|
+
If you are on **Snow Leopard** you have to run `env ARCHFLAGS="-arch x86_64" bundle install`
|
188
|
+
|
189
|
+
## Copyright
|
190
|
+
|
191
|
+
(c) 2009 - 2010 Luca Guidi - [http://lucaguidi.com](http://lucaguidi.com), released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
$:.unshift 'lib'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'spec/rake/spectask'
|
7
|
+
|
8
|
+
task :default => "spec:suite"
|
9
|
+
|
10
|
+
begin
|
11
|
+
require "jeweler"
|
12
|
+
Jeweler::Tasks.new do |gemspec|
|
13
|
+
gemspec.name = "#{ENV["GEM_PREFIX"]}redis-store"
|
14
|
+
gemspec.summary = "Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks."
|
15
|
+
gemspec.description = "Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks."
|
16
|
+
gemspec.email = "guidi.luca@gmail.com"
|
17
|
+
gemspec.homepage = "http://github.com/jodosha/redis-store"
|
18
|
+
gemspec.authors = [ "Luca Guidi" ]
|
19
|
+
gemspec.executables = [ ]
|
20
|
+
gemspec.add_dependency "redis", ">= 2.0.0"
|
21
|
+
end
|
22
|
+
|
23
|
+
Jeweler::GemcutterTasks.new
|
24
|
+
rescue LoadError
|
25
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
26
|
+
end
|
27
|
+
|
28
|
+
namespace :spec do
|
29
|
+
desc "Run all the examples by starting a detached Redis instance"
|
30
|
+
task :suite => :prepare do
|
31
|
+
invoke_with_redis_cluster "spec:run"
|
32
|
+
end
|
33
|
+
|
34
|
+
Spec::Rake::SpecTask.new(:run) do |t|
|
35
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
36
|
+
t.spec_opts = %w(-fs --color)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Run all examples with RCov"
|
41
|
+
task :rcov => :prepare do
|
42
|
+
invoke_with_redis_cluster "rcov_run"
|
43
|
+
end
|
44
|
+
|
45
|
+
Spec::Rake::SpecTask.new(:rcov_run) do |t|
|
46
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
47
|
+
t.rcov = true
|
48
|
+
end
|
49
|
+
|
50
|
+
task :prepare do
|
51
|
+
`mkdir -p tmp && rm tmp/*.rdb`
|
52
|
+
end
|
53
|
+
|
54
|
+
namespace :bundle do
|
55
|
+
task :clean do
|
56
|
+
system "rm -rf ~/.bundle/ ~/.gem/ .bundle/ Gemfile.lock"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
load "tasks/redis.tasks.rb"
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "redis-store"
|
2
|
+
|
3
|
+
module RedisStore
|
4
|
+
module Rack
|
5
|
+
module Session
|
6
|
+
# Redis session storage for Rails, and for Rails only. Derived from
|
7
|
+
# the MemCacheStore code, simply dropping in Redis instead.
|
8
|
+
#
|
9
|
+
# Options:
|
10
|
+
# :key => Same as with the other cookie stores, key name
|
11
|
+
# :secret => Encryption secret for the key
|
12
|
+
# :host => Redis host name, default is localhost
|
13
|
+
# :port => Redis port, default is 6379
|
14
|
+
# :db => Database number, defaults to 0. Useful to separate your session storage from other data
|
15
|
+
# :key_prefix => Prefix for keys used in Redis, e.g. myapp-. Useful to separate session storage keys visibly from others
|
16
|
+
# :expire_after => A number in seconds to set the timeout interval for the session. Will map directly to expiry in Redis
|
17
|
+
module Rails
|
18
|
+
def initialize(app, options = {})
|
19
|
+
# Support old :expires option
|
20
|
+
options[:expire_after] ||= options[:expires]
|
21
|
+
|
22
|
+
super
|
23
|
+
|
24
|
+
servers = [options[:servers]].flatten.compact.map do |server_options|
|
25
|
+
{
|
26
|
+
:host => 'localhost',
|
27
|
+
:port => '6379',
|
28
|
+
:db => 0
|
29
|
+
}.update(Redis::Factory.convert_to_redis_client_options(server_options))
|
30
|
+
end
|
31
|
+
|
32
|
+
@pool = Redis::Factory.create(*servers)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def get_session(env, sid)
|
37
|
+
sid ||= generate_sid
|
38
|
+
begin
|
39
|
+
session = @pool.get(sid) || {}
|
40
|
+
rescue Errno::ECONNREFUSED
|
41
|
+
session = {}
|
42
|
+
end
|
43
|
+
[sid, session]
|
44
|
+
end
|
45
|
+
|
46
|
+
def set_session(env, sid, session_data)
|
47
|
+
options = env['rack.session.options']
|
48
|
+
@pool.set(sid, session_data, options)
|
49
|
+
return(::Redis::Store.rails3? ? sid : true)
|
50
|
+
rescue Errno::ECONNREFUSED
|
51
|
+
return false
|
52
|
+
end
|
53
|
+
|
54
|
+
def destroy(env)
|
55
|
+
if sid = current_session_id(env)
|
56
|
+
@pool.del(sid)
|
57
|
+
end
|
58
|
+
rescue Errno::ECONNREFUSED
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if ::Redis::Store.rails3?
|
67
|
+
class ActionDispatch::Session::RedisSessionStore < ActionDispatch::Session::AbstractStore
|
68
|
+
include RedisStore::Rack::Session::Rails
|
69
|
+
end
|
70
|
+
else
|
71
|
+
class ActionController::Session::RedisSessionStore < ActionController::Session::AbstractStore
|
72
|
+
include RedisStore::Rack::Session::Rails
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
require "redis-store"
|
2
|
+
|
3
|
+
module RedisStore
|
4
|
+
module Cache
|
5
|
+
module Rails2
|
6
|
+
# Instantiate the store.
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# RedisStore.new
|
10
|
+
# # => host: localhost, port: 6379, db: 0
|
11
|
+
#
|
12
|
+
# RedisStore.new "example.com"
|
13
|
+
# # => host: example.com, port: 6379, db: 0
|
14
|
+
#
|
15
|
+
# RedisStore.new "example.com:23682"
|
16
|
+
# # => host: example.com, port: 23682, db: 0
|
17
|
+
#
|
18
|
+
# RedisStore.new "example.com:23682/1"
|
19
|
+
# # => host: example.com, port: 23682, db: 1
|
20
|
+
#
|
21
|
+
# RedisStore.new "example.com:23682/1/theplaylist"
|
22
|
+
# # => host: example.com, port: 23682, db: 1, namespace: theplaylist
|
23
|
+
#
|
24
|
+
# RedisStore.new "localhost:6379/0", "localhost:6380/0"
|
25
|
+
# # => instantiate a cluster
|
26
|
+
def initialize(*addresses)
|
27
|
+
@data = ::Redis::Factory.create(addresses)
|
28
|
+
end
|
29
|
+
|
30
|
+
def write(key, value, options = nil)
|
31
|
+
super
|
32
|
+
method = options && options[:unless_exist] ? :setnx : :set
|
33
|
+
@data.send method, key, value, options
|
34
|
+
end
|
35
|
+
|
36
|
+
def read(key, options = nil)
|
37
|
+
super
|
38
|
+
@data.get key, options
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(key, options = nil)
|
42
|
+
super
|
43
|
+
@data.del key
|
44
|
+
end
|
45
|
+
|
46
|
+
def exist?(key, options = nil)
|
47
|
+
super
|
48
|
+
@data.exists key
|
49
|
+
end
|
50
|
+
|
51
|
+
# Delete objects for matched keys.
|
52
|
+
#
|
53
|
+
# Example:
|
54
|
+
# cache.del_matched "rab*"
|
55
|
+
def delete_matched(matcher, options = nil)
|
56
|
+
instrument(:delete_matched, matcher, options) do
|
57
|
+
@data.keys(matcher).each { |key| @data.del key }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def instrument(operation, key, options = nil)
|
63
|
+
log(operation.to_s, key, options)
|
64
|
+
yield
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module Rails3
|
69
|
+
# Instantiate the store.
|
70
|
+
#
|
71
|
+
# Example:
|
72
|
+
# RedisStore.new
|
73
|
+
# # => host: localhost, port: 6379, db: 0
|
74
|
+
#
|
75
|
+
# RedisStore.new "example.com"
|
76
|
+
# # => host: example.com, port: 6379, db: 0
|
77
|
+
#
|
78
|
+
# RedisStore.new "example.com:23682"
|
79
|
+
# # => host: example.com, port: 23682, db: 0
|
80
|
+
#
|
81
|
+
# RedisStore.new "example.com:23682/1"
|
82
|
+
# # => host: example.com, port: 23682, db: 1
|
83
|
+
#
|
84
|
+
# RedisStore.new "example.com:23682/1/theplaylist"
|
85
|
+
# # => host: example.com, port: 23682, db: 1, namespace: theplaylist
|
86
|
+
#
|
87
|
+
# RedisStore.new "localhost:6379/0", "localhost:6380/0"
|
88
|
+
# # => instantiate a cluster
|
89
|
+
def initialize(*addresses)
|
90
|
+
@data = ::Redis::Factory.create(addresses)
|
91
|
+
super(addresses.extract_options!)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Delete objects for matched keys.
|
95
|
+
#
|
96
|
+
# Example:
|
97
|
+
# cache.del_matched "rab*"
|
98
|
+
def delete_matched(matcher, options = nil)
|
99
|
+
options = merged_options(options)
|
100
|
+
instrument(:delete_matched, matcher.inspect) do
|
101
|
+
matcher = key_matcher(matcher, options)
|
102
|
+
@data.keys(matcher).each { |key| delete_entry(key, options) }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
def write_entry(key, entry, options)
|
108
|
+
method = options && options[:unless_exist] ? :setnx : :set
|
109
|
+
entry = entry.value.to_s if entry.is_a? ActiveSupport::Cache::Entry
|
110
|
+
@data.send method, key, entry, options
|
111
|
+
end
|
112
|
+
|
113
|
+
def read_entry(key, options)
|
114
|
+
raw_value = @data.get key, options
|
115
|
+
if raw_value
|
116
|
+
entry = Marshal.load(raw_value) rescue raw_value
|
117
|
+
entry.is_a?(ActiveSupport::Cache::Entry) ? entry : ActiveSupport::Cache::Entry.new(entry)
|
118
|
+
else
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def delete_entry(key, options)
|
124
|
+
key.include?("*") ? delete_matched(key, options) : @data.del(key)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Add the namespace defined in the options to a pattern designed to match keys.
|
128
|
+
#
|
129
|
+
# This implementation is __different__ than ActiveSupport:
|
130
|
+
# __it doesn't accept Regular expressions__, because the Redis matcher is designed
|
131
|
+
# only for strings with wildcards.
|
132
|
+
def key_matcher(pattern, options)
|
133
|
+
prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
|
134
|
+
if prefix
|
135
|
+
raise "Regexps aren't supported, please use string with wildcards." if pattern.is_a?(Regexp)
|
136
|
+
"#{prefix}:#{pattern}"
|
137
|
+
else
|
138
|
+
pattern
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
Store = ::Redis::Store.rails3? ? Rails3 : Rails2
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
module ActiveSupport
|
148
|
+
module Cache
|
149
|
+
class RedisStore < Store
|
150
|
+
include ::RedisStore::Cache::Store
|
151
|
+
|
152
|
+
# Reads multiple keys from the cache using a single call to the
|
153
|
+
# servers for all keys. Options can be passed in the last argument.
|
154
|
+
#
|
155
|
+
# Example:
|
156
|
+
# cache.read_multi "rabbit", "white-rabbit"
|
157
|
+
# cache.read_multi "rabbit", "white-rabbit", :raw => true
|
158
|
+
def read_multi(*names)
|
159
|
+
@data.mget *names
|
160
|
+
end
|
161
|
+
|
162
|
+
# Increment a key in the store.
|
163
|
+
#
|
164
|
+
# If the key doesn't exist it will be initialized on 0.
|
165
|
+
# If the key exist but it isn't a Fixnum it will be initialized on 0.
|
166
|
+
#
|
167
|
+
# Example:
|
168
|
+
# We have two objects in cache:
|
169
|
+
# counter # => 23
|
170
|
+
# rabbit # => #<Rabbit:0x5eee6c>
|
171
|
+
#
|
172
|
+
# cache.increment "counter"
|
173
|
+
# cache.read "counter", :raw => true # => "24"
|
174
|
+
#
|
175
|
+
# cache.increment "counter", 6
|
176
|
+
# cache.read "counter", :raw => true # => "30"
|
177
|
+
#
|
178
|
+
# cache.increment "a counter"
|
179
|
+
# cache.read "a counter", :raw => true # => "1"
|
180
|
+
#
|
181
|
+
# cache.increment "rabbit"
|
182
|
+
# cache.read "rabbit", :raw => true # => "1"
|
183
|
+
def increment(key, amount = 1)
|
184
|
+
instrument(:increment, key, :amount => amount) do
|
185
|
+
@data.incrby key, amount
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Decrement a key in the store
|
190
|
+
#
|
191
|
+
# If the key doesn't exist it will be initialized on 0.
|
192
|
+
# If the key exist but it isn't a Fixnum it will be initialized on 0.
|
193
|
+
#
|
194
|
+
# Example:
|
195
|
+
# We have two objects in cache:
|
196
|
+
# counter # => 23
|
197
|
+
# rabbit # => #<Rabbit:0x5eee6c>
|
198
|
+
#
|
199
|
+
# cache.decrement "counter"
|
200
|
+
# cache.read "counter", :raw => true # => "22"
|
201
|
+
#
|
202
|
+
# cache.decrement "counter", 2
|
203
|
+
# cache.read "counter", :raw => true # => "20"
|
204
|
+
#
|
205
|
+
# cache.decrement "a counter"
|
206
|
+
# cache.read "a counter", :raw => true # => "-1"
|
207
|
+
#
|
208
|
+
# cache.decrement "rabbit"
|
209
|
+
# cache.read "rabbit", :raw => true # => "-1"
|
210
|
+
def decrement(key, amount = 1)
|
211
|
+
instrument(:decrement, key, :amount => amount) do
|
212
|
+
@data.decrby key, amount
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Clear all the data from the store.
|
217
|
+
def clear
|
218
|
+
instrument(:clear, nil, nil) do
|
219
|
+
@data.flushdb
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def stats
|
224
|
+
@data.info
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|