Class: Arrow::Session::Store
- Extended by:
- Forwardable
- Includes:
- PluginFactory
- Defined in:
- lib/arrow/session/store.rb
Overview
The Arrow::Session::Store class, a derivative of Arrow::Object. Instances of concrete deriviatives of this class provide serialization and semi-permanent storage of session data for Arrow::Session objects.
Derivative Interface ===
In order to create your own session store classes, you need to provide four methods: #insert, #update, #retrieve, #remove. All but one of the methods provides serialization and marking records as dirty in the base class, so unless you want to manage these tasks yourself, you should super() to the parent’s implementation with a block. Examples are provided for each method.
- #insert
-
Insert a new session into the backing store. Example:
def insert super {|data| @io.print(data) } end
- #update
-
Update an existing session’s data in the backing store. Example:
def update super {|data| @io.rewind; @io.truncate(0); @io.print(data) } end
- #retrieve
-
Retrieve the serialized session data from the backing store. Example:
def retrieve super { @io.rewind; @io.read } end
- #delete
-
Delete the session from the backing store. Example:
def delete super {|data| @io.close; File.delete(@session_file) } end
Optional Derivative Interface ===
Serialization ====
If you want to use something other than Marshal for object serialization, you can override the protected methods #serialized_data and #serialized_data= to provide your own serialization.
- #serialized_data
-
Serialize the data in the instance variable @data and return it.
- #serialized_data=( serialized )
-
Deserialize the given
serialized
data and assign it to @data.
Example (serializing to YAML instead of binary):
require 'yaml'
def serialized_data
@data.to_yaml
end
def serialized_data=( data )
@data = YAML.load( data )
end
Lock Recommendation ====
If arrow is configured to use the ‘recommended’ session lock, your session store can recommend one it knows will work (e.g., if your session store is a database, you can recommend a lock that uses database locking). The simple way to do that is to define a RecommendedLocker constant in your class which contains the URI of the locker you wish to use. If you need more control than the URI can provide, you can also override the #create_recommended_lock method, which should return an instance of the locker that should be used.
The method will be given the instantiated Arrow::Session::Id object that identifies the session so that you can derive a filename, primary key, etc.
Example:
def create_recommended_lock( idobj )
return DBITransactionLock.new( idobj.to_s )
end
Authors
-
Michael Granger <[email protected]>
Please see the file LICENSE in the top-level directory for licensing details.
Direct Known Subclasses
Constant Summary collapse
- RecommendedLocker =
The URI of the lock class recommended for use with this Store.
URI.parse( 'file:.' )
- DelegatedMethods =
The methods which are delegate directly to the data hash.
[ :[], :default, :default=, :each, :each_key, :each_pair, :each_value, :empty?, :fetch, :has_key?, :has_value?, :include?, :index, :invert, :keys, :length, :member?, :merge, :rehash, :reject, :select, :size, :sort, :to_a, :value?, :values ]
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
The raw session data hash.
Class Method Summary collapse
-
.create(uri, idobj) ⇒ Object
Overridden factory method: handle a URI object or a name.
-
.derivativeDirs ⇒ Object
Returns the Array of directories to search for derivatives; part of the PluginFactory interface.
Instance Method Summary collapse
-
#[]=(key, value) ⇒ Object
(also: #store)
Set the
value
for the specifiedkey
. -
#clear ⇒ Object
Clear all key/value pairs from the store for this session.
-
#create_recommended_lock(idobj) ⇒ Object
Returns an instance of the recommended lock object for the receiving store.
-
#delete(key, &block) ⇒ Object
Deletes and returns a key-value pair from the receiver whose key is equal to
key
. -
#initialize(uri, idobj) ⇒ Store
constructor
Create a new Arrow::Session::Store object.
-
#insert {|self.serialized_data| ... } ⇒ Object
Insert the current
data
hash into whatever permanent storage the Store object is acting as an interface to. -
#merge!(other, &block) ⇒ Object
(also: #update)
Adds the contents of the
other
hash to the session data, overwriting entries in the session data with values from theother
hash where there are duplicates. -
#modified? ⇒ Boolean
Returns
true
if the receiver’s data is out of sync with the data in the backing store. -
#new? ⇒ Boolean
Returns
true
if the data in the receiver has not yet been saved to the backing store, or if the entry in the backing store has been deleted since it was last saved. -
#reject!(&block) ⇒ Object
(also: #delete_if)
Deletes every key-value pair from the session data for which the
block
evaluates to true. -
#remove ⇒ Object
Permanently remove the data hash associated with the id used in the receiver’s creation from permanent storage.
-
#replace(other) ⇒ Object
Replace the contents of the session hash with those of the given
other
hash. -
#retrieve ⇒ Object
Retrieve the data hash stored in permanent storage associated with the id the object was created with.
-
#save ⇒ Object
Save the session data to the backing store.
Methods inherited from Object
deprecate_class_method, deprecate_method, inherited
Constructor Details
#initialize(uri, idobj) ⇒ Store
Create a new Arrow::Session::Store object.
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/arrow/session/store.rb', line 135 def initialize( uri, idobj ) @data = {} @id = idobj @new = true @modified = false unless idobj.new? self.retrieve end super() end |
Instance Attribute Details
#data ⇒ Object (readonly)
The raw session data hash
158 159 160 |
# File 'lib/arrow/session/store.rb', line 158 def data @data end |
Class Method Details
.create(uri, idobj) ⇒ Object
Overridden factory method: handle a URI object or a name
123 124 125 126 |
# File 'lib/arrow/session/store.rb', line 123 def self::create( uri, idobj ) uri = Arrow::Session.parse_uri( uri ) if uri.is_a?( String ) super( uri.scheme.dup, uri, idobj ) end |
.derivativeDirs ⇒ Object
Returns the Array of directories to search for derivatives; part of the PluginFactory interface.
117 118 119 |
# File 'lib/arrow/session/store.rb', line 117 def self::derivativeDirs [ 'arrow/session', 'arrow/session/store' ] end |
Instance Method Details
#[]=(key, value) ⇒ Object Also known as: store
Set the value
for the specified key
.
162 163 164 165 |
# File 'lib/arrow/session/store.rb', line 162 def []=( key, value ) @data[ key ] = value @modified = true end |
#clear ⇒ Object
Clear all key/value pairs from the store for this session.
183 184 185 186 |
# File 'lib/arrow/session/store.rb', line 183 def clear @data.clear @modified = true end |
#create_recommended_lock(idobj) ⇒ Object
Returns an instance of the recommended lock object for the receiving store. If no recommended locking strategy is known, this method raises a SessionError.
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/arrow/session/store.rb', line 294 def create_recommended_lock( idobj ) self.log.debug "Searching for recommended lock for %s" % self.class.name # Traverse the class hierarchy to find a class which defines a # RecommendedLocker constant adviceClass = self.class.ancestors.find {|klass| klass.const_defined?( :RecommendedLocker ) } or raise SessionError, "No recommended locker for %p" % self.class.ancestors uri = adviceClass.const_get( :RecommendedLocker ) or raise SessionError, "Could not fetch RecommendedLocker constant" self.log.debug "Creating recommended lock %s" % uri uri = Arrow::Session.parse_uri( uri ) if uri.is_a?( String ) lock = Arrow::Session::Lock.create( uri, idobj ) self.log.debug "Created recommended lock object: %p" % lock return lock end |
#delete(key, &block) ⇒ Object
Deletes and returns a key-value pair from the receiver whose key is equal to key
. If the key
is not found, returns the default value. If the optional code-block is given and the key is not found, the block is called with the key, and the return value is used as the result of the method.
174 175 176 177 178 179 |
# File 'lib/arrow/session/store.rb', line 174 def delete( key, &block ) rval = @data.delete( key, &block ) return rval ensure @modified = true if rval != @data.default end |
#insert {|self.serialized_data| ... } ⇒ Object
Insert the current data
hash into whatever permanent storage the Store object is acting as an interface to. Concrete implementations should provide an overriding implementation of this method that calls #super with a block which will be called with the serialized data that should be stored.
253 254 255 256 257 |
# File 'lib/arrow/session/store.rb', line 253 def insert self.log.debug "Inserting session data for key %s" % @id yield( self.serialized_data ) @new = @modified = false end |
#merge!(other, &block) ⇒ Object Also known as: update
Adds the contents of the other
hash to the session data, overwriting entries in the session data with values from the other
hash where there are duplicates. If a block
is given, it is called for each duplicate key, and the return value is the value set in the hash.
194 195 196 197 198 |
# File 'lib/arrow/session/store.rb', line 194 def merge!( other, &block ) # :yields: key, sessionValue, otherValue @data.merge!( other, &block ) ensure @modified = true end |
#modified? ⇒ Boolean
Returns true
if the receiver’s data is out of sync with the data in the backing store.
224 225 226 |
# File 'lib/arrow/session/store.rb', line 224 def modified? @modified end |
#new? ⇒ Boolean
Returns true
if the data in the receiver has not yet been saved to the backing store, or if the entry in the backing store has been deleted since it was last saved.
232 233 234 |
# File 'lib/arrow/session/store.rb', line 232 def new? @new end |
#reject!(&block) ⇒ Object Also known as: delete_if
Deletes every key-value pair from the session data for which the block
evaluates to true.
213 214 215 216 217 218 |
# File 'lib/arrow/session/store.rb', line 213 def reject!( &block ) # :yields: key, value rval = @data.reject!( &block ) return rval ensure @modified = true if rval end |
#remove ⇒ Object
Permanently remove the data hash associated with the id used in the receiver’s creation from permanent storage.
285 286 287 288 |
# File 'lib/arrow/session/store.rb', line 285 def remove self.log.debug "Removing session data for key %s" % @id @new = true end |
#replace(other) ⇒ Object
Replace the contents of the session hash with those of the given other
hash.
204 205 206 207 208 |
# File 'lib/arrow/session/store.rb', line 204 def replace( other ) @data.replace( other ) ensure @modified = true end |
#retrieve ⇒ Object
Retrieve the data hash stored in permanent storage associated with the id the object was created with. Concrete implementations should provide an overriding implementation of this method that calls #super with a block that returns the serialized data to be restored.
276 277 278 279 280 |
# File 'lib/arrow/session/store.rb', line 276 def retrieve self.log.debug "Retrieving session data for key %s" % @id self.serialized_data = yield @new = @modified = false end |
#save ⇒ Object
Save the session data to the backing store
238 239 240 241 242 243 244 245 |
# File 'lib/arrow/session/store.rb', line 238 def save return false unless self.modified? || self.new? if self.new? self.insert else self.update end end |