# -*- 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.
#-----------------------------------------------------------------------------
# Note: encore pas mal faire pour le faire fonctionner en satnd-alone.
# en particulier pour remplacement du modelizationtool, gnration des cls,
# i.e. persistentID, recherche (zcatalog sur ZODB-adaptor) etc.
# ----> object(s)ForKey p.ex.
"""
DatabaseObject
CVS information
$Id: DatabaseObject.py 932 2004-07-20 06:21:57Z sbigaret $
"""
__version__='$Revision: 932 $'[11:-2]
# python
import string
from cgi import escape
import urllib
## Modeling
#
from Modeling.KeyValueCoding import KeyValueCoding
from Modeling.Model import ModelError
from Modeling.utils import capitalizeFirstLetter,isListOrTuple
from Modeling import ClassDescription
# interfaces
from Modeling import interfaces
class DatabaseObject(KeyValueCoding):
"--"
__implements__=(interfaces.RelationshipManipulation.RelationshipManipulationInterface,
interfaces.KeyValueCoding.KeyValueCodingInterface,
interfaces.Faulting.FaultingInterface)
# Object's property
def entityName(self):
"""
Returns the corresponding entity's name.
Note that derived objects **must** override this.
As a reminder this method raises 'MethodShouldBeOverridden'
"""
raise 'MethodShouldBeOverridden'
def clearProperties(self):
"See interfaces.DatabaseObject for details"
self.__dict__={}
def classDescription(self):
"Returns the ClassDescription assigned to the receiver"
return ClassDescription.classDescriptionForName(self.entityName())
def inverseForRelationshipKey(self, aKey):
"""
Returns the name of the relationship pointing back to current entity, or
None if it does not exists.
Note: can be overriden in subclasses if the default behaviour would not
return the correct answer.
"""
return self.classDescription().inverseForRelationshipKey(aKey)
##
## Faulting
##
__faultHandler = None
def clearFault(self):
"""
Conformance to the Faulting interface.
See this interface documentation for details
"""
if not self.isFault():
raise RuntimeError, 'object is not a fault'
self.__faultHandler=None
def faultHandler(self):
"""
Conformance to the Faulting interface.
See this interface documentation for details
"""
return self.__faultHandler
def isFault(self):
"""
Conformance to the Faulting interface.
See this interface documentation for details
"""
return self.__faultHandler is not None
def turnIntoFault(self, aFaultHandler):
"""
Conformance to the Faulting interface.
See this interface documentation for details
"""
self.__faultHandler=aFaultHandler
def willRead(self):
"""
Conformance to the Faulting interface.
See this interface documentation for details
"""
if not self.isFault():
return
self.__faultHandler.completeInitializationOfObject(self)
##
## Preparation of instances to support KeyValueCoding
##
def prepareForInitializationWithKeys(self, keys):
"""
Creates in 'self' the list of attributes specified by keys, if they do not
already exists.
You should not need to call this method directly, it is automatically
called when an object is about to be initialized with values fetched from
a database (or when a fault is fired).
This is part of the support for the KeyValueCoding.
The algorithm used is the following, for a given key in 'keys'
- if 'self' already has an attribute 'key' or '_key', it does nothing
- if 'self' 's class declares an attribute='key' or '_key', that
attribute is created in 'self' and initialized to 'None',
- if neither 'self' nor its class declares such an attribute, an
attribute '_key' is created and initialized to 'None'
See also: 'attributeNameForKey()', 'classAttributeNameForKey()',
KeyValueCoding and the related documentation.
"""
for key in keys:
if not self.attributeNameForKey(key):
attr=self.classAttributeNameForKey(key)
if not attr:
if key and key[0]!='_':
key='_'+key
setattr(self, key, None)
else:
setattr(self, attr, None)
def attributeNameForKey(self, key):
"""
Returns the name of the attribute corresponding to the 'key', i.e. either
'_key' or 'key', or 'None' if the object does not have such an attribute.
When both attributes exists, returned value is '_key'
This is part of the support for the KeyValueCoding.
See also: prepareForInitializationWithKeys()
"""
self_attrs=self.__dict__.keys()
if ('_'+key) in self_attrs: # instance's _key attribute
return '_'+key
if key in self_attrs: # instance's key attribute
return key
return None
def classAttributeNameForKey(self, key):
"""
Returns the name of the object's class attribute corresponding to the
'key', i.e. either '_key' or 'key', or 'None' if the object's class does
not have such an attribute. When both attributes exists, returned value
is '_key'
This is part of the support for the KeyValueCoding.
See also: prepareForInitializationWithKeys()
"""
class_attrs=self.__class__.__dict__.keys()
if ('_'+key) in class_attrs: # class' _key attribute
return '_'+key
if key in class_attrs: # class' key attribute
return key
return None
# KeyValueCoding error handling for private setters
#def handleTakeStoredValueForUnboundKey(self, value, key):
# """
# See interfaces.DatabaseObject for details
# """
# if key and key[0]!='_':
# key='_'+key
# self.__dict__[key]=value
|