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

📄 firebirdconnection.c

📁 适合于Unix/Linux下的一个持久数据库连接池
💻 C
📖 第 1 页 / 共 2 页
字号:
		// make sure each output bind variable gets null terminated		for (short i=0; i<outsqlda->sqld; i++) {			if (outbindisstring[i]) {				outsqlda->sqlvar[i].					sqldata[outsqlda->sqlvar[i].sqllen-1]=0;			}		}		// set column count to 0		outsqlda->sqld=0;		return retval;	}	// handle non-stored procedures...	// describe the cursor	outsqlda->sqld=0;	if (isc_dsql_describe(firebirdconn->error,&stmt,1,outsqlda)) {		return false;	}	if (outsqlda->sqld>MAX_SELECT_LIST_SIZE) {		outsqlda->sqld=MAX_SELECT_LIST_SIZE;	}	for (short i=0; i<outsqlda->sqld; i++) {		// save the actual field type		field[i].type=outsqlda->sqlvar[i].sqltype;		// handle the null indicator		outsqlda->sqlvar[i].sqlind=&field[i].nullindicator;		// coerce the datatypes and point where the data should go		if (outsqlda->sqlvar[i].sqltype==SQL_TEXT || 				outsqlda->sqlvar[i].sqltype==SQL_TEXT+1) {			outsqlda->sqlvar[i].sqldata=field[i].textbuffer;			field[i].sqlrtype=CHAR_DATATYPE;		} else if (outsqlda->sqlvar[i].sqltype==SQL_VARYING ||				outsqlda->sqlvar[i].					sqltype==SQL_VARYING+1) {			outsqlda->sqlvar[i].sqldata=field[i].textbuffer;			field[i].sqlrtype=VARCHAR_DATATYPE;		} else if (outsqlda->sqlvar[i].sqltype==SQL_SHORT ||				outsqlda->sqlvar[i].sqltype==SQL_SHORT+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].shortbuffer;			field[i].sqlrtype=SMALLINT_DATATYPE;		// Looks like sometimes firebird returns INT64's as		// SQL_LONG type.  These can be identified because		// the sqlscale gets set too.  Treat SQL_LONG's with		// an sqlscale as INT64's.		} else if ((outsqlda->sqlvar[i].sqltype==SQL_LONG ||				outsqlda->sqlvar[i].sqltype==SQL_LONG+1) &&				!outsqlda->sqlvar[i].sqlscale) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].longbuffer;			field[i].sqlrtype=INTEGER_DATATYPE;		} else if (		#ifdef SQL_INT64				(outsqlda->sqlvar[i].sqltype==SQL_INT64 ||				outsqlda->sqlvar[i].sqltype==SQL_INT64+1) ||		#endif				((outsqlda->sqlvar[i].sqltype==SQL_LONG ||				outsqlda->sqlvar[i].sqltype==SQL_LONG+1) &&				outsqlda->sqlvar[i].sqlscale)) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].int64buffer;			if (outsqlda->sqlvar[i].sqlsubtype==1) {				field[i].sqlrtype=NUMERIC_DATATYPE;			} else {				field[i].sqlrtype=DECIMAL_DATATYPE;			}		} else if (outsqlda->sqlvar[i].sqltype==SQL_FLOAT ||			outsqlda->sqlvar[i].sqltype==SQL_FLOAT+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].floatbuffer;			field[i].sqlrtype=FLOAT_DATATYPE;		} else if (outsqlda->sqlvar[i].sqltype==SQL_DOUBLE ||			outsqlda->sqlvar[i].sqltype==SQL_DOUBLE+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].doublebuffer;			field[i].sqlrtype=DOUBLE_PRECISION_DATATYPE;		} else if (outsqlda->sqlvar[i].sqltype==SQL_D_FLOAT ||			outsqlda->sqlvar[i].sqltype==SQL_D_FLOAT+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].doublebuffer;			field[i].sqlrtype=D_FLOAT_DATATYPE;		} else if (outsqlda->sqlvar[i].sqltype==SQL_ARRAY || 				outsqlda->sqlvar[i].sqltype==SQL_ARRAY+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].quadbuffer;			field[i].sqlrtype=ARRAY_DATATYPE;		} else if (outsqlda->sqlvar[i].sqltype==SQL_QUAD || 				outsqlda->sqlvar[i].sqltype==SQL_QUAD+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].quadbuffer;			field[i].sqlrtype=QUAD_DATATYPE;		#ifdef SQL_TIMESTAMP		} else if (outsqlda->sqlvar[i].sqltype==SQL_TIMESTAMP || 				outsqlda->sqlvar[i].					sqltype==SQL_TIMESTAMP+1) {		#else		} else if (outsqlda->sqlvar[i].sqltype==SQL_DATE || 				outsqlda->sqlvar[i].sqltype==SQL_DATE+1) {		#endif			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].timestampbuffer;			field[i].sqlrtype=TIMESTAMP_DATATYPE;		#ifdef SQL_TIMESTAMP		} else if (outsqlda->sqlvar[i].sqltype==SQL_TYPE_TIME || 				outsqlda->sqlvar[i].					sqltype==SQL_TYPE_TIME+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].timebuffer;			field[i].sqlrtype=TIME_DATATYPE;		} else if (outsqlda->sqlvar[i].sqltype==SQL_TYPE_DATE || 				outsqlda->sqlvar[i].					sqltype==SQL_TYPE_DATE+1) {			outsqlda->sqlvar[i].sqldata=					(char *)&field[i].datebuffer;			field[i].sqlrtype=DATE_DATATYPE;		#endif		} else if (outsqlda->sqlvar[i].sqltype==SQL_BLOB || 				outsqlda->sqlvar[i].sqltype==SQL_BLOB+1) {			outsqlda->sqlvar[i].sqltype=SQL_BLOB;			outsqlda->sqlvar[i].sqldata=(char *)NULL;			field[i].sqlrtype=BLOB_DATATYPE;		} else {			outsqlda->sqlvar[i].sqltype=SQL_VARYING;			outsqlda->sqlvar[i].sqldata=field[i].textbuffer;			field[i].sqlrtype=UNKNOWN_DATATYPE;		}	}	// Execute the query	return !isc_dsql_execute(firebirdconn->error,&firebirdconn->tr,							&stmt,1,insqlda);}bool firebirdcursor::queryIsNotSelect() {	return (querytype!=isc_info_sql_stmt_select);}bool firebirdcursor::queryIsCommitOrRollback() {	return (querytype==isc_info_sql_stmt_commit ||		querytype==isc_info_sql_stmt_rollback);}const char *firebirdcursor::errorMessage(bool *liveconnection) {	char		msg[512];	ISC_STATUS	*pvector=firebirdconn->error;	// declare a buffer for the error	if (errormsg) {		delete errormsg;	}	errormsg=new stringbuffer();	// get the status message	while (isc_interprete(msg,&pvector)) {		errormsg->append(msg)->append(" \n");	}	// get the error message	// FIXME: vladimir commented this out why?	ISC_LONG	sqlcode=isc_sqlcode(firebirdconn->error);	isc_sql_interprete(sqlcode, msg, 512);	errormsg->append(msg);	*liveconnection=!(charstring::contains(				errormsg->getString(),				"Error reading data from the connection") ||			charstring::contains(				errormsg->getString(),				"Error writing data to the connection"));	return errormsg->getString();}bool firebirdcursor::knowsRowCount() {	return false;}uint64_t firebirdcursor::rowCount() {	return 0;}bool firebirdcursor::knowsAffectedRows() {	return false;}uint64_t firebirdcursor::affectedRows() {	return 0;}uint32_t firebirdcursor::colCount() {	// for exec procedure queries, outsqlda contains output bind values	// rather than column info and there is no result set, thus no column	// info	return outsqlda->sqld;}const char * const *firebirdcursor::columnNames() {	for (short i=0; i<outsqlda->sqld; i++) {		columnnames[i]=outsqlda->sqlvar[i].sqlname;	}	return columnnames;}uint16_t firebirdcursor::columnTypeFormat() {	return (uint16_t)COLUMN_TYPE_IDS;}void firebirdcursor::returnColumnInfo() {	short	precision;	// for each column...	for (short i=0; i<outsqlda->sqld; i++) {		if (field[i].sqlrtype==CHAR_DATATYPE) {			precision=outsqlda->sqlvar[i].sqllen;		} else if (field[i].sqlrtype==VARCHAR_DATATYPE) {			precision=outsqlda->sqlvar[i].sqllen;		} else if (field[i].sqlrtype==SMALLINT_DATATYPE) {			precision=5;		} else if (field[i].sqlrtype==INTEGER_DATATYPE) {			precision=11;		} else if (field[i].sqlrtype==NUMERIC_DATATYPE) {			// FIXME: can be from 1 to 18			// (oddly, scale is given as a negative number)			precision=18+outsqlda->sqlvar[i].sqlscale;		} else if (field[i].sqlrtype==DECIMAL_DATATYPE) {			// FIXME: can be from 1 to 18			// (oddly, scale is given as a negative number)			precision=18+outsqlda->sqlvar[i].sqlscale;		} else if (field[i].sqlrtype==FLOAT_DATATYPE) {			precision=0;		} else if (field[i].sqlrtype==DOUBLE_PRECISION_DATATYPE) {			precision=0;		} else if (field[i].sqlrtype==D_FLOAT_DATATYPE) {			precision=0;		} else if (field[i].sqlrtype==ARRAY_DATATYPE) {			// not sure			precision=0;		} else if (field[i].sqlrtype==QUAD_DATATYPE) {			// not sure			precision=0;		} else if (field[i].sqlrtype==TIMESTAMP_DATATYPE) {			// not sure			precision=0;		} else if (field[i].sqlrtype==TIME_DATATYPE) {			precision=8;		} else if (field[i].sqlrtype==DATE_DATATYPE) {			precision=10;		} else if (field[i].sqlrtype==BLOB_DATATYPE) {			precision=outsqlda->sqlvar[i].sqllen;		} else if (field[i].sqlrtype==UNKNOWN_DATATYPE) {			precision=outsqlda->sqlvar[i].sqllen;		}		// send column definition		// (oddly, scale is given as a negative number)		conn->sendColumnDefinition(outsqlda->sqlvar[i].sqlname,					charstring::length(						outsqlda->sqlvar[i].sqlname),					field[i].sqlrtype,					outsqlda->sqlvar[i].sqllen,					precision,					-outsqlda->sqlvar[i].sqlscale,0,0,0,					0,0,0,0,0);	}}bool firebirdcursor::noRowsToReturn() {	// for exec procedure queries, outsqlda contains output bind values	// rather than a result set and there is no result set	return (queryIsExecSP)?true:!outsqlda->sqld;}bool firebirdcursor::skipRow() {	return fetchRow();}bool firebirdcursor::fetchRow() {	ISC_STATUS	retcode;	if ((retcode=isc_dsql_fetch(firebirdconn->error,					&stmt,1,outsqlda))) {		// if retcode is 100L, then there are no more rows,		// otherwise, there is an error... how do I handle this?		return false;	}	return true;}void firebirdcursor::returnRow() {	for (short col=0; col<outsqlda->sqld; col++) {		// handle a null field		if ((outsqlda->sqlvar[col].sqltype & 1) && 			field[col].nullindicator==-1) {			conn->sendNullField();			continue;		}		// handle a non-null field		if (outsqlda->sqlvar[col].sqltype==SQL_TEXT ||				outsqlda->sqlvar[col].sqltype==SQL_TEXT+1) {			size_t	maxlen=outsqlda->sqlvar[col].sqllen;			size_t	reallen=charstring::length(field[col].								textbuffer);			if (reallen>maxlen) {				reallen=maxlen;			}			conn->sendField(field[col].textbuffer,reallen);		} else if (outsqlda->sqlvar[col].					sqltype==SQL_SHORT ||				outsqlda->sqlvar[col].					sqltype==SQL_SHORT+1) {			stringbuffer	buffer;			buffer.append(field[col].shortbuffer);			conn->sendField(buffer.getString(),					charstring::length(buffer.getString()));		} else if (outsqlda->sqlvar[col].					sqltype==SQL_FLOAT ||				outsqlda->sqlvar[col].					sqltype==SQL_FLOAT+1) {			stringbuffer	buffer;			buffer.append((double)field[col].floatbuffer);			conn->sendField(buffer.getString(),					charstring::length(buffer.getString()));		} else if (outsqlda->sqlvar[col].					sqltype==SQL_DOUBLE ||				outsqlda->sqlvar[col].					sqltype==SQL_DOUBLE+1 ||				outsqlda->sqlvar[col].					sqltype==SQL_D_FLOAT ||				outsqlda->sqlvar[col].					sqltype==SQL_D_FLOAT+1) {			stringbuffer	buffer;			buffer.append((double)field[col].doublebuffer);			conn->sendField(buffer.getString(),					charstring::length(buffer.getString()));		} else if (outsqlda->sqlvar[col].					sqltype==SQL_VARYING ||				outsqlda->sqlvar[col].					sqltype==SQL_VARYING+1) {			// the first 2 bytes are the length in 			// an SQL_VARYING field			int16_t	size;			rawbuffer::copy((void *)&size,					(void *)field[col].textbuffer,					sizeof(int16_t));			conn->sendField(field[col].textbuffer+sizeof(int16_t),					size);		// Looks like sometimes firebird returns INT64's as		// SQL_LONG type.  These can be identified because		// the sqlscale gets set too.  Treat SQL_LONG's with		// an sqlscale as INT64's.		} else if ((outsqlda->sqlvar[col].					sqltype==SQL_LONG ||				outsqlda->sqlvar[col].					sqltype==SQL_LONG+1) &&				!outsqlda->sqlvar[col].sqlscale) {			stringbuffer	buffer;			buffer.append((int32_t)field[col].longbuffer);			conn->sendField(buffer.getString(),					charstring::length(buffer.getString()));		} else if (		#ifdef SQL_INT64				(outsqlda->sqlvar[col].					sqltype==SQL_INT64 ||				outsqlda->sqlvar[col].					sqltype==SQL_INT64+1) ||		#endif				((outsqlda->sqlvar[col].					sqltype==SQL_LONG ||				outsqlda->sqlvar[col].					sqltype==SQL_LONG+1) &&				outsqlda->sqlvar[col].sqlscale)) {			// int64's are weird.  To the left of the decimal			// point is the value/10^scale, to the right is			// value%10^scale			stringbuffer	buffer;			if (outsqlda->sqlvar[col].sqlscale) {				buffer.append((int64_t)(field[col].int64buffer/(int)pow(10.0,(double)-outsqlda->sqlvar[col].sqlscale)))->append(".");				stringbuffer	decimal;				decimal.append((int64_t)(field[col].int64buffer%(int)pow(10.0,(double)-outsqlda->sqlvar[col].sqlscale)));							// gotta get the right number				// of decimal places				for (int32_t i=charstring::length(						decimal.getString());					i<-outsqlda->sqlvar[col].sqlscale;					i++) {					decimal.append("0");				}				buffer.append(decimal.getString());			} else {				buffer.append((int64_t)field[col].int64buffer);			}			conn->sendField(buffer.getString(),					charstring::length(buffer.getString()));		} else if (outsqlda->sqlvar[col].sqltype==SQL_ARRAY ||			outsqlda->sqlvar[col].sqltype==SQL_ARRAY+1 ||			outsqlda->sqlvar[col].sqltype==SQL_QUAD ||			outsqlda->sqlvar[col].sqltype==SQL_QUAD+1) {			// have to handle arrays for real here...			conn->sendNullField();		#ifdef SQL_TIMESTAMP		} else if (outsqlda->sqlvar[col].sqltype==SQL_TIMESTAMP ||			outsqlda->sqlvar[col].sqltype==SQL_TIMESTAMP+1) {			// decode the timestamp			tm	entry_timestamp;			isc_decode_timestamp(&field[col].timestampbuffer,							&entry_timestamp);		#else		} else if (outsqlda->sqlvar[col].sqltype==SQL_DATE ||			outsqlda->sqlvar[col].sqltype==SQL_DATE+1) {			// decode the timestamp			tm	entry_timestamp;			isc_decode_date(&field[col].timestampbuffer,							&entry_timestamp);		#endif			// build a string of "yyyy-mm-dd hh:mm:ss" format			char	buffer[20];			snprintf(buffer,20,"%d-%02d-%02d %02d:%02d:%02d",					entry_timestamp.tm_year+1900,					entry_timestamp.tm_mon+1,					entry_timestamp.tm_mday,					entry_timestamp.tm_hour,					entry_timestamp.tm_min,					entry_timestamp.tm_sec);			conn->sendField(buffer,19);		#ifdef SQL_TIMESTAMP		} else if (outsqlda->sqlvar[col].sqltype==SQL_TYPE_TIME ||			outsqlda->sqlvar[col].sqltype==SQL_TYPE_TIME+1) {			// decode the time			tm	entry_time;			isc_decode_sql_time(&field[col].timebuffer,							&entry_time);			// build a string of "hh:mm:ss" format			char	buffer[9];			snprintf(buffer,9,"%02d:%02d:%02d",					entry_time.tm_hour,					entry_time.tm_min,					entry_time.tm_sec);			conn->sendField(buffer,8);		} else if (outsqlda->sqlvar[col].sqltype==SQL_TYPE_DATE ||			outsqlda->sqlvar[col].sqltype==SQL_TYPE_DATE+1) {			// decode the date			tm	entry_date;			isc_decode_sql_date(&field[col].datebuffer,							&entry_date);			// build a string of "yyyy-mm-dd" format			char	buffer[11];			snprintf(buffer,11,"%d:%02d:%02d",					entry_date.tm_year+1900,					entry_date.tm_mon+1,					entry_date.tm_mday);			conn->sendField(buffer,10);		#endif		} else if (outsqlda->sqlvar[col].sqltype==SQL_BLOB ||				outsqlda->sqlvar[col].sqltype==SQL_BLOB+1) {			// have to handle blobs for real here...			conn->sendNullField();		}	}}void firebirdcursor::cleanUpData(bool freeresult, bool freebinds) {	if (freebinds) {		outbindcount=0;	}}

⌨️ 快捷键说明

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