mongo-store 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -29,7 +29,6 @@ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
29
  spec.rcov = true
30
30
  end
31
31
 
32
- task :spec => :check_dependencies
33
32
 
34
33
  task :default => :spec
35
34
 
data/VERSION CHANGED
@@ -1 +1,2 @@
1
- 0.1.2
1
+ 0.2.0
2
+
@@ -11,10 +11,10 @@ module Rack
11
11
  #
12
12
  # == Usage Example
13
13
  #
14
- # use Rack::Session::Mongo, :connection => @existing_mongodb_connection,
14
+ # use Rack::Session::Mongo, :connection => @existing_mongodb_connection;,
15
15
  # :expire_after => 1800
16
16
  class Mongo < Abstract::ID
17
- attr_reader :mutex, :pool, :connection
17
+ attr_reader :mutex, :pool, :connection, :marshal_data
18
18
  DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :db => 'rack', :collection => 'sessions', :drop => false
19
19
 
20
20
  # Creates a new Mongo session store pool. You probably won't initialize
@@ -35,10 +35,27 @@ module Rack
35
35
  # instance global</i>
36
36
  # @option options [String] :collection ('sessions') the Mongo collection
37
37
  # to use. — <i>pool instance global</i>
38
+ # @option options [boolean] :marshal_data (true) Marshal data into string
39
+ # otherwise store as hash in db. — <i>pool instance global</i>
40
+ # Note: if you use this then the keys used to lookup values must be strings
41
+ # even if you put in symbols. *Example:*
42
+ # request1: session[:test] = true
43
+ # request2: session[:test]
44
+ # > nil
45
+ # session['test']
46
+ # > true
47
+ #
48
+ # The advantage is that you can query the contents of the sessions and
49
+ # potentially make changes on the fly
38
50
  # @option options [Integer] :expire_after (nil) the time in seconds for
39
51
  # the session to last for. *Example:* If this is set to +1800+, the
40
52
  # session will be deleted if the client doesn't make a request within 30
41
53
  # minutes of its last request.
54
+ # @option options [Integer] :clear_expired_after (1800) the time in seconds
55
+ # before we clear out old sessions. *Example:* If this is set to +1800+, the
56
+ # the session will be cleared from mongodb when a session is requested, if
57
+ # it has been 1800 seconds since it was last cleared. setting to -1 will
58
+ # disable this.
42
59
  # @option options [true, false] :defer (false) don't set the session
43
60
  # cookie for this request.
44
61
  # @option options [true, false] :renew (false) causes the generation of
@@ -58,7 +75,11 @@ module Rack
58
75
  @mutex = Mutex.new
59
76
  @connection = @default_options[:connection] || ::Mongo::Connection.new
60
77
  @pool = @connection.db(@default_options[:db]).collection(@default_options[:collection])
78
+ @pool.create_index([['expires', -1]])
61
79
  @pool.create_index('sid', :unique => true)
80
+ @marshal_data = @default_options[:marshal_data].nil? ? true : @default_options[:marshal_data] == true
81
+ @next_expire_period = nil
82
+ @recheck_expire_period = @default_options[:clear_expired_after].nil? ? 1800 : @default_options[:clear_expired_after].to_i
62
83
  end
63
84
 
64
85
  def get_session(env, sid)
@@ -71,6 +92,7 @@ module Rack
71
92
  save_session(sid)
72
93
  end
73
94
  session.instance_variable_set('@old', {}.merge(session))
95
+ session.instance_variable_set('@sid', sid)
74
96
  return [sid, session]
75
97
  ensure
76
98
  @mutex.unlock if env['rack.multithread']
@@ -95,16 +117,25 @@ module Rack
95
117
  end
96
118
 
97
119
  private
120
+
98
121
  def generate_sid
99
122
  loop do
100
123
  sid = super
101
124
  break sid unless find_session(sid)
102
125
  end
103
126
  end
104
-
127
+
105
128
  def find_session(sid)
106
- @pool.remove :expires => {'$lte' => Time.now} # clean out expired sessions
129
+ time = Time.now
130
+ if @recheck_expire_period != -1 && (@next_expire_period.nil? || @next_expire_period < time)
131
+ @next_expire_period = time + @recheck_expire_period
132
+ @pool.remove :expires => {'$lte' => time} # clean out expired sessions
133
+ end
107
134
  session = @pool.find_one :sid => sid
135
+ #if session is expired but hasn't been cleared yet. don't return it.
136
+ if session && session['expires'] != nil && session['expires'] < time
137
+ session = nil
138
+ end
108
139
  session ? unpack(session['data']) : false
109
140
  end
110
141
 
@@ -113,7 +144,7 @@ module Rack
113
144
  end
114
145
 
115
146
  def save_session(sid, session={}, expires=nil)
116
- @pool.update({:sid => sid}, {:sid => sid, :data => pack(session), :expires => expires}, :upsert => true)
147
+ @pool.update({:sid => sid}, {"$set" => {:data => pack(session), :expires => expires}}, :upsert => true)
117
148
  end
118
149
 
119
150
  def merge_sessions(sid, old, new, current=nil)
@@ -127,7 +158,7 @@ module Rack
127
158
  warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty?
128
159
  delete.each{|k| current.delete k }
129
160
 
130
- update = new.keys.select{|k| new[k] != old[k] }
161
+ update = new.keys.select{|k| new[k] != old[k] || new[k].kind_of?(Hash) || new[k].kind_of?(Array) }
131
162
  warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty?
132
163
  update.each{|k| current[k] = new[k] }
133
164
 
@@ -135,12 +166,20 @@ module Rack
135
166
  end
136
167
 
137
168
  def pack(data)
138
- [Marshal.dump(data)].pack("m*")
169
+ if(@marshal_data)
170
+ [Marshal.dump(data)].pack("m*")
171
+ else
172
+ data
173
+ end
139
174
  end
140
175
 
141
176
  def unpack(packed)
142
177
  return nil unless packed
143
- Marshal.load(packed.unpack("m*").first)
178
+ if(@marshal_data)
179
+ Marshal.load(packed.unpack("m*").first)
180
+ else
181
+ packed
182
+ end
144
183
  end
145
184
  end
146
185
  end
@@ -1,62 +1,74 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo-store}
8
- s.version = "0.1.2"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jonathan Rudenberg"]
12
- s.date = %q{2010-10-03}
12
+ s.date = %q{2011-04-26}
13
13
  s.email = %q{jonathan@titanous.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
16
- "README.rdoc"
16
+ "README.rdoc"
17
17
  ]
18
18
  s.files = [
19
19
  ".document",
20
- ".gitignore",
21
- "Gemfile",
22
- "Gemfile.lock",
23
- "LICENSE",
24
- "README.rdoc",
25
- "Rakefile",
26
- "VERSION",
27
- "lib/mongo-store.rb",
28
- "lib/rack/session/mongo.rb",
29
- "mongo-store.gemspec",
30
- "spec/rack-mongo-store_spec.rb",
31
- "spec/spec.opts",
32
- "spec/spec_helper.rb"
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/mongo-store.rb",
27
+ "lib/rack/session/mongo.rb",
28
+ "mongo-store.gemspec",
29
+ "spec/rack-mongo-store_spec.rb",
30
+ "spec/spec.opts",
31
+ "spec/spec_helper.rb"
33
32
  ]
34
33
  s.homepage = %q{http://github.com/titanous/mongo-store}
35
- s.rdoc_options = ["--charset=UTF-8"]
36
34
  s.require_paths = ["lib"]
37
- s.rubygems_version = %q{1.3.7}
35
+ s.rubygems_version = %q{1.7.2}
38
36
  s.summary = %q{Rack session store for MongoDB}
39
37
  s.test_files = [
40
38
  "spec/rack-mongo-store_spec.rb",
41
- "spec/spec_helper.rb"
39
+ "spec/spec_helper.rb"
42
40
  ]
43
41
 
44
42
  if s.respond_to? :specification_version then
45
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
43
  s.specification_version = 3
47
44
 
48
45
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ s.add_runtime_dependency(%q<mongo-store>, [">= 0"])
47
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
48
+ s.add_development_dependency(%q<yard>, [">= 0"])
49
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
50
+ s.add_development_dependency(%q<yard>, [">= 0"])
49
51
  s.add_runtime_dependency(%q<mongo>, [">= 1.0.1"])
50
52
  s.add_runtime_dependency(%q<rack>, [">= 1.1.0"])
51
53
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
52
54
  s.add_development_dependency(%q<yard>, [">= 0"])
53
55
  else
56
+ s.add_dependency(%q<mongo-store>, [">= 0"])
57
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
58
+ s.add_dependency(%q<yard>, [">= 0"])
59
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
60
+ s.add_dependency(%q<yard>, [">= 0"])
54
61
  s.add_dependency(%q<mongo>, [">= 1.0.1"])
55
62
  s.add_dependency(%q<rack>, [">= 1.1.0"])
56
63
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
57
64
  s.add_dependency(%q<yard>, [">= 0"])
58
65
  end
59
66
  else
67
+ s.add_dependency(%q<mongo-store>, [">= 0"])
68
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
69
+ s.add_dependency(%q<yard>, [">= 0"])
70
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
71
+ s.add_dependency(%q<yard>, [">= 0"])
60
72
  s.add_dependency(%q<mongo>, [">= 1.0.1"])
61
73
  s.add_dependency(%q<rack>, [">= 1.1.0"])
62
74
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
@@ -27,15 +27,14 @@ describe 'Rack::Session::Mongo' do
27
27
  it 'should specify connection params' do
28
28
  mongo = Rack::Session::Mongo.new(@incrementor,
29
29
  :connection => Mongo::Connection.new('localhost'), :db => 'rack-test',
30
- :collection => 'mongo-test')
30
+ :collection => 'mongo_test')
31
31
  pool = mongo.pool
32
32
  connection = mongo.connection
33
-
34
- connection.host.should == 'localhost'
33
+ connection.primary[0].should == 'localhost'
35
34
 
36
35
  pool.should be_kind_of(Mongo::Collection)
37
36
  pool.db.name.should == 'rack-test'
38
- pool.name.should == 'mongo-test'
37
+ pool.name.should == 'mongo_test'
39
38
  end
40
39
 
41
40
  it 'creates a new cookie' do
@@ -128,7 +127,20 @@ describe 'Rack::Session::Mongo' do
128
127
  res3['Set-Cookie'][@session_match].should == new_session
129
128
  res3.body.should == '{"counter"=>4}'
130
129
  end
131
-
130
+ it 'should default marshal_data to true' do
131
+ pool = Rack::Session::Mongo.new(@incrementor)
132
+ pool.marshal_data.should == true
133
+ data = {'test' => true}
134
+ pool.send(:pack, data).should == [Marshal.dump(data)].pack("m*")
135
+ pool.send(:unpack, [Marshal.dump(data)].pack("m*"))['test'] == true
136
+ end
137
+ it 'should be able to set marshal_data to false' do
138
+ pool = Rack::Session::Mongo.new(@incrementor, :marshal_data => false)
139
+ pool.marshal_data.should == false
140
+ data = {'test' => true}
141
+ pool.send(:pack, data).should === data
142
+ pool.send(:unpack, data).should === data
143
+ end
132
144
  specify 'omits cookie with :defer option' do
133
145
  pool = Rack::Session::Mongo.new(@incrementor)
134
146
  req = Rack::MockRequest.new(pool)
File without changes
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo-store
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 2
10
- version: 0.1.2
4
+ prerelease:
5
+ version: 0.2.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - Jonathan Rudenberg
@@ -15,71 +10,107 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2010-10-03 00:00:00 -04:00
19
- default_executable:
13
+ date: 2011-04-26 00:00:00 Z
20
14
  dependencies:
21
15
  - !ruby/object:Gem::Dependency
22
- name: mongo
23
- prerelease: false
16
+ name: mongo-store
24
17
  requirement: &id001 !ruby/object:Gem::Requirement
25
18
  none: false
26
19
  requirements:
27
20
  - - ">="
28
21
  - !ruby/object:Gem::Version
29
- hash: 21
30
- segments:
31
- - 1
32
- - 0
33
- - 1
34
- version: 1.0.1
22
+ version: "0"
35
23
  type: :runtime
24
+ prerelease: false
36
25
  version_requirements: *id001
37
26
  - !ruby/object:Gem::Dependency
38
- name: rack
39
- prerelease: false
27
+ name: rspec
40
28
  requirement: &id002 !ruby/object:Gem::Requirement
41
29
  none: false
42
30
  requirements:
43
31
  - - ">="
44
32
  - !ruby/object:Gem::Version
45
- hash: 19
46
- segments:
47
- - 1
48
- - 1
49
- - 0
50
- version: 1.1.0
51
- type: :runtime
33
+ version: 1.2.9
34
+ type: :development
35
+ prerelease: false
52
36
  version_requirements: *id002
53
37
  - !ruby/object:Gem::Dependency
54
- name: rspec
55
- prerelease: false
38
+ name: yard
56
39
  requirement: &id003 !ruby/object:Gem::Requirement
57
40
  none: false
58
41
  requirements:
59
42
  - - ">="
60
43
  - !ruby/object:Gem::Version
61
- hash: 13
62
- segments:
63
- - 1
64
- - 2
65
- - 9
66
- version: 1.2.9
44
+ version: "0"
67
45
  type: :development
46
+ prerelease: false
68
47
  version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 1.2.9
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *id004
69
59
  - !ruby/object:Gem::Dependency
70
60
  name: yard
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ type: :development
71
68
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: mongo
72
+ requirement: &id006 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 1.0.1
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: rack
83
+ requirement: &id007 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.1.0
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: *id007
92
+ - !ruby/object:Gem::Dependency
93
+ name: rspec
94
+ requirement: &id008 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 1.2.9
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *id008
103
+ - !ruby/object:Gem::Dependency
104
+ name: yard
105
+ requirement: &id009 !ruby/object:Gem::Requirement
73
106
  none: false
74
107
  requirements:
75
108
  - - ">="
76
109
  - !ruby/object:Gem::Version
77
- hash: 3
78
- segments:
79
- - 0
80
110
  version: "0"
81
111
  type: :development
82
- version_requirements: *id004
112
+ prerelease: false
113
+ version_requirements: *id009
83
114
  description:
84
115
  email: jonathan@titanous.com
85
116
  executables: []
@@ -91,7 +122,6 @@ extra_rdoc_files:
91
122
  - README.rdoc
92
123
  files:
93
124
  - .document
94
- - .gitignore
95
125
  - Gemfile
96
126
  - Gemfile.lock
97
127
  - LICENSE
@@ -104,13 +134,12 @@ files:
104
134
  - spec/rack-mongo-store_spec.rb
105
135
  - spec/spec.opts
106
136
  - spec/spec_helper.rb
107
- has_rdoc: true
108
137
  homepage: http://github.com/titanous/mongo-store
109
138
  licenses: []
110
139
 
111
140
  post_install_message:
112
- rdoc_options:
113
- - --charset=UTF-8
141
+ rdoc_options: []
142
+
114
143
  require_paths:
115
144
  - lib
116
145
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -118,23 +147,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
147
  requirements:
119
148
  - - ">="
120
149
  - !ruby/object:Gem::Version
121
- hash: 3
122
- segments:
123
- - 0
124
150
  version: "0"
125
151
  required_rubygems_version: !ruby/object:Gem::Requirement
126
152
  none: false
127
153
  requirements:
128
154
  - - ">="
129
155
  - !ruby/object:Gem::Version
130
- hash: 3
131
- segments:
132
- - 0
133
156
  version: "0"
134
157
  requirements: []
135
158
 
136
159
  rubyforge_project:
137
- rubygems_version: 1.3.7
160
+ rubygems_version: 1.7.2
138
161
  signing_key:
139
162
  specification_version: 3
140
163
  summary: Rack session store for MongoDB
data/.gitignore DELETED
@@ -1,23 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- doc
19
- .yardoc
20
- pkg
21
-
22
- ## PROJECT::SPECIFIC
23
- .bundle