]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/plugins/sql_session_store/lib/sql_session_store.rb
Fix some broken tests
[rails.git] / vendor / plugins / sql_session_store / lib / sql_session_store.rb
index 8b0ff156f2473dc82c6f3e391f58baea510e911f..0a5fab7f0e7af29ab6a205e35cfeaae2c5a876bd 100755 (executable)
@@ -1,47 +1,98 @@
-require 'active_record'
-require 'cgi'
-require 'cgi/session'
-begin
-  require 'base64'
-rescue LoadError
-end
+require 'base64'
 
 # +SqlSessionStore+ is a stripped down, optimized for speed version of
 # class +ActiveRecordStore+.
 
-class SqlSessionStore
+# Hack for older versions of Rails
+unless defined?(ActionController::Session::AbstractStore)
+  module ActionController
+    module Session
+      class AbstractStore
+      end
+    end
+  end
+end
+
+class SqlSessionStore < ActionController::Session::AbstractStore
 
   # The class to be used for creating, retrieving and updating sessions.
-  # Defaults to SqlSessionStore::Session, which is derived from +ActiveRecord::Base+.
+  # Defaults to SqlSessionStore::SqlSession, which is derived from +ActiveRecord::Base+.
   #
   # In order to achieve acceptable performance you should implement
   # your own session class, similar to the one provided for Myqsl.
   #
   # Only functions +find_session+, +create_session+,
-  # +update_session+ and +destroy+ are required. See file +mysql_session.rb+.
-
+  # +update_session+ and +destroy+ are required. The best implementations
+  # are +postgresql_session.rb+ and +oracle_session.rb+.
   cattr_accessor :session_class
-  @@session_class = SqlSession
+  self.session_class = SqlSession
+
+  # Rack-ism for Rails 2.3.0
+  SESSION_RECORD_KEY = 'rack.session.record'.freeze
+
+  # Backwards-compat indicators (booleans for speed)
+  cattr_accessor :use_rack_session, :use_cgi_session
+  self.use_rack_session = false
+  self.use_cgi_session  = false
+
+  # For Rack compatibility (Rails 2.3.0+)
+  def get_session(env, sid)
+    sid ||= generate_sid
+    #puts "get_session(#{sid})"
+    session = find_or_create_session(sid)
+    env[SESSION_RECORD_KEY] = session
+    [sid, session.data]
+  end
 
-  # Create a new SqlSessionStore instance.
-  #
-  # +session+ is the session for which this instance is being created.
-  #
-  # +option+ is currently ignored as no options are recognized.
+  # For Rack compatibility (Rails 2.3.0+)
+  def set_session(env, sid, session_data)
+    #puts "set_session(#{sid})"
+    session = env[SESSION_RECORD_KEY]
+    session.update_session(session_data)
+    return true # indicate ok to Rack
+  end
 
-  def initialize(session, option=nil)
-    if @session = @@session_class.find_session(session.session_id)
-      @data = unmarshalize(@session.data)
+  # Create a new SqlSessionStore instance. This method hooks into
+  # the find/create methods of a given driver class.
+  #
+  # +session_id+ is the session ID for which this instance is being created.
+  def find_or_create_session(session_id)
+    if @session = session_class.find_session(session_id)
+      @data = @session.data
     else
-      @session = @@session_class.create_session(session.session_id, marshalize({}))
+      @session = session_class.create_session(session_id)
       @data = {}
     end
+    @session
+  end
+
+  # Below here is for pre-Rails 2.3.0 and not used in Rack-based servers
+  # The CGI::Session methods are a bit odd in that half are class and half
+  # are instance-based methods
+  # Note that +option+ is currently ignored as no options are recognized.
+  def initialize(session, options={})
+    # This is just some optimization since this is called over and over and over
+    if self.use_rack_session
+      super # MUST call super for Rack sessions
+      return true
+    elsif self.use_cgi_session
+      find_or_create_session(session.session_id)
+    else
+      version ||= Rails.version.split('.')
+      if version[0].to_i == 2 && version[1].to_i < 3
+        find_or_create_session(session.session_id)
+        self.use_cgi_session = true
+      else
+        super # MUST call super for Rack sessions
+        self.use_rack_session = true
+      end
+    end
   end
 
   # Update the database and disassociate the session object
   def close
     if @session
-      @session.update_session(marshalize(@data))
+      @session.update_session(@data)
       @session = nil
     end
   end
@@ -57,43 +108,33 @@ class SqlSessionStore
   # Restore session data from the session object
   def restore
     if @session
-      @data = unmarshalize(@session.data)
+      @data = @session.data
     end
   end
 
   # Save session data in the session object
   def update
     if @session
-      @session.update_session(marshalize(@data))
+      @session.update_session(@data)
     end
   end
-
-  private
-  if defined?(Base64)
-    def unmarshalize(data)
-      Marshal.load(Base64.decode64(data))
-    end
-
-    def marshalize(data)
-      Base64.encode64(Marshal.dump(data))
-    end
-  else
-    def unmarshalize(data)
-      Marshal.load(data.unpack("m").first)
-    end
-
-    def marshalize(data)
-      [Marshal.dump(data)].pack("m")
-    end
+  
+  def id
+    @session.id
   end
-
 end
 
+class CGI::Session
+  def id
+    @dbman.id
+  end
+end
 __END__
 
 # This software is released under the MIT license
 #
-# Copyright (c) 2005-2008 Stefan Kaes
+# Copyright (c) 2008, 2009 Nate Wiger
+# Copyright (c) 2005, 2006 Stefan Kaes
 
 # Permission is hereby granted, free of charge, to any person obtaining
 # a copy of this software and associated documentation files (the