⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oracle8connection.c

📁 适合于Unix/Linux下的一个持久数据库连接池
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (OCILobGetLength(oracle8conn->svc,			oracle8conn->err,			lob,&loblength)!=OCI_SUCCESS) {		conn->sendNullField();		return;	}	// handle empty lob's	if (!loblength) {		conn->startSendingLong(0);		conn->sendLongSegment("",0);		conn->endSendingLong();		return;	}	// We should be able to call OCILobRead over and over,	// as long as it returns OCI_NEED_DATA, but OCILobRead	// fails to return OCI_NEED_DATA (at least in version	// 8.1.7 for Linux), so we have to do this instead.	// OCILobRead appears to return OCI_INVALID_HANDLE when	// the LOB is NULL, but this is not documented anywhere.	while (retlen) {		// initialize retlen to the number of characters we want to read		retlen=charstoread;		// read a segment from the lob		sword	retval=OCILobRead(oracle8conn->svc,				oracle8conn->err,				lob,				&retlen,				offset,				(dvoid *)buf,				oracle8conn->maxitembuffersize,				(dvoid *)NULL,				(sb4(*)(dvoid *,CONST dvoid *,ub4,ub1))NULL,				(ub2)0,				(ub1)SQLCS_IMPLICIT);		// OCILobRead returns OCI_INVALID_HANDLE if		// the LOB is NULL.  In that case, return a		// NULL field.		// Otherwise, start sending the field (if we		// haven't already), send a segment of the LOB,		// move to the next segment and reset the		// amount to read.		if (retval==OCI_INVALID_HANDLE) {			conn->sendNullField();			break;		} else {			if (start) {				conn->startSendingLong(loblength);				start=false;			}			conn->sendLongSegment((char *)buf,(int32_t)retlen);			offset=offset+charstoread;		}	}	// if we ever started sending a LOB,	// finish sending it now	if (!start) {		conn->endSendingLong();	}}bool oracle8cursor::executeQuery(const char *query, uint32_t length,							bool execute) {	// initialize the column count	ncols=0;	// get the type of the query (select, insert, update, etc...)	if (OCIAttrGet(stmt,OCI_HTYPE_STMT,			(dvoid *)&stmttype,(ub4 *)NULL,			OCI_ATTR_STMT_TYPE,oracle8conn->err)!=OCI_SUCCESS) {		return false;	}#ifdef HAVE_ORACLE_8i	if (stmttype==OCI_STMT_CREATE) {		checkForTempTable(query,length);	}#endif	// set up how many times to iterate;	// 0 for selects, 1 for non-selects	ub4	iters=1;	if (stmttype==OCI_STMT_SELECT) {		iters=0;	}	// initialize row counters	row=0;	maxrow=0;	totalrows=0;	// execute the query	if (execute) {		if (OCIStmtExecute(oracle8conn->svc,stmt,				oracle8conn->err,iters,				(ub4)0,NULL,NULL,				oracle8conn->statementmode)!=OCI_SUCCESS) {			return false;		}		// reset the prepared flag		prepared=false;	}	// if the query is a select, describe/define it	if (stmttype==OCI_STMT_SELECT) {		// get the column count		if (OCIAttrGet((dvoid *)stmt,OCI_HTYPE_STMT,				(dvoid *)&ncols,(ub4 *)NULL,				OCI_ATTR_PARAM_COUNT,				oracle8conn->err)!=OCI_SUCCESS) {			return false;		}		// run through the columns...		for (sword i=0; i<ncols; i++) {			// get the entire column definition			if (OCIParamGet(stmt,OCI_HTYPE_STMT,				oracle8conn->err,				(dvoid **)&desc[i].paramd,				i+1)!=OCI_SUCCESS) {				return false;			}			// get the column name			if (OCIAttrGet((dvoid *)desc[i].paramd,				OCI_DTYPE_PARAM,				(dvoid **)&desc[i].buf,				(ub4 *)&desc[i].buflen,				(ub4)OCI_ATTR_NAME,				oracle8conn->err)!=OCI_SUCCESS) {				return false;			}			// get the column type			if (OCIAttrGet((dvoid *)desc[i].paramd,				OCI_DTYPE_PARAM,				(dvoid *)&desc[i].dbtype,(ub4 *)NULL,				(ub4)OCI_ATTR_DATA_TYPE,				oracle8conn->err)!=OCI_SUCCESS) {				return false;			}			// get the column precision			if (OCIAttrGet((dvoid *)desc[i].paramd,				OCI_DTYPE_PARAM,				(dvoid *)&desc[i].precision,(ub4 *)NULL,				(ub4)OCI_ATTR_PRECISION,				oracle8conn->err)!=OCI_SUCCESS) {				return false;			}			// get the column scale			if (OCIAttrGet((dvoid *)desc[i].paramd,				OCI_DTYPE_PARAM,				(dvoid *)&desc[i].scale,(ub4 *)NULL,				(ub4)OCI_ATTR_SCALE,				oracle8conn->err)!=OCI_SUCCESS) {				return false;			}			// get whether the column is nullable			if (OCIAttrGet((dvoid *)desc[i].paramd,				OCI_DTYPE_PARAM,				(dvoid *)&desc[i].nullok,(ub4 *)NULL,				(ub4)OCI_ATTR_IS_NULL,				oracle8conn->err)!=OCI_SUCCESS) {				return false;			}			// is the column a LOB?			if (desc[i].dbtype==BLOB_TYPE ||				desc[i].dbtype==CLOB_TYPE ||				desc[i].dbtype==BFILE_TYPE) {				// return 0 for the size of lobs				desc[i].dbsize=0;				// set the NULL indicators to false				rawbuffer::zero(def_indp[i],						sizeof(sb2)*						oracle8conn->fetchatonce);				// allocate a lob descriptor				for (uint32_t j=0;					j<oracle8conn->fetchatonce;					j++) {					if (OCIDescriptorAlloc(						(void *)oracle8conn->env,						(void **)&def_lob[i][j],						OCI_DTYPE_LOB,0,0)) {						return false;					}				}				// define the column as a lob				if (OCIDefineByPos(stmt,&def[i],					oracle8conn->err,					i+1,					(dvoid *)def_lob[i],					(sb4)-1,					desc[i].dbtype,					(dvoid *)0,					0,					(ub2 *)0,					OCI_DEFAULT)!=OCI_SUCCESS) {					return false;				}			} else {				// get the column size				if (OCIAttrGet((dvoid *)desc[i].paramd,					OCI_DTYPE_PARAM,					(dvoid *)&desc[i].dbsize,					(ub4 *)NULL,					(ub4)OCI_ATTR_DATA_SIZE,					oracle8conn->err)!=OCI_SUCCESS) {					return false;				}				// if the column is not a LOB, define it,				// translated to a NULL terminated string				if (OCIDefineByPos(stmt,&def[i],					oracle8conn->err,					i+1,					(dvoid *)def_buf[i],					(sb4)oracle8conn->maxitembuffersize,					SQLT_STR,					(dvoid *)def_indp[i],					(ub2 *)def_col_retlen[i],					def_col_retcode[i],					OCI_DEFAULT)!=OCI_SUCCESS) {					return false;				}				// set the lob member to NULL				for (uint32_t j=0;					j<oracle8conn->fetchatonce;					j++) {					def_lob[i][j]=NULL;				}			}		}	}	// convert integer output binds	for (uint16_t i=0; i<outbindcount; i++) {		if (outintbindstring[i]) {			*outintbind[i]=charstring::					toInteger(outintbindstring[i]);		}	}	return true;}bool oracle8cursor::queryIsNotSelect() {	return (stmttype!=OCI_STMT_SELECT);}bool oracle8cursor::queryIsCommitOrRollback() {	// apparantly in OCI8, the cursor type gets 	// set to 0 for both commits and rollbacks	return (!stmttype);}const char *oracle8cursor::errorMessage(bool *liveconnection) {	// get the message from oracle	text	message[1024];	rawbuffer::zero((void *)message,sizeof(message));	sb4	errcode;	OCIErrorGet((dvoid *)oracle8conn->err,1,			(text *)0,&errcode,			message,sizeof(message),			OCI_HTYPE_ERROR);	message[1023]=(char)NULL;	// check for dead connection or shutdown in progress	// Might need: 1033 - oracle init/shutdown in progress	switch (errcode) {		case 22: // invalid session ID; access denied		case 28: // your session has been killed		case 604: // error occurred at recursive SQL level ...		case 1012: // not logged on		case 1041: // internal error. hostdef extension doesn't exist		case 1089: // immediate shutdown in progress -				// no operations are permitted		case 3114: // not connected to ORACLE		case 3113: // end-of-file on communication channel		case 3135: // connection lost contact			*liveconnection=false;			break;		default:			*liveconnection=true;	}	// only return an error message if the error wasn't a dead database	delete errormessage;	errormessage=new stringbuffer();	if (*liveconnection) {		errormessage->append((const char *)message);	}	return errormessage->getString();}bool oracle8cursor::knowsRowCount() {	return false;}uint64_t oracle8cursor::rowCount() {	return 0;}bool oracle8cursor::knowsAffectedRows() {	return true;}uint64_t oracle8cursor::affectedRows() {	// get the affected row count	ub4	rows;	if (OCIAttrGet(stmt,OCI_HTYPE_STMT,			(dvoid *)&rows,(ub4 *)NULL,			OCI_ATTR_ROW_COUNT,oracle8conn->err)==OCI_SUCCESS) {		return rows;	}	return 0;}uint32_t oracle8cursor::colCount() {	return ncols;}const char * const * oracle8cursor::columnNames() {	for (sword i=0; i<ncols; i++) {		columnnames[i]=(char *)desc[i].buf;	}	return columnnames;}uint16_t oracle8cursor::columnTypeFormat() {	return (uint16_t)COLUMN_TYPE_IDS;}void oracle8cursor::returnColumnInfo() {	// a useful variable	uint16_t	type;	// for each column...	for (sword i=0; i<ncols; i++) {		// set column type		uint16_t	binary=0;		if (desc[i].dbtype==VARCHAR2_TYPE) {			type=VARCHAR2_DATATYPE;		} else if (desc[i].dbtype==NUMBER_TYPE) {			type=NUMBER_DATATYPE;		} else if (desc[i].dbtype==LONG_TYPE) {			type=LONG_DATATYPE;		} else if (desc[i].dbtype==ROWID_TYPE) {			type=ROWID_DATATYPE;		} else if (desc[i].dbtype==DATE_TYPE) {			type=DATE_DATATYPE;		} else if (desc[i].dbtype==RAW_TYPE) {			type=RAW_DATATYPE;			binary=1;		} else if (desc[i].dbtype==LONG_RAW_TYPE) {			type=LONG_RAW_DATATYPE;			binary=1;		} else if (desc[i].dbtype==CHAR_TYPE) {			type=CHAR_DATATYPE;		} else if (desc[i].dbtype==MLSLABEL_TYPE) {			type=MLSLABEL_DATATYPE;		} else if (desc[i].dbtype==BLOB_TYPE) {			type=BLOB_DATATYPE;			binary=1;		} else if (desc[i].dbtype==CLOB_TYPE) {			type=CLOB_DATATYPE;		} else if (desc[i].dbtype==BFILE_TYPE) {			type=BFILE_DATATYPE;			binary=1;		} else {			type=UNKNOWN_DATATYPE;		}		// send the column definition		conn->sendColumnDefinition((char *)desc[i].buf,					(uint16_t)desc[i].buflen,					type,					(uint32_t)desc[i].dbsize,					(uint32_t)desc[i].precision,					(uint32_t)desc[i].scale,					(uint16_t)desc[i].nullok,0,0,					0,0,0,binary,0);	}}bool oracle8cursor::noRowsToReturn() {	return (stmttype!=OCI_STMT_SELECT);}bool oracle8cursor::skipRow() {	if (fetchRow()) {		row++;		return true;	}	return false;}bool oracle8cursor::fetchRow() {	if (row==oracle8conn->fetchatonce) {		row=0;	}	if (row>0 && row==maxrow) {		return false;	}	if (!row) {		OCIStmtFetch(stmt,oracle8conn->err,oracle8conn->fetchatonce,						OCI_FETCH_NEXT,OCI_DEFAULT);		ub4	currentrow;		OCIAttrGet(stmt,OCI_HTYPE_STMT,				(dvoid *)&currentrow,(ub4 *)NULL,				OCI_ATTR_ROW_COUNT,oracle8conn->err);		if (currentrow==totalrows) {			return false;		}		maxrow=currentrow-totalrows;		totalrows=currentrow;	}	return true;}void oracle8cursor::returnRow() {	for (sword col=0; col<ncols; col++) {		// handle NULL's		if (def_indp[col][row]) {			conn->sendNullField();			continue;		}		// in OCI8, longs are just like other datatypes, but LOBS		// are different		if (desc[col].dbtype==BLOB_TYPE ||			desc[col].dbtype==CLOB_TYPE ||			desc[col].dbtype==BFILE_TYPE) {			// send the lob			sendLob(def_lob[col][row],				&def_buf[col][row*oracle8conn->						maxitembuffersize]);#ifdef HAVE_ORACLE_8i			// if the lob is temporary, deallocate it			boolean	templob;			if (OCILobIsTemporary(oracle8conn->env,						oracle8conn->err,						def_lob[col][row],						&templob)!=OCI_SUCCESS) {				continue;			}			if (templob) {				OCILobFreeTemporary(oracle8conn->svc,							oracle8conn->err,							def_lob[col][row]);			}#endif			continue;		}		// handle normal datatypes		conn->sendField((const char *)					&def_buf[col]						[row*oracle8conn->							maxitembuffersize],					(uint32_t)def_col_retlen[col][row]);	}	// increment the row counter	row++;}void oracle8cursor::cleanUpData(bool freeresult, bool freebinds) {	// OCI8 version of ocan(), but since it uses OCIStmtFetch we	// only want to run it if the statement was a select	if (freeresult && stmttype==OCI_STMT_SELECT) {		OCIStmtFetch(stmt,oracle8conn->err,0,				OCI_FETCH_NEXT,OCI_DEFAULT);	}	// free row/column resources	if (freeresult) {		for (ub4 i=0; i<oracle8conn->maxselectlistsize; i++) {			for (uint32_t j=0; j<oracle8conn->fetchatonce; j++) {				if (def_lob[i][j]) {					OCIDescriptorFree(def_lob[i][j],								OCI_DTYPE_LOB);					def_lob[i][j]=NULL;				}			}			// should be able to alloc these in openCursor() and			// free them in closeCursor() rather than letting			// OCIDefineByPos() alloc them and having to clear			// them here, but the alloc fails			if (def[i]) {				OCIHandleFree(def[i],OCI_HTYPE_DEFINE);				def[i]=NULL;			}		}	}	if (freebinds) {		// free lob bind resources#ifdef HAVE_ORACLE_8i		for (uint16_t i=0; i<inbindlobcount; i++) {			OCILobFreeTemporary(oracle8conn->svc,							oracle8conn->err,							inbind_lob[i]);			OCILobClose(oracle8conn->svc,oracle8conn->err,							inbind_lob[i]);			OCIDescriptorFree(inbind_lob[i],OCI_DTYPE_LOB);		}		for (uint16_t i=0; i<outbindlobcount; i++) {			if (outbind_lob[i]) {				OCILobFreeTemporary(oracle8conn->svc,							oracle8conn->err,							outbind_lob[i]);				OCILobClose(oracle8conn->svc,							oracle8conn->err,							outbind_lob[i]);				OCIDescriptorFree(outbind_lob[i],							OCI_DTYPE_LOB);			}		}		inbindlobcount=0;		outbindlobcount=0;#endif		// free regular bind resources		for (uint16_t i=0; i<inbindcount; i++) {			delete[] inintbindstring[i];			inintbindstring[i]=NULL;		}		for (uint16_t i=0; i<outbindcount; i++) {			delete[] outintbindstring[i];			outintbindstring[i]=NULL;			outintbind[i]=NULL;		}		inbindcount=0;		outbindcount=0;		curbindcount=0;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -