Logo ROOT   6.16/01
Reference Guide
TMySQLStatement.cxx
Go to the documentation of this file.
1// @(#)root/mysql:$Id$
2// Author: Sergey Linev 6/02/2006
3
4/*************************************************************************
5 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// SQL statement class for MySQL //
15// //
16// See TSQLStatement class documentation for more details. //
17// //
18//////////////////////////////////////////////////////////////////////////
19
20#include "TMySQLStatement.h"
21#include "TMySQLServer.h"
22#include "TDataType.h"
23#include "TDatime.h"
24#include <stdlib.h>
25
27
29
30#if MYSQL_VERSION_ID >= 40100
31
32////////////////////////////////////////////////////////////////////////////////
33/// Normal constructor.
34/// Checks if statement contains parameters tags.
35
37 TSQLStatement(errout),
38 fStmt(stmt),
39 fNumBuffers(0),
40 fBind(0),
41 fBuffer(0),
42 fWorkingMode(0),
43 fIterationCount(-1),
44 fNeedParBind(kFALSE)
45{
46 ULong_t paramcount = mysql_stmt_param_count(fStmt);
47
48 if (paramcount>0) {
49 fWorkingMode = 1;
50 SetBuffersNumber(paramcount);
51 fNeedParBind = kTRUE;
52 fIterationCount = -1;
53 }
54}
55
56////////////////////////////////////////////////////////////////////////////////
57/// Destructor.
58
60{
61 Close();
62}
63
64////////////////////////////////////////////////////////////////////////////////
65/// Close statement.
66
68{
69 if (fStmt)
70 mysql_stmt_close(fStmt);
71
72 fStmt = 0;
73
75}
76
77
78// Reset error and check that statement exists
79#define CheckStmt(method, res) \
80 { \
81 ClearError(); \
82 if (fStmt==0) { \
83 SetError(-1,"Statement handle is 0",method); \
84 return res; \
85 } \
86 }
87
88// check last mysql statement error code
89#define CheckErrNo(method, force, res) \
90 { \
91 unsigned int stmterrno = mysql_stmt_errno(fStmt); \
92 if ((stmterrno!=0) || force) { \
93 const char* stmterrmsg = mysql_stmt_error(fStmt); \
94 if (stmterrno==0) { stmterrno = 11111; stmterrmsg = "MySQL statement error"; } \
95 SetError(stmterrno, stmterrmsg, method); \
96 return res; \
97 } \
98 }
99
100
101// check last mysql statement error code
102#define CheckGetField(method, res) \
103 { \
104 ClearError(); \
105 if (!IsResultSetMode()) { \
106 SetError(-1,"Cannot get statement parameters",method); \
107 return res; \
108 } \
109 if ((npar<0) || (npar>=fNumBuffers)) { \
110 SetError(-1,Form("Invalid parameter number %d", npar),method); \
111 return res; \
112 } \
113 }
114
115////////////////////////////////////////////////////////////////////////////////
116/// Process statement.
117
119{
120 CheckStmt("Process",kFALSE);
121
122 // if parameters was set, processing just means of closing parameters and variables
123 if (IsSetParsMode()) {
124 if (fIterationCount>=0)
125 if (!NextIteration()) return kFALSE;
126 fWorkingMode = 0;
127 fIterationCount = -1;
128 FreeBuffers();
129 return kTRUE;
130 }
131
132 if (mysql_stmt_execute(fStmt))
133 CheckErrNo("Process",kTRUE, kFALSE);
134
135 return kTRUE;
136}
137
138////////////////////////////////////////////////////////////////////////////////
139/// Return number of affected rows after statement is processed.
140
142{
143 CheckStmt("Process", -1);
144
145 my_ulonglong res = mysql_stmt_affected_rows(fStmt);
146
147 if (res == (my_ulonglong) -1)
148 CheckErrNo("GetNumAffectedRows", kTRUE, -1);
149
150 return (Int_t) res;
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Return number of statement parameters.
155
157{
158 CheckStmt("GetNumParameters", -1);
159
160 Int_t res = mysql_stmt_param_count(fStmt);
161
162 CheckErrNo("GetNumParameters", kFALSE, -1);
163
164 return res;
165}
166
167////////////////////////////////////////////////////////////////////////////////
168/// Store result of statement processing to access them
169/// via GetInt(), GetDouble() and so on methods.
170
172{
173 CheckStmt("StoreResult", kFALSE);
174 if (fWorkingMode!=0) {
175 SetError(-1,"Cannot store result for that statement","StoreResult");
176 return kFALSE;
177 }
178
179 if (mysql_stmt_store_result(fStmt))
180 CheckErrNo("StoreResult",kTRUE, kFALSE);
181
182 // allocate memeory for data reading from query
183 MYSQL_RES* meta = mysql_stmt_result_metadata(fStmt);
184 if (meta) {
185 int count = mysql_num_fields(meta);
186
187 SetBuffersNumber(count);
188
189 MYSQL_FIELD *fields = mysql_fetch_fields(meta);
190
191 for (int n=0;n<count;n++) {
192 SetSQLParamType(n, fields[n].type, (fields[n].flags & UNSIGNED_FLAG) == 0, fields[n].length);
193 if (fields[n].name!=0) {
194 fBuffer[n].fFieldName = new char[strlen(fields[n].name)+1];
195 strcpy(fBuffer[n].fFieldName, fields[n].name);
196 }
197 }
198
199 mysql_free_result(meta);
200 }
201
202 if (fBind==0) return kFALSE;
203
204 /* Bind the buffers */
205 if (mysql_stmt_bind_result(fStmt, fBind))
206 CheckErrNo("StoreResult",kTRUE, kFALSE);
207
208 fWorkingMode = 2;
209
210 return kTRUE;
211}
212
213////////////////////////////////////////////////////////////////////////////////
214/// Return number of fields in result set.
215
217{
218 return IsResultSetMode() ? fNumBuffers : -1;
219}
220
221////////////////////////////////////////////////////////////////////////////////
222/// Returns field name in result set.
223
224const char* TMySQLStatement::GetFieldName(Int_t nfield)
225{
226 if (!IsResultSetMode() || (nfield<0) || (nfield>=fNumBuffers)) return 0;
227
228 return fBuffer[nfield].fFieldName;
229}
230
231////////////////////////////////////////////////////////////////////////////////
232/// Shift cursor to nect row in result set.
233
235{
236 if ((fStmt==0) || !IsResultSetMode()) return kFALSE;
237
238 Bool_t res = !mysql_stmt_fetch(fStmt);
239
240 if (!res) {
241 fWorkingMode = 0;
242 FreeBuffers();
243 }
244
245 return res;
246}
247
248////////////////////////////////////////////////////////////////////////////////
249/// Increment iteration counter for statement, where parameter can be set.
250/// Statement with parameters of previous iteration
251/// automatically will be applied to database.
252
254{
255 ClearError();
256
257 if (!IsSetParsMode() || (fBind==0)) {
258 SetError(-1,"Cannot call for that statement","NextIteration");
259 return kFALSE;
260 }
261
263
264 if (fIterationCount==0) return kTRUE;
265
266 if (fNeedParBind) {
268 if (mysql_stmt_bind_param(fStmt, fBind))
269 CheckErrNo("NextIteration",kTRUE, kFALSE);
270 }
271
272 if (mysql_stmt_execute(fStmt))
273 CheckErrNo("NextIteration", kTRUE, kFALSE);
274
275 return kTRUE;
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// Release all buffers, used by statement.
280
282{
283 if (fBuffer) {
284 for (Int_t n=0; n<fNumBuffers;n++) {
285 free(fBuffer[n].fMem);
286 if (fBuffer[n].fStrBuffer)
287 delete[] fBuffer[n].fStrBuffer;
288 if (fBuffer[n].fFieldName)
289 delete[] fBuffer[n].fFieldName;
290 }
291 delete[] fBuffer;
292 }
293
294 if (fBind)
295 delete[] fBind;
296
297 fBuffer = 0;
298 fBind = 0;
299 fNumBuffers = 0;
300}
301
302////////////////////////////////////////////////////////////////////////////////
303/// Allocate buffers for statement parameters/ result fields.
304
306{
307 FreeBuffers();
308 if (numpars<=0) return;
309
310 fNumBuffers = numpars;
311
313 memset(fBind, 0, sizeof(MYSQL_BIND)*fNumBuffers);
314
315 fBuffer = new TParamData[fNumBuffers];
316 memset(fBuffer, 0, sizeof(TParamData)*fNumBuffers);
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// Convert field value to string.
321
323{
324 if (fBuffer[npar].fResNull) return 0;
325
326 void* addr = fBuffer[npar].fMem;
327 Bool_t sig = fBuffer[npar].fSign;
328
329 if (addr==0) return 0;
330
331 if ((fBind[npar].buffer_type==MYSQL_TYPE_STRING) ||
332 (fBind[npar].buffer_type==MYSQL_TYPE_VAR_STRING))
333 return (const char*) addr;
334
335 if (fBuffer[npar].fStrBuffer==0)
336 fBuffer[npar].fStrBuffer = new char[100];
337
338 char* buf = fBuffer[npar].fStrBuffer;
339
340 switch(fBind[npar].buffer_type) {
341 case MYSQL_TYPE_LONG:
342 if (sig) snprintf(buf,100,"%d",*((int*) addr));
343 else snprintf(buf,100,"%u",*((unsigned int*) addr));
344 break;
345 case MYSQL_TYPE_LONGLONG:
346 if (sig) snprintf(buf,100,"%lld",*((Long64_t*) addr)); else
347 snprintf(buf,100,"%llu",*((ULong64_t*) addr));
348 break;
349 case MYSQL_TYPE_SHORT:
350 if (sig) snprintf(buf,100,"%hd",*((short*) addr)); else
351 snprintf(buf,100,"%hu",*((unsigned short*) addr));
352 break;
353 case MYSQL_TYPE_TINY:
354 if (sig) snprintf(buf,100,"%d",*((char*) addr)); else
355 snprintf(buf,100,"%u",*((unsigned char*) addr));
356 break;
357 case MYSQL_TYPE_FLOAT:
358 snprintf(buf, 100, TSQLServer::GetFloatFormat(), *((float*) addr));
359 break;
360 case MYSQL_TYPE_DOUBLE:
361 snprintf(buf, 100, TSQLServer::GetFloatFormat(), *((double*) addr));
362 break;
363 case MYSQL_TYPE_DATETIME:
364 case MYSQL_TYPE_TIMESTAMP: {
365 MYSQL_TIME* tm = (MYSQL_TIME*) addr;
366 snprintf(buf,100,"%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
367 tm->year, tm->month, tm->day,
368 tm->hour, tm->minute, tm->second);
369 break;
370 }
371 case MYSQL_TYPE_TIME: {
372 MYSQL_TIME* tm = (MYSQL_TIME*) addr;
373 snprintf(buf,100,"%2.2d:%2.2d:%2.2d",
374 tm->hour, tm->minute, tm->second);
375 break;
376 }
377 case MYSQL_TYPE_DATE: {
378 MYSQL_TIME* tm = (MYSQL_TIME*) addr;
379 snprintf(buf,100,"%4.4d-%2.2d-%2.2d",
380 tm->year, tm->month, tm->day);
381 break;
382 }
383 default:
384 return 0;
385 }
386 return buf;
387}
388
389////////////////////////////////////////////////////////////////////////////////
390/// Convert field to numeric value.
391
393{
394 if (fBuffer[npar].fResNull) return 0;
395
396 void* addr = fBuffer[npar].fMem;
397 Bool_t sig = fBuffer[npar].fSign;
398
399 if (addr==0) return 0;
400
401 switch(fBind[npar].buffer_type) {
402 case MYSQL_TYPE_LONG:
403 if (sig) return *((int*) addr); else
404 return *((unsigned int*) addr);
405 break;
406 case MYSQL_TYPE_LONGLONG:
407 if (sig) return *((Long64_t*) addr); else
408 return *((ULong64_t*) addr);
409 break;
410 case MYSQL_TYPE_SHORT:
411 if (sig) return *((short*) addr); else
412 return *((unsigned short*) addr);
413 break;
414 case MYSQL_TYPE_TINY:
415 if (sig) return *((char*) addr); else
416 return *((unsigned char*) addr);
417 break;
418 case MYSQL_TYPE_FLOAT:
419 return *((float*) addr);
420 break;
421 case MYSQL_TYPE_DOUBLE:
422 return *((double*) addr);
423 break;
424#if MYSQL_VERSION_ID >= 50022
425 case MYSQL_TYPE_NEWDECIMAL /* new MYSQL_TYPE fixed precision decimal */:
426#endif
427 case MYSQL_TYPE_STRING:
428 case MYSQL_TYPE_VAR_STRING:
429 case MYSQL_TYPE_BLOB: {
430 char* str = (char*) addr;
431 ULong_t len = fBuffer[npar].fResLength;
432 if ((str==0) || (*str==0) || (len==0)) return 0;
433 Int_t size = fBuffer[npar].fSize;
434 if (1.*len<size)
435 str[len] = 0;
436 else
437 str[size-1] = 0;
438 long double buf = 0;
439 sscanf(str,"%Lf",&buf);
440 return buf;
441 break;
442 }
443 case MYSQL_TYPE_DATETIME:
444 case MYSQL_TYPE_TIMESTAMP: {
445 MYSQL_TIME* tm = (MYSQL_TIME*) addr;
446 TDatime rtm(tm->year, tm->month, tm->day,
447 tm->hour, tm->minute, tm->second);
448 return rtm.Get();
449 break;
450 }
451 case MYSQL_TYPE_DATE: {
452 MYSQL_TIME* tm = (MYSQL_TIME*) addr;
453 TDatime rtm(tm->year, tm->month, tm->day, 0, 0, 0);
454 return rtm.GetDate();
455 break;
456 }
457 case MYSQL_TYPE_TIME: {
458 MYSQL_TIME* tm = (MYSQL_TIME*) addr;
459 TDatime rtm(2000, 1, 1, tm->hour, tm->minute, tm->second);
460 return rtm.GetTime();
461 break;
462 }
463
464 default:
465 return 0;
466 }
467}
468
469////////////////////////////////////////////////////////////////////////////////
470/// Checks if field value is null.
471
473{
474 CheckGetField("IsNull", kTRUE);
475
476 return fBuffer[npar].fResNull;
477}
478
479////////////////////////////////////////////////////////////////////////////////
480/// Return field value as integer.
481
483{
484 CheckGetField("GetInt", 0);
485
486 if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONG) && fBuffer[npar].fSign)
487 return (Int_t) *((int*) fBuffer[npar].fMem);
488
489 return (Int_t) ConvertToNumeric(npar);
490}
491
492////////////////////////////////////////////////////////////////////////////////
493/// Return field value as unsigned integer.
494
496{
497 CheckGetField("GetUInt", 0);
498
499 if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONG) && !fBuffer[npar].fSign)
500 return (UInt_t) *((unsigned int*) fBuffer[npar].fMem);
501
502 return (UInt_t) ConvertToNumeric(npar);
503}
504
505////////////////////////////////////////////////////////////////////////////////
506/// Return field value as long integer.
507
509{
510 CheckGetField("GetLong", 0);
511
512 if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONG) && fBuffer[npar].fSign)
513 return (Long_t) *((int*) fBuffer[npar].fMem);
514
515 return (Long_t) ConvertToNumeric(npar);
516}
517
518////////////////////////////////////////////////////////////////////////////////
519/// Return field value as 64-bit integer.
520
522{
523 CheckGetField("GetLong64", 0);
524
525 if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONGLONG) && fBuffer[npar].fSign)
526 return (Long64_t) *((Long64_t*) fBuffer[npar].fMem);
527
528 return (Long64_t) ConvertToNumeric(npar);
529}
530
531////////////////////////////////////////////////////////////////////////////////
532/// Return field value as unsigned 64-bit integer.
533
535{
536 CheckGetField("GetULong64", 0);
537
538 if ((fBuffer[npar].fSqlType==MYSQL_TYPE_LONGLONG) && !fBuffer[npar].fSign)
539 return (ULong64_t) *((ULong64_t*) fBuffer[npar].fMem);
540
541 return (ULong64_t) ConvertToNumeric(npar);
542}
543
544////////////////////////////////////////////////////////////////////////////////
545/// Return field value as double.
546
548{
549 CheckGetField("GetDouble", 0);
550
551 if (fBuffer[npar].fSqlType==MYSQL_TYPE_DOUBLE)
552 return (Double_t) *((double*) fBuffer[npar].fMem);
553
554 return (Double_t) ConvertToNumeric(npar);
555}
556
557////////////////////////////////////////////////////////////////////////////////
558/// Return field value as string.
559
560const char *TMySQLStatement::GetString(Int_t npar)
561{
562 CheckGetField("GetString", 0);
563
564 if ((fBind[npar].buffer_type==MYSQL_TYPE_STRING)
565 || (fBind[npar].buffer_type==MYSQL_TYPE_BLOB)
566 || (fBind[npar].buffer_type==MYSQL_TYPE_VAR_STRING)
567#if MYSQL_VERSION_ID >= 50022
568 || (fBuffer[npar].fSqlType==MYSQL_TYPE_NEWDECIMAL)
569#endif
570 ) {
571 if (fBuffer[npar].fResNull) return 0;
572 char* str = (char*) fBuffer[npar].fMem;
573 ULong_t len = fBuffer[npar].fResLength;
574 Int_t size = fBuffer[npar].fSize;
575 if (1.*len<size) str[len] = 0; else
576 str[size-1] = 0;
577 return str;
578 }
579
580 return ConvertToString(npar);
581}
582
583////////////////////////////////////////////////////////////////////////////////
584/// Return field value as binary array.
585
586Bool_t TMySQLStatement::GetBinary(Int_t npar, void* &mem, Long_t& size)
587{
588 mem = 0;
589 size = 0;
590
591 CheckGetField("GetBinary", kFALSE);
592
593 if ((fBind[npar].buffer_type==MYSQL_TYPE_STRING) ||
594 (fBind[npar].buffer_type==MYSQL_TYPE_VAR_STRING) ||
595 (fBind[npar].buffer_type==MYSQL_TYPE_BLOB) ||
596 (fBind[npar].buffer_type==MYSQL_TYPE_TINY_BLOB) ||
597 (fBind[npar].buffer_type==MYSQL_TYPE_MEDIUM_BLOB) ||
598 (fBind[npar].buffer_type==MYSQL_TYPE_LONG_BLOB)) {
599 if (fBuffer[npar].fResNull) return kTRUE;
600 mem = fBuffer[npar].fMem;
601 size = fBuffer[npar].fResLength;
602 return kTRUE;
603 }
604
605 return kFALSE;
606}
607
608////////////////////////////////////////////////////////////////////////////////
609/// Return field value as date.
610
611Bool_t TMySQLStatement::GetDate(Int_t npar, Int_t& year, Int_t& month, Int_t& day)
612{
613 CheckGetField("GetDate", kFALSE);
614
615 if (fBuffer[npar].fResNull) return kFALSE;
616
617 switch(fBind[npar].buffer_type) {
618 case MYSQL_TYPE_DATETIME:
619 case MYSQL_TYPE_TIMESTAMP:
620 case MYSQL_TYPE_DATE: {
621 MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem;
622 if (tm==0) return kFALSE;
623 year = tm->year;
624 month = tm->month;
625 day = tm->day;
626 break;
627 }
628 default:
629 return kFALSE;
630 }
631 return kTRUE;
632}
633
634////////////////////////////////////////////////////////////////////////////////
635/// Return field value as time.
636
637Bool_t TMySQLStatement::GetTime(Int_t npar, Int_t& hour, Int_t& min, Int_t& sec)
638{
639 CheckGetField("GetTime", kFALSE);
640
641 if (fBuffer[npar].fResNull) return kFALSE;
642
643 switch(fBind[npar].buffer_type) {
644 case MYSQL_TYPE_DATETIME:
645 case MYSQL_TYPE_TIMESTAMP:
646 case MYSQL_TYPE_TIME: {
647 MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem;
648 if (tm==0) return kFALSE;
649 hour = tm->hour;
650 min = tm->minute;
651 sec = tm->second;
652 break;
653 }
654 default:
655 return kFALSE;
656 }
657 return kTRUE;
658}
659
660////////////////////////////////////////////////////////////////////////////////
661/// Return field value as date & time.
662
663Bool_t TMySQLStatement::GetDatime(Int_t npar, Int_t& year, Int_t& month, Int_t& day, Int_t& hour, Int_t& min, Int_t& sec)
664{
665 CheckGetField("GetDatime", kFALSE);
666
667 if (fBuffer[npar].fResNull) return kFALSE;
668
669 switch(fBind[npar].buffer_type) {
670 case MYSQL_TYPE_DATETIME:
671 case MYSQL_TYPE_TIMESTAMP: {
672 MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem;
673 if (tm==0) return kFALSE;
674 year = tm->year;
675 month = tm->month;
676 day = tm->day;
677 hour = tm->hour;
678 min = tm->minute;
679 sec = tm->second;
680 break;
681 }
682 default:
683 return kFALSE;
684 }
685 return kTRUE;
686}
687
688////////////////////////////////////////////////////////////////////////////////
689/// Return field value as time stamp.
690
691Bool_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)
692{
693 CheckGetField("GetTimstamp", kFALSE);
694
695 if (fBuffer[npar].fResNull) return kFALSE;
696
697 switch(fBind[npar].buffer_type) {
698 case MYSQL_TYPE_DATETIME:
699 case MYSQL_TYPE_TIMESTAMP: {
700 MYSQL_TIME* tm = (MYSQL_TIME*) fBuffer[npar].fMem;
701 if (tm==0) return kFALSE;
702 year = tm->year;
703 month = tm->month;
704 day = tm->day;
705 hour = tm->hour;
706 min = tm->minute;
707 sec = tm->second;
708 frac = 0;
709 break;
710 }
711 default:
712 return kFALSE;
713 }
714 return kTRUE;
715}
716
717////////////////////////////////////////////////////////////////////////////////
718/// Set parameter type to be used as buffer.
719/// Used in both setting data to database and retriving data from data base.
720/// Initialize proper MYSQL_BIND structure and allocate required buffers.
721
722Bool_t TMySQLStatement::SetSQLParamType(Int_t npar, int sqltype, Bool_t sig, ULong_t sqlsize)
723{
724 if ((npar<0) || (npar>=fNumBuffers)) return kFALSE;
725
726 fBuffer[npar].fMem = 0;
727 fBuffer[npar].fSize = 0;
728 fBuffer[npar].fResLength = 0;
729 fBuffer[npar].fResNull = false;
730 fBuffer[npar].fStrBuffer = 0;
731
732 ULong64_t allocsize = 0;
733
734 Bool_t doreset = false;
735
736 switch (sqltype) {
737 case MYSQL_TYPE_LONG: allocsize = sizeof(int); break;
738 case MYSQL_TYPE_LONGLONG: allocsize = sizeof(Long64_t); break;
739 case MYSQL_TYPE_SHORT: allocsize = sizeof(short); break;
740 case MYSQL_TYPE_TINY: allocsize = sizeof(char); break;
741 case MYSQL_TYPE_FLOAT: allocsize = sizeof(float); break;
742 case MYSQL_TYPE_DOUBLE: allocsize = sizeof(double); break;
743#if MYSQL_VERSION_ID >= 50022
744 case MYSQL_TYPE_NEWDECIMAL /* new MYSQL_TYPE fixed precision decimal */:
745#endif
746 case MYSQL_TYPE_STRING: allocsize = sqlsize > 256 ? sqlsize : 256; break;
747 case MYSQL_TYPE_VAR_STRING: allocsize = sqlsize > 256 ? sqlsize : 256; break;
748 case MYSQL_TYPE_MEDIUM_BLOB:
749 case MYSQL_TYPE_LONG_BLOB:
750 case MYSQL_TYPE_BLOB: allocsize = sqlsize >= 65525 ? sqlsize : 65535; break;
751 case MYSQL_TYPE_TINY_BLOB: allocsize = sqlsize > 255 ? sqlsize : 255; break;
752 case MYSQL_TYPE_TIME:
753 case MYSQL_TYPE_DATE:
754 case MYSQL_TYPE_TIMESTAMP:
755 case MYSQL_TYPE_DATETIME: allocsize = sizeof(MYSQL_TIME); doreset = true; break;
756 default: SetError(-1,"Nonsupported SQL type","SetSQLParamType"); return kFALSE;
757 }
758
759 if (allocsize > fgAllocSizeLimit) allocsize = fgAllocSizeLimit;
760
761 fBuffer[npar].fMem = malloc(allocsize);
762 fBuffer[npar].fSize = allocsize;
763 fBuffer[npar].fSqlType = sqltype;
764 fBuffer[npar].fSign = sig;
765
766 if ((allocsize>0) && fBuffer[npar].fMem && doreset)
767 memset(fBuffer[npar].fMem, 0, allocsize);
768
769 fBind[npar].buffer_type = enum_field_types(sqltype);
770 fBind[npar].buffer = fBuffer[npar].fMem;
771 fBind[npar].buffer_length = allocsize;
772 fBind[npar].is_null= &(fBuffer[npar].fResNull);
773 fBind[npar].length = &(fBuffer[npar].fResLength);
774 fBind[npar].is_unsigned = !sig;
775
776 return kTRUE;
777}
778
779////////////////////////////////////////////////////////////////////////////////
780/// Check boundary condition before setting value of parameter.
781/// Return address of parameter buffer.
782
783void *TMySQLStatement::BeforeSet(const char* method, Int_t npar, Int_t sqltype, Bool_t sig, ULong_t size)
784{
785 ClearError();
786
787 if (!IsSetParsMode()) {
788 SetError(-1,"Cannot set parameter for statement", method);
789 return 0;
790 }
791
792 if ((npar<0) || (npar>=fNumBuffers)) {
793 SetError(-1,Form("Invalid parameter number %d",npar), method);
794 return 0;
795 }
796
797 if ((fIterationCount==0) && (fBuffer[npar].fSqlType==0))
798 if (!SetSQLParamType(npar, sqltype, sig, size)) {
799 SetError(-1,"Cannot initialize parameter buffer", method);
800 return 0;
801 }
802
803 if ((fBuffer[npar].fSqlType!=sqltype) ||
804 (fBuffer[npar].fSign != sig)) return 0;
805
806 fBuffer[npar].fResNull = false;
807
808 return fBuffer[npar].fMem;
809}
810
811////////////////////////////////////////////////////////////////////////////////
812/// Set NULL as parameter value.
813/// If NULL should be set for statement parameter during first iteration,
814/// one should call before proper Set... method to identify type of argument for
815/// the future. For instance, if one suppose to have double as type of parameter,
816/// code should look like:
817/// stmt->SetDouble(2, 0.);
818/// stmt->SetNull(2);
819
821{
822 void* addr = BeforeSet("SetNull", npar, MYSQL_TYPE_LONG);
823
824 if (addr!=0)
825 *((int*) addr) = 0;
826
827 if ((npar>=0) && (npar<fNumBuffers))
828 fBuffer[npar].fResNull = true;
829
830 return kTRUE;
831}
832
833////////////////////////////////////////////////////////////////////////////////
834/// Set parameter value as integer.
835
837{
838 void* addr = BeforeSet("SetInt", npar, MYSQL_TYPE_LONG);
839
840 if (addr!=0)
841 *((int*) addr) = value;
842
843 return (addr!=0);
844}
845
846////////////////////////////////////////////////////////////////////////////////
847/// Set parameter value as unsigned integer.
848
850{
851 void* addr = BeforeSet("SetUInt", npar, MYSQL_TYPE_LONG, kFALSE);
852
853 if (addr!=0)
854 *((unsigned int*) addr) = value;
855
856 return (addr!=0);
857}
858
859////////////////////////////////////////////////////////////////////////////////
860/// Set parameter value as long integer.
861
863{
864 void* addr = BeforeSet("SetLong", npar, MYSQL_TYPE_LONG);
865
866 if (addr!=0)
867 *((int*) addr) = value;
868
869 return (addr!=0);
870}
871
872////////////////////////////////////////////////////////////////////////////////
873/// Set parameter value as 64-bit integer.
874
876{
877 void* addr = BeforeSet("SetLong64", npar, MYSQL_TYPE_LONGLONG);
878
879 if (addr!=0)
880 *((Long64_t*) addr) = value;
881
882 return (addr!=0);
883}
884
885////////////////////////////////////////////////////////////////////////////////
886/// Set parameter value as unsigned 64-bit integer.
887
889{
890 void* addr = BeforeSet("SetULong64", npar, MYSQL_TYPE_LONGLONG, kFALSE);
891
892 if (addr!=0)
893 *((ULong64_t*) addr) = value;
894
895 return (addr!=0);
896}
897
898////////////////////////////////////////////////////////////////////////////////
899/// Set parameter value as double.
900
902{
903 void* addr = BeforeSet("SetDouble", npar, MYSQL_TYPE_DOUBLE, kFALSE);
904
905 if (addr!=0)
906 *((double*) addr) = value;
907
908 return (addr!=0);
909}
910
911////////////////////////////////////////////////////////////////////////////////
912/// Set parameter value as string.
913
914Bool_t TMySQLStatement::SetString(Int_t npar, const char* value, Int_t maxsize)
915{
916 Int_t len = value ? strlen(value) : 0;
917
918 void* addr = BeforeSet("SetString", npar, MYSQL_TYPE_STRING, true, maxsize);
919
920 if (addr==0) return kFALSE;
921
922 if (len >= fBuffer[npar].fSize) {
923 free(fBuffer[npar].fMem);
924
925 fBuffer[npar].fMem = malloc(len+1);
926 fBuffer[npar].fSize = len + 1;
927
928 fBind[npar].buffer = fBuffer[npar].fMem;
929 fBind[npar].buffer_length = fBuffer[npar].fSize;
930
931 addr = fBuffer[npar].fMem;
933 }
934
935 if (value) strcpy((char*) addr, value);
936 else ((char*)addr)[0]='\0';
937
938 fBuffer[npar].fResLength = len;
939
940 return kTRUE;
941}
942
943////////////////////////////////////////////////////////////////////////////////
944/// Set parameter value as binary data.
945
946Bool_t TMySQLStatement::SetBinary(Int_t npar, void* mem, Long_t size, Long_t maxsize)
947{
948 if (size>=maxsize) maxsize = size + 1;
949
950 int bin_type = MYSQL_TYPE_BLOB;
951 if (maxsize > 65525) bin_type = MYSQL_TYPE_MEDIUM_BLOB;
952 if (maxsize > 16777205) bin_type = MYSQL_TYPE_LONG_BLOB;
953
954 void* addr = BeforeSet("SetBinary", npar, bin_type, true, maxsize);
955
956 if (addr==0) return kFALSE;
957
958 if (size >= fBuffer[npar].fSize) {
959 free(fBuffer[npar].fMem);
960
961 fBuffer[npar].fMem = malloc(size+1);
962 fBuffer[npar].fSize = size + 1;
963
964 fBind[npar].buffer = fBuffer[npar].fMem;
965 fBind[npar].buffer_length = fBuffer[npar].fSize;
966
967 addr = fBuffer[npar].fMem;
969 }
970
971 memcpy(addr, mem, size);
972
973 fBuffer[npar].fResLength = size;
974
975 return kTRUE;
976}
977
978////////////////////////////////////////////////////////////////////////////////
979/// Set parameter value as date.
980
982{
983 MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetDate", npar, MYSQL_TYPE_DATE);
984
985 if (addr!=0) {
986 addr->year = year;
987 addr->month = month;
988 addr->day = day;
989 }
990
991 return (addr!=0);
992}
993
994////////////////////////////////////////////////////////////////////////////////
995/// Set parameter value as time.
996
998{
999 MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetTime", npar, MYSQL_TYPE_TIME);
1000
1001 if (addr!=0) {
1002 addr->hour = hour;
1003 addr->minute = min;
1004 addr->second = sec;
1005 }
1006
1007 return (addr!=0);
1008}
1009
1010////////////////////////////////////////////////////////////////////////////////
1011/// Set parameter value as date & time.
1012
1013Bool_t TMySQLStatement::SetDatime(Int_t npar, Int_t year, Int_t month, Int_t day, Int_t hour, Int_t min, Int_t sec)
1014{
1015 MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetDatime", npar, MYSQL_TYPE_DATETIME);
1016
1017 if (addr!=0) {
1018 addr->year = year;
1019 addr->month = month;
1020 addr->day = day;
1021 addr->hour = hour;
1022 addr->minute = min;
1023 addr->second = sec;
1024 }
1025
1026 return (addr!=0);
1027}
1028
1029////////////////////////////////////////////////////////////////////////////////
1030/// Set parameter value as timestamp.
1031
1032Bool_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)
1033{
1034 MYSQL_TIME* addr = (MYSQL_TIME*) BeforeSet("SetTimestamp", npar, MYSQL_TYPE_TIMESTAMP);
1035
1036 if (addr!=0) {
1037 addr->year = year;
1038 addr->month = month;
1039 addr->day = day;
1040 addr->hour = hour;
1041 addr->minute = min;
1042 addr->second = sec;
1043 }
1044
1045 return (addr!=0);
1046}
1047
1048#else
1049
1050////////////////////////////////////////////////////////////////////////////////
1051/// Normal constructor.
1052/// For MySQL version < 4.1 no statement is supported
1053
1055{
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Destructor.
1060
1062{
1063}
1064
1065////////////////////////////////////////////////////////////////////////////////
1066/// Close statement
1067
1069{
1070}
1071
1072////////////////////////////////////////////////////////////////////////////////
1073/// Process statement.
1074
1076{
1077 return kFALSE;
1078}
1079
1080////////////////////////////////////////////////////////////////////////////////
1081/// Return number of affected rows after statement is processed.
1082
1084{
1085 return 0;
1086}
1087
1088////////////////////////////////////////////////////////////////////////////////
1089/// Return number of statement parameters.
1090
1092{
1093 return 0;
1094}
1095
1096////////////////////////////////////////////////////////////////////////////////
1097/// Store result of statement processing to access them
1098/// via GetInt(), GetDouble() and so on methods.
1099
1101{
1102 return kFALSE;
1103}
1104
1105////////////////////////////////////////////////////////////////////////////////
1106/// Return number of fields in result set.
1107
1109{
1110 return 0;
1111}
1112
1113////////////////////////////////////////////////////////////////////////////////
1114/// Returns field name in result set.
1115
1117{
1118 return 0;
1119}
1120
1121////////////////////////////////////////////////////////////////////////////////
1122/// Shift cursor to nect row in result set.
1123
1125{
1126 return kFALSE;
1127}
1128
1129
1130////////////////////////////////////////////////////////////////////////////////
1131/// Increment iteration counter for statement, where parameter can be set.
1132/// Statement with parameters of previous iteration
1133/// automatically will be applied to database.
1134
1136{
1137 return kFALSE;
1138}
1139
1140////////////////////////////////////////////////////////////////////////////////
1141/// Release all buffers, used by statement.
1142
1144{
1145}
1146
1147////////////////////////////////////////////////////////////////////////////////
1148/// Allocate buffers for statement parameters/ result fields.
1149
1151{
1152}
1153
1154////////////////////////////////////////////////////////////////////////////////
1155/// Convert field value to string.
1156
1158{
1159 return 0;
1160}
1161
1162////////////////////////////////////////////////////////////////////////////////
1163/// Convert field to numeric value.
1164
1166{
1167 return 0;
1168}
1169
1170////////////////////////////////////////////////////////////////////////////////
1171/// Checks if field value is null.
1172
1174{
1175 return kTRUE;
1176}
1177
1178////////////////////////////////////////////////////////////////////////////////
1179/// Return field value as integer.
1180
1182{
1183 return 0;
1184}
1185
1186////////////////////////////////////////////////////////////////////////////////
1187/// Return field value as unsigned integer.
1188
1190{
1191 return 0;
1192}
1193
1194////////////////////////////////////////////////////////////////////////////////
1195/// Return field value as long integer.
1196
1198{
1199 return 0;
1200}
1201
1202////////////////////////////////////////////////////////////////////////////////
1203/// Return field value as 64-bit integer.
1204
1206{
1207 return 0;
1208}
1209
1210////////////////////////////////////////////////////////////////////////////////
1211/// Return field value as unsigned 64-bit integer.
1212
1214{
1215 return 0;
1216}
1217
1218////////////////////////////////////////////////////////////////////////////////
1219/// Return field value as double.
1220
1222{
1223 return 0.;
1224}
1225
1226////////////////////////////////////////////////////////////////////////////////
1227/// Return field value as string.
1228
1230{
1231 return 0;
1232}
1233
1234////////////////////////////////////////////////////////////////////////////////
1235/// Return field value as binary array.
1236
1238{
1239 return kFALSE;
1240}
1241
1242
1243////////////////////////////////////////////////////////////////////////////////
1244/// Return field value as date.
1245
1247{
1248 return kFALSE;
1249}
1250
1251////////////////////////////////////////////////////////////////////////////////
1252/// Return field value as time.
1253
1255{
1256 return kFALSE;
1257}
1258
1259////////////////////////////////////////////////////////////////////////////////
1260/// Return field value as date & time.
1261
1263{
1264 return kFALSE;
1265}
1266
1267////////////////////////////////////////////////////////////////////////////////
1268/// Return field value as time stamp.
1269
1271{
1272 return kFALSE;
1273}
1274
1275////////////////////////////////////////////////////////////////////////////////
1276/// Set parameter type to be used as buffer.
1277/// Used in both setting data to database and retriving data from data base.
1278/// Initialize proper MYSQL_BIND structure and allocate required buffers.
1279
1281{
1282 return kFALSE;
1283}
1284
1285////////////////////////////////////////////////////////////////////////////////
1286/// Check boundary condition before setting value of parameter.
1287/// Return address of parameter buffer.
1288
1290{
1291 return 0;
1292}
1293
1294////////////////////////////////////////////////////////////////////////////////
1295/// Set NULL as parameter value.
1296/// If NULL should be set for statement parameter during first iteration,
1297/// one should call before proper Set... method to identify type of argument for
1298/// the future. For instance, if one suppose to have double as type of parameter,
1299/// code should look like:
1300/// stmt->SetDouble(2, 0.);
1301/// stmt->SetNull(2);
1302
1304{
1305 return kFALSE;
1306}
1307
1308////////////////////////////////////////////////////////////////////////////////
1309/// Set parameter value as integer.
1310
1312{
1313 return kFALSE;
1314}
1315
1316////////////////////////////////////////////////////////////////////////////////
1317/// Set parameter value as unsigned integer.
1318
1320{
1321 return kFALSE;
1322}
1323
1324////////////////////////////////////////////////////////////////////////////////
1325/// Set parameter value as long integer.
1326
1328{
1329 return kFALSE;
1330}
1331
1332////////////////////////////////////////////////////////////////////////////////
1333/// Set parameter value as 64-bit integer.
1334
1336{
1337 return kFALSE;
1338}
1339
1340////////////////////////////////////////////////////////////////////////////////
1341/// Set parameter value as unsigned 64-bit integer.
1342
1344{
1345 return kFALSE;
1346}
1347
1348////////////////////////////////////////////////////////////////////////////////
1349/// Set parameter value as double.
1350
1352{
1353 return kFALSE;
1354}
1355
1356////////////////////////////////////////////////////////////////////////////////
1357/// Set parameter value as string.
1358
1360{
1361 return kFALSE;
1362}
1363
1364////////////////////////////////////////////////////////////////////////////////
1365/// Set parameter value as binary data.
1366
1368{
1369 return kFALSE;
1370}
1371
1372////////////////////////////////////////////////////////////////////////////////
1373/// Set parameter value as date.
1374
1376{
1377 return kFALSE;
1378}
1379
1380////////////////////////////////////////////////////////////////////////////////
1381/// Set parameter value as time.
1382
1384{
1385 return kFALSE;
1386}
1387
1388////////////////////////////////////////////////////////////////////////////////
1389/// Set parameter value as date & time.
1390
1392{
1393 return kFALSE;
1394}
1395
1396////////////////////////////////////////////////////////////////////////////////
1397/// Set parameter value as timestamp.
1398
1400{
1401 return kFALSE;
1402}
1403
1404#endif // MYSQL_VERSION_ID > 40100
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
unsigned long long ULong64_t
Definition: RtypesCore.h:70
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:363
int type
Definition: TGX11.cxx:120
#define CheckErrNo(method, force, res)
#define CheckGetField(method, defres)
#define CheckStmt(method, res)
char * Form(const char *fmt,...)
#define free
Definition: civetweb.c:1539
#define snprintf
Definition: civetweb.c:1540
#define malloc
Definition: civetweb.c:1536
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:37
static ULong64_t fgAllocSizeLimit
void SetBuffersNumber(Int_t n)
Allocate buffers for statement parameters/ result fields.
void * BeforeSet(const char *method, Int_t npar, Int_t sqltype, Bool_t sig=kTRUE, ULong_t size=0)
Check boundary condition before setting value of parameter.
virtual Int_t GetNumFields()
Return number of fields in result set.
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 &)
Return field value as time stamp.
virtual const char * GetString(Int_t npar)
Return field value as string.
Bool_t IsSetParsMode() const
indicates when parameters bind should be called
virtual Bool_t SetString(Int_t npar, const char *value, Int_t maxsize=256)
Set parameter value as string.
const char * ConvertToString(Int_t npar)
Convert field value to string.
TMySQLStatement(const TMySQLStatement &)
virtual Bool_t Process()
Process statement.
virtual Bool_t GetTime(Int_t npar, Int_t &hour, Int_t &min, Int_t &sec)
Return field value as time.
MYSQL_STMT * fStmt
virtual Bool_t SetDate(Int_t npar, Int_t year, Int_t month, Int_t day)
Set parameter value as date.
virtual Bool_t GetBinary(Int_t npar, void *&mem, Long_t &size)
Return field value as binary array.
virtual Int_t GetNumAffectedRows()
Return number of affected rows after statement is processed.
virtual Bool_t NextResultRow()
Shift cursor to nect row in result set.
virtual Bool_t SetULong64(Int_t npar, ULong64_t value)
Set parameter value as unsigned 64-bit integer.
Int_t fWorkingMode
parameter definition structures
virtual Long_t GetLong(Int_t npar)
Return field value as long integer.
void FreeBuffers()
Release all buffers, used by statement.
Int_t fIterationCount
1 - setting parameters, 2 - retrieving results
virtual Bool_t SetDouble(Int_t npar, Double_t value)
Set parameter value as double.
virtual Bool_t SetInt(Int_t npar, Int_t value)
Set parameter value as integer.
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)
Set parameter value as date & time.
virtual Bool_t IsNull(Int_t npar)
Checks if field value is null.
Bool_t IsResultSetMode() const
virtual ~TMySQLStatement()
Destructor.
Bool_t SetSQLParamType(Int_t npar, int sqltype, Bool_t sig, ULong_t sqlsize=0)
Set parameter type to be used as buffer.
virtual Bool_t SetLong(Int_t npar, Long_t value)
Set parameter value as long integer.
virtual Bool_t SetTime(Int_t npar, Int_t hour, Int_t min, Int_t sec)
Set parameter value as time.
virtual void Close(Option_t *="")
Close statement.
TParamData * fBuffer
array of bind data
virtual Bool_t SetUInt(Int_t npar, UInt_t value)
Set parameter value as unsigned integer.
virtual Bool_t NextIteration()
Increment iteration counter for statement, where parameter can be set.
Bool_t fNeedParBind
number of iteration
virtual Bool_t SetNull(Int_t npar)
Set NULL as parameter value.
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)
Set parameter value as timestamp.
virtual UInt_t GetUInt(Int_t npar)
Return field value as unsigned integer.
virtual Int_t GetInt(Int_t npar)
Return field value as integer.
virtual Bool_t SetLong64(Int_t npar, Long64_t value)
Set parameter value as 64-bit integer.
virtual Bool_t GetDate(Int_t npar, Int_t &year, Int_t &month, Int_t &day)
Return field value as date.
virtual ULong64_t GetULong64(Int_t npar)
Return field value as unsigned 64-bit integer.
Int_t fNumBuffers
executed statement
virtual const char * GetFieldName(Int_t nfield)
Returns field name in result set.
virtual Double_t GetDouble(Int_t npar)
Return field value as double.
virtual Bool_t SetBinary(Int_t npar, void *mem, Long_t size, Long_t maxsize=0x1000)
Set parameter value as binary data.
virtual Bool_t StoreResult()
Store result of statement processing to access them via GetInt(), GetDouble() and so on methods.
virtual Int_t GetNumParameters()
Return number of statement parameters.
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)
Return field value as date & time.
virtual Long64_t GetLong64(Int_t npar)
Return field value as 64-bit integer.
long double ConvertToNumeric(Int_t npar)
Convert field to numeric value.
MYSQL_BIND * fBind
number of statement parameters
static const char * GetFloatFormat()
return current printf format for float/double members, default "%e"
Definition: TSQLServer.cxx:269
void SetError(Int_t code, const char *msg, const char *method=0)
set new values for error fields if method specified, displays error message
void ClearError()
reset error fields
const Int_t n
Definition: legend1.C:16
char * fFieldName
special buffer to be used for string conversions
Bool_t fSign
sqltype of parameter
char * fStrBuffer
indicates if argument is null
ULong_t fResLength
signed - not signed type
Int_t fSize
allocated data buffer
my_bool fResNull
length argument
Int_t fSqlType
size of allocated data