AbstractDBAPI2AdaptorContext.py :  » Database » Modeling-Framework » Modeling-0.9 » Modeling » DatabaseAdaptors » AbstractDBAPI2AdaptorLayer » 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 » DatabaseAdaptors » AbstractDBAPI2AdaptorLayer » AbstractDBAPI2AdaptorContext.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.
#-----------------------------------------------------------------------------


"""
AbstractDBAPI2AdaptorContext

  This module contains the AbstractDBAPI2AdaptorContext class to be inherited
  from when designing an concrete AdaptorContext based on a python
  database-adaptor complying to the python DB-API v2.0.

  CVS information

    $Id: AbstractDBAPI2AdaptorContext.py 934 2004-08-02 20:11:39Z sbigaret $
  
"""

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

from Modeling.logging import db_info,db_trace,db_debug,db_fatal

# Framework
from Modeling.AdaptorContext import AdaptorContext
from Modeling.Adaptor import GeneralAdaptorException

# Interfaces
from Modeling.interfaces.AdaptorContext import IAdaptorContext

import os

class AbstractDBAPI2AdaptorContext(AdaptorContext):
  """
  Your inheriting concrete Adaptor class **must** override:

    - createAdaptorChannel()

  You normally do not need to override other methods. In particular,
  dbAPI_cursorForAdaptorChannel() does not need to be overridden.
  
  """
  
  __implements__ = (IAdaptorContext,)

  def __init__(self, anAdaptor):
    """
    Initialization. You do normally not need to override this method. If you
    do, you **must** explicitly call the superclass' implementation.
    """
    AdaptorContext.__init__.im_func(self, anAdaptor)
    self._cnx=None
    
  def adaptorChannelDidClose(self, aChannel):
    """
    Informs the AdaptorContext that one of its AdaptorChannel has been closed.
    Never invoke this method yourself, it is automatically called by the
    AdaptorChannel.

    Default behaviour leaves the connection to the database open, even when 
    the AdaptorContext has no opened channels ; setting the environment
    variable 'MDL_TRANSIENT_DB_CONNECTION' to any true value closes the
    database connection the AdaptorContext has no opened channels anymore.

    You do not need to override this method when designing a concrete
    AdaptorContext. If you do, however, you must call the superclass
    implementation, and you must keep in mind that the underlying database
    connection may have been closed as well.
    
    Parameter 'aChannel' is currently unused.

    See also: AbstractDBAPI2AdaptorChannel.closeChannel()
              Modeling.AdaptorChannel.closeChannel()
    """
    db_debug('Adaptor channel %s did close'%repr(aChannel))
    if not self.hasOpenChannels():
      ## Close the connexion
      db_debug('Channels are now all closed')

      if self._cnx and os.environ.get('MDL_TRANSIENT_DB_CONNECTION'):
        db_info('Closing the connection to the database')
        self._cnx.close()
        self._cnx=None
  
  def beginTransaction(self):
    """
    Starts a new transaction.

    Raises GeneralAdaptorException if an transaction has already begun.

    See also: Modeling.interfaces.AdaptorContext for details
    """
    db_info('Transaction: BEGIN')
    if self.hasOpenTransaction():
      raise GeneralAdaptorException, 'Another transaction has already begun'
    # pgdb automatically begins a transaction
    self._openConnectionIfNecessary()
    self.transactionDidBegin()

  def commitTransaction(self):
    """
    Commits the currently opened transaction.

    Raises GeneralAdaptorException if no transaction has begun.
    
    See also: Modeling.interfaces.AdaptorContext for details
    """
    db_info('Transaction: COMMIT')
    if not self.hasOpenTransaction():
      raise GeneralAdaptorException, 'No transaction begun'
    self._cnx.commit()
    self.transactionDidCommit()
    
  def createAdaptorChannel(self):
    """
    Returns a brand new instance of the adequate concrete AdaptorChannel.

    Implementation hint: say your adaptor's name is 'Dummy', then you'll
      probably use the following code::

        from DummyAdaptorChannel import DummyAdaptorChannel
        db_trace('Creating DummyAdaptorChannel %s'%repr(channel))
        channel=DummyAdaptorChannel(self)
        self.__addChannel__(channel)
        return channel

      --> It is very important that you do not forget to append the new
          adaptor channel to the list of held channels, using the
          __addChannel__ method.

    Subclasses should override this method without calling the superclass'
    implementation.

    See also: Modeling.interfaces.AdaptorContext for details
    """
    __abstract__()
  
  #def hasOpenTransaction(self):
  #  "See Modeling.interfaces.AdaptorContext for details"
  #  db_trace('-')
  #  raise 'Unimplemented'
  #  #return self._hasOpenTransaction
  
  def rollbackTransaction(self):
    """
    Rollbacks the currently opened transaction.

    Raises GeneralAdaptorException if no transaction has begun.
    
    See also:
    Modeling.interfaces.AdaptorContext for details
    """
    db_info('Transaction: ROLLBACK')
    if not self.hasOpenTransaction():
      raise GeneralAdaptorException, 'No transaction begun'
    self._cnx.rollback()
    self.transactionDidRollback()
    
  #def transactionDidBegin(self):
  #  "See Modeling.interfaces.AdaptorContext for details"
  #  AdaptorContext.transactionDidBegin.im_func(self)
  #
  #def transactionDidCommit(self):
  #  "See Modeling.interfaces.AdaptorContext for details"
  #  AdaptorContext.transactionDidCommit.im_func(self)
  #
  #def transactionDidRollback(self):
  #  "See Modeling.interfaces.AdaptorContext for details"
  #  AdaptorContext.transactionDidRollback.im_func(self)

  ## private & specific AbstractDBAPI2AdaptorLayer method

  def dbAPI_cursorForAdaptorChannel(self):
    """
    Returns a 'cursor' for use by an AbstractDBAPI2AdaptorChannel when it is
    about to open the channel. Never invoke this method, this is automatically
    invoked by the AbstractDBAPI2AdaptorChannel.

    See also: AbstractDBAPI2AdaptorChannel.openChannel()
    """
    db_trace('Called')
    self._openConnectionIfNecessary()
    return self._cnx.cursor()


  def _openConnectionIfNecessary(self):
    """
    Internally used to open a connection to the underlying database, if
    necessary.

    Raises GeneralAdaptorException if the connection cannot be opened --in
    this case the reason why it failed is attached to the exception.
    """
    if not self._cnx:
      cnxDict=self._adaptor.connectionDictionary()
      dict_for_info=cnxDict.copy() ; dict_for_info['password']='xxxx'
      db_info('Opening connection to the DB with conn.Dict: %s'%str(dict_for_info))
      try:
        self._cnx=apply(self.adaptor().underlying_py_adaptor_module().connect,
                        (),
                        self._adaptor.dbAPI_connectionDictionaryForConnect(cnxDict))
      except:
        import StringIO, traceback
        exc=StringIO.StringIO()
        traceback.print_exc(file=exc)
        reason=exc.getvalue()
        del exc
        db_fatal('Unable to open connexion w/ connectionDictionary=%s\nReason:\n%s'%(dict_for_info, reason))
        raise GeneralAdaptorException, 'Unable to open connexion w/ connectionDictionary=%s\nReason:\n%s'%(dict_for_info, reason)

def __abstract__():
  raise 'Unimplemented', 'abstract method, should be implemented in subclasses'
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.