Adaptor.py :  » Database » Modeling-Framework » Modeling-0.9 » Modeling » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Database » Modeling Framework 
Modeling Framework » Modeling 0.9 » Modeling » Adaptor.py
# -*- 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

  CVS information

    $Id: Adaptor.py 932 2004-07-20 06:21:57Z sbigaret $
  
"""

__version__='$Revision: 932 $'[11:-2]

from inspect import isclass
from delegation import DelegateWrapper

# Interfaces
from Modeling.interfaces.Adaptor import IAdaptor

# Framework
from utils import staticmethod,getModule

## Do not access these variables directly -- they are private (MT-safety)
## This holds the adaptors' classes
__adaptorsClasses={} # adaptorName: adaptorClass

## This is for expressionClass
__expressionsClasses={} # adaptorClass: expressionClass

## default delegate
__defaultDelegate=None

# Global reentrant lock
from threading import RLock
__adaptorClass_lock=RLock()
lock=__adaptorClass_lock.acquire
unlock=__adaptorClass_lock.release

# Notifications
AdaptorNeededForNameNotification='AdaptorNeededForNameNotification'

#Exceptions
class AdaptorImportError(ImportError):
  pass
#
class GeneralAdaptorException(RuntimeError):
  pass

class CannotSerializeException(GeneralAdaptorException):
  pass

# module functions / Adaptor ``static'' methods
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.
  """
  lock()
  try:
    if not aModel or not aModel.adaptorName():
      raise ValueError, "Supplied model is null or its adaptor name is empty"
    adaptorName=aModel.adaptorName()
    adaptor=adaptorWithName(adaptorName)
    adaptor.setConnectionDictionary(aModel.connectionDictionary())
    return adaptor
  finally:
    unlock()
    
def adaptorWithName(aName):
  """
  Returns the adaptor.

  Raises AdaptorImportError if the adaptor cannot be loaded.
  """
  if not aName:
    raise ValueError, "Parameter 'aName' is null or empty"
  lock()
  try:
    global __adaptorsClasses
    if __adaptorsClasses.get(aName, None):
      return __adaptorsClasses[aName](aName)

    from Modeling import DatabaseAdaptors

    # try to import the module
    adaptorModuleName=aName+'AdaptorLayer'
    try:
      path=getattr(DatabaseAdaptors,'__path__', None)
      _module=getModule(adaptorModuleName, path)
    except:
      import traceback, cStringIO
      exc=cStringIO.StringIO()
      traceback.print_exc(file=exc)
      raise AdaptorImportError, "Unable to import adaptor for name '%s': "\
            "module %s couldn't be imported\nReason:%s"%(aName,
                                                         adaptorModuleName,
                                                         exc.getvalue())
    if not hasattr(_module, 'adaptorFactory'):
      raise AdaptorImportError, "Imported module %s does not define the "\
            "method 'adaptorFactory()'"%(adaptorModuleName,)
    _factory=getattr(_module, 'adaptorFactory')
    _adaptorClass=None
    if callable(_factory): _adaptorClass=_factory()
    else:                  _adaptorClass=_factory
    __adaptorsClasses[aName]=_adaptorClass
    return _adaptorClass(aName)
  finally:
    unlock()
    
def defaultDelegate():
  """
  Returns the default delegate.

  See also: setDefaultDelegate()
  """
  lock()
  try:
    return __defaultDelegate
  finally:
    unlock()
    
def expressionClassForAdaptor(adaptor):
  """
  Returns the expression class to be used by adaptor, or None if none was
  previously set with 'setExpressionClassForAdaptor()'.
  """
  lock()
  try:
    global __expressionsClasses
    if not isclass(adaptor):
      adaptor=adaptor.__class__
    return __expressionsClasses.get(adaptor, None)
  finally:
    unlock()

def setDefaultDelegate(delegate):
  """
  Sets the default delegate which is assigned to Adaptor instances when they
  are initialized.
  """
  lock()
  try:
    global __defaultDelegate
    __defaultDelegate=delegate
  finally:
    unlock()

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.
  """
  lock()
  try:
    global __expressionsClasses
    if not isclass(sqlExpression):
      sqlExpression=sqlExpression.__class__
    if not isclass(adaptor):
      adaptor=adaptor.__class__
    __expressionsClasses[adaptor]=sqlExpression
  finally:
    unlock()

class Adaptor:
  "See interfaces.Adaptor for details"
  
  __implements__ = (IAdaptor,)

  __raise_exception__='AbstractMethod'
  __raise_msg__      ='Left intentionally unimplemented in this class, '\
                       'subclass should override this method'
  ## Attention: il y en a qui vont tre compltement rcrites et d'autres qui
  ## doivent faire appel  l'implmentation de cette classe, donc bon.

  def __init__(self, name):
    "See interfaces.Adaptor for details"
    self._name=name
    self._connectionDictionary={}
    self._contexts=[]
    #self._delegate=DelegateWrapper(, defaultDelegate())
    
  # Static methods
  adaptorWithModel=staticmethod(adaptorWithModel)
  adaptorWithName=staticmethod(adaptorWithName)
  defaultDelegate=staticmethod(defaultDelegate)
  expressionClassForAdaptor=staticmethod(expressionClassForAdaptor)
  setDefaultDelegate=staticmethod(setDefaultDelegate)
  setExpressionClassForAdaptor=staticmethod(setExpressionClassForAdaptor)

  # Instance methods
  def administrativeConnectionDictionaryForAdaptor(self, anAdaptor):
    "See interfaces.Adaptor for details"
  
  def assertConnectionDictionaryIsValid(self):
    "See interfaces.Adaptor for details"
  
  def assignExternalInfoForAttribute(self, anAttribute):
    "See interfaces.Adaptor for details"
  
  def assignExternalInfoForEntireModel(self, aModel):
    "See interfaces.Adaptor for details"

  def assignExternalInfoForEntity(self, anEntity):
    "See interfaces.Adaptor for details"

  def assignExternalTypeForAttribute(self, anAttribute):
    "See interfaces.Adaptor for details"

  def canServiceModel(self, aModel):
    """
    Compares 'aModel' 's connectionDictionary with self's and returns the
    result
    """
    return aModel.connectionDictionary()!=self._connectionDictionary

  def connectionDictionary(self):
    """
    Returns the connectionDictionary

    See also: setConnectionDictionary()
    """
    return self._connectionDictionary
  
  def contexts(self):
    """
    Returns all AdaptorContexts created and registered with this Adaptor

    See also: createAdaptorContext()
    """
    return tuple(self._contexts)
  
  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.
    """
    raise __raise_exception__, __raise_msg__
  
  def createDatabaseWithAdministrativeConnectionDictionary(self, administrativeConnectionDictionary):
    """
    Connects to the database with the supplied connection dictionary and
    creates the database specified by the Adaptor's connectionDictionary()

    Adaptor's implementation does nothing.

    Subclasses should implement this method without calling this.
    """
    return
  
  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.
    """
    __abstract__()
    
  def delegate(self):
    """
    Returns the delegate for that Adaptor ; when initialized the delegate is
    the one returned by defaultDelegate()
    """
    return self._delegate
  
  def dropDatabaseWithAdministrativeConnectionDictionary(self, administrativeConnectionDictionary):
    "Adaptor's implementation does nothing"
    return
  
  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.
    """
    # First, check if it was overriden with
    # (static) setExpressionClassForAdaptor
    exprClass=Adaptor.expressionClassForAdaptor(self)
    if exprClass is not None:
      return exprClass
    return self.defaultExpressionClass()
  
  def expressionFactory(self):
    "See interfaces.Adaptor for details"

  def externalTypesWithModel(self, aModel):
    "See interfaces.Adaptor for details"

  def fetchedValueForDataValue(self, value, anAttribute):
    """
    Adaptor's implementation returns 'value' without any modification
    """
    return value
  
  def fetchedValueForDateValue(self, value, anAttribute):
    """
    Adaptor's implementation returns 'value' without any modification
    """
    return value
  
  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.
    """
    if anAttribute.externalType()=='NUMERIC':
      return round(value, anAttribute.scale())
    
  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):
    "Unimplemented yet"
    self.__unimplemented__()

  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()
    """
    for context in self.contexts():
      if context.hasOpenChannels():
        return 1
    return 0
  
  def internalTypeForExternalType(self, extType, aModel):
    "See interfaces.Adaptor for details"

  def isDroppedConnectionException(self, exception):
    "See interfaces.Adaptor for details"

  def isValidQualifierType(self, typeName, aModel):
    "See interfaces.Adaptor for details"

  def name(self):
    """
    Returns the name that was used when the concrete Adaptor was instanciated.

    See also: adaptorWithName(), adaptorWithModel()
    """
    return self._name
  
  def prototypeAttributes(self):
    "See interfaces.Adaptor for details"
    self.__unimplemented__()
    
  def setConnectionDictionary(self, connectionDictionary):
    """
    Sets the connectionDictionary.

    Raises ValueError if hasOpenChannels() returns true --in this case the
    connectionDictionary is not set.
    """
    if self.hasOpenChannels():
      raise ValueError, "Connection dictionary cannot be changed while some"\
            "AdaptorChannels are opened"
    self._connectionDictionary=connectionDictionary

  def setDelegate(self, aDelegate):
    """
    Sets the delegate (not used yet)
    """
    self._delegate=aDelegate
    
  #def synchronizationFactory(self):
  #  "See interfaces.Adaptor for details"
  #  self.__unimplemented__()

  def schemaGenerationFactory(self):
    "See interfaces.Adaptor for details"
    __abstract__()
    
  def __unimplemented__(self):
    raise 'Unimplemented', 'Yet unimplemented'


def __abstract__():
  raise 'AbstractMethod', 'Left intentionally unimplemented in this class, '\
        'subclass should override this method'
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.