Exemple #1
0
    def __init__(self, cursor, num_elements, type, size):
        self.environment = cursor.connection.environment

        self.bind_handle = oci.POINTER(oci.OCIBind)()
        self.define_handle = oci.POINTER(oci.OCIDefine)()
        self.bound_cursor_handle = oci.POINTER(oci.OCIStmt)()
        self.bound_name = None
        self.inconverter = None  # public
        self.outconverter = None  # public
        self.bound_pos = 0

        if num_elements < 1:
            self.numElements = self.allocelems = 1
        else:
            self.numElements = self.allocelems = num_elements

        # the OCI will keep a ref to this across multiple calls, so we have to keep one too.
        # to avoid duplication of python-level vs c-level fields, self.actual_elements is a property
        self.c_actual_elements = oci.ub4(0)
        self.internal_fetch_num = 0
        self.is_array = False
        self.is_allocated_internally = True
        self.type = type
        self.actual_length = oci.POINTER(oci.ub2)()
        self.return_code = oci.POINTER(oci.ub2)()

        # set the maximum length of the variable, ensure that a minimum of
        # 2 bytes is allocated to ensure that the array size check works
        self.size = type.size
        if type.is_variable_length:
            if size < ctypes.sizeof(oci.ub2):
                size = ctypes.sizeof(oci.ub2)
            self.size = size

        # allocate the data for the variable
        self.allocate_data()

        # allocate the indicator for the variable
        self.indicator = (self.numElements * oci.sb2)()

        # ensure that all variable values start out NULL
        for i in xrange(self.numElements):
            self.indicator[i] = oci.OCI_IND_NULL

        # for variable length data, also allocate the return code
        if type.is_variable_length:
            self.return_code = (self.numElements * oci.ub2)()

        # perform extended initialization
        if self.type.initialize_proc:
            self.type.initialize_proc(self, cursor)
    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]))
Exemple #3
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()
Exemple #4
0
def OCIAttrGet(param, oci_function, oci_type, oci_subfunction, environment,
               context):
    c_result = oci_type()
    arg3 = oci.POINTER(
        oci.ub4)()  # TODO: move somewhere where it is evaluated only once
    status = oci.OCIAttrGet(param, oci_function, byref(c_result), arg3,
                            oci_subfunction, environment.error_handle)
    environment.check_for_error(status, context)
    return c_result.value
    def new_from_scratch(threaded, events, encoding, nencoding):
        mode = oci.OCI_OBJECT
        if threaded:
            mode |= oci.OCI_THREADED
        #TODO: if EVENTS_SUPPORTED:
        #    if events:
        #        mode |= ociap.OCI_EVENTS

        argtypes = oci.OCIEnvNlsCreate.argtypes
        handle = oci.POINTER(oci.OCIEnv)()

        status = oci.OCIEnvNlsCreate(byref(handle), mode, argtypes[2](),
                                     argtypes[3](), argtypes[4](),
                                     argtypes[5](), 0, None, 0, 0)

        if not handle or (status != oci.OCI_SUCCESS
                          and status != oci.OCI_SUCCESS_WITH_INFO):
            raise InterfaceError("Unable to acquire Oracle environment handle")

        env = Environment(handle)

        c_maxBytesPerCharacter = oci.sb4()
        status = oci.OCINlsNumericInfoGet(handle, env.error_handle,
                                          byref(c_maxBytesPerCharacter),
                                          oci.OCI_NLS_CHARSET_MAXBYTESZ)
        env.check_for_error(status,
                            "Environment_New(): get max bytes per character")
        env.maxBytesPerCharacter = c_maxBytesPerCharacter.value

        env.maxStringBytes = MAX_STRING_CHARS * env.maxBytesPerCharacter

        # acquire whether character set is fixed width
        c_fixedWidth = oci.sb4()
        status = oci.OCINlsNumericInfoGet(handle, env.error_handle,
                                          byref(c_fixedWidth),
                                          oci.OCI_NLS_CHARSET_FIXEDWIDTH)
        env.check_for_error(
            status, "Environment_New(): determine if charset fixed width")
        env.fixedWidth = c_fixedWidth.value

        # determine encodings to use for Unicode values
        env.encoding = env.get_characterset_name(oci.OCI_ATTR_ENV_CHARSET_ID,
                                                 encoding)
        env.nencoding = env.get_characterset_name(oci.OCI_ATTR_ENV_NCHARSET_ID,
                                                  nencoding)

        # fill buffers for number formats
        env.numberToStringFormatBuffer = Environment.set_buffer(
            "TM9", env.encoding)
        env.numberFromStringFormatBuffer = Environment.set_buffer(
            "999999999999999999999999999999999999999999999999999999999999999",
            env.encoding)
        env.nlsNumericCharactersBuffer = Environment.set_buffer(
            "NLS_NUMERIC_CHARACTERS='.,'", env.encoding)

        return env
def OCIParamGet(handle, htype, environment, pos, context):
    # cant pass cast_param to OCI and return non-cast param. ctypes doesn't know the cast param and the non-cast param are the same.
    param_type = oci.POINTER(oci.OCIParam)
    param = ctypes.c_void_p()
    # acquire parameter descriptor
    status = oci.OCIParamGet(handle, htype, environment.error_handle,
                             byref(param), pos)
    environment.check_for_error(status, context)

    result = ctypes.cast(param, param_type)
    return result
Exemple #7
0
    def close(self):
        """Close the connection, disconnecting from the database."""

        self.rollback()  # will check if we are actually connected

        # logoff of the server
        if self.session_handle:
            status = oci.OCISessionEnd(self.handle,
                                       self.environment.error_handle,
                                       self.session_handle, oci.OCI_DEFAULT)
            self.environment.check_for_error(
                status, "Connection_Close(): end session")

        oci.OCIHandleFree(self.handle, oci.OCI_HTYPE_SVCCTX)

        self.handle = oci.POINTER(oci.OCISvcCtx)()
    def __init__(self, handle):
        self.handle = handle

        self.fixedWidth = self.maxBytesPerCharacter = 1
        self.maxStringBytes = MAX_STRING_CHARS
        self.cloneEnv = None  # used for connection pooling, but that is still TODO

        self.numberToStringFormatBuffer = cxBuffer.new_null()
        self.numberFromStringFormatBuffer = cxBuffer.new_null()
        self.nlsNumericCharactersBuffer = cxBuffer.new_null()

        # create the error handle
        error_handle_as_void_p = ctypes.c_void_p()
        argtypes = oci.OCIHandleAlloc.argtypes
        status = oci.OCIHandleAlloc(handle, byref(error_handle_as_void_p),
                                    oci.OCI_HTYPE_ERROR, 0, argtypes[4]())
        self.check_for_error(status, "Environment_New(): create error handle")
        self.error_handle = ctypes.cast(error_handle_as_void_p,
                                        oci.POINTER(oci.OCIError))
    def __init__(self):
        VariableType.__init__(self)
        self.oci_type = oci.POINTER(oci.OCIStmt)

        #self.initialize_proc = None
        #self.finalize_proc = None
        self.pre_define_proc = None
        self.post_define_proc = None
        self.pre_fetch_proc = None
        self.is_null_proc = None
        #self.set_value_proc = None
        #self.get_value_proc = None
        self.get_buffer_size_proc = None
        self.python_type = CURSOR
        self.oracle_type = oci.SQLT_RSET
        self.charset_form = oci.SQLCS_IMPLICIT
        self.size = ctypes.sizeof(self.oci_type)
        self.is_character_data = False
        self.is_variable_length = False
        self.can_be_copied = False
        self.can_be_in_array = False
Exemple #10
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)
 def __init__(self):
     VariableType.__init__(self)
     self.oci_type = oci.POINTER(oci.OCIInterval)
     
     #self.initialize_proc = None
     #self.finalize_proc = None
     self.pre_define_proc = None
     self.post_define_proc = None
     self.pre_fetch_proc = None
     self.is_null_proc = None
     #self.set_value_proc = None
     #self.get_value_proc = None
     self.get_buffer_size_proc = None
     self.python_type = INTERVAL
     self.oracle_type = oci.SQLT_INTERVAL_DS
     self.charset_form = oci.SQLCS_IMPLICIT
     self.size = ctypes.sizeof(self.oci_type)
     self.is_character_data = False
     self.is_variable_length = False
     self.can_be_copied = True
     self.can_be_in_array = True
     
     self.descriptor_manager = DescriptorManager()
Exemple #12
0
    def __init__(self):
        VariableType.__init__(self)
        self.oci_type = oci.POINTER(oci.OCILobLocator)

        self.initialize_proc = self.initialize
        self.finalize_proc = self.finalize
        self.pre_define_proc = None
        self.post_define_proc = None
        self.pre_fetch_proc = self.pre_fetch
        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.python_type = None
        #self.oracle_type = None
        #self.charset_form = None
        self.size = ctypes.sizeof(self.oci_type)
        #self.is_character_data = None
        self.is_variable_length = False
        self.can_be_copied = False
        self.can_be_in_array = False

        self.descriptor_manager = DescriptorManager()
Exemple #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
Exemple #14
0
 def get_typed_data(self, var):
     return ctypes.cast(var.data, oci.POINTER(self.oci_type))