From 8aa8bb839d93fdbd2181a7bd5eef7aab81b39a0f Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Tue, 5 Sep 2006 13:37:08 +0000 Subject: [PATCH] From Sergey Linev: 1. Support of date/time/date&time/timestamp data introduced in TSQLStatement All such data now can be accessed without text conversion. The following methods can be used: SetTime()/GetTime() - only time (hour:min:sec), SetDate()/GetDate() - only date (year-month-day), SetDatime()/GetDatime() - date and time SetTimestamp()/GetTimestamp() - timestamp with seconds fraction For some of these methods TDatime type can be used as parameter / return value. Be aware, that TDatime supports only dates after 1995-01-01. There are also methods to get separately year, month, day, hour, minutes and seconds. 2. Support of binary data in TSQLStatement Most of modern data bases support just binary data, which is typically has SQL type name 'BLOB'. To access data in such columns, GetBinary()/SetBinary() methods should be used. Current implementation supposes, that complete content of the column must be retrieved at once. Therefore very big data of gigabytes size may cause a problem. git-svn-id: http://root.cern.ch/svn/root/trunk@16204 27541ba8-7e3a-0410-8455-c3a389f83636 --- mysql/inc/TMySQLStatement.h | 14 +- mysql/src/TMySQLStatement.cxx | 357 ++++++++++++++++++++++++++++++-- net/inc/TSQLStatement.h | 29 ++- net/src/TSQLStatement.cxx | 175 +++++++++++++++- odbc/inc/TODBCStatement.h | 12 +- oracle/inc/TOracleStatement.h | 21 +- oracle/src/TOracleRow.cxx | 20 +- oracle/src/TOracleServer.cxx | 8 +- oracle/src/TOracleStatement.cxx | 310 ++++++++++++++++++++++++--- 9 files changed, 881 insertions(+), 65 deletions(-) diff --git a/mysql/inc/TMySQLStatement.h b/mysql/inc/TMySQLStatement.h index 97dd3412f39..609b8e6ce20 100644 --- a/mysql/inc/TMySQLStatement.h +++ b/mysql/inc/TMySQLStatement.h @@ -1,4 +1,4 @@ -// @(#)root/mysql:$Name: $:$Id: TMySQLStatement.h,v 1.4 2006/06/25 18:43:24 brun Exp $ +// @(#)root/mysql:$Name: $:$Id: TMySQLStatement.h,v 1.5 2006/06/29 20:36:43 brun Exp $ // Author: Sergey Linev 6/02/2006 /************************************************************************* @@ -67,7 +67,7 @@ private: void FreeBuffers(); void SetBuffersNumber(Int_t n); - void *BeforeSet(Int_t npar, Int_t sqltype, Bool_t sig = kTRUE, Int_t size = 0); + void *BeforeSet(const char* method, Int_t npar, Int_t sqltype, Bool_t sig = kTRUE, Int_t size = 0); public: TMySQLStatement(MYSQL_STMT* stmt, Bool_t errout = kTRUE); @@ -86,6 +86,11 @@ public: virtual Bool_t SetULong64(Int_t npar, ULong64_t value); virtual Bool_t SetDouble(Int_t npar, Double_t value); virtual Bool_t SetString(Int_t npar, const char* value, Int_t maxsize = 256); + virtual Bool_t SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize = 0x1000); + virtual Bool_t SetDate(Int_t npar, Int_t year, Int_t month, Int_t day); + virtual Bool_t SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec); + virtual Bool_t SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec); + virtual Bool_t SetTimestamp(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec, Int_t frac = 0); virtual Bool_t NextIteration(); @@ -105,6 +110,11 @@ public: virtual ULong64_t GetULong64(Int_t npar); virtual Double_t GetDouble(Int_t npar); virtual const char *GetString(Int_t npar); + virtual Bool_t GetBinary(Int_t npar, void* &mem, Long_t& size); + virtual Bool_t GetDate(Int_t npar, Int_t& year, Int_t& month, Int_t& day); + virtual Bool_t GetTime(Int_t npar, Int_t& hour, Int_t& min, Int_t& sec); + virtual Bool_t GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec); + virtual Bool_t GetTimestamp(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec, Int_t&); ClassDef(TMySQLStatement, 0); // SQL statement class for MySQL DB }; diff --git a/mysql/src/TMySQLStatement.cxx b/mysql/src/TMySQLStatement.cxx index 90c4e13bb37..b84ff498a08 100644 --- a/mysql/src/TMySQLStatement.cxx +++ b/mysql/src/TMySQLStatement.cxx @@ -1,4 +1,4 @@ -// @(#)root/mysql:$Name: $:$Id: TMySQLStatement.cxx,v 1.7 2006/07/17 12:36:49 brun Exp $ +// @(#)root/mysql:$Name: $:$Id: TMySQLStatement.cxx,v 1.8 2006/08/30 12:55:09 brun Exp $ // Author: Sergey Linev 6/02/2006 /************************************************************************* @@ -310,7 +310,7 @@ void TMySQLStatement::SetBuffersNumber(Int_t numpars) memset(fBind, 0, sizeof(MYSQL_BIND)*fNumBuffers); fBuffer = new TParamData[fNumBuffers]; - memset(fBuffer, 0, sizeof(fNumBuffers)*fNumBuffers); + memset(fBuffer, 0, sizeof(TParamData)*fNumBuffers); } //______________________________________________________________________________ @@ -452,7 +452,6 @@ long double TMySQLStatement::ConvertToNumeric(Int_t npar) return rtm.GetTime(); break; } - default: return 0; @@ -571,6 +570,140 @@ const char *TMySQLStatement::GetString(Int_t npar) return ConvertToString(npar); } +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetBinary(Int_t npar, void* &mem, Long_t& size) +{ + // Return field value as binary array + + mem = 0; + size = 0; + + CheckGetField("GetBinary", kFALSE); + + if ((fBind[npar].buffer_type==MYSQL_TYPE_STRING) || + (fBind[npar].buffer_type==MYSQL_TYPE_VAR_STRING) || + (fBind[npar].buffer_type==MYSQL_TYPE_BLOB) || + (fBind[npar].buffer_type==MYSQL_TYPE_TINY_BLOB) || + (fBind[npar].buffer_type==MYSQL_TYPE_MEDIUM_BLOB) || + (fBind[npar].buffer_type==MYSQL_TYPE_LONG_BLOB)) { + if (fBuffer[npar].fResNull) return kTRUE; + mem = fBuffer[npar].fMem; + size = fBuffer[npar].fResLength; + return kTRUE; + } + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetDate(Int_t npar, Int_t& year, Int_t& month, Int_t& day) +{ + // return field value as date + + CheckGetField("GetDate", kFALSE); + + if (fBuffer[npar].fResNull) return kFALSE; + + switch(fBind[npar].buffer_type) { + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATE: { + MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem; + if (tm==0) return kFALSE; + year = tm->year; + month = tm->month; + day = tm->day; + break; + } + default: + return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetTime(Int_t npar, Int_t& hour, Int_t& min, Int_t& sec) +{ + // return field value as time + + CheckGetField("GetTime", kFALSE); + + if (fBuffer[npar].fResNull) return kFALSE; + + switch(fBind[npar].buffer_type) { + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_TIME: { + MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem; + if (tm==0) return kFALSE; + hour = tm->hour; + min = tm->minute; + sec = tm->second; + break; + } + default: + return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec) +{ + // return field value as date & time + + CheckGetField("GetDatime", kFALSE); + + if (fBuffer[npar].fResNull) return kFALSE; + + switch(fBind[npar].buffer_type) { + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: { + MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem; + if (tm==0) return kFALSE; + year = tm->year; + month = tm->month; + day = tm->day; + hour = tm->hour; + min = tm->minute; + sec = tm->second; + break; + } + default: + return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetTimestamp(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec, Int_t& frac) +{ + // return field value as time stamp + + CheckGetField("GetTimstamp", kFALSE); + + if (fBuffer[npar].fResNull) return kFALSE; + + switch(fBind[npar].buffer_type) { + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: { + MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem; + if (tm==0) return kFALSE; + year = tm->year; + month = tm->month; + day = tm->day; + hour = tm->hour; + min = tm->minute; + sec = tm->second; + frac = 0; + break; + } + default: + return kFALSE; + } + return kTRUE; +} + //______________________________________________________________________________ Bool_t TMySQLStatement::SetSQLParamType(Int_t npar, int sqltype, bool sig, int sqlsize) { @@ -587,6 +720,7 @@ Bool_t TMySQLStatement::SetSQLParamType(Int_t npar, int sqltype, bool sig, int s fBuffer[npar].fStrBuffer = 0; int allocsize = 0; + bool doreset = false; switch (sqltype) { case MYSQL_TYPE_LONG: allocsize = sizeof(long); break; @@ -601,7 +735,7 @@ Bool_t TMySQLStatement::SetSQLParamType(Int_t npar, int sqltype, bool sig, int s case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_DATETIME: allocsize = sizeof(MYSQL_TIME); break; + case MYSQL_TYPE_DATETIME: allocsize = sizeof(MYSQL_TIME); doreset = true; break; default: SetError(-1,"Nonsupported SQL type","SetSQLParamType"); return kFALSE; } @@ -609,6 +743,9 @@ Bool_t TMySQLStatement::SetSQLParamType(Int_t npar, int sqltype, bool sig, int s fBuffer[npar].fSize = allocsize; fBuffer[npar].fSqlType = sqltype; fBuffer[npar].fSign = sig; + + if ((allocsize>0) && fBuffer[npar].fMem && doreset) + memset(fBuffer[npar].fMem, 0, allocsize); fBind[npar].buffer_type = enum_field_types(sqltype); fBind[npar].buffer = fBuffer[npar].fMem; @@ -621,26 +758,26 @@ Bool_t TMySQLStatement::SetSQLParamType(Int_t npar, int sqltype, bool sig, int s } //______________________________________________________________________________ -void *TMySQLStatement::BeforeSet(Int_t npar, Int_t sqltype, Bool_t sig, Int_t size) +void *TMySQLStatement::BeforeSet(const char* method, Int_t npar, Int_t sqltype, Bool_t sig, Int_t size) { // Check boundary condition before setting value of parameter // Return address of parameter buffer - + ClearError(); if (!IsSetParsMode()) { - SetError(-1,"Cannot set parameter for statement","Set***"); + SetError(-1,"Cannot set parameter for statement", method); return 0; } if ((npar<0) || (npar>=fNumBuffers)) { - SetError(-1,Form("Invalid parameter number %d",npar), "Set***"); + SetError(-1,Form("Invalid parameter number %d",npar), method); return 0; } if ((fIterationCount==0) && (fBuffer[npar].fSqlType==0)) if (!SetSQLParamType(npar, sqltype, sig, size)) { - SetError(-1,"Cannot initialize parameter buffer","BeforeSet"); + SetError(-1,"Cannot initialize parameter buffer", method); return 0; } @@ -663,7 +800,7 @@ Bool_t TMySQLStatement::SetNull(Int_t npar) // stmt->SetDouble(2, 0.); // stmt->SetNull(2); - void* addr = BeforeSet(npar, MYSQL_TYPE_LONG); + void* addr = BeforeSet("SetNull", npar, MYSQL_TYPE_LONG); if (addr!=0) *((long*) addr) = 0; @@ -679,7 +816,7 @@ Bool_t TMySQLStatement::SetInt(Int_t npar, Int_t value) { // Set parameter value as integer - void* addr = BeforeSet(npar, MYSQL_TYPE_LONG); + void* addr = BeforeSet("SetInt", npar, MYSQL_TYPE_LONG); if (addr!=0) *((long*) addr) = value; @@ -692,7 +829,7 @@ Bool_t TMySQLStatement::SetUInt(Int_t npar, UInt_t value) { // Set parameter value as unsigned integer - void* addr = BeforeSet(npar, MYSQL_TYPE_LONG, kFALSE); + void* addr = BeforeSet("SetUInt", npar, MYSQL_TYPE_LONG, kFALSE); if (addr!=0) *((unsigned long*) addr) = value; @@ -705,7 +842,7 @@ Bool_t TMySQLStatement::SetLong(Int_t npar, Long_t value) { // Set parameter value as long integer - void* addr = BeforeSet(npar, MYSQL_TYPE_LONG); + void* addr = BeforeSet("SetLong", npar, MYSQL_TYPE_LONG); if (addr!=0) *((long*) addr) = value; @@ -718,7 +855,7 @@ Bool_t TMySQLStatement::SetLong64(Int_t npar, Long64_t value) { // Set parameter value as 64-bit integer - void* addr = BeforeSet(npar, MYSQL_TYPE_LONGLONG); + void* addr = BeforeSet("SetLong64", npar, MYSQL_TYPE_LONGLONG); if (addr!=0) *((long long*) addr) = value; @@ -731,7 +868,7 @@ Bool_t TMySQLStatement::SetULong64(Int_t npar, ULong64_t value) { // Set parameter value as unsigned 64-bit integer - void* addr = BeforeSet(npar, MYSQL_TYPE_LONGLONG, kFALSE); + void* addr = BeforeSet("SetULong64", npar, MYSQL_TYPE_LONGLONG, kFALSE); if (addr!=0) *((unsigned long long*) addr) = value; @@ -744,7 +881,7 @@ Bool_t TMySQLStatement::SetDouble(Int_t npar, Double_t value) { // Set parameter value as double - void* addr = BeforeSet(npar, MYSQL_TYPE_DOUBLE, kFALSE); + void* addr = BeforeSet("SetDouble", npar, MYSQL_TYPE_DOUBLE, kFALSE); if (addr!=0) *((double*) addr) = value; @@ -759,7 +896,7 @@ 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); + void* addr = BeforeSet("SetString", npar, MYSQL_TYPE_STRING, true, maxsize); if (addr==0) return kFALSE; @@ -783,6 +920,110 @@ Bool_t TMySQLStatement::SetString(Int_t npar, const char* value, Int_t maxsize) return kTRUE; } +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize) +{ + // set parameter value as binary data + + if (size>=maxsize) maxsize = size + 1; + + void* addr = BeforeSet("SetBinary", npar, MYSQL_TYPE_BLOB, true, maxsize); + + if (addr==0) return kFALSE; + + if (size >= fBuffer[npar].fSize) { + free(fBuffer[npar].fMem); + + fBuffer[npar].fMem = malloc(size+1); + fBuffer[npar].fSize = size + 1; + + fBind[npar].buffer = fBuffer[npar].fMem; + fBind[npar].buffer_length = fBuffer[npar].fSize; + + addr = fBuffer[npar].fMem; + fNeedParBind = kTRUE; + } + + memcpy(addr, mem, size); + + fBuffer[npar].fResLength = size; + + return kTRUE; + +} + + + + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetDate(Int_t npar, Int_t year, Int_t month, Int_t day) +{ + // set parameter value as date + + MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetDate", npar, MYSQL_TYPE_DATE); + + if (addr!=0) { + addr->year = year; + addr->month = month; + addr->day = day; + } + + return (addr!=0); +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec) +{ + // set parameter value as time + + MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetTime", npar, MYSQL_TYPE_TIME); + + if (addr!=0) { + addr->hour = hour; + addr->minute = min; + addr->second = sec; + } + + return (addr!=0); +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec) +{ + // set parameter value as date & time + + MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetDatime", npar, MYSQL_TYPE_DATETIME); + + if (addr!=0) { + addr->year = year; + addr->month = month; + addr->day = day; + addr->hour = hour; + addr->minute = min; + addr->second = sec; + } + + return (addr!=0); +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetTimestamp(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec, Int_t) +{ + // set parameter value as timestamp + + MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetTimestamp", npar, MYSQL_TYPE_TIMESTAMP); + + if (addr!=0) { + addr->year = year; + addr->month = month; + addr->day = day; + addr->hour = hour; + addr->minute = min; + addr->second = sec; + } + + return (addr!=0); +} #else @@ -965,6 +1206,47 @@ const char *TMySQLStatement::GetString(Int_t) return 0; } +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetBinary(Int_t, void* &, Long_t&) +{ + // Return field value as binary array + + return kFALSE; +} + + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetDate(Int_t, Int_t&, Int_t&, Int_t&) +{ + // return field value as date + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetTime(Int_t, Int_t&, Int_t&, Int_t&) +{ + // return field value as time + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetDatime(Int_t, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&) +{ + // return field value as date & time + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::GetTimestamp(Int_t, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&) +{ + // return field value as time stamp + + return kFALSE; +} + //______________________________________________________________________________ Bool_t TMySQLStatement::SetSQLParamType(Int_t, int, bool, int) { @@ -976,7 +1258,7 @@ Bool_t TMySQLStatement::SetSQLParamType(Int_t, int, bool, int) } //______________________________________________________________________________ -void *TMySQLStatement::BeforeSet(Int_t, Int_t, Bool_t, Int_t) +void *TMySQLStatement::BeforeSet(const char*, Int_t, Int_t, Bool_t, Int_t) { // Check boundary condition before setting value of parameter // Return address of parameter buffer @@ -1054,5 +1336,44 @@ Bool_t TMySQLStatement::SetString(Int_t, const char*, Int_t) return kFALSE; } +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetBinary(Int_t, void*, Long_t, Long_t) +{ + // set parameter value as binary data + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetDate(Int_t, Int_t, Int_t, Int_t) +{ + // set parameter value as date + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetTime(Int_t, Int_t, Int_t, Int_t) +{ + // set parameter value as time + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetDatime(Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t) +{ + // set parameter value as date & time + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TMySQLStatement::SetTimestamp(Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t) +{ + // set parameter value as timestamp + + return kFALSE; +} #endif // MYSQL_VERSION_ID > 40100 diff --git a/net/inc/TSQLStatement.h b/net/inc/TSQLStatement.h index 153cc20f275..3a04262257a 100644 --- a/net/inc/TSQLStatement.h +++ b/net/inc/TSQLStatement.h @@ -1,4 +1,4 @@ -// @(#)root/net:$Name: $:$Id: TSQLStatement.h,v 1.4 2006/06/02 14:02:03 brun Exp $ +// @(#)root/net:$Name: $:$Id: TSQLStatement.h,v 1.5 2006/06/25 18:43:24 brun Exp $ // Author: Sergey Linev 6/02/2006 /************************************************************************* @@ -18,6 +18,9 @@ #ifndef ROOT_TString #include "TString.h" #endif +#ifndef ROOT_TDatime +#include "TDatime.h" +#endif class TSQLStatement : public TObject { @@ -48,6 +51,16 @@ public: virtual Bool_t SetULong64(Int_t, ULong64_t) { return kFALSE; } virtual Bool_t SetDouble(Int_t, Double_t) { return kFALSE; } virtual Bool_t SetString(Int_t, const char*, Int_t = 256) { return kFALSE; } + virtual Bool_t SetDate(Int_t, Int_t, Int_t, Int_t) { return kFALSE; } + Bool_t SetDate(Int_t, const TDatime&); + virtual Bool_t SetTime(Int_t, Int_t, Int_t, Int_t) { return kFALSE; } + Bool_t SetTime(Int_t, const TDatime&); + virtual Bool_t SetDatime(Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t) { return kFALSE; } + Bool_t SetDatime(Int_t, const TDatime&); + virtual Bool_t SetTimestamp(Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t = 0) { return kFALSE; } + Bool_t SetTimestamp(Int_t, const TDatime&); + virtual void SetTimeFormating(const char*) {} + virtual Bool_t SetBinary(Int_t, void*, Long_t, Long_t = 0x1000) { return kFALSE; } virtual Bool_t Process() = 0; virtual Int_t GetNumAffectedRows() { return 0; } @@ -65,6 +78,20 @@ public: virtual ULong64_t GetULong64(Int_t) { return 0; } virtual Double_t GetDouble(Int_t) { return 0.; } virtual const char *GetString(Int_t) { return 0; } + virtual Bool_t GetBinary(Int_t, void* &, Long_t&) { return kFALSE; } + + virtual Bool_t GetDate(Int_t, Int_t&, Int_t&, Int_t&) { return kFALSE; } + virtual Bool_t GetTime(Int_t, Int_t&, Int_t&, Int_t&) { return kFALSE; } + virtual Bool_t GetDatime(Int_t, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&) { return kFALSE; } + TDatime GetDatime(Int_t); + Int_t GetYear(Int_t); + Int_t GetMonth(Int_t); + Int_t GetDay(Int_t); + Int_t GetHour(Int_t); + Int_t GetMinute(Int_t); + Int_t GetSecond(Int_t); + virtual Bool_t GetTimestamp(Int_t, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&, Int_t&) { return kFALSE; } + TDatime GetTimestamp(Int_t); virtual Bool_t IsError() const { return GetErrorCode()!=0; } virtual Int_t GetErrorCode() const; diff --git a/net/src/TSQLStatement.cxx b/net/src/TSQLStatement.cxx index 396f8fe5f05..599d5bb04fd 100644 --- a/net/src/TSQLStatement.cxx +++ b/net/src/TSQLStatement.cxx @@ -1,4 +1,4 @@ -// @(#)root/net:$Name: $:$Id: TSQLStatement.cxx,v 1.3 2006/06/02 14:02:03 brun Exp $ +// @(#)root/net:$Name: $:$Id: TSQLStatement.cxx,v 1.4 2006/06/25 18:43:24 brun Exp $ // Author: Sergey Linev 6/02/2006 /************************************************************************* @@ -162,6 +162,40 @@ // } // } // +// 4. Working with date/time parameters +// ==================================== +// Current implementation supports date, time, date&time and timestamp +// data (all time intervals not supported yet). To set or get date/time values, +// following methods should be used: +// SetTime()/GetTime() - only time (hour:min:sec), +// SetDate()/GetDate() - only date (year-month-day), +// SetDatime()/GetDatime() - date and time +// SetTimestamp()/GetTimestamp() - timestamp with seconds fraction +// For some of these methods TDatime type can be used as parameter / return value. +// Be aware, that TDatime supports only dates after 1995-01-01. +// There are also methods to get separately year, month, day, hour, minutes and seconds. +// +// Different SQL databases has different treatement of date/time types. +// For instance, MySQL has all correspondent types (TIME, DATE, DATETIME and TIMESTAMP), +// Oracle native driver supports only DATE (which is actually date and time) and TIMESTAMP +// ODBC interface provides access for time, date and timestamps. +// Therefore, one should use correct methods to access such data. +// For instance, in MySQL SQL type 'DATE' is only date (one should use GetDate() to +// access such data), while in Oracle it is date and time. Therefore, +// to get complete data from 'DATE' column in Oracle, one should use GetDatime() method. +// +// The only difference of timestamp from date/time, that it has fractional +// seconds part. Be aware, that fractional part can has different meaning +// (actual value) in different SQL plugins. +// +// 5. Binary data +// ============== +// Most of modern data bases support just binary data, which is +// typically has SQL type name 'BLOB'. To access data in such +// columns, GetBinary()/SetBinary() methods should be used. +// Current implementation supposed, that complete content of the +// column must be retrieved at once. Therefore very big data of +// gigabytes size may cause a problem. // //////////////////////////////////////////////////////////////////////////////// @@ -209,3 +243,142 @@ void TSQLStatement::SetError(Int_t code, const char* msg, const char* method) if ((method!=0) && fErrorOut) Error(method,"Code: %d Msg: %s", code, (msg ? msg : "No message")); } + +//______________________________________________________________________________ +Bool_t TSQLStatement::SetDate(Int_t npar, const TDatime& tm) +{ + // set only date value for specified parameter from TDatime object + + return SetDate(npar, tm.GetYear(), tm.GetMonth(), tm.GetDay()); +} + +//______________________________________________________________________________ +Bool_t TSQLStatement::SetTime(Int_t npar, const TDatime& tm) +{ + // set only time value for specified parameter from TDatime object + + return SetTime(npar, tm.GetHour(), tm.GetMinute(), tm.GetSecond()); +} + +//______________________________________________________________________________ +Bool_t TSQLStatement::SetDatime(Int_t npar, const TDatime& tm) +{ + // set date & time value for specified parameter from TDatime object + + return SetDatime(npar, tm.GetYear(), tm.GetMonth(), tm.GetDay(), + tm.GetHour(), tm.GetMinute(), tm.GetSecond()); +} + +//______________________________________________________________________________ +Bool_t TSQLStatement::SetTimestamp(Int_t npar, const TDatime& tm) +{ + // set timestamp value for specified parameter from TDatime object + + return SetTimestamp(npar, tm.GetYear(), tm.GetMonth(), tm.GetDay(), + tm.GetHour(), tm.GetMinute(), tm.GetSecond(), 0); +} + +//______________________________________________________________________________ +TDatime TSQLStatement::GetDatime(Int_t npar) +{ + // return value of parameter in form of TDatime + // Be aware, that TDatime does not allow dates before 1995-01-01 + + Int_t year, month, day, hour, min, sec; + + if (!GetDatime(npar, year, month, day, hour, min, sec)) + return TDatime(); + + if (year<1995) { + SetError(-1, "Date before year 1995 does not supported by TDatime type", "GetDatime"); + return TDatime(); + } + + return TDatime(year, month, day, hour, min, sec); +} + +//______________________________________________________________________________ +Int_t TSQLStatement::GetYear(Int_t npar) +{ + // return year value for parameter (if applicable) + + Int_t year, month, day, hour, min, sec, frac; + if (GetDate(npar, year, month, day)) return year; + if (GetTimestamp(npar, year, month, day, hour, min, sec, frac)) return year; + return 0; +} + +//______________________________________________________________________________ +Int_t TSQLStatement::GetMonth(Int_t npar) +{ + // return month value for parameter (if applicable) + + Int_t year, month, day, hour, min, sec, frac; + if (GetDate(npar, year, month, day)) return month; + if (GetTimestamp(npar, year, month, day, hour, min, sec, frac)) return month; + return 0; +} + +//______________________________________________________________________________ +Int_t TSQLStatement::GetDay(Int_t npar) +{ + // return day value for parameter (if applicable) + + Int_t year, month, day, hour, min, sec, frac; + if (GetDate(npar, year, month, day)) return day; + if (GetTimestamp(npar, year, month, day, hour, min, sec, frac)) return day; + return 0; +} + +//______________________________________________________________________________ +Int_t TSQLStatement::GetHour(Int_t npar) +{ + // return hours value for parameter (if applicable) + + Int_t year, month, day, hour, min, sec, frac; + if (GetTime(npar, hour, min, sec)) return hour; + if (GetTimestamp(npar, year, month, day, hour, min, sec, frac)) return hour; + return 0; +} + +//______________________________________________________________________________ +Int_t TSQLStatement::GetMinute(Int_t npar) +{ + // return minutes value for parameter (if applicable) + + Int_t year, month, day, hour, min, sec, frac; + if (GetTime(npar, hour, min, sec)) return min; + if (GetTimestamp(npar, year, month, day, hour, min, sec, frac)) return min; + return 0; +} + +//______________________________________________________________________________ +Int_t TSQLStatement::GetSecond(Int_t npar) +{ + // return seconds value for parameter (if applicable) + + Int_t year, month, day, hour, min, sec, frac; + if (GetTime(npar, hour, min, sec)) return sec; + if (GetTimestamp(npar, year, month, day, hour, min, sec, frac)) return sec; + return 0; +} + +//______________________________________________________________________________ +TDatime TSQLStatement::GetTimestamp(Int_t npar) +{ + // return value of parameter in form of TDatime + // Be aware, that TDatime does not allow dates before 1995-01-01 + + Int_t year, month, day, hour, min, sec, frac; + + if (!GetTimestamp(npar, year, month, day, hour, min, sec, frac)) + return TDatime(); + + if (year<1995) { + SetError(-1, "Date before year 1995 does not supported by TDatime type", "GetTimestamp"); + return TDatime(); + } + + return TDatime(year, month, day, hour, min, sec); +} + diff --git a/odbc/inc/TODBCStatement.h b/odbc/inc/TODBCStatement.h index a2bf2b556e2..29ce32a2eeb 100644 --- a/odbc/inc/TODBCStatement.h +++ b/odbc/inc/TODBCStatement.h @@ -1,4 +1,4 @@ -// @(#)root/odbc:$Name: $:$Id: TODBCStatement.h,v 1.6 2006/06/02 14:02:03 brun Exp $ +// @(#)root/odbc:$Name: $:$Id: TODBCStatement.h,v 1.7 2006/06/25 18:43:24 brun Exp $ // Author: Sergey Linev 6/02/2006 /************************************************************************* @@ -92,6 +92,11 @@ public: virtual Bool_t SetULong64(Int_t npar, ULong64_t value); virtual Bool_t SetDouble(Int_t npar, Double_t value); virtual Bool_t SetString(Int_t npar, const char* value, Int_t maxsize = 256); + virtual Bool_t SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize = 0x1000); + virtual Bool_t SetDate(Int_t npar, Int_t year, Int_t month, Int_t day); + virtual Bool_t SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec); + virtual Bool_t SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec); + virtual Bool_t SetTimestamp(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec, Int_t frac = 0); virtual Bool_t NextIteration(); @@ -111,6 +116,11 @@ public: virtual ULong64_t GetULong64(Int_t npar); virtual Double_t GetDouble(Int_t npar); virtual const char *GetString(Int_t npar); + virtual Bool_t GetBinary(Int_t npar, void* &mem, Long_t& size); + virtual Bool_t GetDate(Int_t npar, Int_t& year, Int_t& month, Int_t& day); + virtual Bool_t GetTime(Int_t npar, Int_t& hour, Int_t& min, Int_t& sec); + virtual Bool_t GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec); + virtual Bool_t GetTimestamp(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec, Int_t&); ClassDef(TODBCStatement, 0); //ODBC implementation of TSQLStatement }; diff --git a/oracle/inc/TOracleStatement.h b/oracle/inc/TOracleStatement.h index dc9a6ea4fbc..55134212dcd 100644 --- a/oracle/inc/TOracleStatement.h +++ b/oracle/inc/TOracleStatement.h @@ -1,4 +1,4 @@ -// @(#)root/oracle:$Name: $:$Id: TOracleStatement.h,v 1.3 2006/06/02 14:02:03 brun Exp $ +// @(#)root/oracle:$Name: $:$Id: TOracleStatement.h,v 1.4 2006/06/25 18:43:24 brun Exp $ // Author: Sergey Linev 6/02/2006 /************************************************************************* @@ -20,6 +20,7 @@ #include <occi.h> using namespace oracle::occi; #else +class Environment; class Connection; class Statement; class ResultSet; @@ -32,9 +33,11 @@ protected: struct TBufferRec { char* strbuf; + Long_t strbufsize; char* namebuf; }; + Environment *fEnv; // enviroment Connection *fConn; // connection to Oracle Statement *fStmt; // executed statement ResultSet *fResult; // query result (rows) @@ -44,6 +47,7 @@ protected: Int_t fNumIterations; // size of internal statement buffer Int_t fIterCounter; //counts nextiteration calls and process iterations, if required Int_t fWorkingMode; // 1 - settingpars, 2 - getting results + TString fTimeFmt; // format for date to string conversion, default "MM/DD/YYYY, HH24:MI:SS" Bool_t IsParSettMode() const { return fWorkingMode==1; } Bool_t IsResultSet() const { return (fWorkingMode==2) && (fResult!=0); } @@ -52,7 +56,7 @@ protected: void CloseBuffer(); public: - TOracleStatement(Connection* conn, Statement* stmt, Int_t niter, Bool_t errout = kTRUE); + TOracleStatement(Environment* env, Connection* conn, Statement* stmt, Int_t niter, Bool_t errout = kTRUE); virtual ~TOracleStatement(); virtual void Close(Option_t * = ""); @@ -68,6 +72,12 @@ public: virtual Bool_t SetULong64(Int_t npar, ULong64_t value); virtual Bool_t SetDouble(Int_t npar, Double_t value); virtual Bool_t SetString(Int_t npar, const char* value, Int_t maxsize = 256); + virtual Bool_t SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize = 0x1000); + virtual Bool_t SetDate(Int_t npar, Int_t year, Int_t month, Int_t day); + virtual Bool_t SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec); + virtual Bool_t SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec); + virtual Bool_t SetTimestamp(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec, Int_t frac = 0); + virtual void SetTimeFormating(const char* fmt) { fTimeFmt = fmt; } virtual Bool_t NextIteration(); @@ -87,8 +97,13 @@ public: virtual ULong64_t GetULong64(Int_t npar); virtual Double_t GetDouble(Int_t npar); virtual const char *GetString(Int_t npar); + virtual Bool_t GetBinary(Int_t npar, void* &mem, Long_t& size); + virtual Bool_t GetDate(Int_t npar, Int_t& year, Int_t& month, Int_t& day); + virtual Bool_t GetTime(Int_t npar, Int_t& hour, Int_t& min, Int_t& sec); + virtual Bool_t GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec); + virtual Bool_t GetTimestamp(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec, Int_t& frac); - ClassDef(TOracleStatement, 0); // Statement class for Oracle + ClassDef(TOracleStatement, 0); // SQL statement class for Oracle }; #endif diff --git a/oracle/src/TOracleRow.cxx b/oracle/src/TOracleRow.cxx index d29a32ccea7..6b14de2b6e6 100644 --- a/oracle/src/TOracleRow.cxx +++ b/oracle/src/TOracleRow.cxx @@ -1,4 +1,4 @@ -// @(#)root/oracle:$Name: $:$Id: TOracleRow.cxx,v 1.4 2006/04/12 20:53:45 rdm Exp $ +// @(#)root/oracle:$Name: $:$Id: TOracleRow.cxx,v 1.5 2006/04/12 21:21:20 rdm Exp $ // Author: Yan Liu and Shaowen Wang 23/11/04 /************************************************************************* @@ -119,7 +119,7 @@ void TOracleRow::GetRowData() fDataType = (*fFieldInfo)[field].getInt(MetaData::ATTR_DATA_TYPE); switch (fDataType) { - case 2: //NUMBER + case SQLT_NUM: //NUMBER fPrecision = (*fFieldInfo)[field].getInt(MetaData::ATTR_PRECISION); fScale = (*fFieldInfo)[field].getInt(MetaData::ATTR_SCALE); @@ -132,14 +132,18 @@ void TOracleRow::GetRowData() } break; - case 1: // VARCHAR2 - case 12: // DATE - case 96: // CHAR + case SQLT_CHR: // character string + case SQLT_VCS: // variable character string + case SQLT_AFC: // ansi fixed char + case SQLT_AVC: // ansi var char res = fResult->getString(field+1); break; - case 187: // TIMESTAMP - case 188: // TIMESTAMP WITH TIMEZONE - case 232: // TIMESTAMP WITH LOCAL TIMEZONE + case SQLT_DAT: // Oracle native DATE type + res = (fResult->getDate(field+1)).toText("MM/DD/YYYY, HH24:MI:SS"); + break; + case SQLT_TIMESTAMP: // TIMESTAMP + case SQLT_TIMESTAMP_TZ: // TIMESTAMP WITH TIMEZONE + case SQLT_TIMESTAMP_LTZ: // TIMESTAMP WITH LOCAL TIMEZONE res = (fResult->getTimestamp(field+1)).toText("MM/DD/YYYY, HH24:MI:SS",0); break; default: diff --git a/oracle/src/TOracleServer.cxx b/oracle/src/TOracleServer.cxx index b438707b391..4e4c8b2957c 100644 --- a/oracle/src/TOracleServer.cxx +++ b/oracle/src/TOracleServer.cxx @@ -1,4 +1,4 @@ -// @(#)root/oracle:$Name: $:$Id: TOracleServer.cxx,v 1.12 2006/06/22 08:18:57 brun Exp $ +// @(#)root/oracle:$Name: $:$Id: TOracleServer.cxx,v 1.13 2006/06/25 18:43:24 brun Exp $ // Author: Yan Liu and Shaowen Wang 23/11/04 /************************************************************************* @@ -120,8 +120,10 @@ TSQLStatement *TOracleServer::Statement(const char *sql, Int_t niter) try { oracle::occi::Statement *stmt = fConn->createStatement(sql); - - return new TOracleStatement(fConn, stmt, niter, fErrorOut); + + Blob parblob(fConn); + + return new TOracleStatement(fEnv, fConn, stmt, niter, fErrorOut); } CatchError("Statement") diff --git a/oracle/src/TOracleStatement.cxx b/oracle/src/TOracleStatement.cxx index 484fcad05dd..ea747841d32 100644 --- a/oracle/src/TOracleStatement.cxx +++ b/oracle/src/TOracleStatement.cxx @@ -1,4 +1,4 @@ -// @(#)root/oracle:$Name: $:$Id: TOracleStatement.cxx,v 1.4 2006/06/22 08:18:57 brun Exp $ +// @(#)root/oracle:$Name: $:$Id: TOracleStatement.cxx,v 1.5 2006/06/25 18:43:24 brun Exp $ // Author: Sergey Linev 6/02/2006 @@ -24,8 +24,9 @@ ClassImp(TOracleStatement) //______________________________________________________________________________ -TOracleStatement::TOracleStatement(Connection* conn, Statement* stmt, Int_t niter, Bool_t errout) : +TOracleStatement::TOracleStatement(Environment* env, Connection* conn, Statement* stmt, Int_t niter, Bool_t errout) : TSQLStatement(errout), + fEnv(env), fConn(conn), fStmt(stmt), fResult(0), @@ -34,7 +35,8 @@ TOracleStatement::TOracleStatement(Connection* conn, Statement* stmt, Int_t nite fBufferSize(0), fNumIterations(niter), fIterCounter(0), - fWorkingMode(0) + fWorkingMode(0), + fTimeFmt("MM/DD/YYYY, HH24:MI:SS") { // Normal constructor of TOracleStatement class // On creation time specifies buffer length, which should be @@ -106,18 +108,18 @@ void TOracleStatement::Close(Option_t *) } \ } -#define CheckGetField(method) \ +#define CheckGetField(method, defres) \ { \ ClearError(); \ if (!IsResultSet()) { \ SetError(-1,"There is no result set for statement", method); \ - return 0; \ + return defres; \ } \ if ((npar<0) || (npar>=fBufferSize)) { \ TString errmsg("Invalid parameter number "); \ errmsg+= npar; \ SetError(-1,errmsg.Data(),method); \ - return 0; \ + return defres; \ } \ } @@ -133,6 +135,7 @@ void TOracleStatement::SetBufferSize(Int_t size) fBuffer = new TBufferRec[size]; for (Int_t n=0;n<fBufferSize;n++) { fBuffer[n].strbuf = 0; + fBuffer[n].strbufsize = -1; fBuffer[n].namebuf = 0; } } @@ -349,6 +352,111 @@ Bool_t TOracleStatement::SetString(Int_t npar, const char* value, Int_t maxsize) return kFALSE; } +//______________________________________________________________________________ +Bool_t TOracleStatement::SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize) +{ + // set parameter value as binary data + + CheckSetPar("SetBinary"); + + try { + + // this is when NextIteration is called first time + if (fIterCounter==1) + fStmt->setMaxParamSize(npar+1, maxsize); + + Bytes buf((unsigned char*) mem, size); + + fStmt->setBytes(npar+1, buf); + + return kTRUE; + + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetBinary"); + } + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::SetDate(Int_t npar, Int_t year, Int_t month, Int_t day) +{ + // Set date value for parameter npar + + CheckSetPar("SetDate"); + + try { + Date tm = fStmt->getDate(npar+1); + int o_year; + unsigned int o_month, o_day, o_hour, o_minute, o_second; + tm.getDate(o_year, o_month, o_day, o_hour, o_minute, o_second); + tm.setDate(year, month, day, o_hour, o_minute, o_second); + fStmt->setDate(npar+1, tm); + return kTRUE; + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetDate"); + } + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec) +{ + // Set time value for parameter npar + + CheckSetPar("SetTime"); + + try { + Date tm = fStmt->getDate(npar+1); + int o_year; + unsigned int o_month, o_day, o_hour, o_minute, o_second; + tm.getDate(o_year, o_month, o_day, o_hour, o_minute, o_second); + tm.setDate(o_year, o_month, o_day, hour, min, sec); + fStmt->setDate(npar+1, tm); + return kTRUE; + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetTime"); + } + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec) +{ + // Set date & time value for parameter npar + + CheckSetPar("SetDatime"); + + try { + Date tm(fEnv, year, month, day, hour, min, sec); + fStmt->setDate(npar+1, tm); + return kTRUE; + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetDatime"); + } + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::SetTimestamp(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec, Int_t frac) +{ + // Set date & time value for parameter npar + + CheckSetPar("SetTimestamp"); + + try { + Timestamp tm(fEnv, year, month, day, hour, min, sec, frac); + fStmt->setTimestamp(npar+1, tm); + return kTRUE; + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "SetTimestamp"); + } + + return kFALSE; +} + //______________________________________________________________________________ Bool_t TOracleStatement::NextIteration() { @@ -413,7 +521,7 @@ const char* TOracleStatement::GetFieldName(Int_t npar) { // Return field name in result set - CheckGetField("GetFieldName"); + CheckGetField("GetFieldName", 0); if (!IsResultSet() || (npar<0) || (npar>=fBufferSize)) return 0; @@ -446,11 +554,12 @@ Bool_t TOracleStatement::NextResultRow() if (fResult==0) return kFALSE; try { - for (int n=0;n<fBufferSize;n++) - if (fBuffer[n].strbuf) { + for (int n=0;n<fBufferSize;n++) { + if (fBuffer[n].strbuf) delete[] fBuffer[n].strbuf; - fBuffer[n].strbuf = 0; - } + fBuffer[n].strbuf = 0; + fBuffer[n].strbufsize = -1; + } if (!fResult->next()) { fWorkingMode = 0; CloseBuffer(); @@ -469,7 +578,7 @@ Bool_t TOracleStatement::IsNull(Int_t npar) { // Checks if fieled value in result set is NULL - CheckGetField("IsNull"); + CheckGetField("IsNull", kFALSE); try { return fResult->isNull(npar+1); @@ -485,7 +594,7 @@ Int_t TOracleStatement::GetInt(Int_t npar) { // return field value as integer - CheckGetField("GetInt"); + CheckGetField("GetInt", 0); Int_t res = 0; @@ -504,7 +613,7 @@ UInt_t TOracleStatement::GetUInt(Int_t npar) { // return field value as unsigned integer - CheckGetField("GetUInt"); + CheckGetField("GetUInt", 0); UInt_t res = 0; @@ -524,7 +633,7 @@ Long_t TOracleStatement::GetLong(Int_t npar) { // return field value as long integer - CheckGetField("GetLong"); + CheckGetField("GetLong", 0); Long_t res = 0; @@ -543,7 +652,7 @@ Long64_t TOracleStatement::GetLong64(Int_t npar) { // return field value as 64-bit integer - CheckGetField("GetLong64"); + CheckGetField("GetLong64", 0); Long64_t res = 0; @@ -562,7 +671,7 @@ ULong64_t TOracleStatement::GetULong64(Int_t npar) { // return field value as unsigned 64-bit integer - CheckGetField("GetULong64"); + CheckGetField("GetULong64", 0); ULong64_t res = 0; @@ -581,7 +690,7 @@ Double_t TOracleStatement::GetDouble(Int_t npar) { // return field value as double - CheckGetField("GetDouble"); + CheckGetField("GetDouble", 0.); Double_t res = 0; @@ -600,7 +709,7 @@ const char* TOracleStatement::GetString(Int_t npar) { // return field value as string - CheckGetField("GetString"); + CheckGetField("GetString", 0); if (fBuffer[npar].strbuf!=0) return fBuffer[npar].strbuf; @@ -612,7 +721,7 @@ const char* TOracleStatement::GetString(Int_t npar) std::string res; switch (datatype) { - case 2: { //NUMBER + case SQLT_NUM: { // oracle numeric NUMBER int prec = (*fFieldInfo)[npar].getInt(MetaData::ATTR_PRECISION); int scale = (*fFieldInfo)[npar].getInt(MetaData::ATTR_SCALE); @@ -626,25 +735,30 @@ const char* TOracleStatement::GetString(Int_t npar) } break; } - case 1: // VARCHAR2 - case 12: // DATE - case 96: // CHAR + case SQLT_CHR: // character string + case SQLT_VCS: // variable character string + case SQLT_AFC: // ansi fixed char + case SQLT_AVC: // ansi var char res = fResult->getString(npar+1); break; - case 187: // TIMESTAMP - case 188: // TIMESTAMP WITH TIMEZONE - case 232: // TIMESTAMP WITH LOCAL TIMEZONE - res = (fResult->getTimestamp(npar+1)).toText("MM/DD/YYYY, HH24:MI:SS",0); + case SQLT_DAT: // Oracle native DATE type + res = (fResult->getDate(npar+1)).toText(fTimeFmt.Data()); + break; + case SQLT_TIMESTAMP: // TIMESTAMP + case SQLT_TIMESTAMP_TZ: // TIMESTAMP WITH TIMEZONE + case SQLT_TIMESTAMP_LTZ: // TIMESTAMP WITH LOCAL TIMEZONE + res = (fResult->getTimestamp(npar+1)).toText(fTimeFmt.Data(), 0); break; default: res = fResult->getString(npar+1); - Info("getString","Type %d may not be supported"); + Info("getString","Type %d may not be supported", datatype); } int len = res.length(); if (len>0) { fBuffer[npar].strbuf = new char[len+1]; + fBuffer[npar].strbufsize = len+1; strcpy(fBuffer[npar].strbuf, res.c_str()); } @@ -656,3 +770,143 @@ const char* TOracleStatement::GetString(Int_t npar) return 0; } + +//______________________________________________________________________________ +Bool_t TOracleStatement::GetBinary(Int_t npar, void* &mem, Long_t& size) +{ + // Return field value as binary array + + mem = 0; + size = 0; + + CheckGetField("GetBinary", kFALSE); + + if (fBuffer[npar].strbufsize>=0) { + mem = fBuffer[npar].strbuf; + size = fBuffer[npar].strbufsize; + return kTRUE; + } + + try { + if (fResult->isNull(npar+1)) return kTRUE; + + Blob parblob = fResult->getBlob(npar+1); + + parblob.open(OCCI_LOB_READONLY); + + size = parblob.length(); + + fBuffer[npar].strbufsize = size; + + if (size>0) { + mem = malloc(size); + + fBuffer[npar].strbuf = (char*) mem; + + Stream* parstream = parblob.getStream(); + + char* buf = (char*) mem; + + /*int len = */ parstream->readBuffer(buf, size); + + parblob.closeStream(parstream); + } + + parblob.close(); + + return kTRUE; + + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetBinary"); + } + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::GetDate(Int_t npar, Int_t& year, Int_t& month, Int_t& day) +{ + // return field value as date + + Int_t hour, min, sec; + + return GetDatime(npar, year, month, day, hour, min, sec); +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::GetTime(Int_t npar, Int_t& hour, Int_t& min, Int_t& sec) +{ + // return field value as time + + Int_t year, month, day; + + return GetDatime(npar, year, month, day, hour, min, sec); +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec) +{ + // return field value as date & time + + CheckGetField("GetDatime", kFALSE); + + try { + if (!fResult->isNull(npar+1)) { + int datatype = (*fFieldInfo)[npar].getInt(MetaData::ATTR_DATA_TYPE); + + if (datatype!=SQLT_DAT) return kFALSE; + + Date tm = fResult->getDate(npar+1); + int o_year; + unsigned int o_month, o_day, o_hour, o_minute, o_second; + tm.getDate(o_year, o_month, o_day, o_hour, o_minute, o_second); + year = (Int_t) o_year; + month = (Int_t) o_month; + day = (Int_t) o_day; + hour = (Int_t) o_hour; + min = (Int_t) o_minute; + sec = (Int_t) o_second; + return kTRUE; + } + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetDatime"); + } + + return kFALSE; +} + +//______________________________________________________________________________ +Bool_t TOracleStatement::GetTimestamp(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec, Int_t& frac) +{ + // return field value as date & time + + CheckGetField("GetTimestamp", kFALSE); + + try { + if (!fResult->isNull(npar+1)) { + int datatype = (*fFieldInfo)[npar].getInt(MetaData::ATTR_DATA_TYPE); + + if ((datatype!=SQLT_TIMESTAMP) && + (datatype!=SQLT_TIMESTAMP_TZ) && + (datatype!=SQLT_TIMESTAMP_LTZ)) return kFALSE; + + Timestamp tm = fResult->getTimestamp(npar+1); + int o_year; + unsigned int o_month, o_day, o_hour, o_minute, o_second, o_frac; + tm.getDate(o_year, o_month, o_day); + tm.getTime(o_hour, o_minute, o_second, o_frac); + year = (Int_t) o_year; + month = (Int_t) o_month; + day = (Int_t) o_day; + hour = (Int_t) o_hour; + min = (Int_t) o_minute; + sec = (Int_t) o_second; + frac = (Int_t) o_frac; + return kTRUE; + } + } catch (SQLException &oraex) { + SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), "GetTimestamp"); + } + + return kFALSE; +} -- GitLab