Class | ActiveRecord::SessionStore::SqlBypass |
In: |
vendor/rails/activerecord/lib/active_record/session_store.rb
|
Parent: | Object |
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. Marshaling and unmarshaling are implemented as class methods that you may override. By default, marshaling data is
ActiveSupport::Base64.encode64(Marshal.dump(data))
and unmarshaling data is
Marshal.load(ActiveSupport::Base64.decode64(data))
This marshaling 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.
data | [W] | |
session_id | [R] |
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 182 182: def connection 183: @@connection ||= ActiveRecord::Base.connection 184: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 201 201: def create_table! 202: @@connection.execute "CREATE TABLE \#{table_name} (\nid INTEGER PRIMARY KEY,\n\#{@@connection.quote_column_name(session_id_column)} TEXT UNIQUE,\n\#{@@connection.quote_column_name(data_column)} TEXT\n)\n" 203: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 212 212: def drop_table! 213: @@connection.execute "DROP TABLE #{table_name}" 214: end
Look up a session by id and unmarshal its data if found.
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 187 187: def find_by_session_id(session_id) 188: if record = @@connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{@@connection.quote(session_id)}") 189: new(:session_id => session_id, :marshaled_data => record['data']) 190: end 191: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 193 193: def marshal(data) 194: ActiveSupport::Base64.encode64(Marshal.dump(data)) if data 195: end
Look for normal and marshaled data, self.find_by_session_id‘s way of telling us to postpone unmarshaling until the data is requested. We need to handle a normal data attribute in case of a new record.
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 223 223: def initialize(attributes) 224: @session_id, @data, @marshaled_data = attributes[:session_id], attributes[:data], attributes[:marshaled_data] 225: @new_record = @marshaled_data.nil? 226: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 197 197: def unmarshal(data) 198: Marshal.load(ActiveSupport::Base64.decode64(data)) if data 199: end
Lazy-unmarshal session state.
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 233 233: def data 234: unless @data 235: if @marshaled_data 236: @data, @marshaled_data = self.class.unmarshal(@marshaled_data) || {}, nil 237: else 238: @data = {} 239: end 240: end 241: @data 242: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 273 273: def destroy 274: unless @new_record 275: @@connection.delete "DELETE FROM \#{@@table_name}\nWHERE \#{@@connection.quote_column_name(@@session_id_column)}=\#{@@connection.quote(session_id)}\n", 'Destroy session' 276: end 277: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 244 244: def loaded? 245: !!@data 246: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 228 228: def new_record? 229: @new_record 230: end
# File vendor/rails/activerecord/lib/active_record/session_store.rb, line 248 248: def save 249: return false if !loaded? 250: marshaled_data = self.class.marshal(data) 251: 252: if @new_record 253: @new_record = false 254: @@connection.update "INSERT INTO \#{@@table_name} (\n\#{@@connection.quote_column_name(@@session_id_column)},\n\#{@@connection.quote_column_name(@@data_column)} )\nVALUES (\n\#{@@connection.quote(session_id)},\n\#{@@connection.quote(marshaled_data)} )\n", 'Create session' 255: else 256: @@connection.update "UPDATE \#{@@table_name}\nSET \#{@@connection.quote_column_name(@@data_column)}=\#{@@connection.quote(marshaled_data)}\nWHERE \#{@@connection.quote_column_name(@@session_id_column)}=\#{@@connection.quote(session_id)}\n", 'Update session' 257: end 258: end