class ActiveRecord::SessionStore::SqlBypass
A barebones session store which duck-types with the default session store but bypasses Active Record and issues SQL directly. This is an example session model class meant as a basis for your own classes.
The database connection, table name, and session id and data columns are configurable class attributes. Serializing and deserializeing are implemented as class methods that you may override. By default, serializing data is
::Base64.encode64(Marshal.dump(data))
and deserializing data is
Marshal.load(::Base64.decode64(data))
This serializing behavior is intended to store the widest range of binary
session data in a text
column. For higher performance, store
in a blob
column instead and forgo the Base64 encoding.
Attributes
Use the ActiveRecord::Base.connection by default.
Use the ActiveRecord::Base.connection_pool by default.
Public Class Methods
# File lib/active_record/session_store/sql_bypass.rb, line 53 def connection @connection ||= ActiveRecord::Base.connection end
# File lib/active_record/session_store/sql_bypass.rb, line 57 def connection_pool @connection_pool ||= ActiveRecord::Base.connection_pool end
The data field defaults to 'data'.
# File lib/active_record/session_store/sql_bypass.rb, line 41 cattr_accessor :data_column
Look up a session by id and deserialize its data if found.
# File lib/active_record/session_store/sql_bypass.rb, line 62 def find_by_session_id(session_id) if record = connection.select_one("SELECT #{connection.quote_column_name(data_column)} AS data FROM #{@@table_name} WHERE #{connection.quote_column_name(@@session_id_column)}=#{connection.quote(session_id.to_s)}") new(:session_id => session_id, :serialized_data => record['data']) end end
Look for normal and serialized data, self.find_by_session_id's way of telling us to postpone deserializing until the data is requested. We need to handle a normal data attribute in case of a new record.
# File lib/active_record/session_store/sql_bypass.rb, line 79 def initialize(attributes) @session_id = attributes[:session_id] @data = attributes[:data] @serialized_data = attributes[:serialized_data] @new_record = @serialized_data.nil? end
The session id field defaults to 'session_id'.
# File lib/active_record/session_store/sql_bypass.rb, line 35 cattr_accessor :session_id_column
The table name defaults to 'sessions'.
# File lib/active_record/session_store/sql_bypass.rb, line 29 cattr_accessor :table_name
Public Instance Methods
Lazy-deserialize session state.
# File lib/active_record/session_store/sql_bypass.rb, line 92 def data unless @data if @serialized_data @data, @serialized_data = self.class.deserialize(@serialized_data) || {}, nil else @data = {} end end @data end
# File lib/active_record/session_store/sql_bypass.rb, line 131 def destroy return if @new_record connect = connection connect.delete <<-end_sql, 'Destroy session' DELETE FROM #{table_name} WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id.to_s)} end_sql end
# File lib/active_record/session_store/sql_bypass.rb, line 103 def loaded? @data end
Returns true if the record is persisted, i.e. it's not a new record
# File lib/active_record/session_store/sql_bypass.rb, line 87 def persisted? !@new_record end
# File lib/active_record/session_store/sql_bypass.rb, line 107 def save return false unless loaded? serialized_data = self.class.serialize(data) connect = connection if @new_record @new_record = false connect.update <<-end_sql, 'Create session' INSERT INTO #{table_name} ( #{connect.quote_column_name(session_id_column)}, #{connect.quote_column_name(data_column)} ) VALUES ( #{connect.quote(session_id)}, #{connect.quote(serialized_data)} ) end_sql else connect.update <<-end_sql, 'Update session' UPDATE #{table_name} SET #{connect.quote_column_name(data_column)}=#{connect.quote(serialized_data)} WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)} end_sql end end