示例#1
0
    def _itemDescription(self, space, pos):
        "Return a tuple describing the item at the given position"

        # acquire parameter descriptor
        paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, 1, flavor='raw')
        try:
            status = roci.OCIParamGet(self.handle, roci.OCI_HTYPE_STMT,
                                      self.environment.errorHandle,
                                      rffi.cast(roci.dvoidpp, paramptr), pos)
            self.environment.checkForError(
                status, "Cursor_GetDescription(): parameter")
            param = paramptr[0]
        finally:
            lltype.free(paramptr, flavor='raw')

        try:
            # acquire usable type of item
            varType = interp_variable.typeByOracleDescriptor(
                param, self.environment)

            # acquire internal size of item
            attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub2).TO,
                                    1,
                                    flavor='raw')
            try:
                status = roci.OCIAttrGet(param, roci.OCI_HTYPE_DESCRIBE,
                                         rffi.cast(roci.dvoidp, attrptr),
                                         lltype.nullptr(roci.Ptr(roci.ub4).TO),
                                         roci.OCI_ATTR_DATA_SIZE,
                                         self.environment.errorHandle)
                self.environment.checkForError(
                    status, "Cursor_ItemDescription(): internal size")
                internalSize = rffi.cast(lltype.Signed, attrptr[0])
            finally:
                lltype.free(attrptr, flavor='raw')

            # acquire name of item
            nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO,
                                    1,
                                    flavor='raw')
            lenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO,
                                   1,
                                   flavor='raw')
            try:
                status = roci.OCIAttrGet(param, roci.OCI_HTYPE_DESCRIBE,
                                         rffi.cast(roci.dvoidp, nameptr),
                                         lenptr, roci.OCI_ATTR_NAME,
                                         self.environment.errorHandle)
                self.environment.checkForError(
                    status, "Cursor_ItemDescription(): name")
                name = rffi.charpsize2str(nameptr[0],
                                          rffi.cast(lltype.Signed, lenptr[0]))
            finally:
                lltype.free(nameptr, flavor='raw')
                lltype.free(lenptr, flavor='raw')

            # lookup precision and scale
            if varType is interp_variable.VT_Float:
                attrptr = lltype.malloc(rffi.CArrayPtr(roci.sb1).TO,
                                        1,
                                        flavor='raw')
                try:
                    status = roci.OCIAttrGet(
                        param, roci.OCI_HTYPE_DESCRIBE,
                        rffi.cast(roci.dvoidp, attrptr),
                        lltype.nullptr(roci.Ptr(roci.ub4).TO),
                        roci.OCI_ATTR_SCALE, self.environment.errorHandle)
                    self.environment.checkForError(
                        status, "Cursor_ItemDescription(): scale")
                    scale = rffi.cast(lltype.Signed, attrptr[0])
                finally:
                    lltype.free(attrptr, flavor='raw')

                attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub2).TO,
                                        1,
                                        flavor='raw')
                try:
                    status = roci.OCIAttrGet(
                        param, roci.OCI_HTYPE_DESCRIBE,
                        rffi.cast(roci.dvoidp, attrptr),
                        lltype.nullptr(roci.Ptr(roci.ub4).TO),
                        roci.OCI_ATTR_PRECISION, self.environment.errorHandle)
                    self.environment.checkForError(
                        status, "Cursor_ItemDescription(): precision")
                    precision = rffi.cast(lltype.Signed, attrptr[0])
                finally:
                    lltype.free(attrptr, flavor='raw')
            else:
                scale = 0
                precision = 0

            # lookup whether null is permitted for the attribute
            attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub1).TO,
                                    1,
                                    flavor='raw')
            try:
                status = roci.OCIAttrGet(param, roci.OCI_HTYPE_DESCRIBE,
                                         rffi.cast(roci.dvoidp, attrptr),
                                         lltype.nullptr(roci.Ptr(roci.ub4).TO),
                                         roci.OCI_ATTR_IS_NULL,
                                         self.environment.errorHandle)
                self.environment.checkForError(
                    status, "Cursor_ItemDescription(): nullable")
                nullable = rffi.cast(lltype.Signed, attrptr[0]) != 0
            finally:
                lltype.free(attrptr, flavor='raw')

            # set display size based on data type
            if varType is interp_variable.VT_String:
                displaySize = internalSize
            elif varType is interp_variable.VT_NationalCharString:
                displaySize = internalSize / 2
            elif varType is interp_variable.VT_Binary:
                displaySize = internalSize
            elif varType is interp_variable.VT_FixedChar:
                displaySize = internalSize
            elif varType is interp_variable.VT_FixedNationalChar:
                displaySize = internalSize / 2
            elif varType is interp_variable.VT_Float:
                if precision:
                    displaySize = precision + 1
                    if scale > 0:
                        displaySize += scale + 1
                else:
                    displaySize = 127
            elif varType is interp_variable.VT_DateTime:
                displaySize = 23
            else:
                displaySize = -1

            # return the tuple
            return [
                space.wrap(name),
                space.gettypeobject(varType.typedef),
                space.wrap(displaySize),
                space.wrap(internalSize),
                space.wrap(precision),
                space.wrap(scale),
                space.wrap(nullable)
            ]

        finally:
            roci.OCIDescriptorFree(param, roci.OCI_DTYPE_PARAM)
示例#2
0
    def describe(self, connection, describeHandle):
        "Describe the type and store information about it as needed"

        # describe the type
        status = roci.OCIDescribeAny(
            connection.handle,
            self.environment.errorHandle,
            self.tdo, 0,
            roci.OCI_OTYPE_PTR,
            roci.OCI_DEFAULT,
            roci.OCI_PTYPE_TYPE,
            describeHandle)
        self.environment.checkForError(
            status, "ObjectType_Describe(): describe type")

        # get top level parameter descriptor
        paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO,
                                 1, flavor='raw')
        try:
            status = roci.OCIAttrGet(
                describeHandle, roci.OCI_HTYPE_DESCRIBE,
                rffi.cast(roci.dvoidp, paramptr),
                lltype.nullptr(roci.Ptr(roci.ub4).TO),
                roci.OCI_ATTR_PARAM,
                self.environment.errorHandle)
            self.environment.checkForError(
                status,
                "ObjectType_Describe(): get top level parameter descriptor")
            toplevelParam = paramptr[0]
        finally:
            lltype.free(paramptr, flavor='raw')

        # determine type of type
        typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO,
                                    1, flavor='raw')
        try:
            status = roci.OCIAttrGet(
                toplevelParam, roci.OCI_DTYPE_PARAM,
                rffi.cast(roci.dvoidp, typecodeptr),
                lltype.nullptr(roci.Ptr(roci.ub4).TO),
                roci.OCI_ATTR_TYPECODE,
                self.environment.errorHandle)
            self.environment.checkForError(
                status, "ObjectType_Describe(): get type code")
            typeCode = rffi.cast(lltype.Signed, typecodeptr[0])
        finally:
            lltype.free(typecodeptr, flavor='raw')

        # if a collection, need to determine the sub type
        if typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION:
            self.isCollection = 1

            # determine type of collection
            typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO,
                                        1, flavor='raw')
            try:
                status = roci.OCIAttrGet(
                    toplevelParam, roci.OCI_DTYPE_PARAM,
                    rffi.cast(roci.dvoidp, typecodeptr),
                    lltype.nullptr(roci.Ptr(roci.ub4).TO),
                    roci.OCI_ATTR_TYPECODE,
                    self.environment.errorHandle)
                self.environment.checkForError(
                    status, "ObjectType_Describe(): get collection type code")
                self.collectionTypeCode = typecodeptr[0]
            finally:
                lltype.free(typecodeptr, flavor='raw')

            # acquire collection parameter descriptor
            paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO,
                                     1, flavor='raw')
            try:
                status = roci.OCIAttrGet(
                    toplevelParam, roci.OCI_DTYPE_PARAM,
                    rffi.cast(roci.dvoidp, paramptr),
                    lltype.nullptr(roci.Ptr(roci.ub4).TO),
                    roci.OCI_ATTR_COLLECTION_ELEMENT,
                    self.environment.errorHandle)
                self.environment.checkForError(
                    status,
                    "ObjectType_Describe(): get collection descriptor")
                collectionParam = paramptr[0]
            finally:
                lltype.free(paramptr, flavor='raw')

            # determine type of element
            typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO,
                                        1, flavor='raw')
            try:
                status = roci.OCIAttrGet(
                    collectionParam, roci.OCI_DTYPE_PARAM,
                    rffi.cast(roci.dvoidp, typecodeptr),
                    lltype.nullptr(roci.Ptr(roci.ub4).TO),
                    roci.OCI_ATTR_TYPECODE,
                    self.environment.errorHandle)
                self.environment.checkForError(
                    status, "ObjectType_Describe(): get element type code")
                self.elementTypeCode = rffi.cast(lltype.Signed, typecodeptr[0])
            finally:
                lltype.free(typecodeptr, flavor='raw')

            # if element type is an object type get its type
            if self.elementTypeCode == roci.OCI_TYPECODE_OBJECT:
                self.elementType = W_ObjectType(connection, collectionParam)
            else:
                self.elementType = None

        # determine the number of attributes
        numptr = lltype.malloc(roci.Ptr(roci.ub2).TO,
                               1, flavor='raw')
        try:
            status = roci.OCIAttrGet(
                toplevelParam, roci.OCI_DTYPE_PARAM,
                rffi.cast(roci.dvoidp, numptr),
                lltype.nullptr(roci.Ptr(roci.ub4).TO),
                roci.OCI_ATTR_NUM_TYPE_ATTRS,
                self.environment.errorHandle)
            self.environment.checkForError(
                status, "ObjectType_Describe(): get number of attributes")
            numAttributes = numptr[0]
        finally:
            lltype.free(numptr, flavor='raw')

        # allocate the attribute list and dictionary
        self.attributes = []
        self.attributesByName = {}

        # acquire the list parameter descriptor
        listptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO,
                               1, flavor='raw')
        try:
            status = roci.OCIAttrGet(
                toplevelParam, roci.OCI_DTYPE_PARAM,
                rffi.cast(roci.dvoidp, listptr),
                lltype.nullptr(roci.Ptr(roci.ub4).TO),
                roci.OCI_ATTR_LIST_TYPE_ATTRS,
                self.environment.errorHandle)
            self.environment.checkForError(
                status, "ObjectType_Describe(): get list parameter descriptor")
            attributeListParam = listptr[0]
        finally:
            lltype.free(listptr, flavor='raw')

        # create attribute information for each attribute
        for i in range(numAttributes):
            paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO,
                                    1, flavor='raw')
            try:
                status = roci.OCIParamGet(
                    attributeListParam, roci.OCI_DTYPE_PARAM,
                    self.environment.errorHandle,
                    paramptr, i + 1)
                self.environment.checkForError(
                    status,
                    "ObjectType_Describe(): get attribute param descriptor")
                attribute = W_ObjectAttribute(connection, paramptr[0])
            finally:
                lltype.free(paramptr, flavor='raw')

            self.attributes.append(attribute)
            self.attributesByName[attribute.name] = attribute