Class: CGI::Session::ActiveRecordStore::SqlBypass
- Defined in:
- lib/action_controller/session/active_record_store.rb
Overview
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.
Constant Summary collapse
- @@table_name =
'sessions'
- @@session_id_column =
'session_id'
- @@data_column =
'data'
Instance Attribute Summary collapse
-
#data ⇒ Object
Lazy-unmarshal session state.
-
#session_id ⇒ Object
readonly
Returns the value of attribute session_id.
Class Method Summary collapse
- .connection ⇒ Object
- .create_table! ⇒ Object
- .drop_table! ⇒ Object
-
.find_by_session_id(session_id) ⇒ Object
Look up a session by id and unmarshal its data if found.
- .marshal(data) ⇒ Object
- .unmarshal(data) ⇒ Object
Instance Method Summary collapse
- #destroy ⇒ Object
-
#initialize(attributes) ⇒ SqlBypass
constructor
Look for normal and marshaled data, self.find_by_session_id’s way of telling us to postpone unmarshaling until the data is requested.
- #loaded? ⇒ Boolean
- #new_record? ⇒ Boolean
- #save ⇒ Object
Constructor Details
#initialize(attributes) ⇒ SqlBypass
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.
221 222 223 224 |
# File 'lib/action_controller/session/active_record_store.rb', line 221 def initialize(attributes) @session_id, @data, @marshaled_data = attributes[:session_id], attributes[:data], attributes[:marshaled_data] @new_record = @marshaled_data.nil? end |
Instance Attribute Details
#data ⇒ Object
Lazy-unmarshal session state.
231 232 233 234 235 236 237 238 239 240 |
# File 'lib/action_controller/session/active_record_store.rb', line 231 def data unless @data if @marshaled_data @data, @marshaled_data = self.class.unmarshal(@marshaled_data) || {}, nil else @data = {} end end @data end |
#session_id ⇒ Object (readonly)
Returns the value of attribute session_id.
215 216 217 |
# File 'lib/action_controller/session/active_record_store.rb', line 215 def session_id @session_id end |
Class Method Details
.connection ⇒ Object
186 187 188 |
# File 'lib/action_controller/session/active_record_store.rb', line 186 def connection @@connection ||= ActiveRecord::Base.connection end |
.create_table! ⇒ Object
200 201 202 203 204 205 206 207 208 |
# File 'lib/action_controller/session/active_record_store.rb', line 200 def create_table! @@connection.execute <<-end_sql CREATE TABLE #{table_name} ( id INTEGER PRIMARY KEY, #{@@connection.quote_column_name(session_id_column)} TEXT UNIQUE, #{@@connection.quote_column_name(data_column)} TEXT ) end_sql end |
.drop_table! ⇒ Object
210 211 212 |
# File 'lib/action_controller/session/active_record_store.rb', line 210 def drop_table! @@connection.execute "DROP TABLE #{table_name}" end |
.find_by_session_id(session_id) ⇒ Object
Look up a session by id and unmarshal its data if found.
191 192 193 194 195 |
# File 'lib/action_controller/session/active_record_store.rb', line 191 def find_by_session_id(session_id) if record = @@connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{@@connection.quote(session_id)}") new(:session_id => session_id, :marshaled_data => record['data']) end end |
.marshal(data) ⇒ Object
197 |
# File 'lib/action_controller/session/active_record_store.rb', line 197 def marshal(data) ActiveSupport::Base64.encode64(Marshal.dump(data)) if data end |
.unmarshal(data) ⇒ Object
198 |
# File 'lib/action_controller/session/active_record_store.rb', line 198 def unmarshal(data) Marshal.load(ActiveSupport::Base64.decode64(data)) if data end |
Instance Method Details
#destroy ⇒ Object
269 270 271 272 273 274 275 276 |
# File 'lib/action_controller/session/active_record_store.rb', line 269 def destroy unless @new_record @@connection.delete <<-end_sql, 'Destroy session' DELETE FROM #{@@table_name} WHERE #{@@connection.quote_column_name(@@session_id_column)}=#{@@connection.quote(session_id)} end_sql end end |
#loaded? ⇒ Boolean
242 243 244 |
# File 'lib/action_controller/session/active_record_store.rb', line 242 def loaded? !! @data end |
#new_record? ⇒ Boolean
226 227 228 |
# File 'lib/action_controller/session/active_record_store.rb', line 226 def new_record? @new_record end |
#save ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/action_controller/session/active_record_store.rb', line 246 def save return false if !loaded? marshaled_data = self.class.marshal(data) if @new_record @new_record = false @@connection.update <<-end_sql, 'Create session' INSERT INTO #{@@table_name} ( #{@@connection.quote_column_name(@@session_id_column)}, #{@@connection.quote_column_name(@@data_column)} ) VALUES ( #{@@connection.quote(session_id)}, #{@@connection.quote(marshaled_data)} ) end_sql else @@connection.update <<-end_sql, 'Update session' UPDATE #{@@table_name} SET #{@@connection.quote_column_name(@@data_column)}=#{@@connection.quote(marshaled_data)} WHERE #{@@connection.quote_column_name(@@session_id_column)}=#{@@connection.quote(session_id)} end_sql end end |