AbstractDBAPI2AdaptorChannel.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 » AbstractDBAPI2AdaptorChannel.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.
#-----------------------------------------------------------------------------


"""
AbstractDBAPI2Adaptor

  CVS information

    $Id: AbstractDBAPI2AdaptorChannel.py 933 2004-08-02 19:58:54Z sbigaret $
  
"""

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

from Modeling.logging import db_info,db_trace,db_error,warn
import sys

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

# Interfaces
from Modeling.interfaces.AdaptorChannel import IAdaptorChannel

class AbstractDBAPI2AdaptorChannel(AdaptorChannel):
  """
  Your inheriting concrete Adaptor class **must** override:

    - primaryKeysForNewRowsWithEntity()

  You normally do not need to override other methods. In particular,
  dbAPI_cursor() does not need to be overridden --but you will use it to
  access the underlying cursor.
  
  """
  
  __implements__ = (IAdaptorChannel,)

  # for testing purposes only
  _count_for_execute=0

  def __init__(self, anAdaptorContext):
    "See Modeling.interfaces.AdaptorChannel for details"
    AdaptorChannel.__init__.im_func(self, anAdaptorContext)
    self.__cursor=None
    self.__attrToFetch=[]
    self.__isFetchInProgress=0
    
  def attributesToFetch(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    return tuple(self.__attrToFetch)
  
  def cancelFetch(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__isFetchInProgress=0
    self.__attrToFetch=[]
    
  def closeChannel(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    db_trace('Closing adaptorChannel %s (%s)'%(str(self), hex(id(self))))
    self.cancelFetch() ##
    if self.__cursor is not None:
      # This may happen when, e.g., saveChanges() is sent to an EditingContext
      # but no changes needs to be done hence the channel was not opened
      self.__cursor.close()
      self.__cursor=None
      self._adaptorContext.adaptorChannelDidClose(self)
    else:
      warn('Closing an already closed channel!')
    
  def deleteRowsDescribedByQualifier(self, aQualifier, anEntity):
    """
    Builds the DELETE SQLExpression for 'aQualifier' and 'anEntity' ans
    executes it. Returns the number of rows that were deleted.
    
    Raises GeneralAdaptorException if the channel is not opened, or if it is
    fetching, or if its AdaptorContext has no transaction in progress.
    
    See Modeling.interfaces.AdaptorChannel for details
    """
    openTrans=self._adaptorContext.hasOpenTransaction()
    if not openTrans:
        raise GeneralAdaptorException, "Invalid state: channel's context has no transaction in progress"
    if not self.isOpen():
        raise GeneralAdaptorException, 'Invalid state: channel is not opened'
    #if self.isFetchInProgress():
    #    raise GeneralAdaptorException, 'Invalid state: channel has a fetch in progress'
    sqlExpr=self.adaptorContext().adaptor().expressionClass()(anEntity)
    sqlExpr.prepareDeleteExpressionForQualifier(aQualifier)
    statement=sqlExpr.statement()
    db_info('Evaluating: %s'%statement)
    try:
      self.__cursor.execute(statement)
      self.__class__._count_for_execute+=1
    except:
      exctype, value = sys.exc_info()[:2]
      msg="Couldn't evaluate expression %s. Reason: %s:%s"%(statement, exctype, value)
      db_error(msg)
      raise GeneralAdaptorException, msg
    #import pdb ; pdb.set_trace()
    return self.__cursor.rowcount
    
  def describeModelWithTableNames(self, tableNames):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__unimplemented__()
    
  def describeResults(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__unimplemented__()
    
  def describeStoredProcedureNames(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__unimplemented__()
    
  def describeTableNames(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__unimplemented__()
    
  def evaluateExpression(self, anSQLexpression):
    "See Modeling.interfaces.AdaptorChannel for details"
    #
    openTrans=self._adaptorContext.hasOpenTransaction()
    if not openTrans:
      #if self.isFetchInProgress():
      #  raise GeneralAdaptorException, 'Invalid state: channel has a fetch in progress'
      self._adaptorContext.beginTransaction()
      #self.__isFetchInProgress=1
    wasOpened=self.isOpen()
    if not wasOpened: self.openChannel()
    statement=anSQLexpression.statement()
    db_info('Evaluating: %s'%statement)
    try:
      self.__cursor.execute(statement)
      self.__class__._count_for_execute+=1
    except:
      exctype, value = sys.exc_info()[:2]
      msg="Couldn't evaluate expression %s. Reason: %s:%s"%(statement, exctype, value)
      db_error(msg)
      if not openTrans:
        self._adaptorContext.rollbackTransaction()
      #if not wasOpened: self.closeChannel()
      #self.cancelFetch()
      raise GeneralAdaptorException, msg
    
    if not openTrans:
      self._adaptorContext.commitTransaction()
      #self.cancelFetch() # No!!!! Wait for fetchRow() to do that!
    #if not wasOpened: self.closeChannel()

  def executeStoredProcedure(self, aStoredProcedure, values):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__unimplemented__()
    
  def fetchRow(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    #if not self.isFetchInProgress():
    #  raise GeneralAdaptorException, 'Invalid state: channel has no fetch in progress'
    res=self.__cursor.fetchone() # also has: description
    dict=None
    if res is None:
      self.cancelFetch()
    else: # build dictionary
      dict={}; idx=0
      for key in map(lambda o: o.name(), self.attributesToFetch()):
        dict[key]=res[idx]
        idx+=1
    db_trace('rowcount: %i Returning: %s'%(self.__cursor.rowcount, str(dict)))
    return dict

  def insertRow(self, row, anEntity):
    "See Modeling.interfaces.AdaptorChannel for details"
    sqlExpr=self.adaptorContext().adaptor().expressionClass()(anEntity)
    sqlExpr.prepareInsertExpressionWithRow(row)
    statement=sqlExpr.statement()
    db_info('Evaluating: %s'%statement)
    try:
      self.__cursor.execute(statement)
      self.__class__._count_for_execute+=1
    except:
      exctype, value = sys.exc_info()[:2]
      msg="Couldn't evaluate expression %s. Reason: %s:%s"%(statement, exctype, value)
      db_error(msg)
      raise GeneralAdaptorException, msg
    
  def isFetchInProgress(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    return self.__isFetchInProgress
  
  def isOpen(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    if self.__cursor: return 1
    else: return 0
    
  def openChannel(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    if not self.__cursor: # silently ignores already opened channel
      db_trace('Opening channel %s (%s)'%(str(self), hex(id(self))))
      self.__cursor=self.adaptorContext().dbAPI_cursorForAdaptorChannel()
    
  def primaryKeysForNewRowsWithEntity(self, count, anEntity):
    """
    Generates and returns a list of dictionaries, whose keys are
    PK attributes' names and values the corresponding PK value.

    If 'anEntity' defines more than one PK (compound primary key), returns an
    empty list.

    Parameters:

      count -- the number of primary keys to generate

      anEntity -- the entity for which PKs are generated

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

    This method is correlated with the implementation of your concrete
    SchemaGeneration's methods:
    
      - primaryKeySupportStatementsForEntityGroup()
      
      - dropPrimaryKeySupportStatementsForEntityGroup()

    See also: Modeling.AdaptorChannel.primaryKeysForNewRowsWithEntity()
    """
    __abstract__()
      
  def returnValuesForLastStoredProcedureInvocation(self):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__unimplemented__()
    
  def rowCountForSelectAttributes(self, attributes, aFetchSpecification,
                                  shouldLock, anEntity):
    """
    """
    self.__isFetchInProgress=1
    try:
      self.setAttributesToFetch(attributes)
      sqlExpr=self.adaptorContext().adaptor().expressionClass()(anEntity)
      sqlExpr.prepareSelectCountExpressionWithAttributes(attributes,
                                                         shouldLock,
                                                         aFetchSpecification)
      statement=sqlExpr.statement()
      db_info('Evaluating: %s'%statement)
      try:
        self.__cursor.execute(statement)
        self.__class__._count_for_execute+=1
      except:
        exctype, value = sys.exc_info()[:2]
        msg="Couldn't evaluate expression %s. Reason: %s:%s"%(statement, exctype, value)
        db_error(msg)
        raise GeneralAdaptorException, msg
      return self.__cursor.fetchone()[0]
    finally:
      self.cancelFetch()

  def selectAttributes(self, attributes, aFetchSpecification, shouldLock,
                       anEntity):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__isFetchInProgress=1

    self.setAttributesToFetch(attributes)
    sqlExpr=self.adaptorContext().adaptor().expressionClass()(anEntity)
    sqlExpr.prepareSelectExpressionWithAttributes(attributes, shouldLock,
                                                  aFetchSpecification)
    statement=sqlExpr.statement()
    db_info('Evaluating: %s'%statement)
    try:
      self.__cursor.execute(statement)
      self.__class__._count_for_execute+=1
    except:
      exctype, value = sys.exc_info()[:2]
      msg="Couldn't evaluate expression %s. Reason: %s:%s"%(statement, exctype, value)
      db_error(msg)
      self.cancelFetch()
      raise GeneralAdaptorException, msg
    
  def setAttributesToFetch(self, attributes):
    "See Modeling.interfaces.AdaptorChannel for details"
    self.__attrToFetch=attributes
    
  def updateValuesInRowsDescribedByQualifier(self, row, aQualifier, anEntity):
    """
    Builds the UPDATE SQLExpression for 'row', 'aQualifier' and 'anEntity' and
    executes it.

    Returns the number of rows that were updated.
    
    Raises GeneralAdaptorException if the channel is not opened, or if it is
    fetching, or if its AdaptorContext has no transaction in progress.
    
    See Modeling.interfaces.AdaptorChannel for details
    """
    #if self.isFetchInProgress():
    #    raise GeneralAdaptorException, 'Invalid state: channel has a fetch in progress'
    #self.__isFetchInProgress=1
    openTrans=self._adaptorContext.hasOpenTransaction()
    if not openTrans:
        raise GeneralAdaptorException, "Invalid state: channel's context has no transaction in progress"
    if not self.isOpen():
        raise GeneralAdaptorException, 'Invalid state: channel is not opened'
    sqlExpr=self.adaptorContext().adaptor().expressionClass()(anEntity)
    sqlExpr.prepareUpdateExpressionWithRow(row, aQualifier)
    statement=sqlExpr.statement()
    db_info('Evaluating: %s'%statement)
    try:
      self.__cursor.execute(statement)
      self.__class__._count_for_execute+=1
    except:
      exctype, value = sys.exc_info()[:2]
      msg="Couldn't evaluate expression %s. Reason: %s:%s"%(statement, exctype, value)
      db_error(msg)
      raise GeneralAdaptorException, msg
    return self.__cursor.rowcount
    
  ##def setDelegate(self, aDelegate):
  ##  "See Modeling.interfaces.Adaptor for details"
  ##  Adaptor.setDelegate.im_func(self, aDelegate)

  def __unimplemented__(self):
    raise 'Unimplemented', 'Unimplemented yet'

  # Specific to the AbstractDBAPI2AdaptorChannel
  def dbAPI_cursor(self):
    return self.__cursor
  
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.