def _performDefine(self): # determine number of items in select-list 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_PARAM_COUNT, self.environment.errorHandle) self.environment.checkForError( status, "Cursor_PerformDefine()") numParams = attrptr[0] finally: lltype.free(attrptr, flavor='raw') self.fetchVariables = [] # define a variable for each select-item self.fetchArraySize = self.arraySize for i in range(numParams): var = interp_variable.define(self, i+1, self.fetchArraySize) assert isinstance(var, interp_variable.W_Variable) self.fetchVariables.append(var)
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')
def getDescription(self, space): "Return a list of 7-tuples consisting of the description of " "the define variables" # make sure the cursor is open self._checkOpen(space) # fixup bound cursor, if necessary self._fixupBoundCursor() # if not a query, return None if self.statementType != roci.OCI_STMT_SELECT: return # determine number of items in select-list attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub1).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_PARAM_COUNT, self.environment.errorHandle) self.environment.checkForError(status, "Cursor_GetDescription()") numItems = attrptr[0] finally: lltype.free(attrptr, flavor='raw') return space.newlist([ space.newtuple(self._itemDescription(space, i + 1)) for i in range(numItems) ])
def _setRowCount(self): if self.statementType == roci.OCI_STMT_SELECT: self.rowCount = 0 self.actualRows = -1 self.rowNum = 0 elif self.statementType in (roci.OCI_STMT_INSERT, roci.OCI_STMT_UPDATE, roci.OCI_STMT_DELETE): 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_SetRowCount()") self.rowCount = rffi.cast(lltype.Signed, attrptr[0]) finally: lltype.free(attrptr, flavor='raw') else: self.rowCount = -1
def initialize(self, connection, param): # determine the name of the attribute 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_DTYPE_PARAM, rffi.cast(roci.dvoidp, nameptr), lenptr, roci.OCI_ATTR_NAME, connection.environment.errorHandle) connection.environment.checkForError( status, "ObjectAttribute_Initialize(): get name") self.name = rffi.charpsize2str(nameptr[0], lenptr[0]) finally: lltype.free(nameptr, flavor='raw') lltype.free(lenptr, flavor='raw') # determine the type of the attribute typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, 1, flavor='raw') try: status = roci.OCIAttrGet( param, roci.OCI_DTYPE_PARAM, rffi.cast(roci.dvoidp, typecodeptr), lltype.nullptr(roci.Ptr(roci.ub4).TO), roci.OCI_ATTR_TYPECODE, connection.environment.errorHandle) connection.environment.checkForError( status, "ObjectType_Describe(): get type code") self.typeCode = rffi.cast(lltype.Signed, typecodeptr[0]) finally: lltype.free(typecodeptr, flavor='raw') # if the type of the attribute is object, recurse if self.typeCode in (roci.OCI_TYPECODE_NAMEDCOLLECTION, roci.OCI_TYPECODE_OBJECT): self.subType = W_ObjectType(connection, param) else: self.subType = None
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')
def _getStatementType(self): attrptr = lltype.malloc(rffi.CArrayPtr(roci.ub2).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_STMT_TYPE, self.environment.errorHandle) self.environment.checkForError(status, "Cursor_GetStatementType()") self.statementType = rffi.cast(lltype.Signed, attrptr[0]) finally: lltype.free(attrptr, flavor='raw') self.fetchVariables = None
def fget(self, space): self.checkConnected(space) valueptr = lltype.malloc(rffi.CArrayPtr(oci_value_type).TO, 1, flavor='raw') try: status = roci.OCIAttrGet(self.handle, roci.OCI_HTYPE_SPOOL, rffi.cast(roci.dvoidp, valueptr), lltype.nullptr(roci.Ptr(roci.ub4).TO), oci_attr_code, self.environment.errorHandle) return space.wrap(valueptr[0]) finally: lltype.free(valueptr, flavor='raw')
def _getCharacterSetName(self, space, attribute): # get character set id charsetIdPtr = lltype.malloc(rffi.CArrayPtr(roci.ub2).TO, 1, flavor='raw') try: status = roci.OCIAttrGet(self.environment.handle, roci.OCI_HTYPE_ENV, rffi.cast(roci.dvoidp, charsetIdPtr), lltype.nullptr(roci.Ptr(roci.ub4).TO), attribute, self.environment.errorHandle) self.environment.checkForError( status, "Connection_GetCharacterSetName(): get charset id") charsetId = charsetIdPtr[0] finally: lltype.free(charsetIdPtr, flavor='raw') # get character set name charsetname_buf, charsetname = rffi.alloc_buffer(roci.OCI_NLS_MAXBUFSZ) try: status = roci.OCINlsCharSetIdToName(self.environment.handle, charsetname_buf, roci.OCI_NLS_MAXBUFSZ, charsetId) self.environment.checkForError( status, "Connection_GetCharacterSetName(): get Oracle charset name") ianacharset_buf, ianacharset = rffi.alloc_buffer( roci.OCI_NLS_MAXBUFSZ) try: # get IANA character set name status = roci.OCINlsNameMap(self.environment.handle, ianacharset_buf, roci.OCI_NLS_MAXBUFSZ, charsetname_buf, roci.OCI_NLS_CS_ORA_TO_IANA) self.environment.checkForError( status, "Connection_GetCharacterSetName(): translate NLS charset") charset = rffi.charp2str(ianacharset_buf) finally: rffi.keep_buffer_alive_until_here(ianacharset_buf, ianacharset) finally: rffi.keep_buffer_alive_until_here(charsetname_buf, charsetname) return space.wrap(charset)
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 initialize(self, connection, param): nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, flavor='raw') lenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw') try: # determine the schema of the type status = roci.OCIAttrGet( param, roci.OCI_HTYPE_DESCRIBE, rffi.cast(roci.dvoidp, nameptr), lenptr, roci.OCI_ATTR_SCHEMA_NAME, self.environment.errorHandle) self.environment.checkForError( status, "ObjectType_Initialize(): get schema name") self.schema = rffi.charpsize2str(nameptr[0], lenptr[0]) # determine the name of the type status = roci.OCIAttrGet( param, roci.OCI_HTYPE_DESCRIBE, rffi.cast(roci.dvoidp, nameptr), lenptr, roci.OCI_ATTR_TYPE_NAME, self.environment.errorHandle) self.environment.checkForError( status, "ObjectType_Initialize(): get schema name") self.name = rffi.charpsize2str(nameptr[0], lenptr[0]) finally: lltype.free(nameptr, flavor='raw') lltype.free(lenptr, flavor='raw') # retrieve TDO (type descriptor object) of the parameter tdorefptr = lltype.malloc(rffi.CArrayPtr(roci.OCIRef).TO, 1, flavor='raw') try: status = roci.OCIAttrGet( param, roci.OCI_HTYPE_DESCRIBE, rffi.cast(roci.dvoidp, tdorefptr), lltype.nullptr(roci.Ptr(roci.ub4).TO), roci.OCI_ATTR_REF_TDO, self.environment.errorHandle) self.environment.checkForError( status, "ObjectType_Initialize(): get TDO reference") tdoref = tdorefptr[0] finally: lltype.free(tdorefptr, flavor='raw') tdoptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, 1, flavor='raw') try: status = roci.OCIObjectPin( self.environment.handle, self.environment.errorHandle, tdoref, None, roci.OCI_PIN_ANY, roci.OCI_DURATION_SESSION, roci.OCI_LOCK_NONE, tdoptr) self.environment.checkForError( status, "ObjectType_Initialize(): pin TDO reference") self.tdo = tdoptr[0] finally: lltype.free(tdoptr, flavor='raw') # acquire a describe handle handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIDescribe).TO, 1, flavor='raw') try: status = roci.OCIHandleAlloc( self.environment.handle, handleptr, roci.OCI_HTYPE_DESCRIBE, 0, lltype.nullptr(rffi.CArray(roci.dvoidp))) self.environment.checkForError( status, "ObjectType_Initialize(): allocate describe handle") describeHandle = handleptr[0] finally: lltype.free(handleptr, flavor='raw') # describe the type try: self.describe(connection, describeHandle) finally: roci.OCIHandleFree(describeHandle, roci.OCI_HTYPE_DESCRIBE)
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