📄 tdbquery.cpp
字号:
/*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 + -