# -*- coding: iso-8859-1 -*-
#-----------------------------------------------------------------------------
# Modeling Framework: an Object-Relational Bridge for python
#
# Copyright (c) 2001-2004 Sbastien Bigaret <sbigaret@users.sourceforge.net>
# All rights reserved.
#
# This file is part of the Modeling Framework.
#
# This code is distributed under a "3-clause BSD"-style license;
# see the LICENSE file for details.
#-----------------------------------------------------------------------------
"""
Faulting interface
What are ``faults''?
A fault is an object which has not been fully initialized yet. Within the
framework, faults are heavily used. The reason is that, when an object
'O1'is fetched from a database, it has relationships to other objects. If
these objects were to be fetched along with 'O1', these will also trigger
the fetch for the object they are in relation to, and so on... And
finally, we would end with fetching most of a database's contents into
memory, consuming memory and a lot of CPU cycles even if all what we
needed was the single object.
To prevent such a unacceptable behaviour, objects that are in relation to
some fetched object are not immediately fetched: they are created but not
fully initialized since the data they require is not fetched yet. In other
words, their initialization is deferred until the point where they receive
a message they cannot handle without actually fetching the datas.
This mechanism ensures that the objects are lazily initialized, so that
the memory and CPU consumption is kept as low as possible.
When and how is a fault initialized?
As stated above, a faulted object is fully initialized when it receives a
message it cannot answer to without fetching the real datas. This is
usually automatically triggered *via* a call to 'willRead()'. Say an
object has an attribute 'firstName' which is stored in a table's row ;
since the object needs its data to be retrieved from the database when it
is asked for that attribute, it should implement a getter for 'firstName'
the following way::
def getFirstName():
self.willRead()
return self._firstName
The 'willRead()' method takes care of triggering the fault when necessary,
that is to say: if the object is a fault, it asks its fault handler to
complete its own initialization. Most of the time, this implies a
round-trip to the database.
Let's state this clearly: when an object conforming to the Faulting
interface needs to access one of its possibly uninitialized fields, it
should first call 'willRead()' **before** any of these fields can be
accessed.
More on the default behaviour
uses KeyValueCoding interface: takeStoredValueForKey
In the framework, objects derive from the 'DatabaseObject' class which
offers a default implementation of the 'Faulting' interface. You will
reraly need to override that default implementation.
The general mechanism
... interface, FaultHandler, etc.
CVS information
$Id: Faulting.py 932 2004-07-20 06:21:57Z sbigaret $
"""
__version__='$Revision: 932 $'[11:-2]
try:
from Interface import Base
except:
class Base:
pass
class FaultingInterface(Base):
"""
Handling of Faults, i.e. objects which are initialized only when needed
Faults are like DNA for objects...
Implemented by: 'CustomObject'
"""
##
## NB: commented out for the moment being
##
def clearFault(self):
"""
Invoked after the fault has been fired: it clears the fault status, and
has a consequence release its handler.
DatabaseObject default implementation release the FaultHandler it owned.
Should raise RuntimeError if the object is not a fault.
"""
def faultHandler(self):
"""
Return the FaultHandler which is used when the object needs to be
fully initialized. Returns None if object is not a Fault.
"""
def isFault(self):
"Tells whether the receiver is a fault or not"
def turnIntoFault(self, faultHandler):
"""
Turns the receiver into a fault. Parameter 'faultHandler' is mandatory.
Note that the object is the only owner of the FaultHandler.
"""
def willRead(self):
"""
Triggers the fault and complete the initialization of the object.
Should silently return if object is not a fault.
"""
|