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

📄 tdbquery.cpp

📁 Oracle OCI的C++类的一个封装
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*TDBQuery.cpp*/
#include "TDBQuery.h"



TDBException::TDBException(sword errNumb, OCIError *hErr,const char *cat,const char *sql)
{
	int nLen;
	sb4 errcode;

	nLen = strlen(cat);
	nLen = (nLen >= MAX_ERR_CAT_LENGTH)? MAX_ERR_CAT_LENGTH : nLen;
	strncpy(errCategory,cat,nLen);
	errCategory[nLen] = '\0';
	
	nLen = strlen(sql);
	nLen = nLen >= MAX_SQLSTMT_LENGTH ? MAX_SQLSTMT_LENGTH : nLen;
	strncpy(errSQL,sql,nLen);
	errSQL[nLen] = '\0';
	
	errNo = errNumb;

	(void)OCIErrorGet ((dvoid *) hErr, (ub4) 1, (text *) NULL, &errcode,
			errMessage, (ub4)sizeof(errMessage)-1, (ub4) OCI_HTYPE_ERROR);
}

TDBException::TDBException(const char *sql, const char* errFormat, ...)
{
	int nLen;
	nLen = strlen(sql);
	nLen = (nLen >= MAX_SQLSTMT_LENGTH) ? MAX_SQLSTMT_LENGTH :nLen;
	strncpy(errSQL,sql,nLen);
	errSQL[nLen] = '\0';

	va_list ap;
	va_start(ap, errFormat);
	vsprintf((char *)errMessage, errFormat, ap);	
	va_end(ap);
}

TDBException::~TDBException()
{
}

char *TDBException::GetErrSql() const
{
	return( (char *)errSQL );
}

char *TDBException::GetErrMsg() const
{	
	return( (char *)errMessage);
}

//比较2个字符串是否相同(不考虑大小写)
bool inline CompareStrNoCase(const char *ori, const char *des)
{
	int j,nLen1,nLen2;
	bool sameChar;
	nLen1 = strlen(ori);
	nLen2 = strlen(des);
	if (nLen1!=nLen2) return false;
	sameChar = true;

	/*for (j=0; j<nLen1; j++)
		sameChar =sameChar && (toupper(ori[j]) == toupper(des[j]));*/
	//Modify by YuanSF @ 2005-08-10
	for (j=0; j<nLen1 && sameChar; j++)
		sameChar =(toupper(ori[j]) == toupper(des[j]));
	return sameChar;
}

/********* TConnection implementation *********/
TDBDatabase::TDBDatabase() 
{
	sword errorNo;
	
	errorNo = OCIInitialize((ub4) OCI_DEFAULT|OCI_OBJECT,0, 0,0,0 );
	errorNo = errorNo + OCIEnvInit( (OCIEnv **) &hEnv, (ub4) OCI_DEFAULT,(size_t) 0, (dvoid **) 0 );
	errorNo = errorNo + OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hDBSvc,(ub4) OCI_HTYPE_SVCCTX,(size_t) 0, (dvoid **) 0);
	errorNo = errorNo + OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hDBErr,(ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0);	
	errorNo = errorNo + OCIHandleAlloc( (dvoid *) hEnv, (dvoid **) &hSvr,(ub4) OCI_HTYPE_SERVER,(size_t) 0, (dvoid **) 0);
		
	if ( errorNo != 0 )
		throw TDBException( "TDBDatabase()", ERR_DB_INIT, __LINE__);
	fConnected = false;
	usr = NULL;
	pwd = NULL;
	tns = NULL;
}

TDBDatabase::~TDBDatabase()
{
	delete[] usr;
	delete[] tns;
	delete[] pwd;
	
	if (fConnected) 
		OCIServerDetach(hSvr, hDBErr, OCI_DEFAULT );
	
	OCIHandleFree(hSvr, OCI_HTYPE_SERVER);		
	OCIHandleFree(hDBSvc, OCI_HTYPE_SVCCTX);
	OCIHandleFree(hDBErr,OCI_HTYPE_ERROR);
	OCIHandleFree(hEnv,OCI_HTYPE_ENV);
}

void TDBDatabase::SetLogin(char *user, char *password, char *tnsString) 
{
	if (fConnected)
		throw TDBException("SetLogin()", ERR_SET_LOGIN , __LINE__);
	
	int nLen;
	//保存外部传递的参数
	if ( usr != NULL) 
		delete[] usr;
	if (pwd != NULL)
		delete[] pwd;
	if (tns != NULL)
		delete[] tns;

	//保存外部传递的参数
	if (user)
	{
		nLen = strlen(user);
		usr = new char[nLen+1];
		strncpy(usr,user,nLen);
		usr[nLen] = '\0';
	}
	else
	{
		nLen = 0;
		usr = new char[1];
		usr[0] = '\0';
	}

	if (password)
	{
		nLen = strlen(password);
		pwd = new char[nLen+1];
		strncpy(pwd,password,nLen);
		pwd[nLen] = '\0';
	}
	else
	{
		nLen = 0;
		pwd = new char[1];
		pwd[0] = '\0';
	}
	
	if (tnsString)
	{
		nLen = strlen(tnsString);
		tns = new char[nLen+1];
		strncpy(tns,tnsString,nLen);
		tns[nLen] = '\0';
	}
	else	
	{
		nLen = 0;
		tns = new char[1];
		tns[0] = '\0';
	}
}

void TDBDatabase::CheckError() 
{
	if (fErrorNo != OCI_SUCCESS) 
		throw TDBException(fErrorNo, hDBErr, "Oracle OCI Call", "OCIDatabase");
	
}


//数据库开启事务
void TDBDatabase::TransBegin() 
{
    return;
}

bool TDBDatabase::Connect() 
{
	sword errorNo;

	if (fConnected)
		return true;
	
	if ( (usr == NULL) || (tns==NULL) )
		throw TDBException("Connect()", ERR_CONNECT_NO_LOGIN_INFO, __LINE__);
	
	errorNo = OCIServerAttach(hSvr, hDBErr, (text *)tns, strlen(tns), 0);
	if (errorNo != OCI_SUCCESS)
		throw TDBException(errorNo, hDBErr, "Connect()", "try to connect Server");
	
	//modified: 2003.1
	fErrorNo = OCIHandleAlloc(hEnv, (dvoid **) &hUser,(ub4) OCI_HTYPE_SESSION,(size_t) 0, (dvoid **) 0);
	CheckError();

	fErrorNo = OCIHandleAlloc(hEnv, (dvoid **)&hDBSvc, OCI_HTYPE_SVCCTX,0, 0);
	CheckError();

	fErrorNo = OCIAttrSet (hDBSvc, OCI_HTYPE_SVCCTX, hSvr, 0, OCI_ATTR_SERVER, hDBErr);
	CheckError();

	/* set the username/password in user handle */
	OCIAttrSet(hUser, OCI_HTYPE_SESSION, usr, strlen(usr),OCI_ATTR_USERNAME, hDBErr);
	OCIAttrSet(hUser, OCI_HTYPE_SESSION, pwd, strlen(pwd),OCI_ATTR_PASSWORD, hDBErr);

	// Set the Authentication handle in the service handle
	fErrorNo = OCIAttrSet(hDBSvc, OCI_HTYPE_SVCCTX, hUser, 0, OCI_ATTR_SESSION, hDBErr);
    CheckError();

	fErrorNo=OCISessionBegin (hDBSvc, hDBErr, hUser, OCI_CRED_RDBMS, OCI_DEFAULT);
    CheckError();
	//Set Trans:
	//OCIAttrSet(hDBSvc, OCI_HTYPE_SVCCTX, hTrans, 0, OCI_ATTR_TRANS, hErr);

	return (fConnected = (errorNo == OCI_SUCCESS));
}

bool TDBDatabase::Connect(char *inUsr, char *inPwd, char *inTns) 
{
	SetLogin(inUsr, inPwd, inTns);
	return Connect();
}

void TDBDatabase::Disconnect() 
{
	if (!fConnected) return;
	OCISessionEnd (hDBSvc, hDBErr, hUser, OCI_DEFAULT);
	dword errorNo = OCIServerDetach(hSvr, hDBErr, OCI_DEFAULT );
	if (errorNo != OCI_SUCCESS)
			throw TDBException(errorNo, hDBErr,"Disconnect()", "OCIServerDetatch error");
	fConnected = false;
}

bool TDBQuery::TransBegin()
{
	db->TransBegin();
	return true;
}

void TDBDatabase::Commit()
{
    OCITransCommit(hDBSvc, hDBErr, OCI_DEFAULT);
}

void TDBDatabase::Rollback()
{
	OCITransRollback(hDBSvc, hDBErr, OCI_DEFAULT);
}

TDBField::TDBField()
{
	//初始化列信息,有部分的初始化信息在Describe中进行
	name = NULL;
	hBlob = NULL;
	hDefine = (OCIDefine *) 0; ;
	fDataBuf = NULL;
	fDataIndicator = NULL;
	fParentQuery = NULL;

	fReturnDataLen = 0;
	size = 0;
	precision = 0;
	scale = 0;
	size = 0;
};

TDBField::~TDBField()
{
	if (fDataIndicator != NULL)
		delete[] fDataIndicator;
	if (name != NULL)
		delete[] name; 
	if (fDataBuf != NULL)
		delete[] fDataBuf;
	if (type == SQLT_BLOB)
		OCIDescriptorFree((dvoid *)hBlob, (ub4) OCI_DTYPE_LOB);
}

char* TDBField::AsString() 
{
	int year, month, day, hour, minute, second;
	static char intStr[100];
	int status;

	if (fParentQuery->fBof || fParentQuery->fEof)
		throw TDBException(fParentQuery->fSqlStmt, ERR_NO_DATASET, "AsString()", name);

	if ( isNULL() )
	{
		sprintf((char *)fStrBuffer, NULL_STRING);
		return (char *)fStrBuffer;
	}

	switch ( this->type )
	{
	case DATE_TYPE:
		this->AsDateTimeInternal(year, month, day, hour, minute, second);
		sprintf((char *)fStrBuffer,"%04d%02d%02d%02d%02d%02d", year, month, day,hour, minute, second);
		return (char *)fStrBuffer;
	case INT_TYPE:
		llong intValue;
		if ( (status=OCINumberToInt(fParentQuery->hErr, (OCINumber *)(fDataBuf + (size+1) * fParentQuery->fCurrRow ),sizeof(intValue), OCI_NUMBER_SIGNED,&intValue))!= OCI_SUCCESS)
		{
			fParentQuery->CheckError();
		}
		
		sprintf(intStr, "%ld", intValue);
		return intStr;
	case FLOAT_TYPE:
		//int status;
		double floatValue;
		if ( (status=OCINumberToReal(fParentQuery->hErr, (OCINumber *)(fDataBuf + (size+1) * fParentQuery->fCurrRow ),sizeof(floatValue), &floatValue))!= OCI_SUCCESS)
		{
			fParentQuery->CheckError();
		}

		sprintf(intStr, "%f", floatValue);
		return intStr;		
		//return((char *)(fDataBuf + (size+1) * fParentQuery->fCurrRow));
	case STRING_TYPE:
	case ROWID_TYPE:
		return((char *)(fDataBuf + (size+1) * fParentQuery->fCurrRow));
	case SQLT_BLOB:
		sprintf((char *)fStrBuffer, "BLOB...");
		return (char *)fStrBuffer;
	default:
		throw TDBException(fParentQuery->fSqlStmt, ERR_DATA_TYPE_CONVERT, name, type, "AsString()");
	}
}

bool TDBField::isNULL()
{
	return (fDataIndicator[fParentQuery->fCurrRow]==-1);
}

void  TDBField::AsBlobFile(const char *fileName) 
{
	ub4 offset = 1;
	ub1 buf[MAX_LOB_BUFFER_LENGTH];
	ub4 nActual = 0;	//实际读取数
	ub4 nTry = 0;		//试图读取数
	ub4 totalSize = 0;
	FILE *fileHandle;
	ub4 lobLength;

	if (fParentQuery->fBof || fParentQuery->fEof)
		throw TDBException(fParentQuery->fSqlStmt, ERR_NO_DATASET, "AsBlobFile()", name);

	if (type != SQLT_BLOB)
		throw TDBException(fParentQuery->fSqlStmt, ERR_DATA_TYPE_CONVERT, name, type, "asLobFile()");

	fileHandle = fopen( fileName, (const char *) "wb");
	fseek(fileHandle, 0, 0);
	/* set amount to be read per iteration */
	nTry = nActual = MAX_LOB_BUFFER_LENGTH;
	OCILobGetLength(fParentQuery->db->hDBSvc, fParentQuery->hErr, hBlob, &lobLength);

	while (nActual)
	{
		fParentQuery->fErrorNo = OCILobRead(fParentQuery->db->hDBSvc, fParentQuery->hErr, 
			hBlob, &nActual, (ub4)offset, (dvoid *) buf, (ub4) nTry, (dvoid *)0, 
			(sb4 (*)(dvoid *, CONST dvoid *, ub4, ub1)) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT);
		fParentQuery->CheckError();	  
		
		if (nActual<=0) break;
		
		totalSize += nActual;
		fwrite((void *)buf, (size_t)nActual, (size_t)1, fileHandle);
		offset += nActual;
	}
	fclose(fileHandle);
}

void  TDBField::AsBlobBuffer(unsigned char* &buf, unsigned int *lobLength) 
{
	ub1 innerBuf[MAX_LOB_BUFFER_LENGTH];
	ub4 remainder, nActual, nTry;
	ub4  flushedAmount = 0, offset = 1;

	if (fParentQuery->fBof || fParentQuery->fEof)
		throw TDBException(fParentQuery->fSqlStmt, ERR_NO_DATASET, "AsBlobBuffer()", name);

	if (type != SQLT_BLOB)
		throw TDBException(fParentQuery->fSqlStmt, ERR_DATA_TYPE_CONVERT, name, type, "asLobBuffer()");

	OCILobGetLength(fParentQuery->db->hDBSvc, fParentQuery->hErr, hBlob, &remainder);
	*lobLength = nActual = nTry = remainder;

	try
	{
		buf = new unsigned char[sizeof(ub1) * remainder];
	}
	catch (...)
	{
		throw TDBException(fParentQuery->fSqlStmt, ERR_NOMORE_MEMORY_BE_ALLOCATED, "AsBlobBuffer()", __LINE__);
	}

	nTry = nActual = MAX_LOB_BUFFER_LENGTH;
	while (remainder)
	{		
		fParentQuery->fErrorNo = OCILobRead(fParentQuery->db->hDBSvc, fParentQuery->hErr, 
			hBlob, &nActual, (ub4)offset, (dvoid *)innerBuf, (ub4) nTry, (dvoid *)0, 
			(sb4 (*)(dvoid *, CONST dvoid *, ub4, ub1)) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT);
		fParentQuery->CheckError();	  
		memcpy( (buf) + offset -1, innerBuf, nActual);
		if (nActual<=0) break;
		
		offset += nActual;
		remainder -= nActual;
	}
}

void  TDBField::LoadFromFile(const char *fileName) 
{
	ub4 remainder, nActual, nTry, offset = 1;//从文件中读取的剩余数据量
	ub1 buf[MAX_LOB_BUFFER_LENGTH];
	ub4 LobLength;

⌨️ 快捷键说明

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