# -*- 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.
#-----------------------------------------------------------------------------
"""
Adaptor API
__TBD: general presentation
__TBD: Adaptor.Delegate
How are concrete Adaptors loaded?
...
Implementing an adaptor
- module: naming conventions
- module: should have a function named 'adaptorFactory'
- class: see below
Exceptions: AdaptorImportError, GeneralAdaptorException
CVS information
$Id: Adaptor.py 932 2004-07-20 06:21:57Z sbigaret $
"""
__version__='$Revision: 932 $'[11:-2]
try:
from Interface import Base
except:
class Base:
pass
def adaptorWithModel(aModel):
"""
Returns the adaptor associated to the supplied model: it extracts the name
of the adaptor to be used with the model then calls adaptorWithModel()
Raises ValueError is parameter 'aModel' is None or if its adaptorName
is empty.
Raises AdaptorImportError if the adaptor cannot be loaded.
"""
def adaptorWithName(aName):
"""
Returns the adaptor.
Raises AdaptorImportError if the adaptor cannot be loaded.
"""
def defaultDelegate():
"""
Returns the default delegate.
See: setDefaultDelegate()
"""
# regular EOF API, changed
# def expressionClassName(adaptorClassName):
def expressionClassForAdaptor(adaptor):
"""
Returns the expression class to be used by adaptor, or None if none was
previously set with 'setExpressionClassForAdaptor()'.
"""
def setDefaultDelegate(delegate):
"""
Sets the default delegate which is assigned to Adaptor instances when they
are initialized.
"""
# regular EOF API, changed
# def setExpressionClassName(sqlExpressionClassName, adaptorClassName):
def setExpressionClassForAdaptor(sqlExpression, adaptor):
"""
Sets the SQLExpression to use in conjonction with a particular adaptor.
Parameters 'sqlExpression' and 'adaptor' can be either instances or classes.
"""
class IAdaptor(Base):
"""
Implemented in base class:
assignExternalInfoForEntireModel
connectionDictionary
contexts
delegate
hasOpenChannels
name
setDelegate
setExpressionClassForAdaptor
Implemented, can be overriden (better not, if possible)
setConnectionDictionary
Should be overriden:
assertConnectionDictionaryIsValid
assignExternalInfoForAttribute
assignExternalInfoForEntity
createAdaptorContext
defaultExpressionClass
externalTypesWithModel
internalTypeForExternalType
fetchedValueForDataValue
fetchedValueForDateValue
fetchedValueForNumberValue
fetchedValueForStringValue
fetchedValueForValue
isValidQualifierType
schemaGenerationFactory
Additionnally the class defines the following static methods, none of which
should be overriden by subclasses:
- adaptorWithModel
- adaptorWithName
- defaultDelegate
- expressionClassForAdaptor
- setDefaultDelegate
- setExpressionClassForAdaptor
Methods 'abstract'==no default implementation, concrete subclasses should
override them
"""
def __init__(self, name):
"""
__TBD
Defaults:
- delegate=defaultDelegate() [...]
- no contexts
- empty connectionDictionary
"""
def administrativeConnectionDictionaryForAdaptor(self, anAdaptor):
"""
"""
def assertConnectionDictionaryIsValid(self):
"""
"""
def assignExternalInfoForAttribute(self, anAttribute):
"""
"""
def assignExternalInfoForEntireModel(self, aModel):
"""
"""
def assignExternalInfoForEntity(self, anEntity):
"""
"""
def assignExternalTypeForAttribute(self, anAttribute):
"""
"""
def canServiceModel(self, aModel):
"""
Compares 'aModel' 's connectionDictionary with self's and returns the
result
"""
def connectionDictionary(self):
"""
Returns the connectionDictionary
"""
def contexts(self):
"""
Returns all AdaptorContexts created and registered with this Adaptor
See: createAdaptorContext()
"""
def createAdaptorContext(self):
"""
Instanciates a new AdaptorContext, registers it in the list of contexts()
then returns it.
abstract
Subclasses should override this method to add the appropriate
AdaptorContext to the private attribute 'self._contexts' and return it,
without calling this method.
"""
def createDatabaseWithAdministrativeConnectionDictionary(self, administrativeConnectionDictionary):
"""
Connects to the database with the supplied connection dictionary and
creates the database specified by the Adaptor's connectionDictionary()
Subclasses should implement this method without calling this.
"""
def defaultExpressionClass(self):
"""
Returns the default expression class to be used along with this adaptor.
See 'expressionClass()' for an explanation on how the expression class
is actually determined for an Adaptor.
Subclasses should override this method without calling Adaptor's.
"""
def delegate(self):
"""
Returns the delegate for that Adaptor ; when initialized the delegate is
the one returned by defaultDelegate()
"""
def dropDatabaseWithAdministrativeConnectionDictionary(self, administrativeConnectionDictionary):
"""
Adaptor's implementation does nothing
"""
def expressionClass(self):
"""
Returns the expression class to be used with the Adaptor.
The mechanism used needs a little explanation. First, a concrete Adaptor
comes with (or reuse) a concrete expressionClass (SQLExpression) -- the
method 'defaultExpressionClass()' returns that concrete expression class.
This is also the default value returned by this method.
However, you may need to substitute that default expression class with one
of your own (for example, you may want to subclass that expr.class to
change part of its behaviour). This is what the static method
'setExpressionClassForAdaptor()' does: when called, it registers your
custom expression class for use with a given adaptor. Any subsequent call
to this method --'expressionClass()'-- then returns the registered
expr. class instead of the default one.
To summarize it:
- if 'expressionClassForAdaptor(self)' returns None, the method returns
'self.defaultExpressionClass()'
- otherwise, it returns 'expressionClassForAdaptor(self)'
Subclasses should not override this method.
"""
def expressionFactory(self):
"""
"""
def externalTypesWithModel(self, aModel):
"""
"""
def fetchedValueForDataValue(self, value, anAttribute):
"""
Adaptor's implementation returns 'value' without any modification
"""
def fetchedValueForDateValue(self, value, anAttribute):
"""
Adaptor's implementation returns 'value' without any modification
"""
def fetchedValueForNumberValue(self, value, anAttribute):
"""
Adaptor's implementation returns 'value', possibly modified if
'anAttribute' corresponds to a SQL 'NUMERIC' field with a scale lower
than the number of digits in the fractional part.
For example, the float '4.675' will be converted to '4.68' if
'anAttribute' has a scale of 2.
"""
def fetchedValueForStringValue(self, value, anAttribute):
"""
Adaptor's implementation returns 'value' without modification
"""
def fetchedValueForValue(self, value, anAttribute):
"""
This method examine 'anAttribute' and, according to its externalType,
forwards the message to one of the methods fetchedValueForDataValue(),
fetchedValueForDateValue(), fetchedValueForNumberValue() or
fetchedValueForStringValue().
The purpose here is to return a value, derived from 'value', which
reflects the value as it is actually stored by a database-backend. This is
used by the snapshotting mechanisms in the framework (optimistic locking).
See these methods for a description of their actions.
"""
def handleDroppedConnection(self):
"""
"""
def hasOpenChannels(self):
"""
Forwards the messages to all contexts() and returns 1 (true value) if at
least one of these returned a true value, return 0 (false value)
otherwise.
See: setConnectionDictionary()
"""
def internalTypeForExternalType(self, extType, aModel):
"""
"""
def isDroppedConnectionException(self, exception):
"""
"""
def isValidQualifierType(self, typeName, aModel):
"""
"""
def name(self):
"""
Returns the name that was used when the concrete Adaptor was instanciated.
See: adaptorWithName(), adaptorWithModel()
"""
def prototypeAttributes(self):
"""
"""
def setConnectionDictionary(self, connectionDictionary):
"""
Sets the connectionDictionary.
Raises ValueError if hasOpenChannels() returns true --in this case the
connectionDictionary is not set.
"""
def setDelegate(self, aDelegate):
"""
Sets the delegate
"""
#def synchronizationFactory(self):
# """
# """
def schemaGenerationFactory(self):
"""
Returns the appropriate SchemaGeneration object for the Adaptor.
Subclasses should override this method without calling it
"""
|