Class: PEROBS::ObjectBase

Inherits:
Object
  • Object
show all
Defined in:
lib/perobs/ObjectBase.rb

Overview

Base class for all persistent objects. It provides the functionality common to all classes of persistent objects.

Direct Known Subclasses

Array, Hash, Object

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store) ⇒ 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.



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/perobs/ObjectBase.rb', line 110

def initialize(store)
  @store = store
  unless @store.object_creation_in_progress
    raise ::RuntimeError,
      "All PEROBS objects must exclusively be created by calling " +
      "Store.new(). Never call the object constructor directly."
  end
  @_id = @store.db.new_id
  @_stash_map = nil

  # Let the store know that we have a modified object.
  @store.cache.cache_write(self)
end

Instance Attribute Details

#_idObject (readonly)

Returns the value of attribute _id.



105
106
107
# File 'lib/perobs/ObjectBase.rb', line 105

def _id
  @_id
end

#storeObject (readonly)

Returns the value of attribute store.



105
106
107
# File 'lib/perobs/ObjectBase.rb', line 105

def store
  @store
end

Class Method Details

.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.



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/perobs/ObjectBase.rb', line 154

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 = store.construct_po(Object.const_get(klass))
  # The object gets created with a new ID by default. We need to restore
  # the old one.
  obj._change_id(id)
  obj._deserialize(db_obj['data'])
  obj.post_restore

  obj
end

Instance Method Details

#==(obj) ⇒ Object

Two objects are considered equal if their object IDs are the same.



134
135
136
137
# File 'lib/perobs/ObjectBase.rb', line 134

def ==(obj)
  return false unless obj.is_a?(ObjectBase)
  obj && @_id == obj._id
end

#_change_id(id) ⇒ Object

Library internal method. Do not use outside of this library.



213
214
215
216
217
218
# File 'lib/perobs/ObjectBase.rb', line 213

def _change_id(id)
  # Unregister the object with the old ID from the write cache to prevent
  # cache corruption. The objects are index by ID in the cache.
  @store.cache.unwrite(self)
  @_id = id
end

#_restore(level) ⇒ Object

Restore the object state from the storage back-end.

Parameters:

  • level (Fixnum)

    the transaction nesting level



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/perobs/ObjectBase.rb', line 172

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 not previous state to
  # restore to.
  id = nil
  if @_stash_map
    (level - 1).downto(0) do |lvl|
      if @_stash_map[lvl]
        id = @_stash_map[lvl]
        break
      end
    end
  end
  unless id
    if @store.db.include?(@_id)
      id = @_id
    end
  end
  if id
    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.



200
201
202
203
204
205
206
207
208
209
# File 'lib/perobs/ObjectBase.rb', line 200

def _stash(level)
  db_obj = {
    'class' => self.class.to_s,
    'data' => _serialize
  }
  @_stash_map = [] unless @_stash_map
  # Get a new ID to store this version of the object.
  @_stash_map[level] = stash_id = @store.db.new_id
  @store.db.put_object(db_obj, stash_id)
end

#_syncObject

Write the object into the backing store database.



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/perobs/ObjectBase.rb', line 140

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

#post_restoreObject

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.



130
131
# File 'lib/perobs/ObjectBase.rb', line 130

def post_restore
end