Class: ActiveRecord::SessionStore::SqlBypass
- Inherits:
-
Object
- Object
- ActiveRecord::SessionStore::SqlBypass
- Extended by:
- ClassMethods
- Defined in:
- lib/active_record/session_store/sql_bypass.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. 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.
Constant Summary collapse
- @@table_name =
'sessions'- @@session_id_column =
'session_id'- @@data_column =
'data'
Class Attribute Summary collapse
Instance Attribute Summary collapse
-
#new_record ⇒ Object
(also: #new_record?)
readonly
Returns the value of attribute new_record.
-
#session_id ⇒ Object
Returns the value of attribute session_id.
Class Method Summary collapse
-
.find_by_session_id(session_id) ⇒ Object
Look up a session by id and deserialize its data if found.
Instance Method Summary collapse
- #changed? ⇒ Boolean
-
#data ⇒ Object
Lazy-deserialize session state.
- #data=(data) ⇒ Object
-
#data_column ⇒ Object
:singleton-method: The data field defaults to 'data'.
- #destroy ⇒ Object
-
#initialize(attributes) ⇒ SqlBypass
constructor
Look for normal and serialized data, self.find_by_session_id's way of telling us to postpone deserializing until the data is requested.
- #loaded? ⇒ Boolean
-
#persisted? ⇒ Boolean
Returns true if the record is persisted, i.e.
- #save ⇒ Object
-
#session_id_column ⇒ Object
:singleton-method: The session id field defaults to 'session_id'.
-
#table_name ⇒ Object
:singleton-method: The table name defaults to 'sessions'.
Methods included from ClassMethods
create_table!, deserialize, drop_table!, serialize, serializer_class
Constructor Details
#initialize(attributes) ⇒ SqlBypass
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.
78 79 80 81 82 83 84 85 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 78 def initialize(attributes) @session_id = attributes[:session_id] @retrieved_by = attributes[:retrieved_by] @data = attributes[:data] @serialized_data = attributes[:serialized_data] @new_record = @serialized_data.nil? @data_changed = false end |
Class Attribute Details
.connection ⇒ Object
53 54 55 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 53 def connection @connection ||= ActiveRecord::Base.connection end |
.connection_pool ⇒ Object
57 58 59 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 57 def connection_pool @connection_pool ||= ActiveRecord::Base.connection_pool end |
Instance Attribute Details
#new_record ⇒ Object (readonly) Also known as: new_record?
Returns the value of attribute new_record.
71 72 73 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 71 def new_record @new_record end |
#session_id ⇒ Object
Returns the value of attribute session_id.
72 73 74 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 72 def session_id @session_id end |
Class Method Details
.find_by_session_id(session_id) ⇒ Object
Look up a session by id and deserialize its data if found.
62 63 64 65 66 |
# 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)}") new(:session_id => session_id, :retrieved_by => session_id, :serialized_data => record['data']) end end |
Instance Method Details
#changed? ⇒ Boolean
113 114 115 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 113 def changed? persisted? && (@retrieved_by != session_id || @data_changed) end |
#data ⇒ Object
Lazy-deserialize session state.
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 93 def data unless @data if @serialized_data @data, @serialized_data = self.class.deserialize(@serialized_data) || {}, nil else @data = {} end end @data end |
#data=(data) ⇒ Object
108 109 110 111 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 108 def data=(data) @data_changed = true if data != self.data @data = data end |
#data_column ⇒ Object
:singleton-method: The data field defaults to 'data'.
41 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 41 cattr_accessor :data_column |
#destroy ⇒ Object
147 148 149 150 151 152 153 154 155 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 147 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)} end_sql end |
#loaded? ⇒ Boolean
104 105 106 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 104 def loaded? @data end |
#persisted? ⇒ Boolean
Returns true if the record is persisted, i.e. it's not a new record
88 89 90 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 88 def persisted? !@new_record end |
#save ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 117 def save return false unless loaded? serialized_data = self.class.serialize(data) connect = connection if @new_record @new_record = false result = 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 result = connect.update <<-end_sql, 'Update session' UPDATE #{table_name} SET #{connect.quote_column_name(data_column)}=#{connect.quote(serialized_data)}, #{connect.quote_column_name(session_id_column)}=#{connect.quote(@session_id)} WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(@retrieved_by)} end_sql end @retrieved_by = @session_id @data_changed = false result end |
#session_id_column ⇒ Object
:singleton-method: The session id field defaults to 'session_id'.
35 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 35 cattr_accessor :session_id_column |
#table_name ⇒ Object
:singleton-method: The table name defaults to 'sessions'.
29 |
# File 'lib/active_record/session_store/sql_bypass.rb', line 29 cattr_accessor :table_name |