Beispiel #1
0
    def get_value(self, var, pos):
        """Returns the value stored at the given array position."""
        if not python3_or_better():
            types = (vt_Boolean, vt_Integer)
        else:
            types = (vt_Boolean,)

        typed_data = self.get_typed_data(var)

        if var.type in types:
            c_integer_value = ctypes.c_long()
            status = oci.OCINumberToInt(
                var.environment.error_handle,
                byref(typed_data[pos]),
                ctypes.sizeof(c_integer_value),
                oci.OCI_NUMBER_SIGNED,
                byref(c_integer_value),
            )
            integer_value = c_integer_value.value
            var.environment.check_for_error(status, "NumberVar_GetValue(): as integer")

            if not python3_or_better():
                if var.type is vt_Integer:
                    return integer_value

            return bool(integer_value)

        if var.type in (vt_NumberAsString, vt_LongInteger):
            c_string = ctypes.create_string_buffer(200)
            cast_c_string = ctypes.cast(c_string, oci.POINTER(oci.ub1))

            c_string_length = oci.ub4()
            c_string_length.value = ctypes.sizeof(c_string)

            typed_data = self.get_typed_data(var)
            status = oci.OCINumberToText(
                var.environment.error_handle,
                byref(typed_data[pos]),
                var.environment.numberToStringFormatBuffer.cast_ptr,
                var.environment.numberToStringFormatBuffer.size,
                None,
                0,
                byref(c_string_length),
                cast_c_string,
            )
            var.environment.check_for_error(status, "NumberVar_GetValue(): as string")

            python_string = c_string.value

            unicode_str = cxString_from_encoded_string(python_string, var.environment.encoding)

            if var.type is vt_NumberAsString:
                return unicode_str

            try:
                return int(unicode_str)
            except ValueError:
                pass

        return oracle_number_to_python_float(var.environment, byref(typed_data[pos]))
    def get_value(self, var, pos):
        """Returns the value stored at the given array position."""
        if not python3_or_better():
            types = (vt_Boolean, vt_Integer)
        else:
            types = (vt_Boolean, )

        typed_data = self.get_typed_data(var)

        if var.type in types:
            c_integer_value = ctypes.c_long()
            status = oci.OCINumberToInt(var.environment.error_handle,
                                        byref(typed_data[pos]),
                                        ctypes.sizeof(c_integer_value),
                                        oci.OCI_NUMBER_SIGNED,
                                        byref(c_integer_value))
            integer_value = c_integer_value.value
            var.environment.check_for_error(
                status, "NumberVar_GetValue(): as integer")

            if not python3_or_better():
                if var.type is vt_Integer:
                    return integer_value

            return bool(integer_value)

        if var.type in (vt_NumberAsString, vt_LongInteger):
            c_string = ctypes.create_string_buffer(200)
            cast_c_string = ctypes.cast(c_string, oci.POINTER(oci.ub1))

            c_string_length = oci.ub4()
            c_string_length.value = ctypes.sizeof(c_string)

            typed_data = self.get_typed_data(var)
            status = oci.OCINumberToText(
                var.environment.error_handle, byref(typed_data[pos]),
                var.environment.numberToStringFormatBuffer.cast_ptr,
                var.environment.numberToStringFormatBuffer.size, None, 0,
                byref(c_string_length), cast_c_string)
            var.environment.check_for_error(status,
                                            "NumberVar_GetValue(): as string")

            python_string = c_string.value

            unicode_str = cxString_from_encoded_string(
                python_string, var.environment.encoding)

            if var.type is vt_NumberAsString:
                return unicode_str

            try:
                return int(unicode_str)
            except ValueError:
                pass

        return oracle_number_to_python_float(var.environment,
                                             byref(typed_data[pos]))
    def __init__(self):
        VariableType.__init__(self)
        #self.oci_type = None
        self.initialize_proc = None
        self.finalize_proc = None
        #self.pre_define_proc = self.pre_define
        self.post_define_proc = None
        self.pre_fetch_proc = None
        self.is_null_proc = None
        self.set_value_proc = self.set_value
        self.get_value_proc = self.get_value
        self.get_buffer_size_proc = None

        self.can_be_copied = True
        self.can_be_in_array = True

        # not standard variable type

        self.mapping_python_type_to_method = {
            long: self.set_value_from_long,
            bool: self.set_value_from_boolean,
            float: self.set_value_from_float,
            Decimal: self.set_value_from_decimal,
        }

        if not python3_or_better():
            self.mapping_python_type_to_method[
                int] = self.set_value_from_integer
Beispiel #4
0
    def pre_define(self, var, param):
        """Set the type of value (integer, float or string) that will be returned when values are fetched from this variable."""

        # if the return type has not already been specified, check to see if the
        # number can fit inside an integer by looking at the precision and scale
        if var.type is vt_Float:
            scale = OCIAttrGet(
                param,
                oci.OCI_HTYPE_DESCRIBE,
                oci.sb1,
                oci.OCI_ATTR_SCALE,
                var.environment,
                "NumberVar_PreDefine(): scale",
            )

            precision = OCIAttrGet(
                param,
                oci.OCI_HTYPE_DESCRIBE,
                oci.sb2,
                oci.OCI_ATTR_PRECISION,
                var.environment,
                "NumberVar_PreDefine(): precision",
            )

            if scale == 0 or (scale == -127 and precision == 0):
                var.type = vt_LongInteger

                if not python3_or_better():
                    if 0 < precision < 10:
                        var.type = vt_Integer
Beispiel #5
0
    def __init__(self):
        VariableType.__init__(self)
        # self.oci_type = None
        self.initialize_proc = None
        self.finalize_proc = None
        # self.pre_define_proc = self.pre_define
        self.post_define_proc = None
        self.pre_fetch_proc = None
        self.is_null_proc = None
        self.set_value_proc = self.set_value
        self.get_value_proc = self.get_value
        self.get_buffer_size_proc = None

        self.can_be_copied = True
        self.can_be_in_array = True

        # not standard variable type

        self.mapping_python_type_to_method = {
            long: self.set_value_from_long,
            bool: self.set_value_from_boolean,
            float: self.set_value_from_float,
            Decimal: self.set_value_from_decimal,
        }

        if not python3_or_better():
            self.mapping_python_type_to_method[int] = self.set_value_from_integer
    def type_by_oracle_data_type(self, oracle_data_type, charset_form):
        mapping = {
                    oci.SQLT_LNG: vt_LongString,
                    oci.SQLT_RDD: vt_Rowid,
                    oci.SQLT_BIN: vt_Binary,
                    oci.SQLT_LBI: vt_LongBinary,
                    oci.SQLT_NUM: vt_Float,
                    oci.SQLT_VNU: vt_Float,
                    oci.SQLT_DAT: vt_DateTime,
                    oci.SQLT_ODT: vt_DateTime,
                    oci.SQLT_DATE: vt_Timestamp,
                    oci.SQLT_TIMESTAMP: vt_Timestamp,
                    oci.SQLT_TIMESTAMP_TZ: vt_Timestamp,
                    oci.SQLT_TIMESTAMP_LTZ: vt_Timestamp,
                    oci.SQLT_INTERVAL_DS: vt_Interval,
                    oci.SQLT_BLOB: vt_BLOB,
                    oci.SQLT_BFILE: vt_BFILE,
                    oci.SQLT_RSET: vt_Cursor,
                    oci.SQLT_NTY: vt_Object,
                    #oci.SQLT_BFLOAT: vt_NativeFloat, # TODO: removed #ifdef SQLT_BFLOAT
                    #oci.SQLT_IBFLOAT: vt_NativeFloat,
                    #oci.SQLT_BDOUBLE: vt_NativeFloat,
                    #oci.SQLT_IBDOUBLE: vt_NativeFloat,
                  }

        if oracle_data_type == oci.SQLT_AFC:
            if not python3_or_better() and charset_form == oci.SQLCS_NCHAR:
                return vt_FixedNationalChar
            else:
                return vt_FixedChar

        if oracle_data_type == oci.SQLT_CHR:
            if not python3_or_better() and charset_form == oci.SQLCS_NCHAR:
                return vt_NationalCharString
            else:
                return vt_String
        
        if oracle_data_type == oci.SQLT_CLOB:
            if charset_form == oci.SQLCS_NCHAR:
                return vt_NCLOB
            else:
                return vt_CLOB
        
        try:
            return mapping[oracle_data_type]
        except KeyError:
            raise NotSupportedError("Variable_TypeByOracleDataType: unhandled data type %d" % oracle_data_type)
    def type_by_oracle_data_type(self, oracle_data_type, charset_form):
        mapping = {
            oci.SQLT_LNG: vt_LongString,
            oci.SQLT_RDD: vt_Rowid,
            oci.SQLT_BIN: vt_Binary,
            oci.SQLT_LBI: vt_LongBinary,
            oci.SQLT_NUM: vt_Float,
            oci.SQLT_VNU: vt_Float,
            oci.SQLT_DAT: vt_DateTime,
            oci.SQLT_ODT: vt_DateTime,
            oci.SQLT_DATE: vt_Timestamp,
            oci.SQLT_TIMESTAMP: vt_Timestamp,
            oci.SQLT_TIMESTAMP_TZ: vt_Timestamp,
            oci.SQLT_TIMESTAMP_LTZ: vt_Timestamp,
            oci.SQLT_INTERVAL_DS: vt_Interval,
            oci.SQLT_BLOB: vt_BLOB,
            oci.SQLT_BFILE: vt_BFILE,
            oci.SQLT_RSET: vt_Cursor,
            oci.SQLT_NTY: vt_Object,
            # oci.SQLT_BFLOAT: vt_NativeFloat, # TODO: removed #ifdef SQLT_BFLOAT
            # oci.SQLT_IBFLOAT: vt_NativeFloat,
            # oci.SQLT_BDOUBLE: vt_NativeFloat,
            # oci.SQLT_IBDOUBLE: vt_NativeFloat,
        }

        if oracle_data_type == oci.SQLT_AFC:
            if not python3_or_better() and charset_form == oci.SQLCS_NCHAR:
                return vt_FixedNationalChar
            else:
                return vt_FixedChar

        if oracle_data_type == oci.SQLT_CHR:
            if not python3_or_better() and charset_form == oci.SQLCS_NCHAR:
                return vt_NationalCharString
            else:
                return vt_String

        if oracle_data_type == oci.SQLT_CLOB:
            if charset_form == oci.SQLCS_NCHAR:
                return vt_NCLOB
            else:
                return vt_CLOB

        try:
            return mapping[oracle_data_type]
        except KeyError:
            raise NotSupportedError("Variable_TypeByOracleDataType: unhandled data type %d" % oracle_data_type)
Beispiel #8
0
    def internal_bind(self):
        """Allocate a variable and bind it to the given statement."""

        if self.is_array:
            alloc_elems = self.allocelems
            actual_elements_ref = byref(self.c_actual_elements)
        else:
            alloc_elems = 0
            actual_elements_ref = oci.POINTER(oci.ub4)()

        # perform the bind
        if self.bound_name:
            buffer = cxBuffer.new_from_object(self.bound_name,
                                              self.environment.encoding)
            status = oci.OCIBindByName(self.bound_cursor_handle,
                                       byref(self.bind_handle),
                                       self.environment.error_handle,
                                       buffer.cast_ptr, buffer.size, self.data,
                                       self.bufferSize, self.type.oracle_type,
                                       self.indicator, self.actual_length,
                                       self.return_code, alloc_elems,
                                       actual_elements_ref, oci.OCI_DEFAULT)
        else:
            status = oci.OCIBindByPos(self.bound_cursor_handle,
                                      byref(self.bind_handle),
                                      self.environment.error_handle,
                                      self.bound_pos, self.data,
                                      self.bufferSize, self.type.oracle_type,
                                      self.indicator, self.actual_length,
                                      self.return_code, alloc_elems,
                                      actual_elements_ref, oci.OCI_DEFAULT)

        self.environment.check_for_error(status, "Variable_InternalBind()")

        if not python3_or_better():
            # set the charset form and id if applicable
            if self.type.charset_form != oci.SQLCS_IMPLICIT:
                c_charset_form = oci.ub1(self.type.charset_form)
                status = oci.OCIAttrSet(self.bind_handle, oci.OCI_HTYPE_BIND,
                                        byref(c_charset_form), 0,
                                        oci.OCI_ATTR_CHARSET_FORM,
                                        self.environment.error_handle)
                self.environment.check_for_error(
                    status, "Variable_InternalBind(): set charset form")
                self.type.charset_form = c_charset_form.value

                c_buffer_size = oci.ub4(self.bufferSize)
                status = oci.OCIAttrSet(self.bind_handle, oci.OCI_HTYPE_BIND,
                                        byref(c_buffer_size), 0,
                                        oci.OCI_ATTR_MAXDATA_SIZE,
                                        self.environment.error_handle)
                self.environment.check_for_error(
                    status, "Variable_InternalBind(): set max data size")
                self.bufferSize = self.maxlength = c_buffer_size.value

        # set the max data size for strings
        self.set_max_data_size()
    def get_value(self, var, pos):
        """Returns the value stored at the given array position."""
        data_start_index = pos * var.bufferSize # was pointer arithmetic

        the_data = var.data[data_start_index:data_start_index+var.actual_length[pos]]
        if var.type is vt_Binary:
            return the_data
            
        if not python3_or_better():
            if var.type in (vt_FixedNationalChar, vt_NationalCharString):
                return the_data.decode(var.environment.nencoding)
    
        return cxString_from_encoded_string(the_data, var.environment.encoding)
Beispiel #10
0
    def get_value(self, var, pos):
        """Returns the value stored at the given array position."""
        data_start_index = pos * var.bufferSize  # was pointer arithmetic

        the_data = var.data[data_start_index:data_start_index +
                            var.actual_length[pos]]
        if var.type is vt_Binary:
            return the_data

        if not python3_or_better():
            if var.type in (vt_FixedNationalChar, vt_NationalCharString):
                return the_data.decode(var.environment.nencoding)

        return cxString_from_encoded_string(the_data, var.environment.encoding)
    def internal_bind(self):
        """Allocate a variable and bind it to the given statement."""

        if self.is_array:
            alloc_elems = self.allocelems
            actual_elements_ref = byref(self.c_actual_elements)
        else:
            alloc_elems = 0
            actual_elements_ref = oci.POINTER(oci.ub4)()
        
        # perform the bind
        if self.bound_name:
            buffer = cxBuffer.new_from_object(self.bound_name, self.environment.encoding)
            status = oci.OCIBindByName(self.bound_cursor_handle, byref(self.bind_handle),
                        self.environment.error_handle, buffer.cast_ptr,
                        buffer.size, self.data, self.bufferSize,
                        self.type.oracle_type, self.indicator, self.actual_length,
                        self.return_code, alloc_elems,
                        actual_elements_ref, oci.OCI_DEFAULT)
        else:
            status = oci.OCIBindByPos(self.bound_cursor_handle, byref(self.bind_handle),
                        self.environment.error_handle, self.bound_pos, self.data,
                        self.bufferSize, self.type.oracle_type, self.indicator,
                        self.actual_length, self.return_code, alloc_elems,
                        actual_elements_ref, oci.OCI_DEFAULT)
        
        self.environment.check_for_error(status, "Variable_InternalBind()")

        if not python3_or_better():
            # set the charset form and id if applicable
            if self.type.charset_form != oci.SQLCS_IMPLICIT:
                c_charset_form = oci.ub1(self.type.charset_form)
                status = oci.OCIAttrSet(self.bind_handle, oci.OCI_HTYPE_BIND,
                        byref(c_charset_form), 0, oci.OCI_ATTR_CHARSET_FORM,
                        self.environment.error_handle)
                self.environment.check_for_error(status, "Variable_InternalBind(): set charset form")
                self.type.charset_form = c_charset_form.value
                
                c_buffer_size = oci.ub4(self.bufferSize)
                status = oci.OCIAttrSet(self.bind_handle, oci.OCI_HTYPE_BIND,
                        byref(c_buffer_size), 0, oci.OCI_ATTR_MAXDATA_SIZE,
                        self.environment.error_handle)
                self.environment.check_for_error(status, "Variable_InternalBind(): set max data size")
                self.bufferSize = self.maxlength = c_buffer_size.value

        # set the max data size for strings
        self.set_max_data_size()
Beispiel #12
0
    def _write(self, var, pos, data_obj, offset):
        """Write data to the LOB variable."""

        # verify the data type
        var_type = var.type
        if var_type == vt_BFILE:
            raise TypeError("BFILEs are read only")

        if var_type == vt_BLOB:
            buffer = cxBuffer.new_from_object(data_obj,
                                              var.environment.encoding)
            amount = buffer.size
        elif not python3_or_better() and var_type == vt_NCLOB:
            buffer = cxBuffer.new_from_object(data_obj,
                                              var.environment.nencoding)
            amount = buffer.size
        else:
            buffer = cxBuffer.new_from_object(data_obj,
                                              var.environment.encoding)
            if var.environment.fixedWidth and var.environment.maxBytesPerCharacter > 1:
                amount = buffer.size / var.environment.maxBytesPerCharacter
            else:
                amount = buffer.size

        # nothing to do if no data to write
        if amount == 0:
            return amount

        typed_data = self.get_typed_data(var)
        c_amount = oci.ub4(amount)
        callback_lob_write_type = oci.OCILobWrite.argtypes[9]
        null_oci_callback = callback_lob_write_type()
        status = oci.OCILobWrite(var.connection.handle,
                                 var.environment.error_handle, typed_data[pos],
                                 byref(c_amount), offset, buffer.ptr,
                                 buffer.size, oci.OCI_ONE_PIECE, None,
                                 null_oci_callback, 0, var.type.charset_form)

        var.environment.check_for_error(status, "LobVar_Write()")
        amount = c_amount.value  # not sure if the write can change it, i dont think so, but just for correctness

        return amount
Beispiel #13
0
    def pre_define(self, var, param):
        """Set the type of value (integer, float or string) that will be returned when values are fetched from this variable."""

        # if the return type has not already been specified, check to see if the
        # number can fit inside an integer by looking at the precision and scale
        if var.type is vt_Float:
            scale = OCIAttrGet(param, oci.OCI_HTYPE_DESCRIBE, oci.sb1,
                               oci.OCI_ATTR_SCALE, var.environment,
                               "NumberVar_PreDefine(): scale")

            precision = OCIAttrGet(param, oci.OCI_HTYPE_DESCRIBE, oci.sb2,
                                   oci.OCI_ATTR_PRECISION, var.environment,
                                   "NumberVar_PreDefine(): precision")

            if scale == 0 or (scale == -127 and precision == 0):
                var.type = vt_LongInteger

                if not python3_or_better():
                    if 0 < precision < 10:
                        var.type = vt_Integer
    def _write(self, var, pos, data_obj, offset):
        """Write data to the LOB variable."""
        
        # verify the data type
        var_type = var.type
        if var_type == vt_BFILE:
            raise TypeError("BFILEs are read only")
        
        if var_type == vt_BLOB:
            buffer = cxBuffer.new_from_object(data_obj, var.environment.encoding)
            amount = buffer.size
        elif not python3_or_better() and var_type == vt_NCLOB:
            buffer = cxBuffer.new_from_object(data_obj, var.environment.nencoding)
            amount = buffer.size
        else:
            buffer = cxBuffer.new_from_object(data_obj, var.environment.encoding)
            if var.environment.fixedWidth and var.environment.maxBytesPerCharacter > 1:
                amount = buffer.size / var.environment.maxBytesPerCharacter
            else:
                amount = buffer.size
    
        # nothing to do if no data to write
        if amount == 0:
            return amount
        
        typed_data = self.get_typed_data(var)
        c_amount = oci.ub4(amount)
        callback_lob_write_type = oci.OCILobWrite.argtypes[9]
        null_oci_callback = callback_lob_write_type()
        status = oci.OCILobWrite(var.connection.handle,
                var.environment.error_handle, typed_data[pos], byref(c_amount), offset,
                buffer.ptr, buffer.size, oci.OCI_ONE_PIECE, None, null_oci_callback, 0,
                var.type.charset_form)

        var.environment.check_for_error(status, "LobVar_Write()")
        amount = c_amount.value # not sure if the write can change it, i dont think so, but just for correctness
        
        return amount
Beispiel #15
0
    def __init__(self, environment, context, retrieve_error):
        self.context = context
        if retrieve_error:
            if environment.error_handle:
                handle = environment.error_handle
                handle_type = oci.OCI_HTYPE_ERROR
            else:
                handle = environment.handle
                handle_type = oci.OCI_HTYPE_ENV

            error_text = ctypes.create_string_buffer(4096)
            error_text_as_ub1_pointer = ctypes.cast(error_text, oci.POINTER(oci.ub1))
            c_code = oci.sb4()
            argtypes = oci.OCIErrorGet.argtypes
            status = oci.OCIErrorGet(handle, 1, argtypes[2](), byref(c_code), error_text_as_ub1_pointer, len(error_text), handle_type)
            self.code = c_code.value
            if status != oci.OCI_SUCCESS:
                raise InternalError("No Oracle error?")

            if not python3_or_better():
                self.message = error_text.value
            else:
                self.message = error_text.decode(environment.encoding)
from utils import python3_or_better

if python3_or_better():
    CXORA_BASE_EXCEPTION = Exception
    CXORA_TYPE_ERROR = 'expecting string or bytes object'
else:
    CXORA_BASE_EXCEPTION = StandardError
    CXORA_TYPE_ERROR = 'expecting string, unicode or buffer object'

class Warning(CXORA_BASE_EXCEPTION):
    pass

class Error(CXORA_BASE_EXCEPTION):
    pass

class InterfaceError(Error):
    pass

class DatabaseError(Error):
    pass

class DataError(DatabaseError):
    pass

class OperationalError(DatabaseError):
    pass

class IntegrityError(DatabaseError):
    pass

class InternalError(DatabaseError):
Beispiel #17
0
                or self.type == vt_FixedChar) and self.size > self.type.size:
            c_size = oci.ub4()
            status = oci.OCIAttrSet(self.bind_handle, oci.OCI_HTYPE_BIND,
                                    byref(c_size), 0,
                                    oci.OCI_ATTR_MAXDATA_SIZE,
                                    self.environment.error_handle)
            self.type.size = c_size.value
            self.environment.check_for_error(
                status, "Variable_InternalBind(): set max data size")

    @staticmethod
    def get_display_size(precision, scale, char_size, internal_size):
        return char_size


if not python3_or_better():

    class UNICODE(Variable):
        @staticmethod
        def get_display_size(precision, scale, char_size, internal_size):
            return char_size

    class FIXED_UNICODE(Variable):
        @staticmethod
        def get_display_size(precision, scale, char_size, internal_size):
            return char_size


class FIXED_CHAR(Variable):
    def set_max_data_size(self):
        # TODO: well, self.type here always is vt_FixedChar. But we can refactor this better, the code in the if is the same for strings
Beispiel #18
0
class BaseNumberVarType(VariableType):
    def __init__(self):
        VariableType.__init__(self)
        #self.oci_type = None
        self.initialize_proc = None
        self.finalize_proc = None
        #self.pre_define_proc = self.pre_define
        self.post_define_proc = None
        self.pre_fetch_proc = None
        self.is_null_proc = None
        self.set_value_proc = self.set_value
        self.get_value_proc = self.get_value
        self.get_buffer_size_proc = None

        self.can_be_copied = True
        self.can_be_in_array = True

        # not standard variable type

        self.mapping_python_type_to_method = {
            long: self.set_value_from_long,
            bool: self.set_value_from_boolean,
            float: self.set_value_from_float,
            Decimal: self.set_value_from_decimal,
        }

        if not python3_or_better():
            self.mapping_python_type_to_method[
                int] = self.set_value_from_integer

    def pre_define(self, var, param):
        """Set the type of value (integer, float or string) that will be returned when values are fetched from this variable."""

        # if the return type has not already been specified, check to see if the
        # number can fit inside an integer by looking at the precision and scale
        if var.type is vt_Float:
            scale = OCIAttrGet(param, oci.OCI_HTYPE_DESCRIBE, oci.sb1,
                               oci.OCI_ATTR_SCALE, var.environment,
                               "NumberVar_PreDefine(): scale")

            precision = OCIAttrGet(param, oci.OCI_HTYPE_DESCRIBE, oci.sb2,
                                   oci.OCI_ATTR_PRECISION, var.environment,
                                   "NumberVar_PreDefine(): precision")

            if scale == 0 or (scale == -127 and precision == 0):
                var.type = vt_LongInteger

                if not python3_or_better():
                    if 0 < precision < 10:
                        var.type = vt_Integer

    def get_value(self, var, pos):
        """Returns the value stored at the given array position."""
        if not python3_or_better():
            types = (vt_Boolean, vt_Integer)
        else:
            types = (vt_Boolean, )

        typed_data = self.get_typed_data(var)

        if var.type in types:
            c_integer_value = ctypes.c_long()
            status = oci.OCINumberToInt(var.environment.error_handle,
                                        byref(typed_data[pos]),
                                        ctypes.sizeof(c_integer_value),
                                        oci.OCI_NUMBER_SIGNED,
                                        byref(c_integer_value))
            integer_value = c_integer_value.value
            var.environment.check_for_error(
                status, "NumberVar_GetValue(): as integer")

            if not python3_or_better():
                if var.type is vt_Integer:
                    return integer_value

            return bool(integer_value)

        if var.type in (vt_NumberAsString, vt_LongInteger):
            c_string = ctypes.create_string_buffer(200)
            cast_c_string = ctypes.cast(c_string, oci.POINTER(oci.ub1))

            c_string_length = oci.ub4()
            c_string_length.value = ctypes.sizeof(c_string)

            typed_data = self.get_typed_data(var)
            status = oci.OCINumberToText(
                var.environment.error_handle, byref(typed_data[pos]),
                var.environment.numberToStringFormatBuffer.cast_ptr,
                var.environment.numberToStringFormatBuffer.size, None, 0,
                byref(c_string_length), cast_c_string)
            var.environment.check_for_error(status,
                                            "NumberVar_GetValue(): as string")

            python_string = c_string.value

            unicode_str = cxString_from_encoded_string(
                python_string, var.environment.encoding)

            if var.type is vt_NumberAsString:
                return unicode_str

            try:
                return int(unicode_str)
            except ValueError:
                pass

        return oracle_number_to_python_float(var.environment,
                                             byref(typed_data[pos]))

    def set_value(self, var, pos, value):
        """Set the value of the variable."""

        for type, method in self.mapping_python_type_to_method.iteritems():
            if isinstance(value, type):
                break
        else:
            method = None

        if method is not None:
            return method(var, pos, value)

        raise TypeError("expecting numeric data")

    def set_value_from_long(self, var, pos, value):
        text_value = str(value)
        text_buffer = cxBuffer.new_from_object(text_value,
                                               var.environment.encoding)

        typed_data = self.get_typed_data(var)

        status = oci.OCINumberFromText(
            var.environment.error_handle, text_buffer.cast_ptr,
            text_buffer.size,
            var.environment.numberFromStringFormatBuffer.cast_ptr,
            var.environment.numberFromStringFormatBuffer.size, None, 0,
            byref(typed_data[pos]))

        return var.environment.check_for_error(status,
                                               "NumberVar_SetValueFromLong()")

    def set_value_from_boolean(self, var, pos, value):
        raise NotImplementedError()

    def set_value_from_float(self, var, pos, value):
        double_value = ctypes.c_double(value)
        typed_data = self.get_typed_data(var)

        status = oci.OCINumberFromReal(var.environment.error_handle,
                                       byref(double_value),
                                       ctypes.sizeof(double_value),
                                       byref(typed_data[pos]))
        return var.environment.check_for_error(
            status, "NumberVar_SetValueFromFloat()")

    def get_format_and_text_from_decimal(self, tuple_value):
        """Return the number format and text to use for the Decimal object."""

        # acquire basic information from the value tuple
        sign, digits, scale = tuple_value
        num_digits = len(digits)

        # allocate memory for the string and format to use in conversion
        length = num_digits + abs(scale) + 3
        text_list = []

        format_list = []

        # populate the string and format
        if sign:
            text_list.append('-')
        for i in xrange(num_digits + scale):
            format_list.append('9')
            if i < num_digits:
                digit = digits[i]
            else:
                digit = 0

            text_list.append(str(digit))

        if scale < 0:
            format_list.append('D')
            text_list.append('.')
            for i in xrange(scale, 0):
                format_list.append('9')
                if num_digits + i < 0:
                    digit = 0
                else:
                    digit = digits[num_digits + i]

                text_list.append(str(digit))

        text_obj = cxString_from_ascii(''.join(text_list))
        format_obj = cxString_from_ascii(''.join(format_list))

        return text_obj, format_obj

    def set_value_from_decimal(self, var, pos, value):
        tuple_value = value.as_tuple()
        text_value, format = self.get_format_and_text_from_decimal(tuple_value)
        text_buffer = cxBuffer.new_from_object(text_value,
                                               var.environment.encoding)
        format_buffer = cxBuffer.new_from_object(format,
                                                 var.environment.encoding)

        typed_data = self.get_typed_data(var)

        status = oci.OCINumberFromText(
            var.environment.error_handle, text_buffer.cast_ptr,
            text_buffer.size, format_buffer.cast_ptr, format_buffer.size,
            var.environment.nlsNumericCharactersBuffer.cast_ptr,
            var.environment.nlsNumericCharactersBuffer.size,
            byref(typed_data[pos]))

        return var.environment.check_for_error(
            status, "NumberVar_SetValueFromDecimal()")

    if not python3_or_better():

        def set_value_from_integer(self, var, pos, value):
            """Set the value of the variable from a Python integer."""
            c_integer_value = ctypes.c_long(value)

            typed_data = self.get_typed_data(var)

            status = oci.OCINumberFromInt(var.environment.error_handle,
                                          byref(c_integer_value),
                                          ctypes.sizeof(c_integer_value),
                                          oci.OCI_NUMBER_SIGNED,
                                          byref(typed_data[pos]))

            var.environment.check_for_error(status,
                                            "NumberVar_SetValueFromInteger()")
    def type_by_value(self, value):
        """Return a variable type given a Python object or NULL if the Python object does not have a corresponding 
variable type."""

        # handle scalars
        if value is None:
            return vt_String, 1, None

        if isinstance(value, cxString):
            size = len(value)  # assuming cxString_GetSize = len
            if size > MAX_STRING_CHARS:
                type = vt_LongString
            else:
                type = vt_String
            return type, size, None

        if not python3_or_better():
            if isinstance(value, unicode):
                size = len(value)
                if size > MAX_STRING_CHARS:
                    type = vt_LongString
                else:
                    type = vt_NationalCharString
                return type, size, None

            if isinstance(value, int):
                return vt_Integer, None, None
        else:
            if isinstance(value, bytes):
                size = len(value)
                if size > MAX_BINARY_BYTES:
                    type = vt_LongBinary
                else:
                    type = vt_Binary

                return type, None, None

        if isinstance(value, long):
            return vt_LongInteger, None, None
        if isinstance(value, float):
            return vt_Float, None, None
        if isinstance(value, cxBinary):
            size = len(value)
            if size > MAX_BINARY_BYTES:
                type = vt_LongBinary
            else:
                type = vt_Binary

            return type, size, None

        if isinstance(value, bool):
            return vt_Boolean, None, None
        if isinstance(value, datetime):
            return vt_DateTime, None, None
        if isinstance(value, date):
            return vt_DateTime, None, None
        if isinstance(value, timedelta):
            return vt_Interval, None, None

        from cursor import Cursor

        is_cursor = isinstance(value, Cursor)
        if is_cursor:
            return vt_Cursor, None, None

        if isinstance(value, Decimal):
            return vt_NumberAsString, None, None

        # handle arrays
        if isinstance(value, list):
            for element_value in value:
                if element_value is not None:
                    break

            var_type, _, _ = self.type_by_value(element_value)
            num_elements = len(value)
            size = var_type.size
            return var_type, size, num_elements

        raise NotSupportedError("Variable_TypeByValue(): unhandled data type %.*s" % type(value))
    def type_by_value(self, value):
        """Return a variable type given a Python object or NULL if the Python object does not have a corresponding 
variable type."""

        # handle scalars
        if value is None:
            return vt_String, 1, None

        if isinstance(value, cxString):
            size = len(value) # assuming cxString_GetSize = len
            if size > MAX_STRING_CHARS:
                type = vt_LongString
            else:
                type = vt_String
            return type, size, None

        if not python3_or_better():
            if isinstance(value, unicode):
                size = len(value)
                if size > MAX_STRING_CHARS:
                    type = vt_LongString
                else:
                    type = vt_NationalCharString
                return type, size, None

            if isinstance(value, int):
                return vt_Integer, None, None
        else:
            if isinstance(value, bytes):
                size = len(value)
                if size > MAX_BINARY_BYTES:
                    type = vt_LongBinary
                else:
                    type = vt_Binary

                return type, None, None

        if isinstance(value, long):
            return vt_LongInteger, None, None
        if isinstance(value, float):
            return vt_Float, None, None
        if isinstance(value, cxBinary):
            size = len(value)
            if size > MAX_BINARY_BYTES:
                type = vt_LongBinary
            else:
                type = vt_Binary
            
            return type, size, None

        if isinstance(value, bool):
            return vt_Boolean, None, None
        if isinstance(value, datetime):
            return vt_DateTime, None, None
        if isinstance(value, date):
            return vt_DateTime, None, None
        if isinstance(value, timedelta):
            return vt_Interval, None, None

        from cursor import Cursor

        is_cursor = isinstance(value, Cursor)
        if is_cursor:
            return vt_Cursor, None, None

        if isinstance(value, Decimal):
            return vt_NumberAsString, None, None

        # handle arrays
        if isinstance(value, list):
            for element_value in value:
                if element_value is not None:
                    break

            var_type, _, _ = self.type_by_value(element_value)
            num_elements = len(value)
            size = var_type.size
            return var_type, size, num_elements

        raise NotSupportedError("Variable_TypeByValue(): unhandled data type %.*s" % type(value))
from pythonic_oci import OCIAttrGet, OCIParamGet

from utils import python3_or_better, cxBinary, cxString, MAX_STRING_CHARS, MAX_BINARY_BYTES

from numbervar import vt_Float, vt_NumberAsString, vt_Boolean, vt_LongInteger
from stringvar import vt_String, vt_FixedNationalChar, vt_NationalCharString, vt_FixedChar, vt_Rowid, vt_Binary
from longvar import vt_LongString, vt_LongBinary
from datetimevar import vt_DateTime, vt_Date
from lobvar import vt_NCLOB, vt_CLOB, vt_BLOB, vt_BFILE
from timestampvar import vt_Timestamp
from intervalvar import vt_Interval
from cursorvar import vt_Cursor

from variable import Variable

if not python3_or_better():
    from numbervar import vt_Integer

all_variable_types = [
    vt_Float,
    vt_NumberAsString,
    vt_Boolean,
    vt_LongInteger,
    vt_String,
    vt_FixedNationalChar,
    vt_NationalCharString,
    vt_FixedChar,
    vt_Rowid,
    vt_Binary,
    vt_LongString,
    vt_LongBinary,
Beispiel #22
0
from utils import python3_or_better

if python3_or_better():
    CXORA_BASE_EXCEPTION = Exception
    CXORA_TYPE_ERROR = 'expecting string or bytes object'
else:
    CXORA_BASE_EXCEPTION = StandardError
    CXORA_TYPE_ERROR = 'expecting string, unicode or buffer object'


class Warning(CXORA_BASE_EXCEPTION):
    pass


class Error(CXORA_BASE_EXCEPTION):
    pass


class InterfaceError(Error):
    pass


class DatabaseError(Error):
    pass


class DataError(DatabaseError):
    pass


class OperationalError(DatabaseError):