redis_session 0.1.6
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/lib/redis_session.rb +268 -0
- data/license +20 -0
- data/redis_session.gemsepc +23 -0
- data/spec/add_restore_spec.rb +113 -0
- metadata +89 -0
@@ -0,0 +1,268 @@
|
|
1
|
+
#The MIT License (MIT)
|
2
|
+
#
|
3
|
+
# Copyright (c) 2012 Ido Kanner
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'redis'
|
25
|
+
rescue
|
26
|
+
require 'rubygems'
|
27
|
+
require 'redis'
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
#
|
32
|
+
# A session module
|
33
|
+
#
|
34
|
+
|
35
|
+
module Session
|
36
|
+
|
37
|
+
##
|
38
|
+
#
|
39
|
+
# == Example:
|
40
|
+
#
|
41
|
+
# require 'redis_session'
|
42
|
+
# session = Session::SessionClient.new(:prefix => 'example', :host => '10.0.0.31')
|
43
|
+
#
|
44
|
+
# session.save('key', 'value') # save key with the value of value without expire, return true if successful
|
45
|
+
# puts session.restore('key') # will return "value"
|
46
|
+
#
|
47
|
+
# session.save('self_destruct', 'in', 10) # save the key self_destruct with the value of 'in', and will terminates in 10 seconds
|
48
|
+
# sleep 10.1
|
49
|
+
# session.restore('self_destruct') # returns empty hash
|
50
|
+
# session.restore('self_destruct', nil) # returns default value of nil
|
51
|
+
#
|
52
|
+
# session.save('boom', { :bomb => 'ball' }, 10) # saving a ruby object
|
53
|
+
# puts session.ttl('boom') # should return the seconds left to the key to live or -1
|
54
|
+
#
|
55
|
+
# session.expire('key', 60) # the key will be gone in 60 seconds
|
56
|
+
# puts session.restore('key') # prints 'value'
|
57
|
+
#
|
58
|
+
# puts 'has value' if session.value? 'key' # check if key has a value
|
59
|
+
#
|
60
|
+
# session.delete('key') # deleted it before time :)
|
61
|
+
# # it's alias to remove
|
62
|
+
#
|
63
|
+
# puts 'still here' if session.key? 'key' # do we have the key ?
|
64
|
+
#
|
65
|
+
|
66
|
+
class SessionClient
|
67
|
+
|
68
|
+
##
|
69
|
+
#
|
70
|
+
# Creates an object of SessionClient
|
71
|
+
#
|
72
|
+
# ==== Parameters
|
73
|
+
# :host:: the ip address or host name of the redis server default localhost
|
74
|
+
# :path:: the path to unix socket of redis (instead of :host)
|
75
|
+
# :port:: the port number for the host - default 6379
|
76
|
+
# :db:: the Redis database number - default 0
|
77
|
+
# :prefix:: a prefix string for storing and retriving information
|
78
|
+
# :expire:: global expiry of keys in seconds
|
79
|
+
#
|
80
|
+
|
81
|
+
def initialize(options={})
|
82
|
+
raise ArgumentError, 'options must be Hash' unless options.kind_of? Hash
|
83
|
+
|
84
|
+
options[:host] ||= 'localhost' unless options[:path]
|
85
|
+
options[:port] ||= 6379
|
86
|
+
options[:db] ||= 0
|
87
|
+
options[:prefix] ||= ''
|
88
|
+
options[:expire] ||= 0
|
89
|
+
|
90
|
+
@options = options
|
91
|
+
@redis = Redis.new(@options)
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
#
|
96
|
+
# Getting the prefix name
|
97
|
+
#
|
98
|
+
# returns:: The prefix string
|
99
|
+
#
|
100
|
+
|
101
|
+
def prefix
|
102
|
+
@options[:prefix]
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
#
|
107
|
+
# Changing the prefix string _(will not effect existing keys)_
|
108
|
+
#
|
109
|
+
# prefix:: The new prefix to be set
|
110
|
+
#
|
111
|
+
|
112
|
+
def prefix=(prefix)
|
113
|
+
@options[:prefix] = prefix
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
#
|
118
|
+
# Saving a key with a value
|
119
|
+
#
|
120
|
+
# key:: the name of the key to be saved
|
121
|
+
# value:: the value to save. Can be any Ruby object
|
122
|
+
# ttl:: expiry time to the key. Default nil.
|
123
|
+
#
|
124
|
+
# returns:: true if successful or false otherwise
|
125
|
+
#
|
126
|
+
# *Note*:: If expire was set and ttl is nil, then the key will have expire by the :expire option
|
127
|
+
#
|
128
|
+
|
129
|
+
def save(key, value, ttl = nil)
|
130
|
+
a_key = make_key(key)
|
131
|
+
a_data = Marshal.dump(value)
|
132
|
+
ttl ||= @options[:expire]
|
133
|
+
if ttl > 0
|
134
|
+
@redis.setex(a_key, ttl, a_data)
|
135
|
+
else
|
136
|
+
@redis.set(a_key, a_data)
|
137
|
+
end
|
138
|
+
true
|
139
|
+
rescue
|
140
|
+
false
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
#
|
145
|
+
# Restoring a key's value or providing a default value instead
|
146
|
+
#
|
147
|
+
# key:: The name of the key to restore
|
148
|
+
# default:: The value to provide if no value was given. Default empty Hash
|
149
|
+
#
|
150
|
+
# returns:: The value of the key or default value
|
151
|
+
#
|
152
|
+
|
153
|
+
def restore(key, default={})
|
154
|
+
a_key = make_key(key)
|
155
|
+
data = @redis.get(a_key)
|
156
|
+
data.nil? ? default : Marshal.load(data)
|
157
|
+
rescue
|
158
|
+
default
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
#
|
163
|
+
# Set an expire time in seconds to a key. If the key already has an expire time, it reset it to a new time.
|
164
|
+
#
|
165
|
+
# key:: The name of the key to set the expire time
|
166
|
+
# ttl:: The time in seconds to expire the key
|
167
|
+
#
|
168
|
+
# returns:: true if successful or false if not
|
169
|
+
#
|
170
|
+
|
171
|
+
def expire(key, ttl)
|
172
|
+
a_key = make_key(key)
|
173
|
+
@redis.expire(a_key, ttl)
|
174
|
+
rescue
|
175
|
+
false
|
176
|
+
end
|
177
|
+
|
178
|
+
##
|
179
|
+
#
|
180
|
+
# Examines how much time left to a key in seconds
|
181
|
+
#
|
182
|
+
# key:: The name of a key to check the ttl
|
183
|
+
#
|
184
|
+
# returns:: Returns the number of seconds left, or -1 if key does not exists or no ttl exists for it
|
185
|
+
#
|
186
|
+
|
187
|
+
def ttl(key)
|
188
|
+
a_key = make_key(key)
|
189
|
+
@redis.ttl(a_key)
|
190
|
+
rescue
|
191
|
+
-1
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
#
|
196
|
+
# Deleting a key from the session
|
197
|
+
#
|
198
|
+
# key:: The name of the key to be removed
|
199
|
+
#
|
200
|
+
# returns:: true if successful or false otherwise
|
201
|
+
#
|
202
|
+
|
203
|
+
def remove(key)
|
204
|
+
a_key = make_key(key)
|
205
|
+
@redis.del(a_key)
|
206
|
+
rescue
|
207
|
+
false
|
208
|
+
end
|
209
|
+
|
210
|
+
##
|
211
|
+
#
|
212
|
+
# Check to see if a key exists
|
213
|
+
#
|
214
|
+
# key:: The name of the key to check
|
215
|
+
#
|
216
|
+
# returns:: true if it exists or false otherwise
|
217
|
+
#
|
218
|
+
|
219
|
+
def key?(key)
|
220
|
+
a_key = make_key(key)
|
221
|
+
@redis.exists a_key
|
222
|
+
rescue
|
223
|
+
false
|
224
|
+
end
|
225
|
+
|
226
|
+
##
|
227
|
+
#
|
228
|
+
# Check if a key has a value
|
229
|
+
#
|
230
|
+
# key:: The name of the key to check
|
231
|
+
#
|
232
|
+
# returns:: true if exists or false otherwise
|
233
|
+
#
|
234
|
+
|
235
|
+
def value?(key)
|
236
|
+
a_key = make_key(key)
|
237
|
+
@redis.get(a_key) != nil
|
238
|
+
rescue
|
239
|
+
false
|
240
|
+
end
|
241
|
+
|
242
|
+
##
|
243
|
+
#
|
244
|
+
# Deleting a key from the session
|
245
|
+
#
|
246
|
+
# key:: The name of the key to be removed
|
247
|
+
#
|
248
|
+
# returns:: true if successful or false otherwise
|
249
|
+
#
|
250
|
+
|
251
|
+
alias :delete :remove
|
252
|
+
|
253
|
+
private
|
254
|
+
##
|
255
|
+
#
|
256
|
+
# Generate a key with a prefix string
|
257
|
+
#
|
258
|
+
# key:: The name of the key to generate
|
259
|
+
#
|
260
|
+
# returns:: the key with the prefix
|
261
|
+
#
|
262
|
+
|
263
|
+
def make_key(key)
|
264
|
+
"#{@options[:prefix]}#{key}"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
data/license
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2012 Ido Kanner
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
s.name = 'redis_session'
|
4
|
+
s.version = '0.1.6'
|
5
|
+
s.homepage = 'https://github.com/ik5/redis_session'
|
6
|
+
s.summary = 'A session handler using Redis DB'
|
7
|
+
s.description = <<EOF
|
8
|
+
A session like handler of data using the Redis Database.
|
9
|
+
The session is built with mindset that non web applications
|
10
|
+
can use it just as well as web applications.
|
11
|
+
EOF
|
12
|
+
|
13
|
+
s.files = Dir.glob('lib/**rb') +
|
14
|
+
['redis_session.gemsepc', 'license' ]
|
15
|
+
s.authors = ['Ido Kanner']
|
16
|
+
s.licenses = 'MIT'
|
17
|
+
s.email = 'idokan@gmail.com'
|
18
|
+
s.test_files = Dir.glob('spec/*rb')
|
19
|
+
s.add_dependency('redis')
|
20
|
+
s.add_development_dependency('rspec')
|
21
|
+
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'redis_session'
|
2
|
+
|
3
|
+
describe Session::SessionClient do
|
4
|
+
before do
|
5
|
+
@session = Session::SessionClient.new(:prefix => 'add_test')
|
6
|
+
end
|
7
|
+
after do
|
8
|
+
@session.remove('name')
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'With no values' do
|
12
|
+
it 'should return empty hash' do
|
13
|
+
@session.restore('name').length.should equal(0)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'With saving values' do
|
18
|
+
it 'should restore the "name" with "session"' do
|
19
|
+
@session.save('name', { 'name' => 'session'})
|
20
|
+
restored = @session.restore('name')
|
21
|
+
restored.class.should equal Hash and restored.should eq({'name' => 'session'})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'Having restoring non existed value with default' do
|
26
|
+
it 'should have value of false' do
|
27
|
+
val = @session.restore('non_existed', false)
|
28
|
+
val.should == false
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should not have value of true' do
|
32
|
+
val = @session.restore('non_existed', false)
|
33
|
+
val.should_not == true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'Checking if key and values exists' do
|
38
|
+
it 'should have existed key' do
|
39
|
+
@session.save('name', 1)
|
40
|
+
key = @session.key? 'name'
|
41
|
+
key.should == true
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should have non exited key' do
|
45
|
+
key = @session.key? 'no_key'
|
46
|
+
key.should == false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should have existed value' do
|
50
|
+
@session.save('name', 1)
|
51
|
+
value = @session.value?('name')
|
52
|
+
value.should == true
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not have value' do
|
56
|
+
value = @session.value? 'no_key'
|
57
|
+
value.should == false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'Dealing with prefix' do
|
62
|
+
it 'should return the prefix' do
|
63
|
+
prefix = @session.prefix
|
64
|
+
prefix.should == 'add_test'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should change the prefix' do
|
68
|
+
orig_prefix = @session.prefix
|
69
|
+
@session.prefix = orig_prefix + '_'
|
70
|
+
prefix = @session.prefix
|
71
|
+
prefix.should == orig_prefix + '_'
|
72
|
+
@session.prefix = orig_prefix
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'Working with expire' do
|
77
|
+
it 'should have ttl of 5 seconds when saving' do
|
78
|
+
@session.save('with_ttl', 1, 5)
|
79
|
+
ttl = @session.ttl('with_ttl')
|
80
|
+
ttl.should == 5
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'ttl should not be set' do
|
84
|
+
@session.save('no_ttl', 1)
|
85
|
+
ttl = @session.ttl('no_ttl')
|
86
|
+
ttl.should == -1
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should have ttl of 5 seconds when expiring' do
|
90
|
+
@session.save('no_ttl', 1)
|
91
|
+
@session.expire('no_ttl', 5)
|
92
|
+
ttl = @session.ttl('no_ttl')
|
93
|
+
ttl.should == 5
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'save with ttl, should not exists after 5 seconds' do
|
97
|
+
@session.save('with_ttl', 1, 5)
|
98
|
+
|
99
|
+
sleep 5.1
|
100
|
+
val = @session.value?('with_ttl')
|
101
|
+
val.should == false
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'expire with of 5 seconds, should not exists after it' do
|
105
|
+
@session.save('no_ttl', 1)
|
106
|
+
@session.expire('no_ttl', 5)
|
107
|
+
sleep 5.1
|
108
|
+
val = @session.value?('no_ttl')
|
109
|
+
val.should == false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redis_session
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.6
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ido Kanner
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: redis
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: ! 'A session like handler of data using the Redis Database.
|
47
|
+
|
48
|
+
The session is built with mindset that non web applications
|
49
|
+
|
50
|
+
can use it just as well as web applications.
|
51
|
+
|
52
|
+
'
|
53
|
+
email: idokan@gmail.com
|
54
|
+
executables: []
|
55
|
+
extensions: []
|
56
|
+
extra_rdoc_files: []
|
57
|
+
files:
|
58
|
+
- lib/redis_session.rb
|
59
|
+
- redis_session.gemsepc
|
60
|
+
- license
|
61
|
+
- spec/add_restore_spec.rb
|
62
|
+
homepage: https://github.com/ik5/redis_session
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.8.23
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: A session handler using Redis DB
|
87
|
+
test_files:
|
88
|
+
- spec/add_restore_spec.rb
|
89
|
+
has_rdoc:
|