dsander-redis-store 0.3.8
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 +8 -0
- data/Gemfile +13 -0
- data/MIT-LICENSE +20 -0
- data/README.md +105 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/lib/cache/merb/redis_store.rb +63 -0
- data/lib/cache/rails/redis_store.rb +109 -0
- data/lib/cache/sinatra/redis_store.rb +111 -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 +32 -0
- data/lib/redis/distributed_marshaled_redis.rb +10 -0
- data/lib/redis/marshaled_redis.rb +38 -0
- data/lib/redis/redis_factory.rb +27 -0
- data/redis-store.gemspec +81 -0
- data/spec/cache/merb/redis_store_spec.rb +145 -0
- data/spec/cache/rails/redis_store_spec.rb +174 -0
- data/spec/cache/sinatra/redis_store_spec.rb +194 -0
- data/spec/config/master.conf +171 -0
- data/spec/config/single.conf +171 -0
- data/spec/config/slave.conf +171 -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 +257 -0
- data/spec/rack/session/redis_spec.rb +238 -0
- data/spec/redis/distributed_marshaled_redis_spec.rb +35 -0
- data/spec/redis/marshaled_redis_spec.rb +54 -0
- data/spec/redis/redis_factory_spec.rb +34 -0
- data/spec/spec_helper.rb +19 -0
- data/tasks/redis.tasks.rb +70 -0
- metadata +103 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
module Rack
|
2
|
+
module Cache
|
3
|
+
class EntityStore
|
4
|
+
class RedisBase < EntityStore
|
5
|
+
# The underlying ::Redis instance used to communicate with the Redis daemon.
|
6
|
+
attr_reader :cache
|
7
|
+
|
8
|
+
extend Rack::Utils
|
9
|
+
|
10
|
+
def open(key)
|
11
|
+
data = read(key)
|
12
|
+
data && [data]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.resolve(uri)
|
16
|
+
db = uri.path.sub(/^\//, '')
|
17
|
+
db = "0" if db.empty?
|
18
|
+
server = { :host => uri.host, :port => uri.port || "6379", :db => db }
|
19
|
+
new server
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Redis < RedisBase
|
24
|
+
def initialize(server, options = {})
|
25
|
+
@cache = ::Redis.new server
|
26
|
+
end
|
27
|
+
|
28
|
+
def exist?(key)
|
29
|
+
cache.exists key
|
30
|
+
end
|
31
|
+
|
32
|
+
def read(key)
|
33
|
+
cache.get key
|
34
|
+
end
|
35
|
+
|
36
|
+
def write(body)
|
37
|
+
buf = StringIO.new
|
38
|
+
key, size = slurp(body){|part| buf.write(part) }
|
39
|
+
[key, size] if cache.set(key, buf.string)
|
40
|
+
end
|
41
|
+
|
42
|
+
def purge(key)
|
43
|
+
cache.del key
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
REDIS = Redis
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Rack
|
2
|
+
module Cache
|
3
|
+
class MetaStore
|
4
|
+
class RedisBase < MetaStore
|
5
|
+
extend Rack::Utils
|
6
|
+
|
7
|
+
# The ::MarshaledRedis object used to communicate with the Redis daemon.
|
8
|
+
attr_reader :cache
|
9
|
+
|
10
|
+
def self.resolve(uri)
|
11
|
+
db = uri.path.sub(/^\//, '')
|
12
|
+
db = "0" if db.empty?
|
13
|
+
server = { :host => uri.host, :port => uri.port || "6379", :db => db }
|
14
|
+
new server
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Redis < RedisBase
|
19
|
+
def initialize(server, options = {})
|
20
|
+
@cache = ::MarshaledRedis.new server
|
21
|
+
end
|
22
|
+
|
23
|
+
def read(key)
|
24
|
+
key = hexdigest(key)
|
25
|
+
cache.get(key) || []
|
26
|
+
end
|
27
|
+
|
28
|
+
def write(key, entries)
|
29
|
+
key = hexdigest(key)
|
30
|
+
cache.set(key, entries)
|
31
|
+
end
|
32
|
+
|
33
|
+
def purge(key)
|
34
|
+
cache.del(hexdigest(key))
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
REDIS = Redis
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Merb
|
2
|
+
# HACK for cyclic dependency: redis-store is required before Merb session stores
|
3
|
+
class Mash < Hash; end
|
4
|
+
class SessionContainer < Mash; class_inheritable_accessor :session_store_type end
|
5
|
+
class SessionStoreContainer < SessionContainer; end
|
6
|
+
|
7
|
+
class RedisSession < SessionStoreContainer
|
8
|
+
self.session_store_type = :redis
|
9
|
+
end
|
10
|
+
|
11
|
+
module RedisStore
|
12
|
+
def retrieve_session(session_id)
|
13
|
+
get("session:#{session_id}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def store_session(session_id, data)
|
17
|
+
set("session:#{session_id}", data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete_session(session_id)
|
21
|
+
delete("session:#{session_id}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Rack
|
27
|
+
module Session
|
28
|
+
class Redis
|
29
|
+
include Merb::RedisStore
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Rack
|
2
|
+
module Session
|
3
|
+
class Redis < Abstract::ID
|
4
|
+
attr_reader :mutex, :pool
|
5
|
+
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :redis_server => "localhost:6379"
|
6
|
+
|
7
|
+
def initialize(app, options = {})
|
8
|
+
super
|
9
|
+
@mutex = Mutex.new
|
10
|
+
@pool = RedisFactory.create options[:redis_server] || @default_options[:redis_server]
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_sid
|
14
|
+
loop do
|
15
|
+
sid = super
|
16
|
+
break sid unless @pool.get(sid)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_session(env, sid)
|
21
|
+
session = @pool.get(sid) if sid
|
22
|
+
@mutex.lock if env['rack.multithread']
|
23
|
+
unless sid and session
|
24
|
+
env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
|
25
|
+
session = {}
|
26
|
+
sid = generate_sid
|
27
|
+
ret = @pool.set sid, session
|
28
|
+
raise "Session collision on '#{sid.inspect}'" unless ret
|
29
|
+
end
|
30
|
+
session.instance_variable_set('@old', {}.merge(session))
|
31
|
+
return [sid, session]
|
32
|
+
rescue Errno::ECONNREFUSED
|
33
|
+
warn "#{self} is unable to find server."
|
34
|
+
warn $!.inspect
|
35
|
+
return [ nil, {} ]
|
36
|
+
ensure
|
37
|
+
@mutex.unlock if env['rack.multithread']
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_session(env, session_id, new_session, options)
|
41
|
+
@mutex.lock if env['rack.multithread']
|
42
|
+
session = @pool.get(session_id) rescue {}
|
43
|
+
if options[:renew] or options[:drop]
|
44
|
+
@pool.del session_id
|
45
|
+
return false if options[:drop]
|
46
|
+
session_id = generate_sid
|
47
|
+
@pool.set session_id, 0
|
48
|
+
end
|
49
|
+
old_session = new_session.instance_variable_get('@old') || {}
|
50
|
+
session = merge_sessions session_id, old_session, new_session, session
|
51
|
+
@pool.set session_id, session, options
|
52
|
+
return session_id
|
53
|
+
rescue Errno::ECONNREFUSED
|
54
|
+
warn "#{self} is unable to find server."
|
55
|
+
warn $!.inspect
|
56
|
+
return false
|
57
|
+
ensure
|
58
|
+
@mutex.unlock if env['rack.multithread']
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def merge_sessions(sid, old, new, cur=nil)
|
63
|
+
cur ||= {}
|
64
|
+
unless Hash === old and Hash === new
|
65
|
+
warn 'Bad old or new sessions provided.'
|
66
|
+
return cur
|
67
|
+
end
|
68
|
+
|
69
|
+
delete = old.keys - new.keys
|
70
|
+
warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty?
|
71
|
+
delete.each{|k| cur.delete k }
|
72
|
+
|
73
|
+
update = new.keys.select{|k| new[k] != old[k] }
|
74
|
+
warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty?
|
75
|
+
update.each{|k| cur[k] = new[k] }
|
76
|
+
|
77
|
+
cur
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/redis-store.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "dsander-redis"
|
2
|
+
require "dsander-redis/dist_redis"
|
3
|
+
require "dsander-redis/redis_factory"
|
4
|
+
require "dsander-redis/marshaled_redis"
|
5
|
+
require "dsander-redis/distributed_marshaled_redis"
|
6
|
+
|
7
|
+
# Cache store
|
8
|
+
if defined?(Sinatra)
|
9
|
+
require "cache/sinatra/redis_store"
|
10
|
+
elsif defined?(Merb)
|
11
|
+
# HACK for cyclic dependency: redis-store is required before merb-cache
|
12
|
+
module Merb; module Cache; class AbstractStore; end end end
|
13
|
+
require "cache/merb/redis_store"
|
14
|
+
elsif defined?(Rails)
|
15
|
+
require "cache/rails/redis_store"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Rack::Session
|
19
|
+
if defined?(Rack::Session)
|
20
|
+
require "rack/session/abstract/id"
|
21
|
+
require "rack/session/redis"
|
22
|
+
if defined?(Merb)
|
23
|
+
require "rack/session/merb"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Rack::Cache
|
28
|
+
if defined?(Rack::Cache)
|
29
|
+
require "rack/cache/key"
|
30
|
+
require "rack/cache/redis_metastore"
|
31
|
+
require "rack/cache/redis_entitystore"
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class MarshaledRedis < Redis::Client
|
2
|
+
def set(key, val, options = nil)
|
3
|
+
if options && expires_in(options)
|
4
|
+
set_with_expire key, val, expires_in(options)
|
5
|
+
else
|
6
|
+
super key, (raw?(options) ? val : Marshal.dump(val) )
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def setnx(key, val, options = nil)
|
11
|
+
val = Marshal.dump val unless raw?(options)
|
12
|
+
super key, val
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(key, options = nil)
|
16
|
+
result = call_command([:get, key])
|
17
|
+
result = Marshal.load result if unmarshal?(result, options)
|
18
|
+
result
|
19
|
+
end
|
20
|
+
def multi(&blk)
|
21
|
+
yield(self)
|
22
|
+
end
|
23
|
+
private
|
24
|
+
def unmarshal?(result, options)
|
25
|
+
result && result.size > 0 && !raw?(options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def raw?(options)
|
29
|
+
options && options[:raw]
|
30
|
+
end
|
31
|
+
|
32
|
+
def expires_in(options)
|
33
|
+
if options
|
34
|
+
# Rack::Session Merb Rails/Sinatra
|
35
|
+
options[:expire_after] || options[:expires_in] || options[:expire_in]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class RedisFactory
|
2
|
+
class << self
|
3
|
+
def create(*addresses)
|
4
|
+
addresses = extract_addresses(addresses)
|
5
|
+
if addresses.size > 1
|
6
|
+
DistributedMarshaledRedis.new addresses
|
7
|
+
else
|
8
|
+
MarshaledRedis.new addresses.first || {}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def extract_addresses(addresses)
|
14
|
+
addresses = addresses.flatten.compact
|
15
|
+
addresses.inject([]) do |result, address|
|
16
|
+
host, port = address.split /\:/
|
17
|
+
port, db = port.split /\// if port
|
18
|
+
address = {}
|
19
|
+
address[:host] = host if host
|
20
|
+
address[:port] = port if port
|
21
|
+
address[:db] = db.to_i if db
|
22
|
+
result << address
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/redis-store.gemspec
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{redis-store}
|
8
|
+
s.version = "0.3.7"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Luca Guidi"]
|
12
|
+
s.date = %q{2010-04-21}
|
13
|
+
s.description = %q{Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks.}
|
14
|
+
s.email = %q{guidi.luca@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"Gemfile",
|
21
|
+
"MIT-LICENSE",
|
22
|
+
"README.md",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"lib/cache/merb/redis_store.rb",
|
26
|
+
"lib/cache/rails/redis_store.rb",
|
27
|
+
"lib/cache/sinatra/redis_store.rb",
|
28
|
+
"lib/rack/cache/redis_entitystore.rb",
|
29
|
+
"lib/rack/cache/redis_metastore.rb",
|
30
|
+
"lib/rack/session/merb.rb",
|
31
|
+
"lib/rack/session/redis.rb",
|
32
|
+
"lib/redis-store.rb",
|
33
|
+
"lib/redis/distributed_marshaled_redis.rb",
|
34
|
+
"lib/redis/marshaled_redis.rb",
|
35
|
+
"lib/redis/redis_factory.rb",
|
36
|
+
"redis-store.gemspec",
|
37
|
+
"spec/cache/merb/redis_store_spec.rb",
|
38
|
+
"spec/cache/rails/redis_store_spec.rb",
|
39
|
+
"spec/cache/sinatra/redis_store_spec.rb",
|
40
|
+
"spec/config/master.conf",
|
41
|
+
"spec/config/single.conf",
|
42
|
+
"spec/config/slave.conf",
|
43
|
+
"spec/rack/cache/entitystore/pony.jpg",
|
44
|
+
"spec/rack/cache/entitystore/redis_spec.rb",
|
45
|
+
"spec/rack/cache/metastore/redis_spec.rb",
|
46
|
+
"spec/rack/session/redis_spec.rb",
|
47
|
+
"spec/redis/distributed_marshaled_redis_spec.rb",
|
48
|
+
"spec/redis/marshaled_redis_spec.rb",
|
49
|
+
"spec/redis/redis_factory_spec.rb",
|
50
|
+
"spec/spec_helper.rb",
|
51
|
+
"tasks/redis.tasks.rb"
|
52
|
+
]
|
53
|
+
s.homepage = %q{http://github.com/jodosha/redis-store}
|
54
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
55
|
+
s.require_paths = ["lib"]
|
56
|
+
s.rubygems_version = %q{1.3.6}
|
57
|
+
s.summary = %q{Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks.}
|
58
|
+
s.test_files = [
|
59
|
+
"spec/rack/session/redis_spec.rb",
|
60
|
+
"spec/rack/cache/entitystore/redis_spec.rb",
|
61
|
+
"spec/rack/cache/metastore/redis_spec.rb",
|
62
|
+
"spec/cache/sinatra/redis_store_spec.rb",
|
63
|
+
"spec/cache/rails/redis_store_spec.rb",
|
64
|
+
"spec/cache/merb/redis_store_spec.rb",
|
65
|
+
"spec/spec_helper.rb",
|
66
|
+
"spec/redis/distributed_marshaled_redis_spec.rb",
|
67
|
+
"spec/redis/redis_factory_spec.rb",
|
68
|
+
"spec/redis/marshaled_redis_spec.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
76
|
+
else
|
77
|
+
end
|
78
|
+
else
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "/../../spec_helper")
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module Cache
|
5
|
+
describe "Merb::Cache::RedisStore" do
|
6
|
+
before(:each) do
|
7
|
+
@store = Merb::Cache::RedisStore.new
|
8
|
+
@dstore = Merb::Cache::RedisStore.new :servers => ["localhost:6380/1", "localhost:6381/1"]
|
9
|
+
@rabbit = OpenStruct.new :name => "bunny"
|
10
|
+
@white_rabbit = OpenStruct.new :color => "white"
|
11
|
+
with_store_management do |store|
|
12
|
+
store.write "rabbit", @rabbit
|
13
|
+
store.delete "rub-a-dub"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept connection params" do
|
18
|
+
redis = instantiate_store
|
19
|
+
redis.host.should == "127.0.0.1"
|
20
|
+
redis.port.should == 6379
|
21
|
+
redis.db.should == 0
|
22
|
+
|
23
|
+
redis = instantiate_store "localhost"
|
24
|
+
redis.host.should == "localhost"
|
25
|
+
|
26
|
+
redis = instantiate_store "localhost:6380"
|
27
|
+
redis.host.should == "localhost"
|
28
|
+
redis.port.should == 6380
|
29
|
+
|
30
|
+
redis = instantiate_store "localhost:6380/13"
|
31
|
+
redis.host.should == "localhost"
|
32
|
+
redis.port.should == 6380
|
33
|
+
redis.db.should == 13
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should instantiate a ring" do
|
37
|
+
store = instantiate_store
|
38
|
+
store.should be_kind_of(MarshaledRedis)
|
39
|
+
store = instantiate_store ["localhost:6379/0", "localhost:6379/1"]
|
40
|
+
store.should be_kind_of(DistributedMarshaledRedis)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should verify if writable" do
|
44
|
+
with_store_management do |store|
|
45
|
+
store.writable?("rabbit").should be_true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should read the data" do
|
50
|
+
with_store_management do |store|
|
51
|
+
store.read("rabbit").should === @rabbit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should read raw data" do
|
56
|
+
with_store_management do |store|
|
57
|
+
store.read("rabbit", {}, :raw => true).should == Marshal.dump(@rabbit)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should write the data" do
|
62
|
+
with_store_management do |store|
|
63
|
+
store.write "rabbit", @white_rabbit
|
64
|
+
store.read("rabbit").should === @white_rabbit
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should write raw data" do
|
69
|
+
with_store_management do |store|
|
70
|
+
store.write "rabbit", @white_rabbit, {}, :raw => true
|
71
|
+
store.read("rabbit", {}, :raw => true).should == %(#<OpenStruct color="white">)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should write the data with expiration time" do
|
76
|
+
with_store_management do |store|
|
77
|
+
store.write "rabbit", @white_rabbit, {}, :expires_in => 1.second
|
78
|
+
store.read("rabbit").should === @white_rabbit ; sleep 2
|
79
|
+
store.read("rabbit").should be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should not write data if :unless_exist option is true" do
|
84
|
+
with_store_management do |store|
|
85
|
+
store.write "rabbit", @white_rabbit, {}, :unless_exist => true
|
86
|
+
store.read("rabbit").should === @rabbit
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should write all the data" do
|
91
|
+
with_store_management do |store|
|
92
|
+
store.write_all "rabbit", @white_rabbit
|
93
|
+
store.read("rabbit").should === @white_rabbit
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should fetch data" do
|
98
|
+
with_store_management do |store|
|
99
|
+
store.fetch("rabbit").should == @rabbit
|
100
|
+
store.fetch("rub-a-dub").should be_nil
|
101
|
+
store.fetch("rub-a-dub") { "Flora de Cana" }
|
102
|
+
store.fetch("rub-a-dub").should === "Flora de Cana"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should verify existence" do
|
107
|
+
with_store_management do |store|
|
108
|
+
store.exists?("rabbit").should be_true
|
109
|
+
store.exists?("rab-a-dub").should be_false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should delete data" do
|
114
|
+
with_store_management do |store|
|
115
|
+
store.delete "rabbit"
|
116
|
+
store.read("rabbit").should be_nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should delete all the data" do
|
121
|
+
with_store_management do |store|
|
122
|
+
store.delete_all
|
123
|
+
store.instance_variable_get(:@data).keys("*").flatten.should be_empty
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should delete all the data with bang method" do
|
128
|
+
with_store_management do |store|
|
129
|
+
store.delete_all!
|
130
|
+
store.instance_variable_get(:@data).keys("*").flatten.should be_empty
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
def instantiate_store(addresses = nil)
|
136
|
+
Merb::Cache::RedisStore.new(:servers => [addresses].flatten).instance_variable_get(:@data)
|
137
|
+
end
|
138
|
+
|
139
|
+
def with_store_management
|
140
|
+
yield @store
|
141
|
+
yield @dstore
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|