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)
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