# -*- coding: utf8 -*-
'''
DB MODULE - FoxPro ODBC
*******************************
***  DB MODULE - FoxPro ODBC
*******************************
$RCSfile: dbmod_odbc_foxpro.py,v $
$Revision: 875 $
$Author: markus $
$Date: 2008-04-24 02:23:32 +0200 (Do, 24. Apr 2008) $

The pywrapper database module to access foxpro ODBC datasources.
You will need the mxODBC module to connect to a DSN via ODBC.
The FoxPro ODBC driver does not seem to support parameter passing.
Therefore no real unicode can be passed and all parameters are encoded first into the PSF setting.
'''

import os
from string                             import join
from biocase.wrapper.errorclasses       import *
from biocase.wrapper.sql.base           import sqlBase
from biocase.wrapper.dbmod.base_dbmod   import DBBasemodule

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


# uses inherited ANSI SQL apart from this:
#
# no IN operator supported
sqlBase.multipleCOP['in'] = None
sqlBase.templates['select-limit'] = 'SELECT DISTINCT TOP #3 #1 FROM #2'
#sqlBase.templates['attribute'] = '[#1].[#2]'
#sqlBase.templates['table'] = '[#1]'

__syntax__ = '''SELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] [Alias.] Select_Item 
   [[AS] Column_Name] [, [Alias.] Select_Item [[AS] Column_Name] ...] 
   FROM [FORCE] [DatabaseName!] Table [[AS] Local_Alias] 
   [ [INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] JOIN DatabaseName!] 
      Table [[AS] Local_Alias] [ON JoinCondition ...]
      [[INTO Destination] | [TO FILE FileName [ADDITIVE] | TO PRINTER [PROMPT] | TO SCREEN]] 
      [PREFERENCE PreferenceName] [NOCONSOLE] [PLAIN] [NOWAIT]
      [WHERE JoinCondition [AND JoinCondition ...] [AND | OR FilterCondition [AND | OR FilterCondition ...]]]
   [GROUP BY GroupColumn [, GroupColumn ...]] [HAVING FilterCondition] [UNION [ALL] SELECTCommand] 
   [ORDER BY Order_Item [ASC | DESC] [, Order_Item [ASC | DESC] ...]]
'''     

# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
class DBmodule(DBBasemodule):
    __version__ = '0.21 using mxODBC ?'
    __dbmod__   = u'FoxPro ODBC DB module'
    

    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def __init__(self, psfObj):
                # call createDBconnection method
        DBBasemodule.__init__(self, psfObj)
        # dont use parameters but integrate all parameters into SQL strings:
        self.trans.integrateParametersInSQLString()
        #
        # read DB 8bit encoding
        #
        log.debug("8bit DB Encoding: %s"%(psfObj.encoding))
        self.conn.encoding = psfObj.encoding

    # ------------------   FUNCTION OVERLOAD OF BASE DBMOD MODULE   ------------------
    # --------------------------------------------------------------------------------
    def createDBconnection(self):
        try:
            import mx.ODBC
        except:
            raise DbModuleMissingError('mx_ODBC')
        self.__class__.__version__ = self.__class__.__version__[:-1]+mx.ODBC.__version__
        #
        # connect
        #
        # import OS specific ODBC version:
        # 'posix', 'nt', 'dos', 'mac', 'os2', 'ce', 'java', 'riscos'
        if os.name in ("nt","dos"):
            import mx.ODBC.Windows  as odbc
        elif os.name in ("unix","posix","java"):
            import mx.ODBC.unixODBC     as odbc
        else:
            raise ConnectionError(os=os.name)
        loginParas = "DSN=%s;UID=%s;PWD=%s" % (self.psfObj.database, self.psfObj.user ,self.psfObj.password )
        conn = odbc.DriverConnect( loginParas )
        conn.stringformat = odbc.NATIVE_UNICODE_STRINGFORMAT
        return conn
        


    
    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def execDistinct(self, selectList, whereObj=None):
        '''Select distinct statement. The default routine does a regular select and filters only unique records via Python.'''
        # build SELECT clause
        select = "DISTINCT %s" %(join( [self.joinDBAttrObj(dbt) for dbt in selectList], ', ' ) )
        # get SQL string
        (sql, paras) = self.select(selectList, whereObj, selectReplacementString=select)
        # execute statement
        return [r[0] for r in self.execSQL(sql, paras)]

    
