Ejemplo n.º 1
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()
Ejemplo n.º 2
0
    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()")
Ejemplo n.º 3
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
Ejemplo n.º 4
0
    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()")
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    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()")
Ejemplo n.º 7
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()
Ejemplo n.º 8
0
    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()")
Ejemplo n.º 9
0
    def set_value(self, var, pos, value):
        # get the buffer data and size for binding
        buffer = cxBuffer.new_from_object(value, var.environment.encoding)

        # verify there is enough space to store the value
        if buffer.num_characters > var.size:
            var.resize(buffer.num_characters)

        # copy the string to the Oracle buffer
        # TODO: can't we do better than this pointer arithmetic here?!
        base_ptr_address = ctypes.addressof(var.data) + var.bufferSize * pos

        c_length = oci.ub4.from_address(base_ptr_address)
        c_length.value = buffer.size

        string_address = base_ptr_address + ctypes.sizeof(oci.ub4)
        string_ptr = ctypes.c_void_p(string_address)

        if buffer.size:
            ctypes.memmove(string_ptr, buffer.ptr, buffer.size)
Ejemplo n.º 10
0
 def set_value(self, var, pos, value):
     # get the buffer data and size for binding
     buffer = cxBuffer.new_from_object(value, var.environment.encoding)
     
     # verify there is enough space to store the value
     if buffer.num_characters > var.size:
         var.resize(buffer.num_characters)
     
     # copy the string to the Oracle buffer
     # TODO: can't we do better than this pointer arithmetic here?!
     base_ptr_address = ctypes.addressof(var.data) + var.bufferSize * pos
     
     c_length = oci.ub4.from_address(base_ptr_address)
     c_length.value = buffer.size
     
     string_address = base_ptr_address + ctypes.sizeof(oci.ub4)
     string_ptr = ctypes.c_void_p(string_address)
     
     if buffer.size:
         ctypes.memmove(string_ptr, buffer.ptr, buffer.size)
Ejemplo n.º 11
0
    def set_value(self, var, pos, value):
        # populate the buffer and confirm the maximum size is not exceeded
        buffer = cxBuffer.new_from_object(value, var.environment.encoding)

        if var.type.is_character_data and buffer.num_characters > MAX_STRING_CHARS:
            raise ValueError("string data too large")
        elif not var.type.is_character_data and buffer.size > MAX_BINARY_BYTES:
            raise ValueError("binary data too large")

        # ensure that the buffer is large enough
        if buffer.size > var.bufferSize:
            var.resize(buffer.num_characters)

        # keep a copy of the string
        var.actual_length[pos] = buffer.size
        if buffer.size:
            pointer_to_pos = ctypes.c_void_p(ctypes.addressof(var.data) + var.bufferSize * pos)
            #start_index = var.bufferSize * pos
            #var.data[start_index:start_index+buffer.size] = buffer.ptr.raw[:buffer.size]
            #ctypes.memmove(byref(var.data, var.bufferSize * pos), buffer.ptr, buffer.size)
            ctypes.memmove(pointer_to_pos, buffer.ptr, buffer.size)
Ejemplo n.º 12
0
    def set_value(self, var, pos, value):
        # populate the buffer and confirm the maximum size is not exceeded
        buffer = cxBuffer.new_from_object(value, var.environment.encoding)

        if var.type.is_character_data and buffer.num_characters > MAX_STRING_CHARS:
            raise ValueError("string data too large")
        elif not var.type.is_character_data and buffer.size > MAX_BINARY_BYTES:
            raise ValueError("binary data too large")

        # ensure that the buffer is large enough
        if buffer.size > var.bufferSize:
            var.resize(buffer.num_characters)

        # keep a copy of the string
        var.actual_length[pos] = buffer.size
        if buffer.size:
            pointer_to_pos = ctypes.c_void_p(
                ctypes.addressof(var.data) + var.bufferSize * pos)
            #start_index = var.bufferSize * pos
            #var.data[start_index:start_index+buffer.size] = buffer.ptr.raw[:buffer.size]
            #ctypes.memmove(byref(var.data, var.bufferSize * pos), buffer.ptr, buffer.size)
            ctypes.memmove(pointer_to_pos, buffer.ptr, buffer.size)
Ejemplo n.º 13
0
    def connect(self, mode, twophase, newpassword):
        """Create a new connection object by connecting to the database."""
        credential_type = oci.OCI_CRED_EXT

        # allocate the server handle
        self.server_handle = oci.POINTER(oci.OCIServer)()
        OCIHandleAlloc(
            self.environment, self.server_handle, oci.OCI_HTYPE_SERVER, "Connection_Connect(): allocate server handle"
        )

        buffer = cxBuffer.new_from_object(self.dsn, self.environment.encoding)
        # attach to the server
        status = oci.OCIServerAttach(
            self.server_handle, self.environment.error_handle, buffer.cast_ptr, buffer.size, oci.OCI_DEFAULT
        )
        self.environment.check_for_error(status, "Connection_Connect(): server attach")

        # allocate the service context handle
        self.handle = oci.POINTER(oci.OCISvcCtx)()
        OCIHandleAlloc(
            self.environment, self.handle, oci.OCI_HTYPE_SVCCTX, "Connection_Connect(): allocate service context handle"
        )

        # set attribute for server handle
        status = oci.OCIAttrSet(
            self.handle, oci.OCI_HTYPE_SVCCTX, self.server_handle, 0, oci.OCI_ATTR_SERVER, self.environment.error_handle
        )
        self.environment.check_for_error(status, "Connection_Connect(): set server handle")

        # set the internal and external names; these are needed for global
        # transactions but are limited in terms of the lengths of the strings
        if twophase:
            status = oci.OCIAttrSet(
                self.server_handle,
                oci.OCI_HTYPE_SERVER,
                "cx_Oracle",
                0,
                oci.OCI_ATTR_INTERNAL_NAME,
                self.environment.error_handle,
            )
            self.environment.check_for_error(status, "Connection_Connect(): set internal name")

            status = oci.OCIAttrSet(
                self.server_handle,
                oci.OCI_HTYPE_SERVER,
                "cx_Oracle",
                0,
                oci.OCI_ATTR_EXTERNAL_NAME,
                self.environment.error_handle,
            )
            self.environment.check_for_error(status, "Connection_Connect(): set external name")

        # allocate session handle
        self.session_handle = oci.POINTER(oci.OCISession)()
        OCIHandleAlloc(
            self.environment,
            self.session_handle,
            oci.OCI_HTYPE_SESSION,
            "Connection_Connect(): allocate session handle",
        )

        # set user name in session handle
        buffer = cxBuffer.new_from_object(self.username, self.environment.encoding)
        if buffer.size > 0:
            credential_type = oci.OCI_CRED_RDBMS
            status = oci.OCIAttrSet(
                self.session_handle,
                oci.OCI_HTYPE_SESSION,
                buffer.ptr,
                buffer.size,
                oci.OCI_ATTR_USERNAME,
                self.environment.error_handle,
            )
            self.environment.check_for_error(status, "Connection_Connect(): set user name")

        # set password in session handle
        buffer = cxBuffer.new_from_object(self.password, self.environment.encoding)
        if buffer.size > 0:
            credential_type = oci.OCI_CRED_RDBMS
            status = oci.OCIAttrSet(
                self.session_handle,
                oci.OCI_HTYPE_SESSION,
                buffer.ptr,
                buffer.size,
                oci.OCI_ATTR_PASSWORD,
                self.environment.error_handle,
            )
            self.environment.check_for_error(status, "Connection_Connect(): set password")

        if hasattr(oci, "OCI_ATTR_DRIVER_NAME"):
            buffer = cxBuffer.new_from_object(DRIVER_NAME, self.environment.encoding)
            status = oci.OCIAttrSet(
                self.session_handle,
                oci.OCI_HTYPE_SESSION,
                buffer.ptr,
                buffer.size,
                oci.OCI_ATTR_DRIVER_NAME,
                self.environment.error_handle,
            )
            self.environment.check_for_error(status, "Connection_Connect(): set driver name")

        # set the session handle on the service context handle
        status = oci.OCIAttrSet(
            self.handle,
            oci.OCI_HTYPE_SVCCTX,
            self.session_handle,
            0,
            oci.OCI_ATTR_SESSION,
            self.environment.error_handle,
        )
        self.environment.check_for_error(status, "Connection_Connect(): set session handle")

        # if a new password has been specified, change it which will also
        # establish the session
        # TODO: implement change_password
        if newpassword:
            return self.change_password(self.password)  # TODO: removed one arg, what about the new password?!?!

        # begin the session
        status = oci.OCISessionBegin(
            self.handle, self.environment.error_handle, self.session_handle, credential_type, mode
        )
        try:
            self.environment.check_for_error(status, "Connection_Connect(): begin session")
        except Error:
            self.session_handle = oci.POINTER(
                oci.OCISession
            )()  # who frees the session handle? the failed session begin call?
            raise
Ejemplo n.º 14
0
 def set_buffer(value, encoding):
     if value is None:
         raise  # TODO: what?
     return cxBuffer.new_from_object(value, encoding)
Ejemplo n.º 15
0
 def set_buffer(value, encoding):
     if value is None:
         raise # TODO: what?
     return cxBuffer.new_from_object(value, encoding)
Ejemplo n.º 16
0
    def connect(self, mode, twophase, newpassword):
        """Create a new connection object by connecting to the database."""
        credential_type = oci.OCI_CRED_EXT

        # allocate the server handle
        self.server_handle = oci.POINTER(oci.OCIServer)()
        OCIHandleAlloc(self.environment, self.server_handle,
                       oci.OCI_HTYPE_SERVER,
                       "Connection_Connect(): allocate server handle")

        buffer = cxBuffer.new_from_object(self.dsn, self.environment.encoding)
        # attach to the server
        status = oci.OCIServerAttach(self.server_handle,
                                     self.environment.error_handle,
                                     buffer.cast_ptr, buffer.size,
                                     oci.OCI_DEFAULT)
        self.environment.check_for_error(
            status, "Connection_Connect(): server attach")

        # allocate the service context handle
        self.handle = oci.POINTER(oci.OCISvcCtx)()
        OCIHandleAlloc(
            self.environment, self.handle, oci.OCI_HTYPE_SVCCTX,
            "Connection_Connect(): allocate service context handle")

        # set attribute for server handle
        status = oci.OCIAttrSet(self.handle, oci.OCI_HTYPE_SVCCTX,
                                self.server_handle, 0, oci.OCI_ATTR_SERVER,
                                self.environment.error_handle)
        self.environment.check_for_error(
            status, "Connection_Connect(): set server handle")

        # set the internal and external names; these are needed for global
        # transactions but are limited in terms of the lengths of the strings
        if twophase:
            status = oci.OCIAttrSet(self.server_handle, oci.OCI_HTYPE_SERVER,
                                    "cx_Oracle", 0, oci.OCI_ATTR_INTERNAL_NAME,
                                    self.environment.error_handle)
            self.environment.check_for_error(
                status, "Connection_Connect(): set internal name")

            status = oci.OCIAttrSet(self.server_handle, oci.OCI_HTYPE_SERVER,
                                    "cx_Oracle", 0, oci.OCI_ATTR_EXTERNAL_NAME,
                                    self.environment.error_handle)
            self.environment.check_for_error(
                status, "Connection_Connect(): set external name")

        # allocate session handle
        self.session_handle = oci.POINTER(oci.OCISession)()
        OCIHandleAlloc(self.environment, self.session_handle,
                       oci.OCI_HTYPE_SESSION,
                       "Connection_Connect(): allocate session handle")

        # set user name in session handle
        buffer = cxBuffer.new_from_object(self.username,
                                          self.environment.encoding)
        if buffer.size > 0:
            credential_type = oci.OCI_CRED_RDBMS
            status = oci.OCIAttrSet(self.session_handle, oci.OCI_HTYPE_SESSION,
                                    buffer.ptr, buffer.size,
                                    oci.OCI_ATTR_USERNAME,
                                    self.environment.error_handle)
            self.environment.check_for_error(
                status, "Connection_Connect(): set user name")

        # set password in session handle
        buffer = cxBuffer.new_from_object(self.password,
                                          self.environment.encoding)
        if buffer.size > 0:
            credential_type = oci.OCI_CRED_RDBMS
            status = oci.OCIAttrSet(self.session_handle, oci.OCI_HTYPE_SESSION,
                                    buffer.ptr, buffer.size,
                                    oci.OCI_ATTR_PASSWORD,
                                    self.environment.error_handle)
            self.environment.check_for_error(
                status, "Connection_Connect(): set password")

        if hasattr(oci, 'OCI_ATTR_DRIVER_NAME'):
            buffer = cxBuffer.new_from_object(DRIVER_NAME,
                                              self.environment.encoding)
            status = oci.OCIAttrSet(self.session_handle, oci.OCI_HTYPE_SESSION,
                                    buffer.ptr, buffer.size,
                                    oci.OCI_ATTR_DRIVER_NAME,
                                    self.environment.error_handle)
            self.environment.check_for_error(
                status, "Connection_Connect(): set driver name")

        # set the session handle on the service context handle
        status = oci.OCIAttrSet(self.handle, oci.OCI_HTYPE_SVCCTX,
                                self.session_handle, 0, oci.OCI_ATTR_SESSION,
                                self.environment.error_handle)
        self.environment.check_for_error(
            status, "Connection_Connect(): set session handle")

        # if a new password has been specified, change it which will also
        # establish the session
        #TODO: implement change_password
        if newpassword:
            return self.change_password(
                self.password
            )  # TODO: removed one arg, what about the new password?!?!

        # begin the session
        status = oci.OCISessionBegin(self.handle,
                                     self.environment.error_handle,
                                     self.session_handle, credential_type,
                                     mode)
        try:
            self.environment.check_for_error(
                status, "Connection_Connect(): begin session")
        except Error:
            self.session_handle = oci.POINTER(oci.OCISession)(
            )  # who frees the session handle? the failed session begin call?
            raise