Skip to content
Browse files

session hash imported

  • Loading branch information...
1 parent c2807fb commit 385afd47dab645f97b79c25419ec5e1f5b52babe @tenderlove tenderlove committed May 2, 2012
Showing with 111 additions and 15 deletions.
  1. +111 −15 actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
View
126 actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -73,26 +73,17 @@ class AbstractStore < Rack::Session::Abstract::ID
private
- module DestroyableSession
- def destroy
- clear
- options = @env[Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY] if @env
- options ||= {}
- @by.send(:destroy_session, @env, options[:id], options) if @by
- options[:id] = nil
- @loaded = false
- end
- end
-
- ::Rack::Session::Abstract::SessionHash.send :include, DestroyableSession
-
def prepare_session(env)
session_was = env[ENV_SESSION_KEY]
- env[ENV_SESSION_KEY] = Rack::Session::Abstract::SessionHash.new(self, env)
+ env[ENV_SESSION_KEY] = Request::Session.new(self, env)
env[ENV_SESSION_OPTIONS_KEY] = Request::Session::Options.new(self, env, @default_options)
env[ENV_SESSION_KEY].merge! session_was if session_was
end
+ def loaded_session?(session)
+ !session.is_a?(Request::Session) || session.loaded?
+ end
+
def set_cookie(env, session_id, cookie)
request = ActionDispatch::Request.new(env)
request.cookie_jar[key] = cookie
@@ -102,7 +93,10 @@ def set_cookie(env, session_id, cookie)
class Request
# SessionHash is responsible to lazily load the session from store.
- class Session
+ class Session < Hash
+ ENV_SESSION_KEY = Rack::Session::Abstract::ENV_SESSION_KEY # :nodoc:
+ ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY # :nodoc:
+
class Options #:nodoc:
def initialize(by, env, default_options)
@by = by
@@ -124,6 +118,108 @@ def []=(k,v); @delegate[k] = v; end
def to_hash; @delegate.dup; end
def values_at(*args); @delegate.values_at(*args); end
end
+
+ def destroy
+ clear
+ options = @env[Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY] if @env
+ options ||= {}
+ @by.send(:destroy_session, @env, options[:id], options) if @by
+ options[:id] = nil
+ @loaded = false
+ end
+
+ def initialize(by, env)
+ super()
+ @by = by
+ @env = env
+ @loaded = false
+ end
+
+ def [](key)
+ load_for_read!
+ super(key.to_s)
+ end
+
+ def has_key?(key)
+ load_for_read!
+ super(key.to_s)
+ end
+ alias :key? :has_key?
+ alias :include? :has_key?
+
+ def []=(key, value)
+ load_for_write!
+ super(key.to_s, value)
+ end
+
+ def clear
+ load_for_write!
+ super
+ end
+
+ def to_hash
+ load_for_read!
+ h = {}.replace(self)
+ h.delete_if { |k,v| v.nil? }
+ h
+ end
+
+ def update(hash)
+ load_for_write!
+ super(stringify_keys(hash))
+ end
+
+ def delete(key)
+ load_for_write!
+ super(key.to_s)
+ end
+
+ def inspect
+ if loaded?
+ super
+ else
+ "#<#{self.class}:0x#{self.object_id.to_s(16)} not yet loaded>"
+ end
+ end
+
+ def exists?
+ return @exists if instance_variable_defined?(:@exists)
+ @exists = @by.send(:session_exists?, @env)
+ end
+
+ def loaded?
+ @loaded
+ end
+
+ def empty?
+ load_for_read!
+ super
+ end
+
+ private
+
+ def load_for_read!
+ load! if !loaded? && exists?
+ end
+
+ def load_for_write!
+ load! unless loaded?
+ end
+
+ def load!
+ id, session = @by.send(:load_session, @env)
+ @env[ENV_SESSION_OPTIONS_KEY][:id] = id
+ replace(stringify_keys(session))
+ @loaded = true
+ end
+
+ def stringify_keys(other)
+ hash = {}
+ other.each do |key, value|
+ hash[key.to_s] = value
+ end
+ hash
+ end
end
end
end

0 comments on commit 385afd4

Please sign in to comment.
Something went wrong with that request. Please try again.