Class: PEROBS::ObjectBase
- Inherits:
-
Object
- Object
- PEROBS::ObjectBase
- Defined in:
- lib/perobs/ObjectBase.rb
Overview
Base class for all persistent objects. It provides the functionality common to all classes of persistent objects.
Constant Summary collapse
- NATIVE_CLASSES =
[ NilClass, Integer, Float, String, Time, TrueClass, FalseClass ]
Instance Attribute Summary collapse
-
#_id ⇒ Object
readonly
Returns the value of attribute _id.
-
#myself ⇒ Object
readonly
Returns the value of attribute myself.
-
#store ⇒ Object
readonly
Returns the value of attribute store.
Class Method Summary collapse
-
._finalize(store, id, ruby_object_id) ⇒ Object
This method generates the destructor for the objects of this class.
-
.read(store, id) ⇒ Object
Read an raw object with the specified ID from the backing store and instantiate a new object of the specific type.
Instance Method Summary collapse
-
#==(obj) ⇒ Object
Two objects are considered equal if their object IDs are the same.
- #_check_assignment_value(val) ⇒ Object
-
#_initialize(p) ⇒ Object
This is the real code for initialize.
-
#_restore(level) ⇒ Object
Restore the object state from the storage back-end.
-
#_stash(level) ⇒ Object
Save the object state for this transaction level to the storage back-end.
-
#_sync ⇒ Object
Write the object into the backing store database.
-
#_transfer(store) ⇒ Object
Library internal method to transfer the Object to a new store.
-
#initialize(p) ⇒ ObjectBase
constructor
New PEROBS objects must always be created by calling # Store.new().
-
#restore ⇒ Object
This method can be overloaded by derived classes to do some massaging on the data after it has been restored from the database.
Constructor Details
#initialize(p) ⇒ ObjectBase
New PEROBS objects must always be created by calling # Store.new(). PEROBS users should never call this method or equivalents of derived methods directly.
148 149 150 |
# File 'lib/perobs/ObjectBase.rb', line 148 def initialize(p) _initialize(p) end |
Instance Attribute Details
#_id ⇒ Object (readonly)
Returns the value of attribute _id.
142 143 144 |
# File 'lib/perobs/ObjectBase.rb', line 142 def _id @_id end |
#myself ⇒ Object (readonly)
Returns the value of attribute myself.
142 143 144 |
# File 'lib/perobs/ObjectBase.rb', line 142 def myself @myself end |
#store ⇒ Object (readonly)
Returns the value of attribute store.
142 143 144 |
# File 'lib/perobs/ObjectBase.rb', line 142 def store @store end |
Class Method Details
._finalize(store, id, ruby_object_id) ⇒ Object
This method generates the destructor for the objects of this class. It is done this way to prevent the Proc object hanging on to a reference to self which would prevent the object from being collected. This internal method is not intended for users to call.
173 174 175 |
# File 'lib/perobs/ObjectBase.rb', line 173 def ObjectBase._finalize(store, id, ruby_object_id) proc { store._collect(id, ruby_object_id) } end |
.read(store, id) ⇒ Object
Read an raw object with the specified ID from the backing store and instantiate a new object of the specific type.
241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/perobs/ObjectBase.rb', line 241 def ObjectBase.read(store, id) # Read the object from database. db_obj = store.db.get_object(id) klass = store.class_map.id_to_class(db_obj['class_id']) # Call the constructor of the specified class. obj = Object.const_get(klass).allocate obj._initialize(Handle.new(store, id)) obj._deserialize(db_obj['data']) obj.restore obj end |
Instance Method Details
#==(obj) ⇒ Object
Two objects are considered equal if their object IDs are the same.
202 203 204 205 |
# File 'lib/perobs/ObjectBase.rb', line 202 def ==(obj) return false unless obj.is_a?(ObjectBase) obj && @_id == obj._id end |
#_check_assignment_value(val) ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/perobs/ObjectBase.rb', line 221 def _check_assignment_value(val) if val.respond_to?(:is_poxreference?) # References to other PEROBS::Objects must be handled somewhat # special. if @store != val.store PEROBS.log.fatal 'The referenced object is not part of this store' end elsif val.is_a?(ObjectBase) PEROBS.log.fatal 'A PEROBS::ObjectBase object escaped! ' + 'Have you used self() instead of myself() to get the reference ' + 'of the PEROBS object that you are trying to assign here?' elsif !NATIVE_CLASSES.include?(val.class) PEROBS.log.fatal "Assigning objects of class #{val.class} is not " + "supported. Only PEROBS objects or one of the following classes " + "are supported: #{NATIVE_CLASSES.join(', ')}" end end |
#_initialize(p) ⇒ Object
This is the real code for initialize. It is called from initialize() but also when we restore objects from the database. In the later case, we don’t call the regular constructors. But this code must be exercised on object creation with new() and on restore from DB. param p [PEROBS::Handle] PEROBS handle
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/perobs/ObjectBase.rb', line 157 def _initialize(p) @store = p.store @_id = p.id @store._register_in_memory(self, @_id) ObjectSpace.define_finalizer( self, ObjectBase._finalize(@store, @_id, object_id)) @_stash_map = nil # Allocate a proxy object for this object. User code should only operate # on this proxy, never on self. @myself = POXReference.new(@store, @_id) end |
#_restore(level) ⇒ Object
Restore the object state from the storage back-end.
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/perobs/ObjectBase.rb', line 257 def _restore(level) # Find the most recently stored state of this object. This could be on # any previous stash level or in the regular object DB. If the object # was created during the transaction, there is no previous state to # restore to. data = nil if @_stash_map (level - 1).downto(0) do |lvl| break if (data = @_stash_map[lvl]) end end if data # We have a stashed version that we can restore from. _deserialize(data) elsif @store.db.include?(@_id) # We have no stashed version but can restore from the database. db_obj = store.db.get_object(@_id) _deserialize(db_obj['data']) end end |
#_stash(level) ⇒ Object
Save the object state for this transaction level to the storage back-end. The object gets a new ID that is stored in @_stash_map to map the stash ID back to the original data.
281 282 283 284 285 |
# File 'lib/perobs/ObjectBase.rb', line 281 def _stash(level) @_stash_map ||= ::Array.new # Get a new ID to store this version of the object. @_stash_map[level] = _serialize end |
#_sync ⇒ Object
Write the object into the backing store database.
208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/perobs/ObjectBase.rb', line 208 def _sync # Reset the stash map to ensure that it's reset before the next # transaction is being started. @_stash_map = nil db_obj = { 'class_id' => @store.class_map.class_to_id(self.class.to_s), 'data' => _serialize } @store.db.put_object(db_obj, @_id) end |
#_transfer(store) ⇒ Object
Library internal method to transfer the Object to a new store.
179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/perobs/ObjectBase.rb', line 179 def _transfer(store) @store = store # Remove the previously defined finalizer as it is attached to the old # store. ObjectSpace.undefine_finalizer(self) # Register the object as in-memory object with the new store. @store._register_in_memory(self, @_id) # Register the finalizer for the new store. ObjectSpace.define_finalizer( self, ObjectBase._finalize(@store, @_id, object_id)) @myself = POXReference.new(@store, @_id) end |
#restore ⇒ Object
This method can be overloaded by derived classes to do some massaging on the data after it has been restored from the database. This could either be some sanity check or code to migrate the object from one version to another. It is also the right place to initialize non-persistent instance variables as initialize() will only be called when objects are created for the first time.
198 199 |
# File 'lib/perobs/ObjectBase.rb', line 198 def restore end |