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

📄 parsedata.c

📁 适合于Unix/Linux下的一个持久数据库连接池
💻 C
字号:
// Copyright (c) 1999-2001  David Muse// See the file COPYING for more information#include <config.h>#include <sqlrelay/sqlrclient.h>#include <rudiments/rawbuffer.h>#include <defines.h>#include <datatypes.h>bool sqlrcursor::parseData() {	if (sqlrc->debug) {		sqlrc->debugPreStart();		sqlrc->debugPrint("Parsing Data\n");		sqlrc->debugPreEnd();	}	// if we're already at the end of the result set, then just return	if (endofresultset) {		if (sqlrc->debug) {			sqlrc->debugPreStart();			sqlrc->debugPrint("Already at the end of the result set\n");			sqlrc->debugPreEnd();		}		return true;	}	// useful variables	uint16_t	type;	uint32_t	length;	char		*buffer=NULL;	uint32_t	colindex=0;	column		*currentcol;	row		*currentrow=NULL;	// set firstrowindex to the index of the first row in the buffer	firstrowindex=rowcount;	// keep track of how large the buffer is	uint64_t	rowbuffercount=0;	// get rows	for (;;) {		// get the type of the field		if (getShort(&type)!=sizeof(uint16_t)) {			setError("Failed to get the field type.\n A network error may have occurred");			return false;		}		// check for the end of the result set		if (type==END_RESULT_SET) {			if (sqlrc->debug) {				sqlrc->debugPreStart();				sqlrc->debugPrint("Got end of result set.\n");				sqlrc->debugPreEnd();			}			endofresultset=true;			// if we were stepping through a cached result set			// then we need to close the file			clearCacheSource();			break;		} 		// if we're on the first column, start a new row,		// reset the column pointer, and increment the		// buffer counter and total row counter		if (colindex==0) {			if (rowbuffercount<OPTIMISTIC_ROW_COUNT) {				if (!rows) {					createRowBuffers();				}				currentrow=rows[rowbuffercount];			} else {				if (sqlrc->debug) {					sqlrc->debugPreStart();					sqlrc->debugPrint("Creating extra rows.\n");					sqlrc->debugPreEnd();				}				if (!firstextrarow) {					currentrow=new row(colcount);					firstextrarow=currentrow;				} else {					currentrow->next=new row(colcount);					currentrow=currentrow->next;				}			}			if (colcount>previouscolcount) {				currentrow->resize(colcount);			}			rowbuffercount++;			rowcount++;		}		if (type==NULL_DATA) {			// handle null data			if (returnnulls) {				buffer=NULL;			} else {				buffer=(char *)rowstorage->malloc(1);				buffer[0]=(char)NULL;			}			length=0;		} else if (type==STRING_DATA) {					// handle non-null data			if (getLong(&length)!=sizeof(uint32_t)) {				setError("Failed to get the field length.\n A network error may have occurred");				return false;			}			// for non-long, non-NULL datatypes...			// get the field into a buffer			buffer=(char *)rowstorage->malloc(length+1);			if ((uint32_t)getString(buffer,length)!=length) {				setError("Failed to get the field data.\n A network error may have occurred");				return false;			}			buffer[length]=(char)NULL;		} else if (type==START_LONG_DATA) {			uint64_t	totallength;			if (getLongLong(&totallength)!=sizeof(uint64_t)) {				setError("Failed to get total length.\n A network error may have occurred");				return false;			}			// create a buffer to hold the data			buffer=new char[totallength+1];			// handle a long datatype			uint64_t	offset=0;			for (;;) {				// get the type of the chunk				if (getShort(&type)!=sizeof(uint16_t)) {					delete[] buffer;					setError("Failed to get chunk type.\n A network error may have occurred");					return false;				}				// check to see if we're done				if (type==END_LONG_DATA) {					break;				}				// get the length of the chunk				if (getLong(&length)!=sizeof(uint32_t)) {					delete[] buffer;					setError("Failed to get chunk length.\n A network error may have occurred");					return false;				}				// Oracle in particular has a function that				// returns the number of characters in a CLOB,				// but not the number of bytes.  Since				// varying-width character data can be stored				// in a CLOB, characters may be less than bytes.				// AFAIK, there's no way to get the number of				// bytes.  So, we use the number of characters				// as a starting point, and extend buffer if				// necessary.				if (offset+length>totallength) {					char	*newbuffer=						new char[offset+length+1];					rawbuffer::copy(						newbuffer,buffer,offset);					delete[] buffer;					buffer=newbuffer;					totallength=offset+length;				}				// get the chunk of data				if ((uint32_t)getString(buffer+offset,							length)!=length) {					delete[] buffer;					setError("Failed to get chunk data.\n A network error may have occurred");					return false;				}				offset=offset+length;			}			// NULL terminate the buffer.  This makes 			// certain operations safer and won't hurt			// since the actual length (which doesn't			// include the NULL) is available from			// getFieldLength.			buffer[totallength]=(char)NULL;			length=totallength;		}		// add the buffer to the current row		currentrow->addField(colindex,buffer,length);			if (sqlrc->debug) {			sqlrc->debugPreStart();			if (buffer) {				sqlrc->debugPrint("\"");				sqlrc->debugPrint(buffer);				sqlrc->debugPrint("\",");			} else {				sqlrc->debugPrint(buffer);				sqlrc->debugPrint(",");			}			sqlrc->debugPreEnd();		}		// tag the column as a long data type or not		currentcol=getColumnInternal(colindex);		// set whether this column is a "long type" or not		currentcol->longdatatype=(type==END_LONG_DATA)?1:0;		if (sendcolumninfo==SEND_COLUMN_INFO && 				sentcolumninfo==SEND_COLUMN_INFO) {			// keep track of the longest field			if (length>currentcol->longest) {				currentcol->longest=length;			}		}		// move to the next column, handle end of row 		colindex++;		if (colindex==colcount) {			colindex=0;			if (sqlrc->debug) {				sqlrc->debugPreStart();				sqlrc->debugPrint("\n");				sqlrc->debugPreEnd();			}			// check to see if we've gotten enough rows			if (rsbuffersize && rowbuffercount==rsbuffersize) {				break;			}		}	}	// terminate the row list	if (rowbuffercount>=OPTIMISTIC_ROW_COUNT && currentrow) {		currentrow->next=NULL;		createExtraRowArray();	}	// cache the rows	cacheData();	return true;}void sqlrcursor::createRowBuffers() {	// rows will hang around from now until the cursor is deleted,	// getting reused with each query	rows=new row *[OPTIMISTIC_ROW_COUNT];	for (uint64_t i=0; i<OPTIMISTIC_ROW_COUNT; i++) {		rows[i]=new row(colcount);	}}void sqlrcursor::createExtraRowArray() {	// create the arrays	uint64_t	howmany=rowcount-firstrowindex-OPTIMISTIC_ROW_COUNT;	extrarows=new row *[howmany];		// populate the arrays	row	*currentrow=firstextrarow;	for (uint64_t i=0; i<howmany; i++) {		extrarows[i]=currentrow;		currentrow=currentrow->next;	}}

⌨️ 快捷键说明

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