# -*- coding: utf8 -*-
'''
DB MODULE - DB2
*******************************
***  DB MODULE - DB2
*******************************
$RCSfile: dbmod_db2.py,v $
$Revision: 939 $
$Author: markus $
$Date: 2008-11-17 22:33:56 +0100 (Mo, 17. Nov 2008) $

The biocase.wrapper database module to access generic ODBC datasources.
You will need the mxODBC module to connect to a DSN via ODBC.
'''

import os
from string                             import join
from biocase.wrapper.errorclasses       import *
from biocase.wrapper.static_functions   import unique
from biocase.wrapper.typeconverter      import DBtransformerClass
from biocase.wrapper.sql.operators      import getWhereObjTables
from biocase.wrapper.sql.base           import sqlBase
from biocase.wrapper.sql.select         import sqlSelect

import logging
log = logging.getLogger("pywrapper.dbmod")

# uses inherited ANSI SQL
        

# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
class DBmodule(sqlSelect):
    __version__ = '0.7 using pyDB2 ?'
    __dbmod__   = u'DB2 DB module'
    
    def __repr__(self):
        return ("%s v%s" %(self.__class__.__dbmod__, self.__class__.__version__) )

    def __init__(self, psfObj):
        # setting the psfObj reference to self.psfObj
        sqlSelect.__init__(self, psfObj)
        #
        # connect to DB
        self.conn = self.createDBconnection()
        #
        # read DB 8bit encoding
        log.debug("8bit DB Encoding: %s"%(psfObj.encoding))
        self.conn.encoding = psfObj.encoding

    def __del__(self):
        # release db connection
        try:
            self.conn.close()
            log.debug("successfully closed DB2 db connection.")
        except:
            log.debug("error when trying to close the DB2 db connection.")
            pass

    def createDBconnection(self):
        try:
            import DB2
        except:
            log.debug("The pyDB2 module is not properly installed on your system. You need this module to connect to DB2 sources.")
            raise
        self.__class__.__version__ = self.__class__.__version__[:-1]+DB2.VERSION
        #
        # connect
        #
        # import OS specific DB2 version:
        # 'posix', 'nt', 'dos', 'mac', 'os2', 'ce', 'java', 'riscos'
        if os.name in ("nt","dos"):
            import DB2  as DB2
        elif os.name in ("unix","posix","java"):
            import DB2  as DB2
        else:
            raise ConnectionError(os=os.name)
        conn = DB2.connect(dsn=self.psfObj.database,uid=self.psfObj.user,pwd=self.psfObj.password)
        #conn.stringformat = odbc.NATIVE_UNICODE_STRINGFORMAT
        return conn
            
    def execSelect(self, selectList, whereObj=None, recID=None):
        '''execute a select statement. the selectList gives the wanted attribute/alias tuples and the optional whereObj the WHERE filter.'''
        # get SQL string
        (sql, paras) = self.select(selectList, whereObj)
        # execute statement
        return self.execSQL(sql, paras)

    def execSQL(self, sql, paras):
        # close existing connection and create a new one!
        if self.conn is not None:
            self.conn.close()
        self.conn = self.createDBconnection()
        self.c = self.conn.cursor()
        # execute SQL statement and return result
        log.debug("start DB query")
        try:
            sql = sql.encode(self.psfObj.encoding)
            log.debug("Executing SQL: '%s' with parameters: %s" %(sql, "'"+join([unicode(p) for p in paras], "', '")+"'"))
        except:
            self.c.close()
            raise SQLunicodeGenerationError()
        try:
            self.c.execute(sql, paras)
        except:
            raise SQLError(sql, paras)
        tmp = self.c.fetchall()
        log.debug("end DB query")
        log.info("Hits: %i"%len(tmp))
        if log.isEnabledFor(logging.DEBUG):
            try:
                if type(tmp) == type('a'):
                    rsString = unicode(tmp, self.psfObj.encoding)
                else:
                    rsString = unicode(tmp)
                log.debug("Resulting Recordset:  "+rsString)
            except:
                log.debug("The Recordset Result could not be converted to a string")
        # close cursor and connection!
        self.c.close()
        self.conn.close()
        return tmp
    
