def OracleIntervalToPythonDelta(environment, valueptr): daysptr = lltype.malloc(roci.Ptr(roci.sb4).TO, 1, flavor='raw') hoursptr = lltype.malloc(roci.Ptr(roci.sb4).TO, 1, flavor='raw') minutesptr = lltype.malloc(roci.Ptr(roci.sb4).TO, 1, flavor='raw') secondsptr = lltype.malloc(roci.Ptr(roci.sb4).TO, 1, flavor='raw') fsecondsptr = lltype.malloc(roci.Ptr(roci.sb4).TO, 1, flavor='raw') try: status = roci.OCIIntervalGetDaySecond(environment.handle, environment.errorHandle, daysptr, hoursptr, minutesptr, secondsptr, fsecondsptr, valueptr[0]) environment.checkForError(status, "OracleIntervalToPythonDelta()") space = environment.space w = space.wrap w_timedelta = space.getattr(space.getbuiltinmodule('datetime'), w('timedelta')) days = daysptr[0] seconds = (rffi.cast(lltype.Signed, hoursptr[0]) * 3600 + rffi.cast(lltype.Signed, minutesptr[0]) * 60 + rffi.cast(lltype.Signed, secondsptr[0])) microseconds = rffi.cast(lltype.Signed, fsecondsptr[0]) / 1000 return space.call_function(w_timedelta, w(days), w(seconds), w(microseconds)) finally: lltype.free(daysptr, flavor='raw') lltype.free(hoursptr, flavor='raw') lltype.free(minutesptr, flavor='raw') lltype.free(secondsptr, flavor='raw') lltype.free(fsecondsptr, flavor='raw')
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 _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 _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 getattr(self, space, attr): try: attribute = self.objectType.attributesByName[attr] except KeyError: msg = "ExternalObject has no attribute '%s'" %(attr,) raise OperationError(space.w_AttributeError, space.wrap(msg)) environment = self.objectType.environment scalarvalueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.OCIInd).TO, 1, flavor='raw') valueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, 1, flavor='raw') valueptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, 1, flavor='raw') tdoptr = lltype.malloc(rffi.CArrayPtr(roci.OCIType).TO, 1, flavor='raw') nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, flavor='raw') nameptr[0] = rffi.str2charp(attr) namelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw') namelenptr[0] = rffi.cast(roci.ub4, len(attr)) try: status = roci.OCIObjectGetAttr( environment.handle, environment.errorHandle, self.instance, self.indicator, self.objectType.tdo, nameptr, namelenptr, 1, lltype.nullptr(roci.Ptr(roci.ub4).TO), 0, scalarvalueindicatorptr, valueindicatorptr, valueptr, tdoptr) environment.checkForError( status, "ExternalObject_GetAttributeValue(): getting value") # determine the proper null indicator valueIndicator = valueindicatorptr[0] if not valueIndicator: valueIndicator = rffi.cast(roci.dvoidp, scalarvalueindicatorptr) value = valueptr[0] return convertObject( space, environment, attribute.typeCode, value, valueIndicator, self, attribute.subType) finally: lltype.free(scalarvalueindicatorptr, flavor='raw') lltype.free(valueindicatorptr, flavor='raw') lltype.free(valueptr, flavor='raw') lltype.free(tdoptr, flavor='raw') rffi.free_charp(nameptr[0]) lltype.free(nameptr, flavor='raw') lltype.free(namelenptr, flavor='raw')
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()
def _get_bind_info(self, space, numElements): # avoid bus errors on 64bit platforms numElements = numElements + (rffi.sizeof(roci.dvoidp) - numElements % rffi.sizeof(roci.dvoidp)) # initialize the buffers bindNames = lltype.malloc(roci.Ptr(roci.oratext).TO, numElements, flavor='raw') bindNameLengths = lltype.malloc(roci.Ptr(roci.ub1).TO, numElements, flavor='raw') indicatorNames = lltype.malloc(roci.Ptr(roci.oratext).TO, numElements, flavor='raw') indicatorNameLengths = lltype.malloc(roci.Ptr(roci.ub1).TO, numElements, flavor='raw') duplicate = lltype.malloc(roci.Ptr(roci.ub1).TO, numElements, flavor='raw') bindHandles = lltype.malloc(roci.Ptr(roci.OCIBind).TO, numElements, flavor='raw') foundElementsPtr = lltype.malloc(roci.Ptr(roci.sb4).TO, 1, flavor='raw') try: status = roci.OCIStmtGetBindInfo( self.handle, self.environment.errorHandle, numElements, 1, foundElementsPtr, bindNames, bindNameLengths, indicatorNames, indicatorNameLengths, duplicate, bindHandles) if status != roci.OCI_NO_DATA: self.environment.checkForError(status, "Cursor_GetBindNames()") # Too few elements allocated foundElements = rffi.cast(lltype.Signed, foundElementsPtr[0]) if foundElements < 0: return -foundElements, None names_w = [] # process the bind information returned for i in range(foundElements): if rffi.cast(lltype.Signed, duplicate[i]): continue names_w.append( w_string(space, bindNames[i], rffi.cast(lltype.Signed, bindNameLengths[i]))) return 0, names_w finally: lltype.free(bindNames, flavor='raw') lltype.free(bindNameLengths, flavor='raw') lltype.free(indicatorNames, flavor='raw') lltype.free(indicatorNameLengths, flavor='raw') lltype.free(duplicate, flavor='raw') lltype.free(bindHandles, flavor='raw') lltype.free(foundElementsPtr, flavor='raw')
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 OracleNumberToPythonFloat(environment, valueptr): "Return a Python float object given an oracle number" doubleptr = lltype.malloc(roci.Ptr(rffi.DOUBLE).TO, 1, flavor='raw') try: status = roci.OCINumberToReal(environment.errorHandle, valueptr, rffi.sizeof(rffi.DOUBLE), rffi.cast(roci.dvoidp, doubleptr)) environment.checkForError(status, "OracleNumberToPythonFloat()") return environment.space.wrap(doubleptr[0]) finally: lltype.free(doubleptr, flavor='raw')
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,)))
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 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 _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 _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 OracleTimestampToPythonDate(environment, valueptr): yearptr = lltype.malloc(roci.Ptr(roci.sb2).TO, 1, flavor='raw') monthptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw') dayptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw') hourptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw') minuteptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw') secondptr = lltype.malloc(roci.Ptr(roci.ub1).TO, 1, flavor='raw') fsecondptr = lltype.malloc(roci.Ptr(roci.ub4).TO, 1, flavor='raw') try: status = roci.OCIDateTimeGetDate(environment.handle, environment.errorHandle, valueptr[0], yearptr, monthptr, dayptr) environment.checkForError( status, "OracleTimestampToPythonDate(): date portion") status = roci.OCIDateTimeGetTime(environment.handle, environment.errorHandle, valueptr[0], hourptr, minuteptr, secondptr, fsecondptr) environment.checkForError( status, "OracleTimestampToPythonDate(): time portion") space = environment.space w = space.wrap w_datetime = space.getattr(space.getbuiltinmodule('datetime'), w('datetime')) return space.call_function( w_datetime, w(yearptr[0]), w(monthptr[0]), w(dayptr[0]), w(hourptr[0]), w(minuteptr[0]), w(secondptr[0]), w(rffi.cast(lltype.Signed, fsecondptr[0]) / 1000)) finally: lltype.free(yearptr, flavor='raw') lltype.free(monthptr, flavor='raw') lltype.free(dayptr, flavor='raw') lltype.free(hourptr, flavor='raw') lltype.free(minuteptr, flavor='raw') lltype.free(secondptr, flavor='raw') lltype.free(fsecondptr, flavor='raw')
def getConnection(self, space, pool, w_cclass, purity): """Get a connection using the OCISessionGet() interface rather than using the low level interface for connecting.""" proxyCredentials = False authInfo = lltype.nullptr(roci.OCIAuthInfo.TO) if pool: w_dbname = pool.w_name mode = roci.OCI_SESSGET_SPOOL if not pool.homogeneous and pool.w_username and self.w_username: proxyCredentials = space.is_true( space.ne(pool.w_username, self.w_username)) mode |= roci.OCI_SESSGET_CREDPROXY else: w_dbname = self.w_tnsentry mode = roci.OCI_SESSGET_STMTCACHE stringBuffer = StringBuffer() # set up authorization handle, if needed if not pool or w_cclass or proxyCredentials: # create authorization handle handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIAuthInfo).TO, 1, flavor='raw') try: status = roci.OCIHandleAlloc( self.environment.handle, handleptr, roci.OCI_HTYPE_AUTHINFO, 0, lltype.nullptr(rffi.CArray(roci.dvoidp))) self.environment.checkForError( status, "Connection_GetConnection(): allocate handle") authInfo = handleptr[0] finally: lltype.free(handleptr, flavor='raw') externalCredentials = True # set the user name, if applicable stringBuffer.fill(space, self.w_username) try: if stringBuffer.size > 0: externalCredentials = False status = roci.OCIAttrSet(authInfo, roci.OCI_HTYPE_AUTHINFO, stringBuffer.ptr, stringBuffer.size, roci.OCI_ATTR_USERNAME, self.environment.errorHandle) self.environment.checkForError( status, "Connection_GetConnection(): set user name") finally: stringBuffer.clear() # set the password, if applicable stringBuffer.fill(space, self.w_password) try: if stringBuffer.size > 0: externalCredentials = False status = roci.OCIAttrSet(authInfo, roci.OCI_HTYPE_AUTHINFO, stringBuffer.ptr, stringBuffer.size, roci.OCI_ATTR_PASSWORD, self.environment.errorHandle) self.environment.checkForError( status, "Connection_GetConnection(): set password") finally: stringBuffer.clear() # if no user name or password are set, using external credentials if not pool and externalCredentials: mode |= roci.OCI_SESSGET_CREDEXT # set the connection class, if applicable if roci.OCI_ATTR_CONNECTION_CLASS is not None: stringBuffer.fill(space, w_cclass) try: if stringBuffer.size > 0: externalCredentials = False status = roci.OCIAttrSet( authInfo, roci.OCI_HTYPE_AUTHINFO, stringBuffer.ptr, stringBuffer.size, roci.OCI_ATTR_CONNECTION_CLASS, self.environment.errorHandle) self.environment.checkForError( status, "Connection_GetConnection(): set connection class") finally: stringBuffer.clear() # set the purity, if applicable if (roci.OCI_ATTR_PURITY is not None and purity != roci.OCI_ATTR_PURITY_DEFAULT): purityptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw') purityptr[0] = rffi.cast(roci.ub4, purity) try: status = roci.OCIAttrSet(authInfo, roci.OCI_HTYPE_AUTHINFO, rffi.cast(roci.dvoidp, purityptr), rffi.sizeof(roci.ub4), roci.OCI_ATTR_PURITY, self.environment.errorHandle) self.environment.checkForError( status, "Connection_GetConnection(): set purity") finally: lltype.free(purityptr, flavor='raw') # acquire the new session stringBuffer.fill(space, w_dbname) foundptr = lltype.malloc(rffi.CArrayPtr(roci.boolean).TO, 1, flavor='raw') handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCISvcCtx).TO, 1, flavor='raw') try: status = roci.OCISessionGet( self.environment.handle, self.environment.errorHandle, handleptr, authInfo, stringBuffer.ptr, stringBuffer.size, None, 0, lltype.nullptr(roci.Ptr(roci.oratext).TO), lltype.nullptr(roci.Ptr(roci.ub4).TO), foundptr, mode) self.environment.checkForError( status, "Connection_GetConnection(): get connection") self.handle = handleptr[0] finally: stringBuffer.clear() lltype.free(foundptr, flavor='raw') lltype.free(handleptr, flavor='raw') # eliminate the authorization handle immediately, if applicable if authInfo: roci.OCIHandleFree(authInfo, roci.OCI_HTYPE_AUTHINFO) # copy members in the case where a pool is being used if pool: if not proxyCredentials: self.w_username = pool.w_username self.w_password = pool.w_password self.w_tnsentry = pool.w_tnsentry self.sessionPool = pool self.release = True
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
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)