#! /usr/bin/env python

# Copyright (c) 2000 Roman Milner
# See the file COPYING for more information

import sys
from time import localtime, time, mktime
import string
import exceptions

try:
    import PySQLRClient
    SQLR_type = 'c'
except ImportError:
    import PySQLRAPI
    SQLR_type = 'pure'

apilevel = '2.0'
threadsafety = 0
paramstyle = 'pyformat'


def switch_api(api_type):
    global SQLR_type, PySQLRClient, PySQLRAPI
    if api_type == 'c':
        import PySQLRClient
        SQLR_type = 'c'
    else:
        import PySQLRAPI
        SQLR_type = 'pure'
        

class Error(exceptions.StandardError):
    pass

class Warning(exceptions.StandardError):
    pass

class InterfaceError(Error):
    pass

class DatabaseError(Error):
    pass

class InternalError(DatabaseError):
    pass

class OperationalError(DatabaseError):
    pass

class ProgrammingError(DatabaseError):
    pass

class IntegrityError(DatabaseError):
    pass

class DataError(DatabaseError):
    pass

class NotSupportedError(DatabaseError):
    pass


def connect(connection_parm, user, password):
    "takes (host, port), user, password"
    return SQLR(connection_parm, user, password)


class SQLR:

    def __init__(self, connection_parm, user, password):
        self.connection_parm = connection_parm
        self.user = user
        self.password = password
        self.get_con()
        self.arraysize = 1

    def get_con(self):
        if SQLR_type == 'c':
            self.cur_con = PySQLRClient.sqlrclient(self.connection_parm, self.user, self.password, 1, 10)
        else:
            a = PySQLRAPI.ListenerClient(self.connection_parm, self.user, self.password)
            self.cur_con = a.get_connection()
        return self.cur_con

    def close(self):
        self.cur_con.endSession()
        del(self.cur_con)

    def commit(self):
        try:
            self.cur_con.sendQuery('commit')
        except AttributeError:
            self.get_con()
            self.commit()

    def rollback(self):
        pass

    def cursor(self):
        return SQLR_Cursor(self.cur_con, self.connection_parm, self.user, self.password, self)


class SQLR_Cursor:


    def __init__(self, con, connection_parm, user, password, other):
        self.other  = other
        self.connection_parm = connection_parm
        self.cur_con = con
        self.user = user
        self.password = password
        self.cur_row = 0
        self.arraysize = 1
        
    def execute(self, operation):
        self.cur_row = 0
        self.cur_operation = operation
        #ssql = string.join(string.split(string.strip(operation)), ' ')
        try:
            self.cur_con.sendQuery(operation)
        except AttributeError:
            self.cur_con = self.other.get_con()
            self.cur_con.sendQuery(operation)
        the_error = self.cur_con.errorMessage()
        if the_error:
            raise DatabaseError, '<pre>%s</pre>' % the_error
        self.__set_description()
        
    def fetchone(self):
        rc =  self.__get_row()
        return rc

    def fetchmany(self, size=None):
        if not size:
            size = self.arraysize
        num_rows = self.cur_con.rowCount()
        if size >= num_rows:
            size = num_rows #-1
        rc = self.cur_con.getRowRange(self.cur_row, size)
        self.cur_row = size
        return rc

    def fetchall(self):
        rc = []
        num_rows = self.cur_con.rowCount()
        for row in range(self.cur_row, num_rows):
            rc.append(self.__get_row())
        return rc

    def setinputsizes(self):
        pass

    def close(self):
        pass

    def __get_row(self):
        row = self.cur_con.getRow(self.cur_row)
        self.cur_row = self.cur_row + 1
        return row

    def __set_description(self):
        desc = []
        col_c = self.cur_con.colCount()
        if not col_c:
            self.description = []
            return None
        for field in range(col_c):
            row = []
            row.append(self.cur_con.getColumnName(field),)
            row.append(self.cur_con.getColumnType(field),)
            row.append(self.cur_con.getColumnLength(field))
            desc.append(tuple(row))
        self.description = tuple(desc)
        return tuple(desc)