00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "TODBCStatement.h"
00023 #include "TODBCServer.h"
00024 #include "TDataType.h"
00025 #include "Riostream.h"
00026
00027 #include <sqlext.h>
00028 #include <stdlib.h>
00029
00030 #define kSqlTime 123781
00031 #define kSqlDate 123782
00032 #define kSqlTimestamp 123783
00033 #define kSqlBinary 123784
00034
00035
00036 ClassImp(TODBCStatement)
00037
00038
00039 TODBCStatement::TODBCStatement(SQLHSTMT stmt, Int_t rowarrsize, Bool_t errout) :
00040 TSQLStatement(errout)
00041 {
00042
00043
00044 fHstmt = stmt;
00045 fBufferPreferredSize = rowarrsize;
00046
00047 fBuffer = 0;
00048 fStatusBuffer = 0;
00049 fNumBuffers = 0;
00050 fBufferLength = 0;
00051 fBufferCounter = 0;
00052
00053 fWorkingMode = 0;
00054
00055 fNumParsProcessed = 0;
00056 fNumRowsFetched = 0;
00057
00058 SQLSMALLINT paramsCount = 0;
00059 SQLRETURN retcode = SQLNumParams(fHstmt, ¶msCount);
00060 if (ExtractErrors(retcode,"Constructor"))
00061 paramsCount = 0;
00062
00063 if (paramsCount>0) {
00064
00065 fWorkingMode = 1;
00066 fNumParsProcessed = 0;
00067
00068 SQLSetStmtAttr(fHstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
00069
00070 SQLUINTEGER setsize = fBufferPreferredSize;
00071 retcode = SQLSetStmtAttr(fHstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) setsize, 0);
00072 ExtractErrors(retcode,"Constructor");
00073
00074 SQLUINTEGER getsize = 0;
00075
00076 retcode = SQLGetStmtAttr(fHstmt, SQL_ATTR_PARAMSET_SIZE, &getsize, 0, 0);
00077 ExtractErrors(retcode,"Constructor");
00078
00079 Int_t bufferlen = fBufferPreferredSize;
00080
00081
00082 if (getsize<=1) bufferlen=1; else
00083 if (getsize!=setsize) {
00084 SQLSetStmtAttr(fHstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) 1, 0);
00085 bufferlen = 1;
00086 }
00087
00088 SetNumBuffers(paramsCount, bufferlen);
00089
00090 SQLSetStmtAttr(fHstmt, SQL_ATTR_PARAM_STATUS_PTR, fStatusBuffer, 0);
00091 SQLSetStmtAttr(fHstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &fNumParsProcessed, 0);
00092
00093
00094 fBufferCounter = -1;
00095 }
00096
00097 fNumRowsFetched = 0;
00098 fLastResultRow = 0;
00099 }
00100
00101
00102 TODBCStatement::~TODBCStatement()
00103 {
00104
00105
00106 Close();
00107 }
00108
00109
00110 void TODBCStatement::Close(Option_t *)
00111 {
00112
00113
00114 FreeBuffers();
00115
00116 SQLFreeHandle(SQL_HANDLE_STMT, fHstmt);
00117
00118 fHstmt=0;
00119 }
00120
00121
00122 Bool_t TODBCStatement::Process()
00123 {
00124
00125
00126 ClearError();
00127
00128 SQLRETURN retcode = SQL_SUCCESS;
00129
00130 if (IsParSettMode()) {
00131
00132
00133 if (fBufferCounter>=0) {
00134
00135 if ((fBufferCounter>0) && (fBufferCounter<fBufferLength-1)) {
00136 SQLUINTEGER setsize = fBufferCounter+1;
00137 SQLSetStmtAttr(fHstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) setsize, 0);
00138 }
00139 retcode = SQLExecute(fHstmt);
00140 }
00141
00142
00143
00144 fWorkingMode = 0;
00145 FreeBuffers();
00146 fBufferCounter = -1;
00147 } else {
00148
00149
00150
00151 retcode = SQLExecute(fHstmt);
00152 }
00153
00154 return !ExtractErrors(retcode, "Process");
00155 }
00156
00157
00158 Int_t TODBCStatement::GetNumAffectedRows()
00159 {
00160
00161
00162 ClearError();
00163
00164 SQLLEN rowCount;
00165 SQLRETURN retcode = SQL_SUCCESS;
00166
00167 retcode = SQLRowCount(fHstmt, &rowCount);
00168
00169 if (ExtractErrors(retcode, "GetNumAffectedRows")) return -1;
00170
00171 return rowCount;
00172 }
00173
00174
00175 Bool_t TODBCStatement::StoreResult()
00176 {
00177
00178
00179
00180
00181 ClearError();
00182
00183 if (IsParSettMode()) {
00184 SetError(-1,"Call Process() method before","StoreResult");
00185 return kFALSE;
00186 }
00187
00188 FreeBuffers();
00189
00190 SQLSMALLINT columnCount = 0;
00191
00192 SQLRETURN retcode = SQLNumResultCols(fHstmt, &columnCount);
00193 if (ExtractErrors(retcode, "StoreResult")) return kFALSE;
00194
00195 if (columnCount==0) return kFALSE;
00196
00197 SetNumBuffers(columnCount, fBufferPreferredSize);
00198
00199 SQLULEN arrsize = fBufferLength;
00200
00201 SQLSetStmtAttr(fHstmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);
00202 SQLSetStmtAttr(fHstmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) arrsize, 0);
00203 SQLSetStmtAttr(fHstmt, SQL_ATTR_ROW_STATUS_PTR, fStatusBuffer, 0);
00204 SQLSetStmtAttr(fHstmt, SQL_ATTR_ROWS_FETCHED_PTR, &fNumRowsFetched, 0);
00205
00206 for (int n=0;n<fNumBuffers;n++) {
00207 SQLCHAR columnName[1024];
00208 SQLSMALLINT nameLength;
00209 SQLSMALLINT dataType;
00210 SQLULEN columnSize;
00211 SQLSMALLINT decimalDigits;
00212 SQLSMALLINT nullable;
00213
00214 retcode = SQLDescribeCol(fHstmt, n+1, columnName, 1024,
00215 &nameLength, &dataType,
00216 &columnSize, &decimalDigits, &nullable);
00217
00218 BindColumn(n, dataType, columnSize);
00219
00220 if (nameLength>0) {
00221 fBuffer[n].fBnamebuffer = new char[nameLength+1];
00222 strcpy(fBuffer[n].fBnamebuffer, (const char*) columnName);
00223 }
00224 }
00225
00226 fNumRowsFetched = 0;
00227 fLastResultRow = 0;
00228
00229 fWorkingMode = 2;
00230
00231 return kTRUE;
00232 }
00233
00234
00235 Int_t TODBCStatement::GetNumFields()
00236 {
00237
00238
00239 return IsResultSet() ? fNumBuffers : -1;
00240 }
00241
00242
00243 const char* TODBCStatement::GetFieldName(Int_t nfield)
00244 {
00245
00246
00247 ClearError();
00248
00249 if (!IsResultSet() || (nfield<0) || (nfield>=fNumBuffers)) return 0;
00250
00251 return fBuffer[nfield].fBnamebuffer;
00252 }
00253
00254
00255
00256 Bool_t TODBCStatement::NextResultRow()
00257 {
00258
00259
00260 ClearError();
00261
00262 if (!IsResultSet()) return kFALSE;
00263
00264 if ((fNumRowsFetched==0) ||
00265 (1.*fBufferCounter >= 1.*(fNumRowsFetched-1))) {
00266
00267 fBufferCounter = 0;
00268 fNumRowsFetched = 0;
00269
00270 SQLRETURN retcode = SQLFetchScroll(fHstmt, SQL_FETCH_NEXT, 0);
00271 if (retcode==SQL_NO_DATA) fNumRowsFetched=0; else
00272 ExtractErrors(retcode,"NextResultRow");
00273
00274
00275
00276
00277 if (!IsError() && (retcode!=SQL_NO_DATA) && (fNumRowsFetched==0)) {
00278 SQLULEN rownumber = 0;
00279 SQLRETURN retcode2 = SQLGetStmtAttr(fHstmt, SQL_ATTR_ROW_NUMBER, &rownumber, 0, 0);
00280 ExtractErrors(retcode2, "NextResultRow");
00281
00282 if (!IsError()) {
00283 fNumRowsFetched = rownumber - fLastResultRow;
00284 fLastResultRow = rownumber;
00285 }
00286 }
00287
00288 if (1.*fNumRowsFetched>fBufferLength)
00289 SetError(-1, "Missmatch between buffer length and fetched rows number", "NextResultRow");
00290
00291 if (IsError() || (fNumRowsFetched==0)) {
00292 fWorkingMode = 0;
00293 FreeBuffers();
00294 }
00295
00296 } else
00297 fBufferCounter++;
00298
00299 return IsResultSet();
00300 }
00301
00302
00303 Bool_t TODBCStatement::ExtractErrors(SQLRETURN retcode, const char* method)
00304 {
00305
00306
00307 if ((retcode== SQL_SUCCESS) || (retcode == SQL_SUCCESS_WITH_INFO)) return kFALSE;
00308
00309 SQLINTEGER i = 0;
00310 SQLINTEGER native;
00311 SQLCHAR state[ 7 ];
00312 SQLCHAR text[256];
00313 SQLSMALLINT len;
00314 SQLRETURN ret;
00315 do {
00316 ret = SQLGetDiagRec(SQL_HANDLE_STMT, fHstmt, ++i, state, &native, text,
00317 sizeof(text), &len );
00318 if (ret == SQL_SUCCESS) SetError(native, (const char*) text, method);
00319
00320 }
00321 while( ret == SQL_SUCCESS );
00322 return kTRUE;
00323 }
00324
00325
00326 Bool_t TODBCStatement::NextIteration()
00327 {
00328
00329
00330 ClearError();
00331
00332 if (!IsParSettMode() || (fBuffer==0) || (fBufferLength<=0)) return kFALSE;
00333
00334 if (fBufferCounter>=fBufferLength-1) {
00335 SQLRETURN retcode = SQLExecute(fHstmt);
00336 if (ExtractErrors(retcode,"NextIteration")) return kFALSE;
00337 fBufferCounter = 0;
00338 } else
00339 fBufferCounter++;
00340
00341
00342 fStatusBuffer[fBufferCounter] = SQL_ROW_SUCCESS;
00343
00344 return kTRUE;
00345 }
00346
00347
00348 Int_t TODBCStatement::GetNumParameters()
00349 {
00350
00351
00352 return IsParSettMode() ? fNumBuffers : 0;
00353 }
00354
00355
00356 void TODBCStatement::SetNumBuffers(Int_t isize, Int_t ilen)
00357 {
00358
00359
00360 FreeBuffers();
00361
00362 fNumBuffers = isize;
00363 fBufferLength = ilen;
00364 fBufferCounter = 0;
00365
00366 fBuffer = new ODBCBufferRec_t[fNumBuffers];
00367 for (Int_t n=0;n<fNumBuffers;n++) {
00368 fBuffer[n].fBroottype = 0;
00369 fBuffer[n].fBsqltype = 0;
00370 fBuffer[n].fBsqlctype = 0;
00371 fBuffer[n].fBbuffer = 0;
00372 fBuffer[n].fBelementsize = 0;
00373 fBuffer[n].fBlenarray = 0;
00374 fBuffer[n].fBstrbuffer = 0;
00375 fBuffer[n].fBnamebuffer = 0;
00376 }
00377
00378 fStatusBuffer = new SQLUSMALLINT[fBufferLength];
00379 }
00380
00381
00382 void TODBCStatement::FreeBuffers()
00383 {
00384
00385
00386 if (fBuffer==0) return;
00387 for (Int_t n=0;n<fNumBuffers;n++) {
00388 if (fBuffer[n].fBbuffer!=0)
00389 free(fBuffer[n].fBbuffer);
00390 delete[] fBuffer[n].fBlenarray;
00391 delete[] fBuffer[n].fBstrbuffer;
00392 delete[] fBuffer[n].fBnamebuffer;
00393 }
00394
00395 delete[] fStatusBuffer;
00396 delete[] fBuffer;
00397 fBuffer = 0;
00398 fNumBuffers = 0;
00399 fBufferLength = 0;
00400 fStatusBuffer = 0;
00401 }
00402
00403
00404 Bool_t TODBCStatement::BindColumn(Int_t ncol, SQLSMALLINT sqltype, SQLUINTEGER size)
00405 {
00406
00407
00408 ClearError();
00409
00410 if ((ncol<0) || (ncol>=fNumBuffers)) {
00411 SetError(-1,"Internal error. Column number invalid","BindColumn");
00412 return kFALSE;
00413 }
00414
00415 if (fBuffer[ncol].fBsqltype!=0) {
00416 SetError(-1,"Internal error. Bind for column already done","BindColumn");
00417 return kFALSE;
00418 }
00419
00420 SQLSMALLINT sqlctype = 0;
00421 switch (sqltype) {
00422 case SQL_CHAR:
00423 case SQL_VARCHAR: sqlctype = SQL_C_CHAR; break;
00424 case SQL_BINARY:
00425 case SQL_LONGVARBINARY:
00426 case SQL_VARBINARY: sqlctype = SQL_C_BINARY; break;
00427 case SQL_LONGVARCHAR: Info("BindColumn","BIG VARCHAR not supported yet"); return kFALSE; break;
00428
00429 case SQL_DECIMAL: sqlctype = SQL_C_DOUBLE; break;
00430 case SQL_NUMERIC: sqlctype = SQL_C_DOUBLE; break;
00431 case SQL_SMALLINT: sqlctype = SQL_C_SLONG; break;
00432 case SQL_INTEGER: sqlctype = SQL_C_SLONG; break;
00433 case SQL_FLOAT: sqlctype = SQL_C_FLOAT; break;
00434 case SQL_REAL:
00435 case SQL_DOUBLE: sqlctype = SQL_C_DOUBLE; break;
00436 case SQL_TINYINT: sqlctype = SQL_C_STINYINT; break;
00437 case SQL_BIGINT: sqlctype = SQL_C_SBIGINT; break;
00438 case SQL_TYPE_DATE: sqlctype = SQL_C_TYPE_DATE; break;
00439 case SQL_TYPE_TIME: sqlctype = SQL_C_TYPE_TIME; break;
00440 case SQL_TYPE_TIMESTAMP: sqlctype = SQL_C_TYPE_TIMESTAMP; break;
00441 default: {
00442 SetError(-1, Form("SQL type %d not supported",sqltype), "BindColumn");
00443 return kFALSE;
00444 }
00445 }
00446
00447 int elemsize = 0;
00448
00449 switch (sqlctype) {
00450 case SQL_C_ULONG: elemsize = sizeof(SQLUINTEGER); break;
00451 case SQL_C_SLONG: elemsize = sizeof(SQLINTEGER); break;
00452 case SQL_C_UBIGINT: elemsize = sizeof(ULong64_t); break;
00453 case SQL_C_SBIGINT: elemsize = sizeof(Long64_t); break;
00454 case SQL_C_USHORT: elemsize = sizeof(SQLUSMALLINT); break;
00455 case SQL_C_SSHORT: elemsize = sizeof(SQLSMALLINT); break;
00456 case SQL_C_UTINYINT: elemsize = sizeof(SQLCHAR); break;
00457 case SQL_C_STINYINT: elemsize = sizeof(SQLSCHAR); break;
00458 case SQL_C_FLOAT: elemsize = sizeof(SQLREAL); break;
00459 case SQL_C_DOUBLE: elemsize = sizeof(SQLDOUBLE); break;
00460 case SQL_C_CHAR: elemsize = size; break;
00461 case SQL_C_BINARY: elemsize = size; break;
00462 case SQL_C_TYPE_DATE: elemsize = sizeof(DATE_STRUCT); break;
00463 case SQL_C_TYPE_TIME: elemsize = sizeof(TIME_STRUCT); break;
00464 case SQL_C_TYPE_TIMESTAMP: elemsize = sizeof(TIMESTAMP_STRUCT); break;
00465
00466 default: {
00467 SetError(-1, Form("SQL C Type %d is not supported",sqlctype), "BindColumn");
00468 return kFALSE;
00469 }
00470 }
00471
00472 fBuffer[ncol].fBroottype = 0;
00473 fBuffer[ncol].fBsqltype = sqltype;
00474 fBuffer[ncol].fBsqlctype = sqlctype;
00475 fBuffer[ncol].fBbuffer = malloc(elemsize * fBufferLength);
00476 fBuffer[ncol].fBelementsize = elemsize;
00477 fBuffer[ncol].fBlenarray = new SQLLEN[fBufferLength];
00478
00479 SQLRETURN retcode =
00480 SQLBindCol(fHstmt, ncol+1, sqlctype, fBuffer[ncol].fBbuffer,
00481 elemsize,
00482 fBuffer[ncol].fBlenarray);
00483
00484 return !ExtractErrors(retcode, "BindColumn");
00485 }
00486
00487
00488 Bool_t TODBCStatement::BindParam(Int_t npar, Int_t roottype, Int_t size)
00489 {
00490
00491
00492 ClearError();
00493
00494 if ((npar<0) || (npar>=fNumBuffers)) return kFALSE;
00495
00496 if (fBuffer[npar].fBroottype!=0) {
00497 SetError(-1,Form("ParameterType for par %d already specified", npar),"BindParam");
00498 return kFALSE;
00499 }
00500
00501 SQLSMALLINT sqltype = 0, sqlctype = 0;
00502 int elemsize = 0;
00503
00504 switch (roottype) {
00505 case kUInt_t: sqltype = SQL_INTEGER; sqlctype = SQL_C_ULONG; elemsize = sizeof(SQLUINTEGER); break;
00506 case kInt_t: sqltype = SQL_INTEGER; sqlctype = SQL_C_SLONG; elemsize = sizeof(SQLINTEGER); break;
00507 case kULong_t: sqltype = SQL_INTEGER; sqlctype = SQL_C_ULONG; elemsize = sizeof(SQLUINTEGER); break;
00508 case kLong_t: sqltype = SQL_INTEGER; sqlctype = SQL_C_SLONG; elemsize = sizeof(SQLINTEGER); break;
00509
00510
00511
00512 case kULong64_t: sqltype = SQL_BIGINT; sqlctype = SQL_C_UBIGINT; elemsize = sizeof(ULong64_t); break;
00513 case kLong64_t: sqltype = SQL_BIGINT; sqlctype = SQL_C_SBIGINT; elemsize = sizeof(Long64_t); break;
00514
00515 case kUShort_t: sqltype = SQL_SMALLINT;sqlctype = SQL_C_USHORT; elemsize = sizeof(SQLUSMALLINT); break;
00516 case kShort_t: sqltype = SQL_SMALLINT;sqlctype = SQL_C_SSHORT; elemsize = sizeof(SQLSMALLINT); break;
00517 case kUChar_t: sqltype = SQL_TINYINT; sqlctype = SQL_C_UTINYINT; elemsize = sizeof(SQLCHAR); break;
00518 case kChar_t: sqltype = SQL_TINYINT; sqlctype = SQL_C_STINYINT; elemsize = sizeof(SQLSCHAR); break;
00519 case kBool_t: sqltype = SQL_TINYINT; sqlctype = SQL_C_UTINYINT; elemsize = sizeof(SQLCHAR); break;
00520 case kFloat_t: sqltype = SQL_FLOAT; sqlctype = SQL_C_FLOAT; elemsize = sizeof(SQLREAL); break;
00521 case kFloat16_t: sqltype = SQL_FLOAT; sqlctype = SQL_C_FLOAT; elemsize = sizeof(SQLREAL); break;
00522 case kDouble_t: sqltype = SQL_DOUBLE; sqlctype = SQL_C_DOUBLE; elemsize = sizeof(SQLDOUBLE); break;
00523 case kDouble32_t: sqltype = SQL_DOUBLE; sqlctype = SQL_C_DOUBLE; elemsize = sizeof(SQLDOUBLE); break;
00524 case kCharStar: sqltype = SQL_CHAR; sqlctype = SQL_C_CHAR; elemsize = size; break;
00525 case kSqlBinary: sqltype = SQL_BINARY; sqlctype = SQL_C_BINARY; elemsize = size; break;
00526 case kSqlDate: sqltype = SQL_TYPE_DATE; sqlctype = SQL_C_TYPE_DATE; elemsize = sizeof(DATE_STRUCT); break;
00527 case kSqlTime: sqltype = SQL_TYPE_TIME; sqlctype = SQL_C_TYPE_TIME; elemsize = sizeof(TIME_STRUCT); break;
00528 case kSqlTimestamp: sqltype = SQL_TYPE_TIMESTAMP; sqlctype = SQL_C_TYPE_TIMESTAMP; elemsize = sizeof(TIMESTAMP_STRUCT); break;
00529 default: {
00530 SetError(-1, Form("Root type %d is not supported", roottype), "BindParam");
00531 return kFALSE;
00532 }
00533 }
00534
00535 void* buffer = malloc(elemsize * fBufferLength);
00536 SQLLEN* lenarray = new SQLLEN[fBufferLength];
00537 SQLRETURN retcode =
00538 SQLBindParameter(fHstmt, npar+1, SQL_PARAM_INPUT,
00539 sqlctype, sqltype, 0, 0,
00540 buffer, elemsize, lenarray);
00541
00542 if (ExtractErrors(retcode, "BindParam")) {
00543 free(buffer);
00544 delete[] lenarray;
00545 return kFALSE;
00546 }
00547
00548 fBuffer[npar].fBroottype = roottype;
00549 fBuffer[npar].fBsqlctype = sqlctype;
00550 fBuffer[npar].fBsqltype = sqltype;
00551 fBuffer[npar].fBbuffer = buffer;
00552 fBuffer[npar].fBelementsize = elemsize;
00553 fBuffer[npar].fBlenarray = lenarray;
00554
00555 return kTRUE;
00556 }
00557
00558
00559 void* TODBCStatement::GetParAddr(Int_t npar, Int_t roottype, Int_t length)
00560 {
00561
00562
00563 ClearError();
00564
00565 if ((fBuffer==0) || (npar<0) || (npar>=fNumBuffers) || (fBufferCounter<0)) {
00566 SetError(-1, "Invalid parameter number","GetParAddr");
00567 return 0;
00568 }
00569
00570 if (fBuffer[npar].fBbuffer==0) {
00571 if (IsParSettMode() && (roottype!=0) && (fBufferCounter==0))
00572 if (!BindParam(npar, roottype, length)) return 0;
00573
00574 if (fBuffer[npar].fBbuffer==0) return 0;
00575 }
00576
00577 if (roottype!=0)
00578 if (fBuffer[npar].fBroottype!=roottype) return 0;
00579
00580 return (char*)fBuffer[npar].fBbuffer + fBufferCounter*fBuffer[npar].fBelementsize;
00581 }
00582
00583
00584 long double TODBCStatement::ConvertToNumeric(Int_t npar)
00585 {
00586
00587 void* addr = GetParAddr(npar);
00588 if (addr==0) return 0;
00589
00590 switch (fBuffer[npar].fBsqlctype) {
00591 case SQL_C_ULONG: return *((SQLUINTEGER*) addr); break;
00592 case SQL_C_SLONG: return *((SQLINTEGER*) addr); break;
00593 case SQL_C_UBIGINT: return *((ULong64_t*) addr); break;
00594 case SQL_C_SBIGINT: return *((Long64_t*) addr); break;
00595 case SQL_C_USHORT: return *((SQLUSMALLINT*) addr); break;
00596 case SQL_C_SSHORT: return *((SQLSMALLINT*) addr); break;
00597 case SQL_C_UTINYINT: return *((SQLCHAR*) addr); break;
00598 case SQL_C_STINYINT: return *((SQLSCHAR*) addr); break;
00599 case SQL_C_FLOAT: return *((SQLREAL*) addr); break;
00600 case SQL_C_DOUBLE: return *((SQLDOUBLE*) addr); break;
00601 case SQL_C_TYPE_DATE: {
00602 DATE_STRUCT* dt = (DATE_STRUCT*) addr;
00603 TDatime rtm(dt->year, dt->month, dt->day, 0, 0, 0);
00604 return rtm.GetDate();
00605 break;
00606 }
00607 case SQL_C_TYPE_TIME: {
00608 TIME_STRUCT* tm = (TIME_STRUCT*) addr;
00609 TDatime rtm(2000, 1, 1, tm->hour, tm->minute, tm->second);
00610 return rtm.GetTime();
00611 break;
00612 }
00613 case SQL_C_TYPE_TIMESTAMP: {
00614 TIMESTAMP_STRUCT* tm = (TIMESTAMP_STRUCT*) addr;
00615 TDatime rtm(tm->year, tm->month, tm->day,
00616 tm->hour, tm->minute, tm->second);
00617 return rtm.Get();
00618 break;
00619 }
00620 }
00621 return 0;
00622 }
00623
00624
00625 const char* TODBCStatement::ConvertToString(Int_t npar)
00626 {
00627
00628 void* addr = GetParAddr(npar);
00629 if (addr==0) return 0;
00630 if (fBuffer[npar].fBstrbuffer==0)
00631 fBuffer[npar].fBstrbuffer = new char[100];
00632
00633 char* buf = fBuffer[npar].fBstrbuffer;
00634
00635 switch(fBuffer[npar].fBsqlctype) {
00636 #if (SIZEOF_LONG == 8)
00637 case SQL_C_SLONG: snprintf(buf, 100, "%d", *((SQLINTEGER*) addr)); break;
00638 case SQL_C_ULONG: snprintf(buf, 100, "%u", *((SQLUINTEGER*) addr)); break;
00639 #else
00640 case SQL_C_SLONG: snprintf(buf, 100, "%ld", *((SQLINTEGER*) addr)); break;
00641 case SQL_C_ULONG: snprintf(buf, 100, "%lu", *((SQLUINTEGER*) addr)); break;
00642 #endif
00643 case SQL_C_SBIGINT: snprintf(buf, 100, "%lld", *((Long64_t*) addr)); break;
00644 case SQL_C_UBIGINT: snprintf(buf, 100, "%llu", *((ULong64_t*) addr)); break;
00645 case SQL_C_SSHORT: snprintf(buf, 100, "%hd", *((SQLSMALLINT*) addr)); break;
00646 case SQL_C_USHORT: snprintf(buf, 100, "%hu", *((SQLUSMALLINT*) addr)); break;
00647 case SQL_C_STINYINT:snprintf(buf, 100, "%d", *((SQLSCHAR*) addr)); break;
00648 case SQL_C_UTINYINT:snprintf(buf, 100, "%u", *((SQLCHAR*) addr)); break;
00649 case SQL_C_FLOAT: snprintf(buf, 100, TSQLServer::GetFloatFormat(), *((SQLREAL*) addr)); break;
00650 case SQL_C_DOUBLE: snprintf(buf, 100, TSQLServer::GetFloatFormat(), *((SQLDOUBLE*) addr)); break;
00651 case SQL_C_TYPE_DATE: {
00652 DATE_STRUCT* dt = (DATE_STRUCT*) addr;
00653 snprintf(buf,100,"%4.4d-%2.2d-%2.2d",
00654 dt->year, dt->month, dt->day);
00655 break;
00656 }
00657 case SQL_C_TYPE_TIME: {
00658 TIME_STRUCT* tm = (TIME_STRUCT*) addr;
00659 snprintf(buf,100,"%2.2d:%2.2d:%2.2d",
00660 tm->hour, tm->minute, tm->second);
00661 break;
00662 }
00663 case SQL_C_TYPE_TIMESTAMP: {
00664 TIMESTAMP_STRUCT* tm = (TIMESTAMP_STRUCT*) addr;
00665 snprintf(buf,100,"%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
00666 tm->year, tm->month, tm->day,
00667 tm->hour, tm->minute, tm->second);
00668 break;
00669 }
00670 default: return 0;
00671 }
00672
00673 return buf;
00674 }
00675
00676
00677 Bool_t TODBCStatement::IsNull(Int_t npar)
00678 {
00679
00680
00681 void* addr = GetParAddr(npar);
00682 if (addr==0) return kTRUE;
00683
00684 return fBuffer[npar].fBlenarray[fBufferCounter] == SQL_NULL_DATA;
00685 }
00686
00687
00688 Int_t TODBCStatement::GetInt(Int_t npar)
00689 {
00690
00691 void* addr = GetParAddr(npar);
00692 if (addr==0) return 0;
00693
00694 if (fBuffer[npar].fBsqlctype==SQL_C_SLONG)
00695 return (Int_t) *((SQLINTEGER*) addr);
00696
00697 return (Int_t) ConvertToNumeric(npar);
00698 }
00699
00700
00701 UInt_t TODBCStatement::GetUInt(Int_t npar)
00702 {
00703
00704 void* addr = GetParAddr(npar);
00705 if (addr==0) return 0;
00706
00707 if (fBuffer[npar].fBsqlctype==SQL_C_ULONG)
00708 return (UInt_t) *((SQLUINTEGER*) addr);
00709
00710 return (UInt_t) ConvertToNumeric(npar);
00711 }
00712
00713
00714 Long_t TODBCStatement::GetLong(Int_t npar)
00715 {
00716
00717 void* addr = GetParAddr(npar);
00718 if (addr==0) return 0;
00719
00720 if (fBuffer[npar].fBsqlctype==SQL_C_SLONG)
00721 return (Long_t) *((SQLINTEGER*) addr);
00722
00723 return (Long_t) ConvertToNumeric(npar);
00724 }
00725
00726
00727 Long64_t TODBCStatement::GetLong64(Int_t npar)
00728 {
00729
00730 void* addr = GetParAddr(npar);
00731 if (addr==0) return 0;
00732
00733 if (fBuffer[npar].fBsqlctype==SQL_C_SBIGINT)
00734 return *((Long64_t*) addr);
00735
00736 return (Long64_t) ConvertToNumeric(npar);
00737 }
00738
00739
00740 ULong64_t TODBCStatement::GetULong64(Int_t npar)
00741 {
00742
00743 void* addr = GetParAddr(npar);
00744 if (addr==0) return 0;
00745
00746 if (fBuffer[npar].fBsqlctype==SQL_C_UBIGINT)
00747 return *((ULong64_t*) addr);
00748
00749 return (ULong64_t) ConvertToNumeric(npar);
00750 }
00751
00752
00753 Double_t TODBCStatement::GetDouble(Int_t npar)
00754 {
00755
00756 void* addr = GetParAddr(npar);
00757 if (addr==0) return 0;
00758
00759 if (fBuffer[npar].fBsqlctype==SQL_C_DOUBLE)
00760 return *((SQLDOUBLE*) addr);
00761
00762 return (Double_t) ConvertToNumeric(npar);
00763 }
00764
00765
00766 const char* TODBCStatement::GetString(Int_t npar)
00767 {
00768
00769
00770 void* addr = GetParAddr(npar);
00771 if (addr==0) return 0;
00772
00773 if (fBuffer[npar].fBsqlctype==SQL_C_CHAR) {
00774
00775
00776 int len = fBuffer[npar].fBlenarray[fBufferCounter];
00777
00778 if ((len == SQL_NULL_DATA) || (len==0)) return 0;
00779
00780 char* res = (char*) addr;
00781 if (len < fBuffer[npar].fBelementsize) {
00782 *(res + len) = 0;
00783 return res;
00784 }
00785
00786 if (len > fBuffer[npar].fBelementsize) {
00787 SetError(-1, Form("Problems with string size %d", len), "GetString");
00788 return 0;
00789 }
00790
00791 if (fBuffer[npar].fBstrbuffer==0)
00792 fBuffer[npar].fBstrbuffer = new char[len+1];
00793
00794 strlcpy(fBuffer[npar].fBstrbuffer, res, len+1);
00795
00796 res = fBuffer[npar].fBstrbuffer;
00797 *(res + len) = 0;
00798 return res;
00799 }
00800
00801 return ConvertToString(npar);
00802 }
00803
00804
00805 Bool_t TODBCStatement::GetBinary(Int_t npar, void* &mem, Long_t& size)
00806 {
00807
00808
00809 mem = 0;
00810 size = 0;
00811
00812 void* addr = GetParAddr(npar);
00813 if (addr==0) return kFALSE;
00814
00815 if ((fBuffer[npar].fBsqlctype==SQL_C_BINARY) ||
00816 (fBuffer[npar].fBsqlctype==SQL_C_CHAR)) {
00817
00818
00819 int len = fBuffer[npar].fBlenarray[fBufferCounter];
00820
00821 if ((len == SQL_NULL_DATA) || (len==0)) return kTRUE;
00822
00823 size = len;
00824
00825 if (fBuffer[npar].fBstrbuffer==0)
00826 fBuffer[npar].fBstrbuffer = new char[size];
00827
00828 memcpy(fBuffer[npar].fBstrbuffer, addr, size);
00829
00830 mem = fBuffer[npar].fBstrbuffer;
00831
00832 return kTRUE;
00833 }
00834
00835 return kFALSE;
00836 }
00837
00838
00839
00840 Bool_t TODBCStatement::GetDate(Int_t npar, Int_t& year, Int_t& month, Int_t& day)
00841 {
00842
00843
00844 void* addr = GetParAddr(npar);
00845 if (addr==0) return kFALSE;
00846
00847 if (fBuffer[npar].fBsqlctype!=SQL_C_TYPE_DATE) return kFALSE;
00848
00849 DATE_STRUCT* dt = (DATE_STRUCT*) addr;
00850 year = dt->year;
00851 month = dt->month;
00852 day = dt->day;
00853
00854 return kTRUE;
00855 }
00856
00857
00858 Bool_t TODBCStatement::GetTime(Int_t npar, Int_t& hour, Int_t& min, Int_t& sec)
00859 {
00860
00861
00862 void* addr = GetParAddr(npar);
00863 if (addr==0) return kFALSE;
00864
00865 if (fBuffer[npar].fBsqlctype!=SQL_C_TYPE_TIME) return kFALSE;
00866
00867 TIME_STRUCT* tm = (TIME_STRUCT*) addr;
00868 hour = tm->hour;
00869 min = tm->minute;
00870 sec = tm->second;
00871
00872 return kTRUE;
00873 }
00874
00875
00876 Bool_t TODBCStatement::GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec)
00877 {
00878
00879
00880 void* addr = GetParAddr(npar);
00881 if (addr==0) return kFALSE;
00882
00883 if (fBuffer[npar].fBsqlctype!=SQL_C_TYPE_TIMESTAMP) return kFALSE;
00884
00885 TIMESTAMP_STRUCT* tm = (TIMESTAMP_STRUCT*) addr;
00886
00887 year = tm->year;
00888 month = tm->month;
00889 day = tm->day;
00890 hour = tm->hour;
00891 min = tm->minute;
00892 sec = tm->second;
00893 return kTRUE;
00894 }
00895
00896
00897 Bool_t TODBCStatement::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)
00898 {
00899
00900
00901 void* addr = GetParAddr(npar);
00902 if (addr==0) return kFALSE;
00903
00904 if (fBuffer[npar].fBsqlctype!=SQL_C_TYPE_TIMESTAMP) return kFALSE;
00905
00906 TIMESTAMP_STRUCT* tm = (TIMESTAMP_STRUCT*) addr;
00907
00908 year = tm->year;
00909 month = tm->month;
00910 day = tm->day;
00911 hour = tm->hour;
00912 min = tm->minute;
00913 sec = tm->second;
00914 frac = tm->fraction;
00915 return kTRUE;
00916 }
00917
00918
00919
00920 Bool_t TODBCStatement::SetNull(Int_t npar)
00921 {
00922
00923
00924
00925
00926
00927
00928
00929
00930 void* addr = GetParAddr(npar, kInt_t);
00931 if (addr!=0)
00932 *((SQLINTEGER*) addr) = 0;
00933
00934 if ((npar>=0) && (npar<fNumBuffers))
00935 fBuffer[npar].fBlenarray[fBufferCounter] = SQL_NULL_DATA;
00936
00937 return kTRUE;
00938 }
00939
00940
00941 Bool_t TODBCStatement::SetInt(Int_t npar, Int_t value)
00942 {
00943
00944 void* addr = GetParAddr(npar, kInt_t);
00945 if (addr==0) return kFALSE;
00946
00947 *((SQLINTEGER*) addr) = value;
00948
00949 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
00950
00951 return kTRUE;
00952 }
00953
00954
00955 Bool_t TODBCStatement::SetUInt(Int_t npar, UInt_t value)
00956 {
00957
00958 void* addr = GetParAddr(npar, kUInt_t);
00959 if (addr==0) return kFALSE;
00960
00961 *((SQLUINTEGER*) addr) = value;
00962
00963 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
00964
00965 return kTRUE;
00966 }
00967
00968
00969 Bool_t TODBCStatement::SetLong(Int_t npar, Long_t value)
00970 {
00971
00972 void* addr = GetParAddr(npar, kLong_t);
00973 if (addr==0) return kFALSE;
00974
00975 *((SQLINTEGER*) addr) = value;
00976
00977 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
00978
00979 return kTRUE;
00980 }
00981
00982
00983 Bool_t TODBCStatement::SetLong64(Int_t npar, Long64_t value)
00984 {
00985
00986 void* addr = GetParAddr(npar, kLong64_t);
00987 if (addr==0) return kFALSE;
00988
00989 *((Long64_t*) addr) = value;
00990
00991 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
00992
00993 return kTRUE;
00994 }
00995
00996
00997 Bool_t TODBCStatement::SetULong64(Int_t npar, ULong64_t value)
00998 {
00999
01000
01001 void* addr = GetParAddr(npar, kULong64_t);
01002 if (addr==0) return kFALSE;
01003
01004 *((ULong64_t*) addr) = value;
01005
01006 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
01007
01008 return kTRUE;
01009 }
01010
01011
01012 Bool_t TODBCStatement::SetDouble(Int_t npar, Double_t value)
01013 {
01014
01015
01016 void* addr = GetParAddr(npar, kDouble_t);
01017 if (addr==0) return kFALSE;
01018
01019 *((SQLDOUBLE*) addr) = value;
01020
01021 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
01022
01023 return kTRUE;
01024 }
01025
01026
01027 Bool_t TODBCStatement::SetString(Int_t npar, const char* value, Int_t maxsize)
01028 {
01029
01030 void* addr = GetParAddr(npar, kCharStar, maxsize);
01031
01032 if (addr==0) return kFALSE;
01033
01034 int len = value==0 ? 0 : strlen(value);
01035
01036 if (len>=fBuffer[npar].fBelementsize) {
01037 len = fBuffer[npar].fBelementsize;
01038 strlcpy((char*) addr, value, len+1);
01039 fBuffer[npar].fBlenarray[fBufferCounter] = len;
01040 } else
01041 if (len>0) {
01042 strcpy((char*) addr, value);
01043 fBuffer[npar].fBlenarray[fBufferCounter] = SQL_NTS;
01044 } else {
01045 *((char*) addr) = 0;
01046 fBuffer[npar].fBlenarray[fBufferCounter] = SQL_NTS;
01047 }
01048
01049 return kTRUE;
01050 }
01051
01052
01053 Bool_t TODBCStatement::SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize)
01054 {
01055
01056
01057 void* addr = GetParAddr(npar, kSqlBinary, maxsize);
01058 if (addr==0) return kFALSE;
01059
01060 if (size>fBuffer[npar].fBelementsize)
01061 size = fBuffer[npar].fBelementsize;
01062
01063 memcpy(addr, mem, size);
01064 fBuffer[npar].fBlenarray[fBufferCounter] = size;
01065
01066 return kTRUE;
01067 }
01068
01069
01070 Bool_t TODBCStatement::SetDate(Int_t npar, Int_t year, Int_t month, Int_t day)
01071 {
01072
01073
01074 void* addr = GetParAddr(npar, kSqlDate);
01075 if (addr==0) return kFALSE;
01076
01077 DATE_STRUCT* dt = (DATE_STRUCT*) addr;
01078 dt->year = year;
01079 dt->month = month;
01080 dt->day = day;
01081
01082 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
01083
01084 return kTRUE;
01085 }
01086
01087
01088 Bool_t TODBCStatement::SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec)
01089 {
01090
01091
01092 void* addr = GetParAddr(npar, kSqlTime);
01093 if (addr==0) return kFALSE;
01094
01095 TIME_STRUCT* tm = (TIME_STRUCT*) addr;
01096 tm->hour = hour;
01097 tm->minute = min;
01098 tm->second = sec;
01099
01100 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
01101
01102 return kTRUE;
01103 }
01104
01105
01106 Bool_t TODBCStatement::SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec)
01107 {
01108
01109
01110 void* addr = GetParAddr(npar, kSqlTimestamp);
01111 if (addr==0) return kFALSE;
01112
01113 TIMESTAMP_STRUCT* tm = (TIMESTAMP_STRUCT*) addr;
01114 tm->year = year;
01115 tm->month = month;
01116 tm->day = day;
01117 tm->hour = hour;
01118 tm->minute = min;
01119 tm->second = sec;
01120 tm->fraction = 0;
01121
01122 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
01123
01124 return kTRUE;
01125 }
01126
01127
01128 Bool_t TODBCStatement::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)
01129 {
01130
01131
01132 void* addr = GetParAddr(npar, kSqlTimestamp);
01133 if (addr==0) return kFALSE;
01134
01135 TIMESTAMP_STRUCT* tm = (TIMESTAMP_STRUCT*) addr;
01136 tm->year = year;
01137 tm->month = month;
01138 tm->day = day;
01139 tm->hour = hour;
01140 tm->minute = min;
01141 tm->second = sec;
01142 tm->fraction = frac;
01143
01144 fBuffer[npar].fBlenarray[fBufferCounter] = 0;
01145
01146 return kTRUE;
01147 }