#include "TMySQLStatement.h"
#include "TDataType.h"
#include "snprintf.h"
ClassImp(TMySQLStatement)
#if MYSQL_VERSION_ID >= 40100
TMySQLStatement::TMySQLStatement(MYSQL_STMT* stmt, Bool_t errout) :
TSQLStatement(errout),
fStmt(stmt),
fNumBuffers(0),
fBind(0),
fBuffer(0),
fWorkingMode(0)
{
unsigned long paramcount = mysql_stmt_param_count(fStmt);
if (paramcount>0) {
fWorkingMode = 1;
SetBuffersNumber(paramcount);
fNeedParBind = kTRUE;
fIterationCount = -1;
}
}
TMySQLStatement::~TMySQLStatement()
{
Close();
}
void TMySQLStatement::Close(Option_t *)
{
if (fStmt)
mysql_stmt_close(fStmt);
fStmt = 0;
FreeBuffers();
}
#define CheckStmt(method, res) \
{ \
ClearError(); \
if (fStmt==0) { \
SetError(-1,"Statement handle is 0",method); \
return res; \
} \
}
#define CheckErrNo(method, force, res) \
{ \
unsigned int errno = mysql_stmt_errno(fStmt); \
if ((errno!=0) || force) { \
const char* errmsg = mysql_stmt_error(fStmt); \
if (errno==0) { errno = 11111; errmsg = "MySQL statement error"; } \
SetError(errno, errmsg, method); \
return res; \
} \
}
#define CheckGetField(method, res) \
{ \
ClearError(); \
if (!IsResultSetMode()) { \
SetError(-1,"Cannot get statement parameters",method); \
return res; \
} \
if ((npar<0) || (npar>=fNumBuffers)) { \
SetError(-1,Form("Invalid parameter number %d", npar),method); \
return res; \
} \
}
Bool_t TMySQLStatement::Process()
{
CheckStmt("Process",kFALSE);
if (IsSetParsMode()) {
if (fIterationCount>=0)
if (!NextIteration()) return kFALSE;
fWorkingMode = 0;
fIterationCount = -1;
FreeBuffers();
return kTRUE;
}
if (mysql_stmt_execute(fStmt))
CheckErrNo("Process",kTRUE, kFALSE);
return kTRUE;
}
Int_t TMySQLStatement::GetNumAffectedRows()
{
CheckStmt("Process", -1);
my_ulonglong res = mysql_stmt_affected_rows(fStmt);
if (res == (my_ulonglong) -1)
CheckErrNo("GetNumAffectedRows", kTRUE, -1);
return (Int_t) res;
}
Int_t TMySQLStatement::GetNumParameters()
{
CheckStmt("GetNumParameters", -1);
Int_t res = mysql_stmt_param_count(fStmt);
CheckErrNo("GetNumParameters", kFALSE, -1);
return res;
}
Bool_t TMySQLStatement::StoreResult()
{
CheckStmt("StoreResult", kFALSE);
if (fWorkingMode!=0) {
SetError(-1,"Cannot store result for that statement","StoreResult");
return kFALSE;
}
if (mysql_stmt_store_result(fStmt))
CheckErrNo("StoreResult",kTRUE, kFALSE);
MYSQL_RES* meta = mysql_stmt_result_metadata(fStmt);
if (meta) {
int count = mysql_num_fields(meta);
SetBuffersNumber(count);
MYSQL_FIELD *fields = mysql_fetch_fields(meta);
for (int n=0;n<count;n++) {
SetSQLParamType(n, fields[n].type, true, fields[n].length);
if (fields[n].name!=0) {
fBuffer[n].fFieldName = new char[strlen(fields[n].name)+1];
strcpy(fBuffer[n].fFieldName, fields[n].name);
}
}
mysql_free_result(meta);
}
if (fBind==0) return kFALSE;
if (mysql_stmt_bind_result(fStmt, fBind))
CheckErrNo("StoreResult",kTRUE, kFALSE);
fWorkingMode = 2;
return kTRUE;
}
Int_t TMySQLStatement::GetNumFields()
{
return IsResultSetMode() ? fNumBuffers : -1;
}
const char* TMySQLStatement::GetFieldName(Int_t nfield)
{
if (!IsResultSetMode() || (nfield<0) || (nfield>=fNumBuffers)) return 0;
return fBuffer[nfield].fFieldName;
}
Bool_t TMySQLStatement::NextResultRow()
{
if ((fStmt==0) || !IsResultSetMode()) return kFALSE;
Bool_t res = !mysql_stmt_fetch(fStmt);
if (!res) {
fWorkingMode = 0;
FreeBuffers();
}
return res;
}
Bool_t TMySQLStatement::NextIteration()
{
ClearError();
if (!IsSetParsMode() || (fBind==0)) {
SetError(-1,"Cannot call for that statement","NextIteration");
return kFALSE;
}
fIterationCount++;
if (fIterationCount==0) return kTRUE;
if (fNeedParBind) {
fNeedParBind = kFALSE;
if (mysql_stmt_bind_param(fStmt, fBind))
CheckErrNo("NextIteration",kTRUE, kFALSE);
}
if (mysql_stmt_execute(fStmt))
CheckErrNo("NextIteration", kTRUE, kFALSE);
return kTRUE;
}
void TMySQLStatement::FreeBuffers()
{
if (fBuffer) {
for (Int_t n=0; n<fNumBuffers;n++) {
free(fBuffer[n].fMem);
if (fBuffer[n].fStrBuffer)
delete[] fBuffer[n].fStrBuffer;
if (fBuffer[n].fFieldName)
delete[] fBuffer[n].fFieldName;
}
delete[] fBuffer;
}
if (fBind)
delete[] fBind;
fBuffer = 0;
fBind = 0;
fNumBuffers = 0;
}
void TMySQLStatement::SetBuffersNumber(Int_t numpars)
{
FreeBuffers();
if (numpars<=0) return;
fNumBuffers = numpars;
fBind = new MYSQL_BIND[fNumBuffers];
memset(fBind, 0, sizeof(MYSQL_BIND)*fNumBuffers);
fBuffer = new TParamData[fNumBuffers];
memset(fBuffer, 0, sizeof(fNumBuffers)*fNumBuffers);
}
const char* TMySQLStatement::ConvertToString(Int_t npar)
{
if (fBuffer[npar].fResNull) return 0;
void* addr = fBuffer[npar].fMem;
bool sig = fBuffer[npar].fSign;
if (addr==0) return 0;
if ((fBind[npar].buffer_type==MYSQL_TYPE_STRING) ||
(fBind[npar].buffer_type==MYSQL_TYPE_VAR_STRING))
return (const char*) addr;
if (fBuffer[npar].fStrBuffer==0)
fBuffer[npar].fStrBuffer = new char[100];
char* buf = fBuffer[npar].fStrBuffer;
switch(fBind[npar].buffer_type) {
case MYSQL_TYPE_LONG:
if (sig) snprintf(buf,100,"%ld",*((long*) addr));
else snprintf(buf,100,"%lu",*((unsigned long*) addr));
break;
case MYSQL_TYPE_LONGLONG:
if (sig) snprintf(buf,100,"%lld",*((long long*) addr)); else
snprintf(buf,100,"%llu",*((unsigned long long*) addr));
break;
case MYSQL_TYPE_SHORT:
if (sig) snprintf(buf,100,"%hd",*((short*) addr)); else
snprintf(buf,100,"%hu",*((unsigned short*) addr));
break;
case MYSQL_TYPE_TINY:
if (sig) snprintf(buf,100,"%d",*((char*) addr)); else
snprintf(buf,100,"%u",*((unsigned char*) addr));
break;
case MYSQL_TYPE_FLOAT:
snprintf(buf,100,"%f",*((float*) addr));
break;
case MYSQL_TYPE_DOUBLE:
snprintf(buf,100,"%f",*((double*) addr));
break;
default:
return 0;
}
return buf;
}
long double TMySQLStatement::ConvertToNumeric(Int_t npar)
{
if (fBuffer[npar].fResNull) return 0;
void* addr = fBuffer[npar].fMem;
bool sig = fBuffer[npar].fSign;
if (addr==0) return 0;
switch(fBind[npar].buffer_type) {
case MYSQL_TYPE_LONG:
if (sig) return *((long*) addr); else
return *((unsigned long*) addr);
break;
case MYSQL_TYPE_LONGLONG:
if (sig) return *((long long*) addr); else
return *((unsigned long long*) addr);
break;
case MYSQL_TYPE_SHORT:
if (sig) return *((short*) addr); else
return *((unsigned short*) addr);
break;
case MYSQL_TYPE_TINY:
if (sig) return *((char*) addr); else
return *((unsigned char*) addr);
break;
case MYSQL_TYPE_FLOAT:
return *((float*) addr);
break;
case MYSQL_TYPE_DOUBLE:
return *((double*) addr);
break;
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING: {
const char* str = (const char*) addr;
if ((str==0) || (*str==0)) return 0;
long double buf = 0;
sscanf(str,"%Lf",&buf);
return buf;
break;
}
default:
return 0;
}
return 0;
}
Bool_t TMySQLStatement::IsNull(Int_t npar)
{
CheckGetField("IsNull", kTRUE);
return fBuffer[npar].fResNull;
}
Int_t TMySQLStatement::GetInt(Int_t npar)
{
CheckGetField("GetInt", 0);
if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONG) && fBuffer[npar].fSign)
return (Int_t) *((long*) fBuffer[npar].fMem);
return (Int_t) ConvertToNumeric(npar);
}
UInt_t TMySQLStatement::GetUInt(Int_t npar)
{
CheckGetField("GetUInt", 0);
if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONG) && !fBuffer[npar].fSign)
return (UInt_t) *((unsigned long*) fBuffer[npar].fMem);
return (UInt_t) ConvertToNumeric(npar);
}
Long_t TMySQLStatement::GetLong(Int_t npar)
{
CheckGetField("GetLong", 0);
if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONG) && fBuffer[npar].fSign)
return (Long_t) *((long*) fBuffer[npar].fMem);
return (Long_t) ConvertToNumeric(npar);
}
Long64_t TMySQLStatement::GetLong64(Int_t npar)
{
CheckGetField("GetLong64", 0);
if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONGLONG) && fBuffer[npar].fSign)
return (Long64_t) *((long long*) fBuffer[npar].fMem);
return (Long64_t) ConvertToNumeric(npar);
}
ULong64_t TMySQLStatement::GetULong64(Int_t npar)
{
CheckGetField("GetULong64", 0);
if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONGLONG) && !fBuffer[npar].fSign)
return (ULong64_t) *((unsigned long long*) fBuffer[npar].fMem);
return (ULong64_t) ConvertToNumeric(npar);
}
Double_t TMySQLStatement::GetDouble(Int_t npar)
{
CheckGetField("GetDouble", 0);
if (fBuffer[npar].fSqlType==MYSQL_TYPE_DOUBLE)
return (Double_t) *((double*) fBuffer[npar].fMem);
return (Double_t) ConvertToNumeric(npar);
}
const char *TMySQLStatement::GetString(Int_t npar)
{
CheckGetField("GetString", 0);
if ((fBind[npar].buffer_type==MYSQL_TYPE_STRING) ||
(fBind[npar].buffer_type==MYSQL_TYPE_VAR_STRING))
return (const char*) fBuffer[npar].fMem;
return ConvertToString(npar);
}
Bool_t TMySQLStatement::SetSQLParamType(Int_t npar, int sqltype, bool sig, int sqlsize)
{
if ((npar<0) || (npar>=fNumBuffers)) return kFALSE;
fBuffer[npar].fMem = 0;
fBuffer[npar].fSize = 0;
fBuffer[npar].fResLength = 0;
fBuffer[npar].fResNull = false;
fBuffer[npar].fStrBuffer = 0;
int allocsize = 0;
switch (sqltype) {
case MYSQL_TYPE_LONG: allocsize = sizeof(long); break;
case MYSQL_TYPE_LONGLONG: allocsize = sizeof(long long); break;
case MYSQL_TYPE_SHORT: allocsize = sizeof(short); break;
case MYSQL_TYPE_TINY: allocsize = sizeof(char); break;
case MYSQL_TYPE_FLOAT: allocsize = sizeof(float); break;
case MYSQL_TYPE_DOUBLE: allocsize = sizeof(double); break;
case MYSQL_TYPE_STRING: allocsize = sqlsize > 256 ? sqlsize : 256; break;
case MYSQL_TYPE_VAR_STRING: allocsize = sqlsize > 256 ? sqlsize : 256; break;
default: SetError(-1,"Nonsupported SQL type","SetSQLParamType"); return kFALSE;
}
fBuffer[npar].fMem = malloc(allocsize);
fBuffer[npar].fSize = allocsize;
fBuffer[npar].fSqlType = sqltype;
fBuffer[npar].fSign = sig;
fBind[npar].buffer_type = enum_field_types(sqltype);
fBind[npar].buffer = fBuffer[npar].fMem;
fBind[npar].buffer_length = allocsize;
fBind[npar].is_null= &(fBuffer[npar].fResNull);
fBind[npar].length = &(fBuffer[npar].fResLength);
fBind[npar].is_unsigned = !sig;
return kTRUE;
}
void *TMySQLStatement::BeforeSet(Int_t npar, Int_t sqltype, Bool_t sig, Int_t size)
{
ClearError();
if (!IsSetParsMode()) {
SetError(-1,"Cannot set parameter for statement","Set***");
return 0;
}
if ((npar<0) || (npar>=fNumBuffers)) {
SetError(-1,Form("Invalid parameter number %d",npar), "Set***");
return 0;
}
if ((fIterationCount==0) && (fBuffer[npar].fSqlType==0))
if (!SetSQLParamType(npar, sqltype, sig, size)) {
SetError(-1,"Cannot initialize parameter buffer","BeforeSet");
return 0;
}
if ((fBuffer[npar].fSqlType!=sqltype) ||
(fBuffer[npar].fSign != sig)) return 0;
fBuffer[npar].fResNull = false;
return fBuffer[npar].fMem;
}
Bool_t TMySQLStatement::SetNull(Int_t npar)
{
void* addr = BeforeSet(npar, MYSQL_TYPE_LONG);
if (addr!=0)
*((long*) addr) = 0;
if ((npar>=0) && (npar<fNumBuffers))
fBuffer[npar].fResNull = true;
return kTRUE;
}
Bool_t TMySQLStatement::SetInt(Int_t npar, Int_t value)
{
void* addr = BeforeSet(npar, MYSQL_TYPE_LONG);
if (addr!=0)
*((long*) addr) = value;
return (addr!=0);
}
Bool_t TMySQLStatement::SetUInt(Int_t npar, UInt_t value)
{
void* addr = BeforeSet(npar, MYSQL_TYPE_LONG, kFALSE);
if (addr!=0)
*((unsigned long*) addr) = value;
return (addr!=0);
}
Bool_t TMySQLStatement::SetLong(Int_t npar, Long_t value)
{
void* addr = BeforeSet(npar, MYSQL_TYPE_LONG);
if (addr!=0)
*((long*) addr) = value;
return (addr!=0);
}
Bool_t TMySQLStatement::SetLong64(Int_t npar, Long64_t value)
{
void* addr = BeforeSet(npar, MYSQL_TYPE_LONGLONG);
if (addr!=0)
*((long long*) addr) = value;
return (addr!=0);
}
Bool_t TMySQLStatement::SetULong64(Int_t npar, ULong64_t value)
{
void* addr = BeforeSet(npar, MYSQL_TYPE_LONGLONG, kFALSE);
if (addr!=0)
*((unsigned long long*) addr) = value;
return (addr!=0);
}
Bool_t TMySQLStatement::SetDouble(Int_t npar, Double_t value)
{
void* addr = BeforeSet(npar, MYSQL_TYPE_DOUBLE, kFALSE);
if (addr!=0)
*((double*) addr) = value;
return (addr!=0);
}
Bool_t TMySQLStatement::SetString(Int_t npar, const char* value, Int_t maxsize)
{
Int_t len = value ? strlen(value) : 0;
void* addr = BeforeSet(npar, MYSQL_TYPE_STRING, true, maxsize);
if (addr==0) return kFALSE;
if (len >= fBuffer[npar].fSize) {
free(fBuffer[npar].fMem);
fBuffer[npar].fMem = malloc(len+1);
fBuffer[npar].fSize = len + 1;
fBind[npar].buffer = fBuffer[npar].fMem;
fBind[npar].buffer_length = fBuffer[npar].fSize;
addr = fBuffer[npar].fMem;
fNeedParBind = kTRUE;
}
strcpy((char*) addr, value);
fBuffer[npar].fResLength = len;
return kTRUE;
}
#else
TMySQLStatement::TMySQLStatement(MYSQL_STMT*, Bool_t)
{
}
TMySQLStatement::~TMySQLStatement()
{
}
void TMySQLStatement::Close(Option_t *)
{
}
Bool_t TMySQLStatement::Process()
{
return kFALSE;
}
Int_t TMySQLStatement::GetNumAffectedRows()
{
return 0;
}
Int_t TMySQLStatement::GetNumParameters()
{
return 0;
}
Bool_t TMySQLStatement::StoreResult()
{
return kFALSE;
}
Int_t TMySQLStatement::GetNumFields()
{
return 0;
}
const char* TMySQLStatement::GetFieldName(Int_t)
{
return 0;
}
Bool_t TMySQLStatement::NextResultRow()
{
return kFALSE;
}
Bool_t TMySQLStatement::NextIteration()
{
return kFALSE;
}
void TMySQLStatement::FreeBuffers()
{
}
void TMySQLStatement::SetBuffersNumber(Int_t)
{
}
const char* TMySQLStatement::ConvertToString(Int_t)
{
return 0;
}
long double TMySQLStatement::ConvertToNumeric(Int_t)
{
return 0;
}
Bool_t TMySQLStatement::IsNull(Int_t)
{
return kTRUE;
}
Int_t TMySQLStatement::GetInt(Int_t)
{
return 0;
}
UInt_t TMySQLStatement::GetUInt(Int_t)
{
return 0;
}
Long_t TMySQLStatement::GetLong(Int_t)
{
return 0;
}
Long64_t TMySQLStatement::GetLong64(Int_t)
{
return 0;
}
ULong64_t TMySQLStatement::GetULong64(Int_t)
{
return 0;
}
Double_t TMySQLStatement::GetDouble(Int_t)
{
return 0.;
}
const char *TMySQLStatement::GetString(Int_t)
{
return 0;
}
Bool_t TMySQLStatement::SetSQLParamType(Int_t, int, bool, int)
{
return kFALSE;
}
void *TMySQLStatement::BeforeSet(Int_t, Int_t, Bool_t, Int_t)
{
return 0;
}
Bool_t TMySQLStatement::SetNull(Int_t)
{
return kFALSE;
}
Bool_t TMySQLStatement::SetInt(Int_t, Int_t)
{
return kFALSE;
}
Bool_t TMySQLStatement::SetUInt(Int_t, UInt_t)
{
return kFALSE;
}
Bool_t TMySQLStatement::SetLong(Int_t, Long_t)
{
return kFALSE;
}
Bool_t TMySQLStatement::SetLong64(Int_t, Long64_t)
{
return kFALSE;
}
Bool_t TMySQLStatement::SetULong64(Int_t, ULong64_t)
{
return kFALSE;
}
Bool_t TMySQLStatement::SetDouble(Int_t, Double_t)
{
return kFALSE;
}
Bool_t TMySQLStatement::SetString(Int_t, const char*, Int_t)
{
return kFALSE;
}
#endif // MYSQL_VERSION_ID > 40100
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.