Module: Persistence::Object::Complex::ObjectInstance

Includes:
CascadingConfiguration::Hash, Attributes, ClassAndObjectInstance
Included in:
Persistence::Object::Complex
Defined in:
lib/persistence/object/complex/object_instance.rb

Overview

Methods applied to object instances of complex objects enabled with persistence capabilities.

Instance Method Summary collapse

Methods included from ClassAndObjectInstance

#attr_delete_cascades, #attr_delete_cascades!, #attr_delete_does_not_cascade, #attr_delete_does_not_cascade!, #delete_cascades, #delete_cascades?

Methods included from Attributes

#atomic_attribute?, #atomic_attribute_accessor?, #atomic_attribute_accessors, #atomic_attribute_reader?, #atomic_attribute_readers, #atomic_attribute_status, #atomic_attribute_writer?, #atomic_attribute_writers, #atomic_attributes, #attr_atomic_accessor, #attr_atomic_reader, #attr_atomic_writer, #attr_non_atomic_accessor, #attr_non_atomic_reader, #attr_non_atomic_writer, #attrs_atomic!, #attrs_non_atomic!, #non_atomic_attribute?, #non_atomic_attribute_accessor?, #non_atomic_attribute_accessors, #non_atomic_attribute_reader?, #non_atomic_attribute_readers, #non_atomic_attribute_status, #non_atomic_attribute_writer?, #non_atomic_attribute_writers, #non_atomic_attributes, #persistent_attribute?, #persistent_attribute_accessor?, #persistent_attribute_accessors, #persistent_attribute_reader?, #persistent_attribute_readers, #persistent_attribute_status, #persistent_attribute_writer?, #persistent_attribute_writers, #persistent_attributes

Instance Method Details

#==(other_object) ⇒ true, false

Objects are equivalent if they are identical in standard Ruby terms or if their persistence state is equivalent.

Parameters:

  • other_object

    Object comparing self to

Returns:

  • (true, false)

    Whether self is equal to other object.



38
39
40
41
42
# File 'lib/persistence/object/complex/object_instance.rb', line 38

def ==( other_object )

  return super( other_object ) || persistence_state_equal?( other_object )
  
end

#attribute_indexesCompositingHash{Symbol,String=>Persistence::Object::Complex::Index::AttributeIndex}

Hash holding attribute indexes: index_name => index.

Returns:



25
# File 'lib/persistence/object/complex/object_instance.rb', line 25

attr_hash :attribute_indexes, ::Persistence::Object::IndexHash

#cease!Object

cease! #



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/persistence/object/complex/object_instance.rb', line 159

def cease!
  
  global_id = persistence_id
  
  if persistence_hash_in_port = super

    persistence_hash_in_port.each do |this_attribute, this_value|

      if this_value.is_a?( ::Persistence::Object::Complex::ComplexObject ) and 
         this_value.delete_cascades?

        this_value.cease!

      end

    end

  end
  
  self.persistence_id = nil
  
  return self
  
end

#get_attribute(attribute) ⇒ Object

Method used when defining implicit getter for attr_atomic/attr_non_atomic.



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/persistence/object/complex/object_instance.rb', line 193

def get_attribute( attribute )
  
  value = nil

  variable_name = attribute.variable_name

  # if we're atomic and have an ID, get from persistence port (call accessor read method)
  if persistence_id and atomic_attribute_reader?( attribute )

    # the first time we load the attribute we load the object corresponding to the ID
    # once our object has been loaded we don't need to get it again
    # so we can check to see if the object-local variable is already set to a value, 
    # in which case we do not load it from the persistence port    
    if instance_variable_defined?( variable_name )
      
      value = instance_variable_get( variable_name )

    else
      
      value = persistence_bucket.get_attribute( self, attribute )

      if value.is_a?( ::Persistence::Object::Complex::ComplexObject )

        value.persistence_port = persistence_port

        value = value.persist

        # we only want to store atomic attributes that are complex objects
        instance_variable_set( variable_name, value )

      end

    end

  # otherwise get from object (not yet persisted)
  else

    value = instance_variable_get( variable_name )

  end

  return value
  
end

#index_attributesObject

Perform indexing on attributes with indexes.

Returns:

  • self



119
120
121
122
123
124
125
126
127
# File 'lib/persistence/object/complex/object_instance.rb', line 119

def index_attributes

  self.class.attribute_indexes.each do |this_attribute_name, this_attribute_index|
    this_attribute_index.index_object( self )
  end
  
  return self

end

#load_atomic_stateObject

Helper method to load atomic state into object so that it can be inspected.

Returns:

  • self



286
287
288
289
290
291
292
293
294
# File 'lib/persistence/object/complex/object_instance.rb', line 286

def load_atomic_state
  
  atomic_attribute_readers.each do |this_attribute|
    instance_variable_set( this_attribute.variable_name, __send__( this_attribute ) )
  end
  
  return self
  
end

#load_persistence_hash(port, persistence_ivar_hash) ⇒ Object

Helper method for creating object when persisting from storage port.

Parameters:

  • port

    Storage port object is being loaded from.

  • persistence_ivar_hash

    Hash of data from storage port.

Returns:

  • self



362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/persistence/object/complex/object_instance.rb', line 362

def load_persistence_hash( port, persistence_ivar_hash )

  self.persistence_port = port

  persistence_ivar_hash.each do |this_attribute_name, this_attribute_value|

    if this_attribute_value.is_a?( ::Persistence::Object::Complex::ComplexObject )
      this_attribute_value = this_attribute_value.persist
    end
    
    load_persistence_value( this_attribute_name, this_attribute_value )
    
  end

  return self

end

#load_persistence_value(attribute_name, attribute_value) ⇒ Object

Helper method for loading data from persistence hash from storage port.

Parameters:

  • attribute_name

    Attribute being loaded.

  • attribute_value

    Attribute value to load.

Returns:

  • self



395
396
397
398
399
400
401
# File 'lib/persistence/object/complex/object_instance.rb', line 395

def load_persistence_value( attribute_name, attribute_value )
  
  __send__( attribute_name.write_accessor_name, attribute_value )

  return self
  
end

#persist(*args) ⇒ Object

persist #



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/persistence/object/complex/object_instance.rb', line 133

def persist( *args )

  index_instance, key, no_key = parse_object_args_for_index_value_no_value( args )

  unless persistence_id
    if no_key
      raise ::Persistence::Exception::KeyValueRequired, 
            'Key value required if persistence ID does not already exist for self. : ' + args.to_s
    end
    unless self.persistence_id = index_instance.get_object_id( key )
      # if we got no persistence id, return nil
      return nil
    end
  end
  
  persistence_hash_from_port = persistence_bucket.get_object_hash( persistence_id )
  load_persistence_hash( persistence_port, persistence_hash_from_port )
  
  return self

end

#persist!(*args) ⇒ Object

persist! #



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/persistence/object/complex/object_instance.rb', line 91

def persist!( *args )

  this_call_generates_id = ( persistence_id ? false : true )

  super
  
  if this_call_generates_id
    remove_atomic_attribute_values
  end    

  # index object attributes    
  index_attributes

  return self

end

#persist_as_sub_object_or_attribute_and_return_id_or_value(value) ⇒ Object

Helper method for persistence for nested objects.



305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/persistence/object/complex/object_instance.rb', line 305

def persist_as_sub_object_or_attribute_and_return_id_or_value( value )

  if is_complex_object?( value ) and ! self.class.persists_flat?( value )

    value.persist!

    sub_id_or_attribute_value = ::Persistence::Object::Complex::ComplexObject.new( value )

  else

    sub_id_or_attribute_value = value

  end

  return sub_id_or_attribute_value
  
end

#persistence_hash_to_portHash

Generate hash representing object.

Returns:

  • (Hash)

    Hash representing information to reproduce object instance.



334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/persistence/object/complex/object_instance.rb', line 334

def persistence_hash_to_port

  persistence_hash = ::Persistence::Object::Complex::Attributes::HashToPort.new
  persistence_hash.persistence_object = self

  persistent_attribute_writers.each do |this_attribute|
    persistence_hash[ this_attribute ] = __send__( this_attribute )
  end

  return persistence_hash

end

#persistence_state_equal?(other_object) ⇒ true, false

Reports whether objects are equivalent from a persistence perspective.

Parameters:

  • other_object

    Object comparing self to

Returns:

  • (true, false)

    Whether self is equal to other object in terms of persisted state.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/persistence/object/complex/object_instance.rb', line 55

def persistence_state_equal?( other_object )

  objects_are_equal = false

  if other_object.is_a?( ::Persistence::Object::Complex::ObjectInstance )  and
     self.class.equal?( other_object.class )                               and
     other_object.respond_to?( :persistence_id )                           and 
     persistence_id == other_object.persistence_id
    
    # test non-atomic attributes for equality
    if objects_are_equal = non_atomic_attribute_readers.empty? or 
       objects_are_equal = ( persistence_hash_to_port == other_object.persistence_hash_to_port )
    
      # test atomic attributes for equality
      unless atomic_attribute_readers.empty?
    
        atomic_attribute_readers.each do |this_attribute|
          this_value = __send__( this_attribute )
          this_other_value = other_object.__send__( this_attribute )
          break unless objects_are_equal = ( this_value == this_other_value )
        end
        
      end
      
    end
    
  end
  
  return objects_are_equal
  
end

#set_attribute(attribute, value) ⇒ Object

Method used when defining implicit setter for attr_atomic/attr_non_atomic.



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/persistence/object/complex/object_instance.rb', line 247

def set_attribute( attribute, value )
  
  variable_name = attribute.variable_name
  
  # if we're atomic and have an ID, put to persistence port
  if persistence_id and atomic_attribute?( attribute )
    
    if is_complex_object?( value )
      instance_variable_set( variable_name, value )
    end

    value = persist_as_sub_object_or_attribute_and_return_id_or_value( value )

    persistence_bucket.put_attribute!( self, attribute, value )

    if self.class.has_attribute_index?( attribute )
       self.class.attribute_indexes[ attribute ].index_object( self )
    end
    
  # otherwise get from object
  else

    instance_variable_set( variable_name, value )

  end

  return value
  
end