示例#1
0
    def _internalFetch(self, space, numRows):
        if not self.fetchVariables:
            raise OperationError(
                get(space).w_InterfaceError, space.wrap("query not executed"))

        status = roci.OCIStmtFetch(self.handle, self.environment.errorHandle,
                                   numRows, roci.OCI_FETCH_NEXT,
                                   roci.OCI_DEFAULT)

        if status != roci.OCI_NO_DATA:
            self.environment.checkForError(status,
                                           "Cursor_InternalFetch(): fetch")

        for var in self.fetchVariables:
            assert isinstance(var, interp_variable.W_Variable)
            var.internalFetchNum += 1

        attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw')
        try:
            status = roci.OCIAttrGet(self.handle, roci.OCI_HTYPE_STMT,
                                     rffi.cast(roci.dvoidp, attrptr),
                                     lltype.nullptr(roci.Ptr(roci.ub4).TO),
                                     roci.OCI_ATTR_ROW_COUNT,
                                     self.environment.errorHandle)

            self.environment.checkForError(
                status, "Cursor_InternalFetch(): row count")

            self.actualRows = (rffi.cast(lltype.Signed, attrptr[0]) -
                               self.rowCount)
            self.rowNum = 0
        finally:
            lltype.free(attrptr, flavor='raw')
示例#2
0
    def acquire(self, space, __args__):
        (w_user, w_password, w_cclass, w_purity
         ) = __args__.parse_obj(
            None, "acquire",
            Signature(["user", "password", "cclass", "purity"]),
            defaults_w=[None, None, None, space.w_False])
        if self.homogeneous and (w_user or w_password):
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("pool is homogeneous. "
                           "Proxy authentication is not possible."))

        self.checkConnected(space)

        if __args__.keywords:
            keywords = __args__.keywords + ["pool"]
        else:
            keywords = ["pool"]
        if __args__.keywords_w:
            keywords_w = __args__.keywords_w + [space.wrap(self)]
        else:
            keywords_w = [space.wrap(self)]

        newargs = Arguments(space,
                            __args__.arguments_w,
                            keywords,
                            keywords_w)
        return space.call_args(self.w_connectionType, newargs)
示例#3
0
    def arrayvar(self, space, w_type, w_value, size=0):
        # determine the type of variable
        varType = interp_variable.typeByPythonType(space, self, w_type)
        if varType.isVariableLength and size == 0:
            size = varType.size

        # determine the number of elements to create
        if space.is_true(space.isinstance(w_value, space.w_list)):
            numElements = space.len_w(w_value)
        elif space.is_true(space.isinstance(w_value, space.w_int)):
            numElements = space.int_w(w_value)
        else:
            raise OperationError(
                get(space).w_NotSupportedError,
                space.wrap("expecting integer or list of values"))

        # create the variable
        var = varType(self, numElements, size)
        var.makeArray(space)

        # set the value, if applicable
        if space.is_true(space.isinstance(w_value, space.w_list)):
            var.setArrayValue(space, w_value)

        return var
示例#4
0
    def _release(self, space, w_connection, mode):
        from pypy.module.oracle.interp_connect import W_Connection
        connection = space.interp_w(W_Connection, w_connection)

        self.checkConnected(space)

        if connection.sessionPool is not self:
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("connection not acquired with this session pool"))

        # attempt a rollback
        status = roci.OCITransRollback(
            connection.handle, connection.environment.errorHandle,
            roci.OCI_DEFAULT)
        # if dropping the connection from the pool, ignore the error
        if mode != roci.OCI_SESSRLS_DROPSESS:
            self.environment.checkForError(
                status, "SessionPool_Release(): rollback")

        # release the connection
        status = roci.OCISessionRelease(
            connection.handle, connection.environment.errorHandle,
            None, 0, mode)
        self.environment.checkForError(
            status, "SessionPool_Release(): release session")

        # ensure that the connection behaves as closed
        connection.sessionPool = None
        connection.handle = lltype.nullptr(roci.OCISvcCtx.TO)
示例#5
0
    def execute(self, space, w_stmt, __args__):
        args_w, kw_w = __args__.unpack()

        if space.is_w(w_stmt, space.w_None):
            w_stmt = None

        if len(args_w) > 1:
            raise OperationError(
                space.w_TypeError,
                space.wrap("Too many arguments"))
        elif len(args_w) == 1:
            if len(kw_w) > 0:
                raise OperationError(
                    interp_error.get(space).w_InterfaceError,
                    space.wrap(
                        "expecting argument or keyword arguments, not both"))
            w_vars = args_w[0]
        elif len(kw_w) > 0:
            w_vars = space.newdict()
            for key, w_value in kw_w.iteritems():
                space.setitem(w_vars, space.wrap(key), w_value)
        else:
            w_vars = None

        # make sure the cursor is open
        self._checkOpen(space)

        return self._execute(space, w_stmt, w_vars)
示例#6
0
    def acquire(self, space, __args__):
        (w_user, w_password, w_cclass, w_purity) = __args__.parse_obj(
            None,
            "acquire",
            Signature(["user", "password", "cclass", "purity"]),
            defaults_w=[None, None, None, space.w_False])
        if self.homogeneous and (w_user or w_password):
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("pool is homogeneous. "
                           "Proxy authentication is not possible."))

        self.checkConnected(space)

        if __args__.keywords:
            keywords = __args__.keywords + ["pool"]
        else:
            keywords = ["pool"]
        if __args__.keywords_w:
            keywords_w = __args__.keywords_w + [space.wrap(self)]
        else:
            keywords_w = [space.wrap(self)]

        newargs = Arguments(space, __args__.arguments_w, keywords, keywords_w)
        return space.call_args(self.w_connectionType, newargs)
示例#7
0
    def _release(self, space, w_connection, mode):
        from pypy.module.oracle.interp_connect import W_Connection
        connection = space.interp_w(W_Connection, w_connection)

        self.checkConnected(space)

        if connection.sessionPool is not self:
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("connection not acquired with this session pool"))

        # attempt a rollback
        status = roci.OCITransRollback(connection.handle,
                                       connection.environment.errorHandle,
                                       roci.OCI_DEFAULT)
        # if dropping the connection from the pool, ignore the error
        if mode != roci.OCI_SESSRLS_DROPSESS:
            self.environment.checkForError(status,
                                           "SessionPool_Release(): rollback")

        # release the connection
        status = roci.OCISessionRelease(connection.handle,
                                        connection.environment.errorHandle,
                                        None, 0, mode)
        self.environment.checkForError(
            status, "SessionPool_Release(): release session")

        # ensure that the connection behaves as closed
        connection.sessionPool = None
        connection.handle = lltype.nullptr(roci.OCISvcCtx.TO)
示例#8
0
    def _setBindVariablesByPos(self, space,
                               w_vars, numElements, arrayPos, defer):
        "handle positional binds"
        # make sure positional and named binds are not being intermixed
        if self.bindDict is not None:
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("positional and named binds cannot be intermixed"))

        if self.bindList is None:
            self.bindList = []

        vars_w = space.fixedview(w_vars)
        for i in range(len(vars_w)):
            w_value = vars_w[i]
            if i < len(self.bindList):
                origVar = self.bindList[i]
                if space.is_w(origVar, space.w_None):
                    origVar = None
            else:
                origVar = None
            newVar = self._setBindVariableHelper(space, w_value, origVar,
                                                 numElements, arrayPos, defer)
            if newVar:
                if i < len(self.bindList):
                    self.bindList[i] = newVar
                else:
                    assert i == len(self.bindList)
                    self.bindList.append(newVar)
示例#9
0
    def arrayvar(self, space, w_type, w_value, size=0):
        # determine the type of variable
        varType = interp_variable.typeByPythonType(space, self, w_type)
        if varType.isVariableLength and size == 0:
            size = varType.size

        # determine the number of elements to create
        if space.isinstance_w(w_value, space.w_list):
            numElements = space.len_w(w_value)
        elif space.isinstance_w(w_value, space.w_int):
            numElements = space.int_w(w_value)
        else:
            raise OperationError(
                get(space).w_NotSupportedError,
                space.wrap("expecting integer or list of values"))

        # create the variable
        var = varType(self, numElements, size)
        var.makeArray(space)

        # set the value, if applicable
        if space.isinstance_w(w_value, space.w_list):
            var.setArrayValue(space, w_value)

        return var
示例#10
0
    def execute(self, space, w_stmt, __args__):
        args_w, kw_w = __args__.unpack()

        if space.is_w(w_stmt, space.w_None):
            w_stmt = None

        if len(args_w) > 1:
            raise OperationError(space.w_TypeError,
                                 space.wrap("Too many arguments"))
        elif len(args_w) == 1:
            if len(kw_w) > 0:
                raise OperationError(
                    interp_error.get(space).w_InterfaceError,
                    space.wrap(
                        "expecting argument or keyword arguments, not both"))
            w_vars = args_w[0]
        elif len(kw_w) > 0:
            w_vars = space.newdict()
            for key, w_value in kw_w.iteritems():
                space.setitem(w_vars, space.wrap(key), w_value)
        else:
            w_vars = None

        # make sure the cursor is open
        self._checkOpen(space)

        return self._execute(space, w_stmt, w_vars)
示例#11
0
    def _setBindVariablesByPos(self, space, w_vars, numElements, arrayPos,
                               defer):
        "handle positional binds"
        # make sure positional and named binds are not being intermixed
        if self.bindDict is not None:
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("positional and named binds cannot be intermixed"))

        if self.bindList is None:
            self.bindList = []

        vars_w = space.fixedview(w_vars)
        for i in range(len(vars_w)):
            w_value = vars_w[i]
            if i < len(self.bindList):
                origVar = self.bindList[i]
                if space.is_w(origVar, space.w_None):
                    origVar = None
            else:
                origVar = None
            newVar = self._setBindVariableHelper(space, w_value, origVar,
                                                 numElements, arrayPos, defer)
            if newVar:
                if i < len(self.bindList):
                    self.bindList[i] = newVar
                else:
                    assert i == len(self.bindList)
                    self.bindList.append(newVar)
示例#12
0
    def _internalPrepare(self, space, w_stmt, w_tag):
        # make sure we don't get a situation where nothing is to be executed
        if w_stmt is None and self.w_statement is None:
            raise OperationError(
                interp_error.get(space).w_ProgrammingError,
                space.wrap("no statement specified "
                           "and no prior statement prepared"))

        # nothing to do if the statement is identical to the one already stored
        # but go ahead and prepare anyway for create, alter and drop statments
        if w_stmt is None or w_stmt == self.w_statement:
            if self.statementType not in (roci.OCI_STMT_CREATE,
                                          roci.OCI_STMT_DROP,
                                          roci.OCI_STMT_ALTER):
                return
            w_stmt = self.w_statement
        else:
            self.w_statement = w_stmt

        # release existing statement, if necessary
        self.w_statementTag = w_tag
        self.freeHandle(space)

        # prepare statement
        self.isOwned = False
        handleptr = lltype.malloc(roci.Ptr(roci.OCIStmt).TO,
                                  1, flavor='raw')
        stmtBuffer = StringBuffer()
        tagBuffer = StringBuffer()
        stmtBuffer.fill(space, w_stmt)
        tagBuffer.fill(space, w_tag)
        try:
            status = roci.OCIStmtPrepare2(
                self.connection.handle, handleptr,
                self.environment.errorHandle,
                stmtBuffer.ptr, stmtBuffer.size,
                tagBuffer.ptr, tagBuffer.size,
                roci.OCI_NTV_SYNTAX, roci.OCI_DEFAULT)

            self.environment.checkForError(
                status, "Connection_InternalPrepare(): prepare")
            self.handle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')
            stmtBuffer.clear()
            tagBuffer.clear()

        # clear bind variables, if applicable
        if not self.setInputSizes:
            self.bindList = None
            self.bindDict = None

        # clear row factory, if applicable
        self.rowFactory = None

        # determine if statement is a query
        self._getStatementType()
示例#13
0
    def _internalPrepare(self, space, w_stmt, w_tag):
        # make sure we don't get a situation where nothing is to be executed
        if w_stmt is None and self.w_statement is None:
            raise OperationError(
                interp_error.get(space).w_ProgrammingError,
                space.wrap("no statement specified "
                           "and no prior statement prepared"))

        # nothing to do if the statement is identical to the one already stored
        # but go ahead and prepare anyway for create, alter and drop statments
        if w_stmt is None or w_stmt == self.w_statement:
            if self.statementType not in (roci.OCI_STMT_CREATE,
                                          roci.OCI_STMT_DROP,
                                          roci.OCI_STMT_ALTER):
                return
            w_stmt = self.w_statement
        else:
            self.w_statement = w_stmt

        # release existing statement, if necessary
        self.w_statementTag = w_tag
        self.freeHandle(space)

        # prepare statement
        self.isOwned = False
        handleptr = lltype.malloc(roci.Ptr(roci.OCIStmt).TO,
                                  1, flavor='raw')
        stmtBuffer = StringBuffer()
        tagBuffer = StringBuffer()
        stmtBuffer.fill(space, w_stmt)
        tagBuffer.fill(space, w_tag)
        try:
            status = roci.OCIStmtPrepare2(
                self.connection.handle, handleptr,
                self.environment.errorHandle,
                stmtBuffer.ptr, stmtBuffer.size,
                tagBuffer.ptr, tagBuffer.size,
                roci.OCI_NTV_SYNTAX, roci.OCI_DEFAULT)

            self.environment.checkForError(
                status, "Connection_InternalPrepare(): prepare")
            self.handle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')
            stmtBuffer.clear()
            tagBuffer.clear()

        # clear bind variables, if applicable
        if not self.setInputSizes:
            self.bindList = None
            self.bindDict = None

        # clear row factory, if applicable
        self.rowFactory = None

        # determine if statement is a query
        self._getStatementType()
示例#14
0
    def checkForError(self, status, context):
        if status in (roci.OCI_SUCCESS, roci.OCI_SUCCESS_WITH_INFO):
            return

        if status != roci.OCI_INVALID_HANDLE:
            # At this point it is assumed that the Oracle
            # environment is fully initialized
            error = W_Error(self.space, self, context, 1)
            if error.code in (1, 1400, 2290, 2291, 2292):
                w_type = get(self.space).w_IntegrityError
            elif error.code in (1012, 1033, 1034, 1089, 3113, 3114, 12203, 12500, 12571):
                w_type = get(self.space).w_OperationalError
            else:
                w_type = get(self.space).w_DatabaseError
            raise OperationError(w_type, self.space.wrap(error))

        error = W_Error(self.space, self, context, 0)
        error.code = 0
        error.w_message = self.space.wrap("Invalid handle!")
        raise OperationError(get(self.space).w_DatabaseError, self.space.wrap(error))
示例#15
0
    def _verifyFetch(self, space):
        # make sure the cursor is open
        self._checkOpen(space)

        # fixup bound cursor, if necessary
        self._fixupBoundCursor()

        # make sure the cursor is for a query
        if self.statementType != roci.OCI_STMT_SELECT:
            raise OperationError(
                get(space).w_InterfaceError, space.wrap("not a query"))
示例#16
0
    def _verifyFetch(self, space):
        # make sure the cursor is open
        self._checkOpen(space)

        # fixup bound cursor, if necessary
        self._fixupBoundCursor()

        # make sure the cursor is for a query
        if self.statementType != roci.OCI_STMT_SELECT:
            raise OperationError(
                get(space).w_InterfaceError,
                space.wrap("not a query"))
示例#17
0
    def checkForError(self, status, context):
        if status in (roci.OCI_SUCCESS, roci.OCI_SUCCESS_WITH_INFO):
            return

        if status != roci.OCI_INVALID_HANDLE:
            # At this point it is assumed that the Oracle
            # environment is fully initialized
            error = W_Error(self.space, self, context, 1)
            if error.code in (1, 1400, 2290, 2291, 2292):
                w_type = get(self.space).w_IntegrityError
            elif error.code in (1012, 1033, 1034, 1089, 3113, 3114, 12203,
                                12500, 12571):
                w_type = get(self.space).w_OperationalError
            else:
                w_type = get(self.space).w_DatabaseError
            raise OperationError(w_type, self.space.wrap(error))

        error = W_Error(self.space, self, context, 0)
        error.code = 0
        error.w_message = self.space.wrap("Invalid handle!")
        raise OperationError(
            get(self.space).w_DatabaseError, self.space.wrap(error))
示例#18
0
 def _setErrorOffset(self, space, e):
     if e.match(space, get(space).w_DatabaseError):
         attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw')
         try:
             status = roci.OCIAttrGet(
                 self.handle, roci.OCI_HTYPE_STMT,
                 rffi.cast(roci.dvoidp, attrptr),
                 lltype.nullptr(roci.Ptr(roci.ub4).TO),
                 roci.OCI_ATTR_PARSE_ERROR_OFFSET,
                 self.environment.errorHandle)
             e.offset = attrptr[0]
         finally:
             lltype.free(attrptr, flavor='raw')
示例#19
0
    def bindnames(self, space):
        # make sure the cursor is open
        self._checkOpen(space)

        # ensure that a statement has already been prepared
        if not self.w_statement:
            raise OperationError(get(space).w_ProgrammingError,
                                 space.wrap("statement must be prepared first"))

        nbElements, names = self._get_bind_info(space, 8)
        if nbElements:
            _, names = self._get_bind_info(space, nbElements)
        return space.newlist(names)
示例#20
0
    def bindnames(self, space):
        # make sure the cursor is open
        self._checkOpen(space)

        # ensure that a statement has already been prepared
        if not self.w_statement:
            raise OperationError(get(space).w_ProgrammingError,
                                 space.wrap("statement must be prepared first"))

        nbElements, names = self._get_bind_info(space, 8)
        if nbElements:
            _, names = self._get_bind_info(space, nbElements)
        return space.newlist(names)
示例#21
0
 def _setErrorOffset(self, space, e):
     if e.match(space, get(space).w_DatabaseError):
         attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw')
         try:
             roci.OCIAttrGet(
                 self.handle, roci.OCI_HTYPE_STMT,
                 rffi.cast(roci.dvoidp, attrptr),
                 lltype.nullptr(roci.Ptr(roci.ub4).TO),
                 roci.OCI_ATTR_PARSE_ERROR_OFFSET,
                 self.environment.errorHandle)
             e.offset = attrptr[0]
         finally:
             lltype.free(attrptr, flavor='raw')
示例#22
0
 def startup(self, space):
     from pypy.module.oracle.interp_error import get
     state = get(space)
     state.startup(space)
     (state.w_DecimalType,
      state.w_DateTimeType, state.w_DateType, state.w_TimedeltaType,
      ) = space.fixedview(space.appexec([], """():
          import decimal, datetime
          return (decimal.Decimal,
                  datetime.datetime, datetime.date, datetime.timedelta)
     """))
     space.setattr(space.wrap(self),
                   space.wrap("Timestamp"), state.w_DateTimeType)
     space.setattr(space.wrap(self),
                   space.wrap("Date"), state.w_DateType)
示例#23
0
文件: __init__.py 项目: sota/pypy-old
 def startup(self, space):
     from pypy.module.oracle.interp_error import get
     state = get(space)
     state.startup(space)
     (
         state.w_DecimalType,
         state.w_DateTimeType,
         state.w_DateType,
         state.w_TimedeltaType,
     ) = space.fixedview(
         space.appexec([], """():
          import decimal, datetime
          return (decimal.Decimal,
                  datetime.datetime, datetime.date, datetime.timedelta)
     """))
     space.setattr(space.wrap(self), space.wrap("Timestamp"),
                   state.w_DateTimeType)
     space.setattr(space.wrap(self), space.wrap("Date"), state.w_DateType)
示例#24
0
    def create(space, threaded, events):
        "Create a new environment object from scratch"
        mode = roci.OCI_OBJECT
        if threaded:
            mode |= roci.OCI_THREADED
        if events:
            mode |= roci.OCI_EVENTS

        handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIEnv).TO, 1, flavor="raw")

        try:

            status = roci.OCIEnvNlsCreate(
                handleptr,
                mode,
                None,
                None,
                None,
                None,
                0,
                lltype.nullptr(rffi.CArray(roci.dvoidp)),
                config.CHARSETID,
                config.CHARSETID,
            )

            if not handleptr[0] or status not in (roci.OCI_SUCCESS, roci.OCI_SUCCESS_WITH_INFO):
                raise OperationError(
                    get(space).w_InterfaceError, space.wrap("Unable to acquire Oracle environment handle")
                )

            handle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor="raw")

        try:
            newenv = Environment(space, handle)
        except:
            roci.OCIHandleFree(handle, roci.OCI_HTYPE_ENV)
            raise

        newenv.maxBytesPerCharacter = config.BYTES_PER_CHAR
        newenv.maxStringBytes = config.BYTES_PER_CHAR * config.MAX_STRING_CHARS
        return newenv
示例#25
0
    def _setBindVariablesByName(self, space, w_vars, numElements, arrayPos,
                                defer):
        "handle named binds"
        # make sure positional and named binds are not being intermixed
        if self.bindList is not None:
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("positional and named binds cannot be intermixed"))

        if self.bindDict is None:
            self.bindDict = space.newdict()

        items = space.fixedview(space.call_method(w_vars, "iteritems"))
        for item in items:
            w_key, w_value = space.fixedview(item, 2)
            origVar = space.finditem(self.bindDict, w_key)
            newVar = self._setBindVariableHelper(space, w_value, origVar,
                                                 numElements, arrayPos, defer)
            if newVar:
                space.setitem(self.bindDict, w_key, newVar)
示例#26
0
    def _setBindVariablesByName(self, space,
                                w_vars, numElements, arrayPos, defer):
        "handle named binds"
        # make sure positional and named binds are not being intermixed
        if self.bindList is not None:
            raise OperationError(
                get(space).w_ProgrammingError,
                space.wrap("positional and named binds cannot be intermixed"))

        if self.bindDict is None:
            self.bindDict = space.newdict()

        items = space.fixedview(space.call_method(w_vars, "iteritems"))
        for item in items:
            w_key, w_value = space.fixedview(item, 2)
            origVar = space.finditem(self.bindDict, w_key)
            newVar = self._setBindVariableHelper(space, w_value, origVar,
                                                 numElements, arrayPos, defer)
            if newVar:
                space.setitem(self.bindDict, w_key, newVar)
示例#27
0
    def _setBindVariableHelper(self, space, w_value, origVar, numElements,
                               arrayPos, defer):

        valueIsVariable = space.is_true(
            space.isinstance(w_value,
                             get(space).w_Variable))
        newVar = None

        # handle case where variable is already bound
        if origVar:
            assert isinstance(origVar, interp_variable.W_Variable)

            # if the value is a variable object, rebind it if necessary
            if valueIsVariable:
                newVar = space.interp_w(interp_variable.W_Variable, w_value)
                assert isinstance(newVar, interp_variable.W_Variable)
                if newVar == origVar:
                    newVar = None

            # if the number of elements has changed, create a new variable
            # this is only necessary for executemany() since execute() always
            # passes a value of 1 for the number of elements
            elif numElements > origVar.allocatedElements:
                newVar = origVar.clone(self, numElements, origVar.size)
                assert isinstance(newVar, interp_variable.W_Variable)
                newVar.setValue(space, arrayPos, w_value)

            # otherwise, attempt to set the value
            else:
                try:
                    origVar.setValue(space, arrayPos, w_value)
                except OperationError, e:
                    # executemany() should simply fail after the first element
                    if arrayPos > 0:
                        raise
                    # anything other than IndexError or TypeError should fail
                    if (not e.match(space, space.w_IndexError)
                            and not e.match(space, space.w_TypeError)):
                        raise
                    # catch the exception and try to create a new variable
                    origVar = None
示例#28
0
    def create(space, threaded, events):
        "Create a new environment object from scratch"
        mode = roci.OCI_OBJECT
        if threaded:
            mode |= roci.OCI_THREADED
        if events:
            mode |= roci.OCI_EVENTS

        handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIEnv).TO,
                                  1, flavor='raw')

        try:

            status = roci.OCIEnvNlsCreate(
                handleptr, mode,
                None,
                None, None, None,
                0, lltype.nullptr(rffi.CArray(roci.dvoidp)),
                config.CHARSETID, config.CHARSETID)

            if not handleptr[0] or status not in (roci.OCI_SUCCESS,
                                                  roci.OCI_SUCCESS_WITH_INFO):
                raise OperationError(
                    get(space).w_InterfaceError,
                    space.wrap(
                        "Unable to acquire Oracle environment handle"))

            handle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')

        try:
            newenv = Environment(space, handle)
        except:
            roci.OCIHandleFree(handle, roci.OCI_HTYPE_ENV)
            raise

        newenv.maxBytesPerCharacter = config.BYTES_PER_CHAR
        newenv.maxStringBytes = config.BYTES_PER_CHAR * config.MAX_STRING_CHARS
        return newenv
示例#29
0
    def _setBindVariableHelper(self, space, w_value, origVar,
                               numElements, arrayPos, defer):

        valueIsVariable = space.isinstance_w(w_value, get(space).w_Variable)
        newVar = None

        # handle case where variable is already bound
        if origVar:
            assert isinstance(origVar, interp_variable.W_Variable)

            # if the value is a variable object, rebind it if necessary
            if valueIsVariable:
                newVar = space.interp_w(interp_variable.W_Variable, w_value)
                assert isinstance(newVar, interp_variable.W_Variable)
                if newVar == origVar:
                    newVar = None

            # if the number of elements has changed, create a new variable
            # this is only necessary for executemany() since execute() always
            # passes a value of 1 for the number of elements
            elif numElements > origVar.allocatedElements:
                newVar = origVar.clone(
                    self, numElements, origVar.size)
                assert isinstance(newVar, interp_variable.W_Variable)
                newVar.setValue(space, arrayPos, w_value)

            # otherwise, attempt to set the value
            else:
                try:
                    origVar.setValue(space, arrayPos, w_value)
                except OperationError, e:
                    # executemany() should simply fail after the first element
                    if arrayPos > 0:
                        raise
                    # anything other than IndexError or TypeError should fail
                    if (not e.match(space, space.w_IndexError) and
                        not e.match(space, space.w_TypeError)):
                        raise
                    # catch the exception and try to create a new variable
                    origVar = None
示例#30
0
    def _internalFetch(self, space, numRows):
        if not self.fetchVariables:
            raise OperationError(
                get(space).w_InterfaceError,
                space.wrap("query not executed"))

        status = roci.OCIStmtFetch(
            self.handle,
            self.environment.errorHandle,
            numRows,
            roci.OCI_FETCH_NEXT,
            roci.OCI_DEFAULT)

        if status != roci.OCI_NO_DATA:
            self.environment.checkForError(
                status,
                "Cursor_InternalFetch(): fetch")

        for var in self.fetchVariables:
            assert isinstance(var, interp_variable.W_Variable)
            var.internalFetchNum += 1

        attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO,
                                1, flavor='raw')
        try:
            status = roci.OCIAttrGet(
                self.handle, roci.OCI_HTYPE_STMT,
                rffi.cast(roci.dvoidp, attrptr),
                lltype.nullptr(roci.Ptr(roci.ub4).TO),
                roci.OCI_ATTR_ROW_COUNT,
                self.environment.errorHandle)

            self.environment.checkForError(
                status, "Cursor_InternalFetch(): row count")

            self.actualRows = (rffi.cast(lltype.Signed, attrptr[0])
                               - self.rowCount)
            self.rowNum = 0
        finally:
            lltype.free(attrptr, flavor='raw')
示例#31
0
def convertObject(space, environment, typeCode,
                  value, indicator, var, subtype):

    # null values returned as None
    if (rffi.cast(lltype.Signed,
                  rffi.cast(roci.Ptr(roci.OCIInd),
                            indicator)[0])
        ==
        rffi.cast(lltype.Signed, roci.OCI_IND_NULL)):
        return space.w_None

    if typeCode in (roci.OCI_TYPECODE_CHAR,
                    roci.OCI_TYPECODE_VARCHAR,
                    roci.OCI_TYPECODE_VARCHAR2):
        strValue = rffi.cast(roci.Ptr(roci.OCIString), value)[0]
        ptr = roci.OCIStringPtr(environment.handle, strValue)
        size = roci.OCIStringSize(environment.handle, strValue)
        return config.w_string(space, ptr, rffi.cast(lltype.Signed, size))
    elif typeCode == roci.OCI_TYPECODE_NUMBER:
        return transform.OracleNumberToPythonFloat(
            environment,
            rffi.cast(roci.Ptr(roci.OCINumber), value))
    elif typeCode == roci.OCI_TYPECODE_DATE:
        dateValue = rffi.cast(roci.Ptr(roci.OCIDate), value)
        return transform.OracleDateToPythonDateTime(environment, dateValue)
    elif typeCode == roci.OCI_TYPECODE_TIMESTAMP:
        dateValue = rffi.cast(roci.Ptr(roci.OCIDateTime), value)
        return transform.OracleTimestampToPythonDate(environment, dateValue)
    elif typeCode == roci.OCI_TYPECODE_OBJECT:
        return space.wrap(W_ExternalObject(var, subtype, value, indicator,
                                           isIndependent=False))
    elif typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION:
        return convertCollection(space, environment, value, var, subtype)

    raise OperationError(
        get(space).w_NotSupportedError,
        space.wrap(
            "ExternalObjectVar_GetAttributeValue(): unhandled data type %d" % (
                typeCode,)))
示例#32
0
def convertObject(space, environment, typeCode,
                  value, indicator, var, subtype):

    # null values returned as None
    if (rffi.cast(lltype.Signed,
                  rffi.cast(roci.Ptr(roci.OCIInd),
                            indicator)[0])
        ==
        rffi.cast(lltype.Signed, roci.OCI_IND_NULL)):
        return space.w_None

    if typeCode in (roci.OCI_TYPECODE_CHAR,
                    roci.OCI_TYPECODE_VARCHAR,
                    roci.OCI_TYPECODE_VARCHAR2):
        strValue = rffi.cast(roci.Ptr(roci.OCIString), value)[0]
        ptr = roci.OCIStringPtr(environment.handle, strValue)
        size = roci.OCIStringSize(environment.handle, strValue)
        return config.w_string(space, ptr, size)
    elif typeCode == roci.OCI_TYPECODE_NUMBER:
        return transform.OracleNumberToPythonFloat(
            environment,
            rffi.cast(roci.Ptr(roci.OCINumber), value))
    elif typeCode == roci.OCI_TYPECODE_DATE:
        dateValue = rffi.cast(roci.Ptr(roci.OCIDate), value)
        return transform.OracleDateToPythonDateTime(environment, dateValue)
    elif typeCode == roci.OCI_TYPECODE_TIMESTAMP:
        dateValue = rffi.cast(roci.Ptr(roci.OCIDateTime), value)
        return transform.OracleTimestampToPythonDate(environment, dateValue)
    elif typeCode == roci.OCI_TYPECODE_OBJECT:
        return space.wrap(W_ExternalObject(var, subtype, value, indicator,
                                           isIndependent=False))
    elif typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION:
        return convertCollection(space, environment, value, var, subtype)

    raise OperationError(
        get(space).w_NotSupportedError,
        space.wrap(
            "ExternalObjectVar_GetAttributeValue(): unhandled data type %d" % (
                typeCode,)))
示例#33
0
    def setinputsizes(self, space, __args__):
        args_w, kw_w = __args__.unpack()

        # only expect keyword arguments or positional arguments, not both
        if args_w and kw_w:
            raise OperationError(
                interp_error.get(space).w_InterfaceError,
                space.wrap(
                    "expecting argument or keyword arguments, not both"))

        # make sure the cursor is open
        self._checkOpen(space)

        # eliminate existing bind variables
        self.bindList = None
        self.bindDict = None

        self.setInputSizes = True

        # process each input
        if kw_w:
            self.bindDict = space.newdict()
            for key, w_value in kw_w.iteritems():
                var = interp_variable.newVariableByType(
                    space, self, w_value, self.bindArraySize)
                space.setitem(self.bindDict, space.wrap(key), var)
            return self.bindDict
        else:
            self.bindList = [None] * len(args_w)
            for i in range(len(args_w)):
                w_value = args_w[i]
                if space.is_w(w_value, space.w_None):
                    var = None
                else:
                    var = interp_variable.newVariableByType(
                        space, self, w_value, self.bindArraySize)
                self.bindList[i] = var
            return space.newlist(self.bindList)
示例#34
0
    def setinputsizes(self, space, __args__):
        args_w, kw_w = __args__.unpack()

        # only expect keyword arguments or positional arguments, not both
        if args_w and kw_w:
            raise OperationError(
                interp_error.get(space).w_InterfaceError,
                space.wrap(
                    "expecting argument or keyword arguments, not both"))

        # make sure the cursor is open
        self._checkOpen(space)

        # eliminate existing bind variables
        self.bindList = None
        self.bindDict = None

        self.setInputSizes = True

        # process each input
        if kw_w:
            self.bindDict = space.newdict()
            for key, w_value in kw_w.iteritems():
                var = interp_variable.newVariableByType(
                    space, self, w_value, self.bindArraySize)
                space.setitem(self.bindDict, space.wrap(key), var)
            return self.bindDict
        else:
            self.bindList = [None] * len(args_w)
            for i in range(len(args_w)):
                w_value = args_w[i]
                if space.is_w(w_value, space.w_None):
                    var = None
                else:
                    var = interp_variable.newVariableByType(
                        space, self, w_value, self.bindArraySize)
                self.bindList[i] = var
            return space.newlist(self.bindList)
示例#35
0
    def executemany(self, space, w_stmt, w_list_of_args):
        if space.is_w(w_stmt, space.w_None):
            w_stmt = None
        if not space.isinstance_w(w_list_of_args, space.w_list):
            raise OperationError(
                space.w_TypeError,
                space.wrap("list expected"))

        # make sure the cursor is open
        self._checkOpen(space)

        # prepare the statement
        self._internalPrepare(space, w_stmt, None)

        # queries are not supported as the result is undefined
        if self.statementType == roci.OCI_STMT_SELECT:
            raise OperationError(
                get(space).w_NotSupportedError,
                space.wrap("queries not supported: results undefined"))

        # perform binds
        args_w = space.listview(w_list_of_args)
        numrows = len(args_w)
        for i in range(numrows):
            w_arguments = args_w[i]
            deferred = i < numrows - 1
            if space.isinstance_w(w_arguments, space.w_dict):
                self._setBindVariablesByName(
                    space, w_arguments, numrows, i, deferred)
            else:
                self._setBindVariablesByPos(
                    space, w_arguments, numrows, i, deferred)
        self._performBind(space)

        # execute the statement, but only if the number of rows is greater than
        # zero since Oracle raises an error otherwise
        if numrows > 0:
            self._internalExecute(space, numIters=numrows)
示例#36
0
    def executemany(self, space, w_stmt, w_list_of_args):
        if space.is_w(w_stmt, space.w_None):
            w_stmt = None
        if not space.is_true(space.isinstance(w_list_of_args, space.w_list)):
            raise OperationError(
                space.w_TypeError,
                space.wrap("list expected"))

        # make sure the cursor is open
        self._checkOpen(space)

        # prepare the statement
        self._internalPrepare(space, w_stmt, None)

        # queries are not supported as the result is undefined
        if self.statementType == roci.OCI_STMT_SELECT:
            raise OperationError(
                get(space).w_NotSupportedError,
                space.wrap("queries not supported: results undefined"))

        # perform binds
        args_w = space.listview(w_list_of_args)
        numrows = len(args_w)
        for i in range(numrows):
            w_arguments = args_w[i]
            deferred = i < numrows - 1
            if space.is_true(space.isinstance(w_arguments, space.w_dict)):
                self._setBindVariablesByName(
                    space, w_arguments, numrows, i, deferred)
            else:
                self._setBindVariablesByPos(
                    space, w_arguments, numrows, i, deferred)
        self._performBind(space)

        # execute the statement, but only if the number of rows is greater than
        # zero since Oracle raises an error otherwise
        if numrows > 0:
            self._internalExecute(space, numIters=numrows)
示例#37
0
 def _checkConnected(self, space):
     if not self.handle:
         raise OperationError(
             interp_error.get(space).w_InterfaceError,
             space.wrap("not connected"))
示例#38
0
 def _verify(self, space):
     if self.internalFetchNum != self.lobVar.internalFetchNum:
         raise OperationError(
             get(space).w_ProgrammingError,
             space.wrap(
                 "LOB variable no longer valid after subsequent fetch"))
示例#39
0
    def descr_new(space, w_subtype,
                  w_user, w_password, w_dsn,
                  min, max, increment,
                  w_connectiontype=Null,
                  threaded=False,
                  getmode=roci.OCI_SPOOL_ATTRVAL_NOWAIT,
                  events=False,
                  homogeneous=True):
        self = space.allocate_instance(W_SessionPool, w_subtype)
        W_SessionPool.__init__(self)

        if w_connectiontype is not None:
            if not space.is_true(space.issubtype(w_connectiontype,
                                                 get(space).w_Connection)):
                raise OperationError(
                    interp_error.get(space).w_ProgrammingError,
                    space.wrap(
                        "connectiontype must be a subclass of Connection"))
            self.w_connectionType = w_connectiontype
        else:
            self.w_connectionType = get(space).w_Connection

        self.w_username = w_user
        self.w_password = w_password
        self.w_tnsentry = w_dsn

        self.minSessions = min
        self.maxSessions = max
        self.sessionIncrement = increment
        self.homogeneous = homogeneous

        # set up the environment
        self.environment = interp_environ.Environment.create(
            space, threaded, events)

        # create the session pool handle
        handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIServer).TO,
                                  1, flavor='raw')
        try:
            status = roci.OCIHandleAlloc(
                self.environment.handle,
                handleptr, roci.OCI_HTYPE_SPOOL, 0,
                lltype.nullptr(rffi.CArray(roci.dvoidp)))
            self.environment.checkForError(
                status, "SessionPool_New(): allocate handle")
            self.handle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')

        # prepare pool mode
        poolMode = roci.OCI_SPC_STMTCACHE
        if self.homogeneous:
            poolMode |= roci.OCI_SPC_HOMOGENEOUS

        # create the session pool
        user_buf = config.StringBuffer()
        user_buf.fill(space, self.w_username)
        password_buf = config.StringBuffer()
        password_buf.fill(space, self.w_password)
        dsn_buf = config.StringBuffer()
        dsn_buf.fill(space, self.w_tnsentry)
        poolnameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1,
                                    flavor='raw')
        poolnamelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1,
                                       flavor='raw')

        try:
            status = roci.OCISessionPoolCreate(
                self.environment.handle,
                self.environment.errorHandle,
                self.handle,
                poolnameptr, poolnamelenptr,
                dsn_buf.ptr, dsn_buf.size,
                min, max, increment,
                user_buf.ptr, user_buf.size,
                password_buf.ptr, password_buf.size,
                poolMode)
            self.environment.checkForError(
                status, "SessionPool_New(): create pool")

            self.w_name = config.w_string(space, poolnameptr[0],
                                          poolnamelenptr[0])
        finally:
            user_buf.clear()
            password_buf.clear()
            dsn_buf.clear()

        return space.wrap(self)
示例#40
0
    def descr_new(space,
                  w_subtype,
                  w_user,
                  w_password,
                  w_dsn,
                  min,
                  max,
                  increment,
                  w_connectiontype=Null,
                  threaded=False,
                  getmode=roci.OCI_SPOOL_ATTRVAL_NOWAIT,
                  events=False,
                  homogeneous=True):
        self = space.allocate_instance(W_SessionPool, w_subtype)
        W_SessionPool.__init__(self)

        if w_connectiontype is not None:
            if not space.is_true(
                    space.issubtype(w_connectiontype,
                                    get(space).w_Connection)):
                raise OperationError(
                    interp_error.get(space).w_ProgrammingError,
                    space.wrap(
                        "connectiontype must be a subclass of Connection"))
            self.w_connectionType = w_connectiontype
        else:
            self.w_connectionType = get(space).w_Connection

        self.w_username = w_user
        self.w_password = w_password
        self.w_tnsentry = w_dsn

        self.minSessions = min
        self.maxSessions = max
        self.sessionIncrement = increment
        self.homogeneous = homogeneous

        # set up the environment
        self.environment = interp_environ.Environment.create(
            space, threaded, events)

        # create the session pool handle
        handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIServer).TO,
                                  1,
                                  flavor='raw')
        try:
            status = roci.OCIHandleAlloc(
                self.environment.handle, handleptr, roci.OCI_HTYPE_SPOOL, 0,
                lltype.nullptr(rffi.CArray(roci.dvoidp)))
            self.environment.checkForError(
                status, "SessionPool_New(): allocate handle")
            self.handle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')

        # prepare pool mode
        poolMode = roci.OCI_SPC_STMTCACHE
        if self.homogeneous:
            poolMode |= roci.OCI_SPC_HOMOGENEOUS

        # create the session pool
        user_buf = config.StringBuffer()
        user_buf.fill(space, self.w_username)
        password_buf = config.StringBuffer()
        password_buf.fill(space, self.w_password)
        dsn_buf = config.StringBuffer()
        dsn_buf.fill(space, self.w_tnsentry)
        poolnameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO,
                                    1,
                                    flavor='raw')
        poolnamelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO,
                                       1,
                                       flavor='raw')

        try:
            status = roci.OCISessionPoolCreate(
                self.environment.handle, self.environment.errorHandle,
                self.handle, poolnameptr, poolnamelenptr, dsn_buf.ptr,
                dsn_buf.size, min, max, increment, user_buf.ptr, user_buf.size,
                password_buf.ptr, password_buf.size, poolMode)
            self.environment.checkForError(status,
                                           "SessionPool_New(): create pool")

            self.w_name = config.w_string(
                space, poolnameptr[0],
                rffi.cast(lltype.Signed, poolnamelenptr[0]))
        finally:
            user_buf.clear()
            password_buf.clear()
            dsn_buf.clear()
            lltype.free(poolnameptr, flavor='raw')
            lltype.free(poolnamelenptr, flavor='raw')

        return space.wrap(self)
示例#41
0
 def checkConnected(self, space):
     if not self.handle:
         raise OperationError(
             get(space).w_InterfaceError,
             space.wrap("not connected"))
示例#42
0
 def _checkOpen(self, space):
     if not self.isOpen:
         raise OperationError(
             interp_error.get(space).w_InterfaceError,
             space.wrap("not open"))
示例#43
0
 def _verify(self, space):
     if self.internalFetchNum != self.lobVar.internalFetchNum:
         raise OperationError(
             get(space).w_ProgrammingError,
             space.wrap(
                 "LOB variable no longer valid after subsequent fetch"))
示例#44
0
    def connect(self, space, mode, twophase):
        stringBuffer = StringBuffer()

        # allocate the server handle
        handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIServer).TO,
                                  1, flavor='raw')
        try:
            status = roci.OCIHandleAlloc(
                self.environment.handle,
                handleptr, roci.OCI_HTYPE_SERVER, 0,
                lltype.nullptr(rffi.CArray(roci.dvoidp)))
            self.environment.checkForError(
                status, "Connection_Connect(): allocate server handle")
            self.serverHandle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')

        # attach to the server
        stringBuffer.fill(space, self.w_tnsentry)
        try:
            status = roci.OCIServerAttach(
                self.serverHandle,
                self.environment.errorHandle,
                stringBuffer.ptr, stringBuffer.size,
                roci.OCI_DEFAULT)
            self.environment.checkForError(
                status, "Connection_Connect(): server attach")
        finally:
            stringBuffer.clear()

        # allocate the service context handle
        handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCISvcCtx).TO,
                                  1, flavor='raw')

        try:
            status = roci.OCIHandleAlloc(
                self.environment.handle,
                handleptr, roci.OCI_HTYPE_SVCCTX, 0,
                lltype.nullptr(rffi.CArray(roci.dvoidp)))
            self.environment.checkForError(
                status, "Connection_Connect(): allocate service context handle")
            self.handle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')

        # set attribute for server handle
        status = roci.OCIAttrSet(
            self.handle, roci.OCI_HTYPE_SVCCTX,
            self.serverHandle, 0,
            roci.OCI_ATTR_SERVER,
            self.environment.errorHandle)
        self.environment.checkForError(
            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:
            raise OperationError(
                interp_error.get(space).w_NotSupportedError,
                space.wrap("XXX write me"))

        # allocate the session handle
        handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCISession).TO,
                                  1, flavor='raw')
        try:
            status = roci.OCIHandleAlloc(
                self.environment.handle,
                handleptr, roci.OCI_HTYPE_SESSION, 0,
                lltype.nullptr(rffi.CArray(roci.dvoidp)))
            self.environment.checkForError(
                status, "Connection_Connect(): allocate session handle")
            self.sessionHandle = handleptr[0]
        finally:
            lltype.free(handleptr, flavor='raw')

        credentialType = roci.OCI_CRED_EXT

        # set user name in session handle
        stringBuffer.fill(space, self.w_username)
        try:
            if stringBuffer.size > 0:
                credentialType = roci.OCI_CRED_RDBMS
                status = roci.OCIAttrSet(
                    self.sessionHandle,
                    roci.OCI_HTYPE_SESSION,
                    stringBuffer.ptr, stringBuffer.size,
                    roci.OCI_ATTR_USERNAME,
                    self.environment.errorHandle)
                self.environment.checkForError(
                    status, "Connection_Connect(): set user name")
        finally:
            stringBuffer.clear()

        # set password in session handle
        stringBuffer.fill(space, self.w_password)
        try:
            if stringBuffer.size > 0:
                credentialType = roci.OCI_CRED_RDBMS
                status = roci.OCIAttrSet(
                    self.sessionHandle,
                    roci.OCI_HTYPE_SESSION,
                    stringBuffer.ptr, stringBuffer.size,
                    roci.OCI_ATTR_PASSWORD,
                    self.environment.errorHandle)
                self.environment.checkForError(
                    status, "Connection_Connect(): set password")
        finally:
            stringBuffer.clear()

        # set the session handle on the service context handle
        status = roci.OCIAttrSet(
            self.handle, roci.OCI_HTYPE_SVCCTX,
            self.sessionHandle, 0,
            roci.OCI_ATTR_SESSION,
            self.environment.errorHandle)
        self.environment.checkForError(
            status, "Connection_Connect(): set session handle")
    
        # if a new password has been specified, change it which will also
        # establish the session

        # begin the session
        status = roci.OCISessionBegin(
            self.handle, self.environment.errorHandle,
            self.sessionHandle, credentialType, mode)
        try:
            self.environment.checkForError(
                status, "Connection_Connect(): begin session")
        except:
            self.sessionHandle = lltype.nullptr(roci.OCISession.TO)
            raise
示例#45
0
 def _checkOpen(self, space):
     if not self.isOpen:
         raise OperationError(
             interp_error.get(space).w_InterfaceError,
             space.wrap("not open"))