sapdbapi.py :  » Database » PyDO » skunkweb-3.4.4 » pylibs » PyDO » 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 » PyDO 
PyDO » skunkweb 3.4.4 » pylibs » PyDO » sapdbapi.py
#
# sapdbapi.py A implementation of the Python database API 20 for SAP DB
#
#     ========== licence begin LGPL
#     Copyright (C) 2001 SAP AG
#
#     This library is free software; you can redistribute it and/or
#     modify it under the terms of the GNU Lesser General Public
#     License as published by the Free Software Foundation; either
#     version 2.1 of the License, or (at your option) any later version.
#
#     This library is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#     Lesser General Public License for more details.
#
#     You should have received a copy of the GNU Lesser General Public
#     License along with this library; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#     ========== licence end

import string
from exceptions import StandardError
import time
import cStringIO

try:
    import thread
    _connectionLock = thread.allocate_lock ()
except ImportError:
    class _PseudoLock:
        def acquire (self, waitflag = 0):
            pass

        def release (self):
            pass

        def locked (self):
            return None

    _connectionLock = _PseudoLock ()

import sapdb

apilevel = '2.0'

threadsafety = 1

paramstyle = 'named'

def wrapCall (call, *args):
    try:
        # print call, args
        result = apply (call, args)
        # print '==>', result
    except sapdb.SQLError, err:
        raise ProgrammingError (err)
    except sapdb.CommunicationError, err:
        raise OperationalError (err)
    return result

#
# data types
#
class _AbstractType:
    def __init__ (self, name, sqlNames):
        self.name = name
        self.sqlNames = sqlNames

    def __str__ (self):
        return self.name

    def __cmp__ (self, other):
        if other in self.sqlNames:
            return 0
        else:
            return -1

STRING = _AbstractType ('STRING',
    ['Char', 'Varchar', 'Long'])
BINARY = _AbstractType ('BINARY',
    ['Char Binary', 'Varchar Binary', 'Long Binary', 'Long byte_t'])
NUMBER = _AbstractType ('NUMBER',
    ['Integer', 'Smallint', 'Decimal', 'Fixed', 'Float'])
DATETIME = _AbstractType ('DATETIME',
    ['Date', 'Time', 'Timestamp'])
ROWID = None

#
# connection class
#
class Connection:
    def __init__ (self, user, password, database, host = '', **config):
        configList = map (lambda item: item [0] + '=' + item [1], config.items ())
        configString = string.join (configList, '&')
        try:
            _connectionLock.acquire ()
            self.__connection = wrapCall (sapdb.connect, user, password,
                database, host, configString)
        finally:
            _connectionLock.release ()
        if host:
            self.id = user + '@' + host + ':' + database
        else:
            self.id = user + '@' + database
        self.typeTranslations = None

    def close (self):
        try:
            _connectionLock.acquire ()
            if self.__connection is not None:
                wrapCall (self.__connection.release)
        finally:
            _connectionLock.release ()

    __del__ = close
    def commit (self):
        wrapCall (self.__connection.commit)

    def rollback (self):
        wrapCall (self.__connection.rollback)

    def cursor (self):
        result = Cursor (self.__connection)
        if self.typeTranslations != None:
            result.setTypeTranslation (self.typeTranslations)
        return result

    def __str__ (self):
        return '<sapdbapi.Connection ' + self.id + '>'

    def setTypeTranslation (self, transDict):
        self.typeTranslations = transDict

connect = Connection

#
#  cursor class
#
class Cursor:
    def __init__ (self, rawConnection):
        self.__connection = rawConnection
        self.description = None
        self.rowcount = -1
        self.arraysize = 1
        self.__prepared = None
        self.__lastop = None
        self.__cursor = None
        self.__typeTranslation = {}

    def close (self):
        try:
            if self.__prepared:
                self.__prepared.close ()
                self.__prepared = None
        except:
            pass
        try:
            if self.__cursor:
                self.__cursor.close ()
                self.__cursor = None
        except:
            pass
        self.__connection = None

    def __handleResult (self, result):
        if isinstance (result, sapdb.SapDB_ResultSet):
            self.__cursor = result
            self.__setDescription (result)
            if self.__typeTranslation:
                self.__instantiateTranslation ()
            result = self
        else:
            self.__cursor = None
        return result

    def __setDescription (self, cursor):
        self.description = description = []
        for i in xrange (cursor.columnCount ()):
            name, typename, size, frac = cursor.columnInfo (i)
            description.append ((name, typename, size, size, size, frac, 1))


    def __executeDirect (self, operation):
        result = self.__connection.sql (operation)
        return self.__handleResult (result)

    def __getParsed (self, operation):
        if operation and (self.__lastop != operation):
            self.__parsed = self.__connection.prepare (operation)
            self.__lastop = operation
        return self.__parsed

    def __executeParsed (self, parsed, arguments):
        return self.__handleResult (self.__parsed.execute (arguments))

    def execute (self, operation, parameters = None):
        if parameters == None:
            result = wrapCall (self.__executeDirect, operation)
        else:
            parsed = self.__getParsed (operation)
            result = wrapCall (self.__executeParsed, parsed, parameters)
        return result

    def __executemany (self, operation, seq_of_parameters):
        parsed = self.__getParsed (operation)
        for item in seq_of_parameters:
            parsed.execute (item)

    def executemany (self, operation, seq_of_parameters):
        wrapCall (self.__executemany, operation, seq_of_parameters)

    def __getCursor (self):
        result = self.__cursor
        if not result:
            exc = ProgrammingError ()
            exc.message = 'Not a cursor'
            raise exc
        return result

    def __fetchone (self):
        cursor = self.__getCursor ()
        return self.nextFromCursor (cursor)

    def fetchone (self):
        return wrapCall (self.__fetchone)

    def __fetchmany (self, arraysize):
        cursor = self.__getCursor ()
        result = []
        for i in xrange (arraysize):
            row = self.nextFromCursor (cursor)
            if not row:
                break
            result.append (row)
        return result

    def fetchmany (self, size = None):
        if size == None:
            size = self.arraysize
        return wrapCall (self.__fetchmany, size)

    def __fetchall (self):
        cursor = self.__getCursor ()
        result = []
        while 1:
            row = self.nextFromCursor (cursor)
            if not row:
                break
            result.append (row)
        return result

    def fetchall (self):
        return wrapCall (self.__fetchall)

    def setinputsizes (self, sizes):
        pass

    def setoutputsizes (self, size, column = None):
        pass

    def setTranslation (self, translatorList):
        # TODO: make sure the count equals the number of output columns
        self.__translatorList = translatorList
        self.nextFromCursor = self.__nextTranslatedFromCursor

    def __nextTranslatedFromCursor (self, cursor):
        row = cursor.next ()
        if not row:
            return None
        result = [None] * len (row)
        for i in xrange (len (row)):
            translator = self.__translatorList [i]
            if translator is None:
                result [i] = row [i]
            else:
                result [i] = translator (row [i])
        return tuple (result)

    def __nextRawFromCursor (self, cursor):
        return cursor.next ()

    nextFromCursor = __nextRawFromCursor   # untranslated is the default

    def setTypeTranslation (self, transDict):
        self.__typeTranslation.update (transDict)
        if self.__cursor:
            self.__instantiateTranslation ()

    def __instantiateTranslation (self):
        cursor = self.__cursor
        colCount = cursor.columnCount ()
        translations = [None] * colCount
        transDict = self.__typeTranslation
        for i in xrange (colCount):
            typeName = cursor.columnInfo (i) [1]
            try:
                translations [i] = transDict [typeName]
            except KeyError:
                pass
        self.setTranslation (translations)

    def callproc (self, procname, parameters = None):
        if parameters:
            questionmarks = '?' + ', ?' * (len (parameters) - 1)
        procCmd = 'call ' + procname + '(' + questionmarks + ')'
        parsed = self.__getParsed (procCmd)
        resultValues = wrapCall (parsed.execute, parameters)
        desc = parsed.getDescription ()
        resultIndex = 0
        for paramIndex in xrange (len (desc)):
            if desc [paramIndex] [-1] in ['OUT', 'INOUT']:
                parameters [paramIndex] = resultValues [resultIndex]
                resultIndex = resultIndex + 1

#
# exception classes
#
class Error (StandardError):
    __internalException = None
    def __init__ (self, exception = None):
        StandardError.__init__ (self)
        if exception:
            self.__dict__.update (exception.__dict__)
            self.__internalException = exception

    def __str__ (self):
        if self.__internalException:
            return str (self.__internalException)
        else:
            return StandardError.__str__ (self)

class DatabaseError (Error):
    pass

class OperationalError (DatabaseError):
    pass

class ProgrammingError (DatabaseError):
    pass

#
# input conversions
#

def Date (year, month, day):
    return "%04d%02d%02d" % (year, month, day)

def Time (hour, minute, second):
    return "%04d%02d%02d" % (hour, minute, second)

def Timestamp (year, month, day, hour, minute, second, micros = 0):
    return "%04d%02d%02d%02d%02d%02d%06d" % (year, month, day, hour, minute, second, micros)

def DateFromTicks (ticks):
    return apply (Date, time.localtime (ticks) [:3])

def TimeFromTicks (ticks):
    return apply (Time, time.localtime (ticks) [3:6])

def TimestampFromTicks (ticks):
    return apply (Timestamp, time.localtime (ticks) [:6])


def Binary (data):
    return cStringIO.StringIO (data)

#
# output conversions
#
# Date: YYYYMMDD
# Time: 00HHMMSS
# Timestamp: YYYYMMDDHHMMSSmmmmmm

def dateTuple (sapdbDate):
    if sapdbDate is None:
        return None
    return int (sapdbDate[:4]), int (sapdbDate[4:6]), int (sapdbDate[6:])

def timeTuple (sapdbTime):
    if sapdbTime is None:
        return None
    return int (sapdbTime[2:4]), int (sapdbTime[4:6]), int (sapdbTime[6:])

def timestampTuple (sapdbTimestamp):
    if sapdbTimestamp is None:
        return None
    return time.localtime (timestampVal (sapdbTimestamp))

tupleTranslation = {
    'Date': dateTuple,
    'Time': timeTuple,
    'Timestamp': timestampTuple,
}

def dateVal (sapdbDate):
    if sapdbDate is None:
        return None
    year, month, day = dateTuple (sapdbDate)
    return time.mktime ((year, month, day, -1, -1, -1, -1, -1, -1,))

def timeVal (sapdbTime):
    if sapdbTime is None:
        return None
    hour, minute, second = timeTuple (sapdbTime)
    return time.mktime ((1970, 1, 2, hour, minute, second, -1, -1, -1,))

def timestampVal (sapdbTimestamp):
    if sapdbTimestamp is None:
        return None
    year = int (sapdbTimestamp [:4])
    month = int (sapdbTimestamp [4:6])
    day = int (sapdbTimestamp [6:8])
    hour = int (sapdbTimestamp [8:10])
    minute = int (sapdbTimestamp [10:12])
    second = int (sapdbTimestamp [12:14])
    micros = int (sapdbTimestamp [14:])
    return time.mktime ((year, month, day, hour, minute, second, -1, -1, -1,))


valTranslation = {
    'Date': dateVal,
    'Time': timeVal,
    'Timestamp': timestampVal,
}

class AbstractTimeFormat:
    def __init__ (self, fmt):
        self.fmt = fmt

    def __call__ (self, sapdbString):
        localtime = time.localtime ( self.toTime(sapdbString))
        return time.strftime (self.fmt, localtime)

class DateFormat (AbstractTimeFormat):
    def toTime (self, sapdbDate):
        return dateVal (sapdbDate)

class TimeFormat (AbstractTimeFormat):
    def toTime (self, sapdbTime):
        return timeVal (sapdbTime)

class TimestampFormat (AbstractTimeFormat):
    def toTime (self, sapdbTimestamp):
        return timestampVal (sapdbTimestamp)

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.