From 19e8b42a56536e0621097c337546557565579c57 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 6 Mar 2005 23:34:03 +0000 Subject: Changed ActiveRecordStore to use Marshal instead of YAML as the latter proved troublesome in persisting circular dependencies. Updating existing applications MUST clear their existing session table from data to start using this updated store #739 [Jamis Buck] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@866 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../session/active_record_store.rb | 33 +++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'actionpack/lib/action_controller/session/active_record_store.rb') diff --git a/actionpack/lib/action_controller/session/active_record_store.rb b/actionpack/lib/action_controller/session/active_record_store.rb index 9e0db037d0..6238b8cbee 100644 --- a/actionpack/lib/action_controller/session/active_record_store.rb +++ b/actionpack/lib/action_controller/session/active_record_store.rb @@ -3,21 +3,25 @@ begin require 'active_record' require 'cgi' require 'cgi/session' +require 'base64' # Contributed by Tim Bates class CGI class Session - # ActiveRecord database based session storage class. + # Active Record database-based session storage class. # # Implements session storage in a database using the ActiveRecord ORM library. Assumes that the database # has a table called +sessions+ with columns +id+ (numeric, primary key), +sessid+ and +data+ (text). - # The session data is stored in the +data+ column in YAML format; the user is responsible for ensuring that - # only data that can be YAMLized is stored in the session. + # The session data is stored in the +data+ column in the binary Marshal format; the user is responsible for ensuring that + # only data that can be Marshaled is stored in the session. + # + # Adding +created_at+ or +updated_at+ datetime columns to the sessions table will enable stamping of the data, which can + # be used to clear out old sessions. + # + # It's highly recommended to have an index on the sessid column to improve performance. class ActiveRecordStore # The ActiveRecord class which corresponds to the database table. class Session < ActiveRecord::Base - serialize :data - # Isn't this class definition beautiful? end # Create a new ActiveRecordStore instance. This constructor is used internally by CGI::Session. @@ -30,8 +34,8 @@ class CGI # This session's ActiveRecord database row will be created if it does not exist, or opened if it does. def initialize(session, option=nil) ActiveRecord::Base.silence do - @session = Session.find_by_sessid(session.session_id) || Session.new("sessid" => session.session_id, "data" => {}) - @data = @session.data + @session = Session.find_by_sessid(session.session_id) || Session.new("sessid" => session.session_id, "data" => marshalize({})) + @data = unmarshalize(@session.data) end end @@ -52,18 +56,27 @@ class CGI # Restore session state from the session's ActiveRecord object. def restore return unless @session - @data = @session.data + @data = unmarshalize(@session.data) end # Save session state in the session's ActiveRecord object. def update return unless @session - ActiveRecord::Base.silence { @session.update_attribute "data", @data } + ActiveRecord::Base.silence { @session.update_attribute "data", marshalize(@data) } end + + private + def unmarshalize(data) + Marshal.load(Base64.decode64(data)) + end + + def marshalize(data) + Base64.encode64(Marshal.dump(data)) + end end #ActiveRecordStore end #Session end #CGI rescue LoadError # Couldn't load Active Record, so don't make this store available -end \ No newline at end of file +end -- cgit v1.2.3