![]() |
|
|||
File indexing completed on 2025-08-03 08:22:03
0001 // $Id: MySQLResultSet.cxx,v 1.1.1.1 2004/02/18 20:58:02 dave Exp $ 0002 //*-- Author : Valeriy Onuchin 26/02/2001 0003 // 0004 // RDBC driver to MySQL database implemented with MySQL C API. 0005 // 0006 // ++ The code consists of some parts stolen from mm JDBC and 0007 // MyODBC ODBC drivers and other mysql-related open sources. 0008 // 0009 0010 // 0011 ///////////////////////////////////////////////////////////////////// 0012 // 0013 // A TSQLResultSet provides access to a table of data. A 0014 // TSQLResultSet object is usually generated by executing 0015 // TSQLStatement. 0016 // 0017 // A TSQLResultSet maintains a cursor pointing to its current row 0018 // of data. Initially the cursor is positioned before the first 0019 // row. The Next() method moves the cursor to the next row. 0020 // 0021 // The GetXXX methods retrieve column values for the current row. 0022 // You can retrieve values using either the index number of the 0023 // column or the name of the column. In general,using the column 0024 // index will be more efficient. Columns are numbered from 1. 0025 // 0026 // For maximum portability, TSQLResultSet columns within each row 0027 // should be read in left-to-right order and each column should be 0028 // read only once. 0029 // 0030 // For the GetXXX methods, the driver attempts to convert the 0031 // underlying data to the specified ROOT type and returns a suitable 0032 // value. See the specification for allowable mappings 0033 // from SQL types to ROOT types with the TSQLResultSet::GetXXX 0034 // methods. 0035 // 0036 // Column names used as input to GetXXX methods are case 0037 // insensitive. When performing a GetXXX using a column name, 0038 // if several columns have the same name, then the value of the 0039 // first matching column will be returned. The column name option 0040 // is designed to be used when column names are used in the SQL 0041 // query. For columns that are NOT explicitly named in the query, 0042 // it is best to use column numbers. If column names are used, there 0043 // is no way for the programmer to guarantee that they actually refer 0044 // to the intended columns. 0045 // 0046 // A TSQLResultSet is automatically closed by the TSQLStatement that 0047 // generated it when that TSQLStatement is closed, re-executed, 0048 // or used to retrieve the next result from a sequence of multiple 0049 // results. 0050 // 0051 // The number, types and properties of a TSQLResultSet's columns are 0052 // provided by the TSQLResulSetMetaData object returned by the 0053 // GetMetaData() method. 0054 // 0055 // See also: 0056 // TSQLStatement::ExecuteQuery(const TString&), 0057 // TSQLStatement::GetResultSet(), TSQLResultSetMetaData 0058 // 0059 //___________________________________________________________________ 0060 // 0061 // kCONCUR_READ_ONLY 0062 // 0063 // The concurrency mode for a TSQLResultSet object that may 0064 // NOT be updated. 0065 //___________________________________________________________________ 0066 // 0067 // kCONCUR_UPDATABLE 0068 // 0069 // The concurrency mode for a TSQLResultSet 0070 // object that may be updated. 0071 //___________________________________________________________________ 0072 // 0073 // kFETCH_FORWARD 0074 // 0075 // The rows in a result set will be 0076 // processed in a forward direction; first-to-last. 0077 //___________________________________________________________________ 0078 // 0079 // kFETCH_REVERSE 0080 // 0081 // The rows in a result set will be 0082 // processed in a reverse direction; last-to-first. 0083 //___________________________________________________________________ 0084 // 0085 // kFETCH_UNKNOWN 0086 // 0087 // The order in which rows in a result set 0088 // will be processed is unknown. 0089 //___________________________________________________________________ 0090 // 0091 // kTYPE_FORWARD_ONLY 0092 // 0093 // The type for a TSQLResultSet object whose 0094 // cursor may move only forward. 0095 //___________________________________________________________________ 0096 // 0097 // kTYPE_SCROLL_INSENSITIVE 0098 // 0099 // The type for a TSQLResultSet object that is 0100 // scrollable but generally not sensitive to changes made by 0101 // others. 0102 //___________________________________________________________________ 0103 // 0104 // kTYPE_SCROLL_SENSITIVE 0105 // 0106 // The type for a TSQLResultSet object that is 0107 // scrollable and generally sensitive to changes made by 0108 // others. 0109 // 0110 ///////////////////////////////////////////////////////////////////// 0111 0112 #include <RDBC/TSQLResultSet.h> 0113 #include <RDBC/TSQLResultSetMetaData.h> 0114 #include <RDBC/TSQLStatement.h> 0115 #include <TList.h> 0116 #include <TMath.h> 0117 #include <TStopwatch.h> 0118 #include <TBuffer.h> 0119 #include <TTree.h> 0120 #include <TRandom.h> 0121 #include <TBranch.h> 0122 #include <iostream> 0123 #include <sstream> 0124 #include <ctype.h> 0125 #include <time.h> 0126 0127 #include <TSQLRow.h> 0128 #include "MySQLResultSetPrivate.h" 0129 0130 ClassImpQ(TSQLResultSet) 0131 0132 ///////////////////////////////////////////////////////////////////// 0133 // 0134 // MySQLRow rewritten from TMySQLRow 0135 // 0136 ///////////////////////////////////////////////////////////////////// 0137 class MySQLRow: public TSQLRow 0138 { 0139 friend class TSQLResultSet; 0140 0141 private: 0142 0143 MYSQL_RES *fResult; // current result set 0144 MYSQL_ROW fFields; // current row 0145 ULong_t *fFieldLength; // length of each field in the row 0146 0147 MySQLRow(void *res) 0148 { 0149 fResult = (MYSQL_RES *) res; 0150 fFields = (MYSQL_ROW)fResult->current_row; 0151 fFieldLength = 0; 0152 } 0153 0154 MySQLRow* Set(void *res) 0155 { 0156 fResult = (MYSQL_RES *) res; 0157 fFields = (MYSQL_ROW)fResult->current_row; 0158 fFieldLength = 0; 0159 return this; 0160 } 0161 0162 virtual ~MySQLRow() 0163 { 0164 if(fFields) Close(); 0165 } 0166 0167 void Close(Option_t *opt="") 0168 { 0169 // Close row. 0170 0171 if (!fFields) return; 0172 0173 fFields = 0; 0174 fResult = 0; 0175 fFieldLength = 0; 0176 } 0177 0178 Bool_t IsValid(Int_t field) 0179 { 0180 // Check if row is open and field index within range. 0181 0182 if (!fFields) { 0183 // Error("IsValid", "row closed"); 0184 return kFALSE; 0185 } 0186 0187 if (field < 0 || field >= (Int_t)mysql_num_fields(fResult)) { 0188 //Error("IsValid", "field index out of bounds"); 0189 return kFALSE; 0190 } 0191 return kTRUE; 0192 } 0193 0194 ULong_t GetFieldLength(Int_t field) 0195 { 0196 // Get length in bytes of specified field. 0197 0198 if (!IsValid(field)) return 0; 0199 0200 if (!fFieldLength) 0201 fFieldLength = mysql_fetch_lengths(fResult); 0202 0203 if (!fFieldLength) { 0204 // Error("GetFieldLength", "cannot get field length"); 0205 return 0; 0206 } 0207 0208 return fFieldLength[field]; 0209 } 0210 0211 const char* GetField(Int_t field) 0212 { 0213 // Get specified field from row (0 <= field < GetFieldCount()). 0214 0215 if (!IsValid(field)) return 0; 0216 0217 return fFields[field]; 0218 } 0219 }; 0220 0221 ///////////////////////////////////////////////////////////////////// 0222 //___________________________________________________________________ 0223 TSQLResultSet::TSQLResultSet(TSQLStatement* stmt,void* imp):TSQL(imp) 0224 { 0225 // ctor 0226 0227 fStatement = stmt; 0228 MySQLResultSetPrivate* pd = (MySQLResultSetPrivate*)fImp; 0229 fRow = new RDBCRow(pd->fMYSQL_RES); 0230 fMetaData = 0; // create it later, when TSQLResultSet::GetMetaData() 0231 } 0232 0233 //___________________________________________________________________ 0234 TSQLResultSet::~TSQLResultSet() 0235 { 0236 // destructor. 0237 0238 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0239 0240 if(fMetaData) delete fMetaData; 0241 if(fRow) delete fRow; 0242 if(imp) delete imp; 0243 0244 Destroyed(); 0245 } 0246 0247 //___________________________________________________________________ 0248 Bool_t TSQLResultSet::WasNull() 0249 { 0250 // Reports whether the last column read had a value of SQL NULL. 0251 // Note that you must first call GetXXX on a column to try to 0252 // read its value and then call WasNull() to see if the value 0253 // read was SQL NULL. 0254 // 0255 // Returns: 0256 // kTRUE if last column read was SQL NULL and 0257 // kFALSE - otherwise 0258 // Throws: 0259 // TSQLException - if a database access error occurs 0260 0261 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0262 return imp->fWasNull; 0263 } 0264 0265 //___________________________________________________________________ 0266 TString TSQLResultSet::GetString( Int_t columnIndex ) 0267 { 0268 // Gets the value of a column in the current row as a TString. 0269 // 0270 // Parameters: 0271 // columnIndex - the first column is 1, the second is 2, ... 0272 // Returns: 0273 // the column value; if the value is SQL NULL, the result 0274 // is null 0275 // Throws: 0276 // TSQLException - if a database access error occurs 0277 0278 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0279 0280 if(!imp->fMYSQL_RES->field_count) { 0281 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0282 return ""; 0283 } 0284 0285 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0286 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0287 return ""; 0288 } 0289 0290 return imp->fMYSQL_RES->current_row[columnIndex-1]; 0291 } 0292 0293 //___________________________________________________________________ 0294 Bool_t TSQLResultSet::GetBoolean( Int_t columnIndex ) 0295 { 0296 // Gets the value of a column in the current row as a boolean. 0297 // 0298 // Parameters: 0299 // columnIndex - the first column is 1, the second is 2, ... 0300 // Returns: 0301 // the column value; if the value is SQL NULL, the result is 0302 // kFALSE 0303 // Throws: 0304 // TSQLException - if a database access error occurs 0305 0306 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0307 0308 if(!imp->fMYSQL_RES->field_count) { 0309 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002",)); 0310 return kFALSE; 0311 } 0312 0313 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0314 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0315 return kFALSE; 0316 } 0317 0318 const char* str = imp->fMYSQL_RES->current_row[columnIndex-1]; 0319 0320 return ( str && strlen(str) ) ? 0321 (str[0] == 't') || (str[0] == 'T') || 0322 (str[0] == 'y') || (str[0] == 'Y') || 0323 (str[0] == '1') || (str[0] == '1') : kFALSE; 0324 } 0325 0326 //___________________________________________________________________ 0327 Char_t TSQLResultSet::GetByte( Int_t columnIndex ) 0328 { 0329 // Gets the value of a column in the current row as a byte. 0330 // 0331 // Parameters: 0332 // columnIndex - the first column is 1, the second is 2, ... 0333 // Returns: 0334 // the column value; if the value is SQL NULL, 0335 // the result is 0 0336 // Throws: 0337 // TSQLException - if a database access error occurs 0338 0339 Char_t return_value = 0; 0340 0341 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0342 0343 if(!imp->fMYSQL_RES->field_count) { 0344 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0345 return 0; 0346 } 0347 0348 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0349 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0350 return 0; 0351 } 0352 0353 const char* str = imp->fMYSQL_RES->current_row[columnIndex-1]; 0354 0355 switch( imp->MYSQL_RES->fields[column-1].type ) { 0356 case FIELD_TYPE_DECIMAL: 0357 case FIELD_TYPE_TINY: 0358 case FIELD_TYPE_SHORT: 0359 case FIELD_TYPE_LONG: 0360 case FIELD_TYPE_FLOAT: 0361 case FIELD_TYPE_DOUBLE: 0362 case FIELD_TYPE_LONGLONG: 0363 case FIELD_TYPE_INT24: 0364 return (Char_t)atoi(str); 0365 default: 0366 return str[0]; 0367 } 0368 return 0; // not reached 0369 } 0370 0371 //___________________________________________________________________ 0372 Short_t TSQLResultSet::GetShort( Int_t columnIndex ) 0373 { 0374 // Gets the value of a column in the current row as a Short_t. 0375 // 0376 // Parameters: 0377 // columnIndex - the first column is 1, the second is 2, ... 0378 // Returns: 0379 // the column value; if the value is SQL NULL, 0380 // the result is 0 0381 // Throws: 0382 // TSQLException - if a database access error occurs 0383 0384 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0385 0386 if(!imp->fMYSQL_RES->field_count) { 0387 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0388 return 0; 0389 } 0390 0391 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0392 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0393 return 0; 0394 } 0395 0396 return (Short_t)atoi(imp->fMYSQL_RES->current_row[columnIndex-1]); 0397 } 0398 0399 //___________________________________________________________________ 0400 Int_t TSQLResultSet::GetInt( Int_t columnIndex ) 0401 { 0402 // Gets the value of a column in the current row as a Int_t. 0403 // 0404 // Parameters: 0405 // columnIndex - the first column is 1, the second is 2, ... 0406 // Returns: 0407 // the column value; if the value is SQL NULL, 0408 // the result is 0 0409 // Throws: 0410 // TSQLException - if a database access error occurs 0411 0412 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0413 0414 if(!imp->fMYSQL_RES->field_count) { 0415 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0416 return 0; 0417 } 0418 0419 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0420 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0421 return 0; 0422 } 0423 0424 return (Int_t)atoi(imp->fMYSQL_RES->current_row[columnIndex-1]); 0425 } 0426 0427 //___________________________________________________________________ 0428 Long_t TSQLResultSet::GetLong( Int_t columnIndex ) 0429 { 0430 // Gets the value of a column in the current row as a Long_t. 0431 // 0432 // Parameters: 0433 // columnIndex - the first column is 1, the second is 2, ... 0434 // Returns: 0435 // the column value; if the value is SQL NULL, 0436 // the result is 0 0437 // Throws: 0438 // TSQLException - if a database access error occurs 0439 0440 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0441 0442 if(!imp->fMYSQL_RES->field_count) { 0443 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0444 return 0; 0445 } 0446 0447 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0448 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0449 return 0; 0450 } 0451 0452 char* value = imp->fMYSQL_RES->current_row[columnIndex-1]; 0453 Int_t length = strlen(value); 0454 0455 // .... MyDOBC says "Check if it could be a date...... :)" 0456 0457 if( length >= 10 && value[4] == '-' && value[7] == '-' && (!value[10] || value[10] == ' ') ) { 0458 return ((Long_t) atol(value)*10000L+(Long_t) atol(value+5)*100L+(Long_t) atol(value+8)); 0459 } else { 0460 return (Long_t)atol(value); 0461 } 0462 } 0463 0464 //___________________________________________________________________ 0465 Float_t TSQLResultSet::GetFloat( Int_t columnIndex ) 0466 { 0467 // Gets the value of a column in the current row as a Float_t. 0468 // 0469 // Parameters: 0470 // columnIndex - the first column is 1, the second is 2, ... 0471 // Returns: 0472 // the column value; if the value is SQL NULL, 0473 // the result is 0 0474 // Throws: 0475 // TSQLException - if a database access error occurs 0476 0477 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0478 0479 if(!imp->fMYSQL_RES->field_count) { 0480 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0481 return 0; 0482 } 0483 0484 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0485 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0486 return 0; 0487 } 0488 0489 return (Float_t)atof(imp->fMYSQL_RES->current_row[columnIndex-1]); 0490 } 0491 0492 //___________________________________________________________________ 0493 Double_t TSQLResultSet::GetDouble( Int_t columnIndex ) 0494 { 0495 // Gets the value of a column in the current row as a Double_t. 0496 // 0497 // Parameters: 0498 // columnIndex - the first column is 1, the second is 2, ... 0499 // Returns: 0500 // the column value; if the value is SQL NULL, 0501 // the result is 0 0502 // Throws: 0503 // TSQLException - if a database access error occurs 0504 0505 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0506 0507 if(!imp->fMYSQL_RES->field_count) { 0508 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0509 return 0; 0510 } 0511 0512 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0513 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0514 return 0; 0515 } 0516 0517 return (Double_t)atof(imp->fMYSQL_RES->current_row[columnIndex-1]); 0518 } 0519 0520 //___________________________________________________________________ 0521 TArrayC TSQLResultSet::GetBytes( Int_t columnIndex ) 0522 { 0523 // Gets the value of a column in the current row as a char array. 0524 // The chars represent the raw values returned by the driver. 0525 // 0526 // Parameters: 0527 // columnIndex - the first column is 1, the second is 2, ... 0528 // Returns: 0529 // the column value; if the value is SQL NULL, 0530 // the result is null 0531 // Throws: 0532 // TSQLException - if a database access error occurs 0533 0534 TArrayC array; 0535 0536 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0537 0538 if(!imp->fMYSQL_RES->field_count) { 0539 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0540 return array; 0541 } 0542 0543 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0544 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0545 return array; 0546 } 0547 0548 return array; 0549 } 0550 0551 //___________________________________________________________________ 0552 TSQLDate TSQLResultSet::GetDate( Int_t columnIndex ) 0553 { 0554 // Gets the value of a column in the current row as a TSQLDate 0555 // object. 0556 // 0557 // Parameters: 0558 // columnIndex - the first column is 1, the second is 2, ... 0559 // Returns: 0560 // the column value; if the value is SQL NULL, 0561 // the result is null 0562 // Throws: 0563 // TSQLException - if a database access error occurs 0564 0565 TSQLDate return_value; 0566 0567 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0568 0569 if(!imp->fMYSQL_RES->field_count) { 0570 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0571 return ; 0572 } 0573 0574 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0575 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0576 return ; 0577 } 0578 0579 return return_value; 0580 } 0581 0582 //___________________________________________________________________ 0583 TSQLTime TSQLResultSet::GetTime( Int_t columnIndex ) 0584 { 0585 // Gets the value of a column in the current row as a TSQLTime 0586 // object. 0587 // 0588 // Parameters: 0589 // columnIndex - the first column is 1, the second is 2, ... 0590 // Returns: 0591 // the column value; if the value is SQL NULL, 0592 // the result is null 0593 // Throws: 0594 // TSQLException - if a database access error occurs 0595 0596 TSQLTime return_value; 0597 0598 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0599 0600 if(!imp->fMYSQL_RES->field_count) { 0601 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0602 return ; 0603 } 0604 0605 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0606 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0607 return ; 0608 } 0609 0610 return return_value; 0611 } 0612 0613 //___________________________________________________________________ 0614 TSQLTimestamp TSQLResultSet::GetTimestamp( Int_t columnIndex ) 0615 { 0616 // Gets the value of a column in the current row as a 0617 // TSQLTimestamp object. 0618 // 0619 // Parameters: 0620 // columnIndex - the first column is 1, the second is 2, ... 0621 // Returns: 0622 // the column value; if the value is SQL NULL, 0623 // the result is null 0624 // Throws: 0625 // TSQLException - if a database access error occurs 0626 0627 TSQLTimestamp return_value; 0628 0629 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0630 0631 if(!imp->fMYSQL_RES->field_count) { 0632 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0633 return ; 0634 } 0635 0636 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0637 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0638 return ; 0639 } 0640 0641 return return_value; 0642 } 0643 0644 //___________________________________________________________________ 0645 TBuffer* TSQLResultSet::GetAsciiStream( Int_t columnIndex ) 0646 { 0647 // Gets the value of a column in the current row as a stream 0648 // of ASCII characters. The value can then be read in chunks from 0649 // the stream. This method is particularly suitable for 0650 // retrieving large LONGVARCHAR values. The driver will do 0651 // any necessary conversion from the database format into ASCII. 0652 // 0653 // Note: All the data in the returned stream must be read prior 0654 // to getting the value of any other column. The next call to 0655 // a get method implicitly closes the stream. Also, a stream 0656 // may return 0 when the method available is called whether 0657 // there is data available or not. 0658 // 0659 // Parameters: 0660 // columnIndex - the first column is 1, the second is 2, ... 0661 // Returns: 0662 // A TBuffer that delivers the database column 0663 // value as a stream of one char ASCII characters. 0664 // If the value is SQL NULL then the result is null. 0665 // 0666 // Throws: 0667 // TSQLException - if a database access error occurs 0668 0669 TBuffer* buffer = 0; 0670 0671 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0672 0673 if(!imp->fMYSQL_RES->field_count) { 0674 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0675 return buffer; 0676 } 0677 0678 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0679 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0680 return buffer; 0681 } 0682 0683 return buffer; 0684 } 0685 0686 //___________________________________________________________________ 0687 TBuffer* TSQLResultSet::GetBinaryStream( Int_t columnIndex ) 0688 { 0689 // Gets the value of a column in the current row as a stream of 0690 // uninterpreted chars. The value can then be read in chunks 0691 // from the stream. This method is particularly suitable for 0692 // retrieving large LONGVARBINARY values. 0693 // 0694 // Note: All the data in the returned stream must be read 0695 // prior to getting the value of any other column. The next 0696 // call to a Get method implicitly closes the stream. Also, 0697 // a stream may return 0 when the method available is called 0698 // whether there is data available or not. 0699 // 0700 // Parameters: 0701 // columnIndex - the first column is 1, the second is 2, ... 0702 // Returns: 0703 // TBuffer that delivers the database column 0704 // value as a stream of uninterpreted chars. If the value 0705 // is SQL NULL then the result is null. 0706 // Throws: 0707 // TSQLException - if a database access error occurs 0708 0709 TBuffer* buffer = 0; 0710 0711 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0712 0713 if(!imp->fMYSQL_RES->field_count) { 0714 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0715 return buffer; 0716 } 0717 0718 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0719 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0720 return buffer; 0721 } 0722 0723 return buffer; 0724 } 0725 0726 //___________________________________________________________________ 0727 TObject* TSQLResultSet::GetObject( Int_t columnIndex ) 0728 { 0729 // Gets the value of a column in the current row as ROOT object. 0730 // 0731 // Parameters: 0732 // columnIndex - the first column is 1, the second is 2, ... 0733 // Returns: 0734 // TObject 0735 // Throws: 0736 // TSQLException - if a database access error occurs 0737 0738 TObject* obj =0; 0739 0740 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 0741 0742 if(!imp->fMYSQL_RES->field_count) { 0743 Throw(new TSQLException("Query generated no fields for ResultSet", "S1002")); 0744 return obj; 0745 } 0746 0747 if( (UInt_t)(columnIndex-1) >= imp->fMYSQL_RES->field_count ) { 0748 Throw(new TSQLException(Form("Invalid column number ( %d > %d )",columnIndex,imp->fMYSQL_RES->field_count+1),"S1002",); 0749 return obj; 0750 } 0751 0752 TBuffer *b = GetBinaryStream(columnIndex); 0753 obj = b->ReadObject(TObject::Class()); 0754 b->DetachBuffer(); 0755 delete b; 0756 return obj; 0757 } 0758 0759 //___________________________________________________________________ 0760 TString TSQLResultSet::GetString( const TString& columnName ) 0761 { 0762 // Gets the value of a column in the current row as a TString. 0763 // 0764 // Parameters: 0765 // columnName - the SQL name of the column 0766 // Returns: 0767 // the column value; if the value is SQL NULL, 0768 // the result is null 0769 // Throws: 0770 // TSQLException - if a database access error occurs 0771 0772 return GetString(FindColumn(columnName)); 0773 } 0774 0775 //___________________________________________________________________ 0776 Bool_t TSQLResultSet::GetBoolean( const TString& columnName ) 0777 { 0778 // Gets the value of a column in the current row as a boolean. 0779 // 0780 // Parameters: 0781 // columnName - the SQL name of the column 0782 // Returns: 0783 // the column value; if the value is SQL NULL, 0784 // the result is kFALSE 0785 // Throws: 0786 // TSQLException - if a database access error occurs 0787 0788 return GetBoolean(FindColumn(columnName)); 0789 } 0790 0791 //___________________________________________________________________ 0792 Char_t TSQLResultSet::GetByte( const TString& columnName ) 0793 { 0794 // Gets the value of a column in the current row as a Char_t. 0795 // 0796 // Parameters: 0797 // columnName - the SQL name of the column 0798 // Returns: 0799 // the column value; if the value is SQL NULL, 0800 // the result is 0 0801 // Throws: 0802 // TSQLException - if a database access error occurs 0803 0804 return GetByte(FindColumn(columnName)); 0805 } 0806 0807 //___________________________________________________________________ 0808 Short_t TSQLResultSet::GetShort( const TString& columnName ) 0809 { 0810 // Gets the value of a column in the current row as a Short_t. 0811 // 0812 // Parameters: 0813 // columnName - the SQL name of the column 0814 // Returns: 0815 // the column value; if the value is SQL NULL, 0816 // the result is 0 0817 // Throws: 0818 // TSQLException - if a database access error occurs 0819 0820 return GetShort(FindColumn(columnName)); 0821 } 0822 0823 //___________________________________________________________________ 0824 Int_t TSQLResultSet::GetInt( const TString& columnName ) 0825 { 0826 // Gets the value of a column in the current row as a Int_t. 0827 // 0828 // Parameters: 0829 // columnName - the SQL name of the column 0830 // Returns: 0831 // the column value; if the value is SQL NULL, 0832 // the result is 0 0833 // Throws: 0834 // TSQLException - if a database access error occurs 0835 0836 return GetInt(FindColumn(columnName)); 0837 } 0838 0839 //___________________________________________________________________ 0840 Long_t TSQLResultSet::GetLong( const TString& columnName ) 0841 { 0842 // Gets the value of a column in the current row as a Long_t. 0843 // 0844 // Parameters: 0845 // columnName - the SQL name of the column 0846 // Returns: 0847 // the column value; if the value is SQL NULL, 0848 // the result is 0 0849 // Throws: 0850 // TSQLException - if a database access error occurs 0851 0852 return GetLong(FindColumn(columnName)); 0853 } 0854 0855 //___________________________________________________________________ 0856 Float_t TSQLResultSet::GetFloat( const TString& columnName ) 0857 { 0858 // Gets the value of a column in the current row as a Float_t. 0859 // 0860 // Parameters: 0861 // columnName - the SQL name of the column 0862 // Returns: 0863 // the column value; if the value is SQL NULL, 0864 // the result is 0 0865 // Throws: 0866 // TSQLException - if a database access error occurs 0867 0868 return GetFloat(FindColumn(columnName)); 0869 } 0870 0871 //___________________________________________________________________ 0872 Double_t TSQLResultSet::GetDouble( const TString& columnName ) 0873 { 0874 // Gets the value of a column in the current row as a Double_t. 0875 // 0876 // Parameters: 0877 // columnName - the SQL name of the column 0878 // Returns: 0879 // the column value; if the value is SQL NULL, 0880 // the result is 0 0881 // Throws: 0882 // TSQLException - if a database access error occurs 0883 0884 return GetDouble(FindColumn(columnName)); 0885 } 0886 0887 //___________________________________________________________________ 0888 TArrayC TSQLResultSet::GetBytes( const TString& columnName ) 0889 { 0890 // Gets the value of a column in the current row as a char 0891 // array. The chars represent the raw values returned by the 0892 // driver. 0893 // 0894 // Parameters: 0895 // columnName - the SQL name of the column 0896 // Returns: 0897 // the column value; if the value is SQL NULL, 0898 // the result is null 0899 // Throws: 0900 // TSQLException - if a database access error occurs 0901 0902 return GetBytes(FindColumn(columnName)); 0903 } 0904 0905 //___________________________________________________________________ 0906 TSQLDate TSQLResultSet::GetDate( const TString& columnName ) 0907 { 0908 // Gets the value of a column in the current row as a TSQLDate 0909 // object. 0910 // 0911 // Parameters: 0912 // columnName - the SQL name of the column 0913 // Returns: 0914 // the column value; if the value is SQL NULL, 0915 // the result is null 0916 // Throws: 0917 // TSQLException - if a database access error occurs 0918 0919 return GetDate(FindColumn(columnName)); 0920 } 0921 0922 //___________________________________________________________________ 0923 TSQLTime TSQLResultSet::GetTime( const TString& columnName ) 0924 { 0925 // Gets the value of a column in the current row as a TSQLTime 0926 // object. 0927 // 0928 // Parameters: 0929 // columnName - the SQL name of the column 0930 // Returns: 0931 // the column value; if the value is SQL NULL, 0932 // the result is null 0933 // Throws: 0934 // TSQLException - if a database access error occurs 0935 0936 return GetTime(FindColumn(columnName)); 0937 } 0938 0939 //___________________________________________________________________ 0940 TSQLTimestamp TSQLResultSet::GetTimestamp( const TString& columnName ) 0941 { 0942 // Gets the value of a column in the current row as a 0943 // TSQLTimestamp object. 0944 // 0945 // Parameters: 0946 // columnName - the SQL name of the column 0947 // Returns: 0948 // the column value; if the value is SQL NULL, 0949 // the result is null 0950 // Throws: 0951 // TSQLException - if a database access error occurs 0952 0953 return GetTimestamp(FindColumn(columnName)); 0954 } 0955 0956 //___________________________________________________________________ 0957 TBuffer* TSQLResultSet::GetAsciiStream( const TString& columnName ) 0958 { 0959 // Gets the value of a column in the current row as a stream 0960 // of ASCII characters. The value can then be read in chunks 0961 // from the stream. This method is particularly suitable for 0962 // retrieving large LONGVARCHAR values. The driver will do 0963 // any necessary conversion from the database format into ASCII. 0964 // 0965 // Note: All the data in the returned stream must be read prior 0966 // to getting the value of any other column. The next call to 0967 // a Get method implicitly closes the stream. Also, a stream 0968 // may return 0 when the method available is called whether 0969 // there is data available or not. 0970 // 0971 // Parameters: 0972 // columnName - the SQL name of the column 0973 // Returns: 0974 // TBuffer that delivers the database column 0975 // value as a stream of one char ASCII characters. If 0976 // the value is SQL NULL then the result is null. 0977 // Throws: 0978 // TSQLException - if a database access error occurs 0979 0980 return GetAsciiStream(FindColumn(columnName)); 0981 } 0982 0983 //___________________________________________________________________ 0984 TBuffer* TSQLResultSet::GetBinaryStream( const TString& columnName ) 0985 { 0986 // Gets the value of a column in the current row as a stream of 0987 // uninterpreted chars. The value can then be read in chunks 0988 // from the stream. This method is particularly suitable for 0989 // retrieving large LONGVARBINARY values. The driver will 0990 // do any necessary conversion from the database format into 0991 // uninterpreted chars. 0992 // 0993 // Note: All the data in the returned stream must be read 0994 // prior to getting the value of any other column. The next 0995 // call to a Get method implicitly closes the stream. Also, 0996 // a stream may return 0 when the method available is called 0997 // whether there is data available or not. 0998 // 0999 // Parameters: 1000 // columnName - the SQL name of the column 1001 // Returns: 1002 // TBuffer that delivers the database column 1003 // value as a stream of uninterpreted chars. If the value 1004 // is SQL NULL then the result is null. 1005 // Throws: 1006 // TSQLException - if a database access error occurs 1007 1008 return GetBinaryStream(FindColumn(columnName)); 1009 } 1010 1011 //___________________________________________________________________ 1012 TObject* TSQLResultSet::GetObject( const TString& columnName ) 1013 { 1014 // Gets the value of a column in the current row as ROOT object. 1015 // 1016 // Parameters: 1017 // columnIndex - the first column is 1, the second is 2, ... 1018 // Returns: 1019 // TObject 1020 // Throws: 1021 // TSQLException - if a database access error occurs 1022 1023 return GetObject(FindColumn(columnName)); 1024 } 1025 1026 //___________________________________________________________________ 1027 TString TSQLResultSet::GetCursorName() 1028 { 1029 // Gets the name of the SQL cursor used by this TSQLResultSet. 1030 // 1031 // In SQL, a result table is retrieved through a cursor that 1032 // is named. The current row of a result can be updated or 1033 // deleted using a positioned Update/Delete statement that 1034 // references the cursor name. To insure that the cursor has 1035 // the proper isolation level to support update, the cursor's 1036 // select statement should be of the form 'SELECT FOR UPDATE'. 1037 // If the 'FOR UPDATE' clause is omitted the positioned 1038 // updates may fail. 1039 // The current row of a TSQLResultSet is also the current row 1040 // of this SQL cursor. 1041 // 1042 // Note: If positioned update is not supported a 1043 // SQLException is thrown 1044 // Returns: 1045 // the TSQLResultSet's SQL cursor name 1046 // Throws: 1047 // TSQLException - if a database access error occurs 1048 1049 return "NO_NAME"; // no cursors supported ... 1050 } 1051 1052 //___________________________________________________________________ 1053 TSQLResultSetMetaData* TSQLResultSet::GetMetaData() 1054 { 1055 // Retrieves the number, types and properties of a 1056 // TSQLResultSet's columns. 1057 // 1058 // Returns: 1059 // the description of a TSQLResultSet's columns 1060 // Throws: 1061 // TSQLException - if a database access error occurs 1062 1063 return fMetaData ? fMetaData : fMetaData = new TSQLResultSetMetaData(this,fImp); 1064 } 1065 1066 //___________________________________________________________________ 1067 Int_t TSQLResultSet::FindColumn( const TString& columnName ) 1068 { 1069 // Maps the given resultset column name to its TSQLResultSet 1070 // column index. 1071 // 1072 // Parameters: 1073 // columnName - the name of the column 1074 // Returns: 1075 // the column index 1076 // Throws: 1077 // TSQLException - if a database access error occurs 1078 1079 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1080 1081 for( int i=0; i < imp->fMYSQL_RES->field_count; i++ ) { 1082 !strcmp(columnName.Data(),imp->fMYSQL_RES->fields[i].name) ? return i :;; 1083 } 1084 return 0; 1085 } 1086 1087 //___________________________________________________________________ 1088 Bool_t TSQLResultSet::IsBeforeFirst() 1089 { 1090 // Indicates whether the cursor is before the first row in 1091 // the result set. 1092 // 1093 // Returns: 1094 // kTRUE if the cursor is before the first row, 1095 // kFALSE otherwise. Returns kFALSE when the 1096 // result set contains no rows. 1097 // Throws: 1098 // TSQLException - if a database access error occurs 1099 1100 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1101 return (!imp->fMYSQL_RES->row_count) ? kFALSE : (fCurrentRow == -1); 1102 } 1103 1104 //___________________________________________________________________ 1105 Bool_t TSQLResultSet::IsAfterLast() 1106 { 1107 // Indicates whether the cursor is after the last row in 1108 // the result set. 1109 // 1110 // Returns: 1111 // kTRUE if the cursor is after the last row, 1112 // kFALSE otherwise. Returns kFALSE when the 1113 // result set contains no rows. 1114 // Throws: 1115 // TSQLException - if a database access error occurs 1116 1117 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1118 return (!imp->fMYSQL_RES->row_count) ? kFALSE : (fCurrentRow == imp->fMYSQL_RES->row_count); 1119 } 1120 1121 //___________________________________________________________________ 1122 Bool_t TSQLResultSet::IsFirst() 1123 { 1124 // Indicates whether the cursor is on the first row of 1125 // the result set. 1126 // 1127 // Returns: 1128 // kTRUE if the cursor is on the first row, 1129 // kFALSE otherwise. 1130 // Throws: 1131 // TSQLException - if a database access error occurs 1132 1133 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1134 return (!imp->fMYSQL_RES->row_count) ? kFALSE : (fCurrentRow == 0); 1135 } 1136 1137 //___________________________________________________________________ 1138 Bool_t TSQLResultSet::IsLast() 1139 { 1140 // Indicates whether the cursor is on the last row of the 1141 // result set. 1142 // 1143 // Note: Calling the method IsLast() may be expensive because 1144 // the driver might need to fetch ahead one row in 1145 // order to determine whether the current row is the 1146 // last row in the result set. 1147 // 1148 // Returns: 1149 // kTRUE if the cursor is on the last row, 1150 // kFALSE otherwise. 1151 // Throws: 1152 // TSQLException - if a database access error occurs 1153 1154 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1155 return (!imp->fMYSQL_RES->row_count) ? kFALSE : (fCurrentRow == imp->fMYSQL_RES->row_count-1); 1156 } 1157 1158 //___________________________________________________________________ 1159 void TSQLResultSet::BeforeFirst() 1160 { 1161 // Moves the cursor to the front of the result set, just before 1162 // the first row. Has no effect if the result set contains no 1163 // rows. 1164 // 1165 // Throws: 1166 // TSQLException - if a database access error occurs or 1167 // the result set type is kTYPE_FORWARD_ONLY 1168 1169 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1170 1171 if( imp->fOnInsertRow ) imp->fOnInsertRow = kFALSE; 1172 if( imp->fDoingUpdates ) imp->fDoingUpdates = kFALSE; 1173 1174 if( !imp->fMYSQL_RES->row_count ) return; 1175 else { 1176 imp->fCurrentRow = -1; 1177 This_Row = null; 1178 } 1179 } 1180 1181 //___________________________________________________________________ 1182 void TSQLResultSet::AfterLast() 1183 { 1184 // Moves the cursor to the end of the result set, just after 1185 // the last row. Has no effect if the result set contains no 1186 // rows. 1187 // 1188 // Throws: 1189 // TSQLException - if a database access error occurs or 1190 // the result set type is kTYPE_FORWARD_ONLY 1191 1192 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1193 1194 if( imp->fOnInsertRow ) imp->fOnInsertRow = kFALSE; 1195 if( imp->fDoingUpdates ) imp->fDoingUpdates = kFALSE; 1196 1197 if( !imp->fMYSQL_RES->row_count ) { 1198 imp->fRurrentRow = imp->fMYSQL_RES->row_count; 1199 This_Row = null; 1200 } 1201 } 1202 1203 //___________________________________________________________________ 1204 Int_t TSQLResultSet::GetRow() 1205 { 1206 // Retrieves the current row number. The first row is number 1, 1207 // the second number 2, and so on. 1208 // 1209 // Returns: 1210 // the current row number; 0 if there is no current row 1211 // Throws: 1212 // TSQLException - if a database access error occurs 1213 1214 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 1215 1216 return ( imp->fCurrentRow < 0 || 1217 imp->fCurrentRow > imp->fMYSQL_RES->row_count ) ? 0 : imp->fCurrentRow+1; 1218 } 1219 1220 //___________________________________________________________________ 1221 //void TSQLResultSet::SetFetchDirection(Int_t direction) 1222 //{ 1223 // Gives a hint as to the direction in which the rows in this 1224 // result set will be processed. The initial value is determined 1225 // by the TSQLStatement that produced the result set. 1226 // The fetch direction may be changed at any time. 1227 // 1228 // Throws: 1229 // TSQLException - if a database access error occurs or 1230 // the result set type is kTYPE_FORWARD_ONLY and the fetch 1231 // direction is not forward 1232 // 1233 //} 1234 1235 //___________________________________________________________________ 1236 //Int_t TSQLResultSet::GetFetchDirection() 1237 //{ 1238 // Returns the fetch direction for this result set. 1239 // 1240 // Returns: 1241 // the current fetch direction for this result set 1242 // Throws: 1243 // TSQLException - if a database access error occurs 1244 // 1245 // using namespace odbc; 1246 // odbc::ResultSet* rs = (odbc::ResultSet*)fImp; 1247 // return_value = rs->getFetchDirection(); 1248 //} 1249 1250 //___________________________________________________________________ 1251 void TSQLResultSet::SetFetchSize(Int_t rows) 1252 { 1253 // Gives the driver a hint as to the number of rows that 1254 // should be fetched from the database when more rows are needed 1255 // for this result set. If the fetch size specified is zero, 1256 // the driver ignores the value and is free to make its own 1257 // best guess as to what the fetch size should be. The default 1258 // value is set by the statement that created the result set. 1259 // The fetch size may be changed at any time. 1260 // 1261 // Parameters: 1262 // rows - the number of rows to fetch 1263 // Throws: 1264 // TSQLException - if a database access error occurs or the 1265 // condition 0 <= rows <= GetMaxRows() is not satisfied. 1266 1267 if (rows < 0 /* || rows > getMaxRows()*/) { 1268 throw new SQLException("Value must be between 0 and getMaxRows()", "S1009"); 1269 } 1270 1271 _fetch_size = rows; 1272 } 1273 1274 //___________________________________________________________________ 1275 Int_t TSQLResultSet::GetFetchSize() 1276 { 1277 // Returns the fetch size for this result set. 1278 // 1279 // Returns: 1280 // the current fetch size for this result set 1281 // Throws: 1282 // TSQLException - if a database access error occurs 1283 1284 Int_t return_value = 0; 1285 1286 return return_value; 1287 } 1288 1289 //___________________________________________________________________ 1290 Int_t TSQLResultSet::GetType() 1291 { 1292 // Returns the type of this result set. The type is 1293 // determined by the TSQLStatement that created the result set. 1294 // 1295 // Returns: 1296 // kTYPE_FORWARD_ONLY, kTYPE_SCROLL_INSENSITIVE, or 1297 // kTYPE_SCROLL_SENSITIVE 1298 // Throws: 1299 // TSQLException - if a database access error occurs 1300 1301 Int_t return_value = kTYPE_SCROLL_INSENSITIVE; 1302 return return_value; 1303 } 1304 1305 //___________________________________________________________________ 1306 Int_t TSQLResultSet::GetConcurrency() 1307 { 1308 // Returns the concurrency mode of this result set. The 1309 // concurrency used is determined by the TSQLStatement that 1310 // created the result set. 1311 // 1312 // Returns: 1313 // the concurrency type, kCONCUR_READ_ONLY or 1314 // kCONCUR_UPDATABLE 1315 // Throws: 1316 // TSQLException - if a database access error occurs 1317 1318 Int_t return_value = 0; 1319 1320 return return_value; 1321 } 1322 1323 //___________________________________________________________________ 1324 Bool_t TSQLResultSet::RowUpdated() 1325 { 1326 // Indicates whether the current row has been updated. The 1327 // value returned depends on whether or not the result set 1328 // can detect updates. 1329 // 1330 // Returns: 1331 // kTRUE if the row has been visibly updated by 1332 // the owner or another, and updates are detected 1333 // Throws: 1334 // TSQLException - if a database access error occurs 1335 // See Also: 1336 // TSQLDatabaseMetaData::updatesAreDetected(Int_t) 1337 1338 Bool_t return_value = kFALSE; 1339 1340 return return_value; 1341 } 1342 1343 //___________________________________________________________________ 1344 Bool_t TSQLResultSet::RowInserted() 1345 { 1346 // Indicates whether the current row has had an insertion. 1347 // The value returned depends on whether or not the 1348 // result set can detect visible inserts. 1349 // 1350 // Returns: 1351 // kTRUE if a row has had an insertion and insertions 1352 // are detected 1353 // Throws: 1354 // TSQLException - if a database access error occurs 1355 // See Also: 1356 // TSQLDatabaseMetaData::insertsAreDetected(Int_t) 1357 1358 Bool_t return_value = kFALSE; 1359 1360 return return_value; 1361 } 1362 1363 //___________________________________________________________________ 1364 Bool_t TSQLResultSet::RowDeleted() 1365 { 1366 // Indicates whether a row has been deleted. A deleted row 1367 // may leave a visible "hole" in a result set. This method 1368 // can be used to detect holes in a result set. The value 1369 // returned depends on whether or not the result set can 1370 // detect deletions. 1371 // 1372 // Returns: 1373 // kTRUE if a row was deleted and deletions are detected 1374 // Throws: 1375 // TSQLException - if a database access error occurs 1376 // See Also: 1377 // TSQLDatabaseMetaData::deletesAreDetected(Int_t) 1378 1379 Bool_t return_value = kFALSE; 1380 1381 return return_value; 1382 } 1383 1384 //___________________________________________________________________ 1385 void TSQLResultSet::UpdateNull( Int_t columnIndex ) 1386 { 1387 // Give a nullable column a null value. The UpdateXXX methods 1388 // are used to update column values in the current row, 1389 // or the insert row. The UpdateXXX methods do not update the 1390 // underlying database; instead the UpdateRow() or InsertRow() 1391 // methods are called to update the database. 1392 // 1393 // Parameters: 1394 // columnIndex - the first column is 1, the second is 2, ... 1395 // Throws: 1396 // TSQLException - if a database access error occurs 1397 1398 } 1399 1400 //___________________________________________________________________ 1401 void TSQLResultSet::UpdateBoolean( Int_t columnIndex,Bool_t x ) 1402 { 1403 // Updates a column with a boolean value. The UpdateXXX 1404 // methods are used to update column values in the current row, 1405 // or the insert row. The UpdateXXX methods do not update the 1406 // underlying database; instead the UpdateRow() or InsertRow() 1407 // methods are called to update the database. 1408 // 1409 // Parameters: 1410 // columnIndex - the first column is 1, the second is 2, ... 1411 // x - the new column value 1412 // Throws: 1413 // TSQLException - if a database access error occurs 1414 1415 } 1416 1417 //___________________________________________________________________ 1418 void TSQLResultSet::UpdateByte( Int_t columnIndex,Char_t x ) 1419 { 1420 // Updates a column with a Char_t value. The UpdateXXX methods 1421 // are used to update column values in the current row, 1422 // or the insert row. The UpdateXXX methods do not update the 1423 // underlying database; instead the UpdateRow() or InsertRow() 1424 // methods are called to update the database. 1425 // 1426 // Parameters: 1427 // columnIndex - the first column is 1, the second is 2, ... 1428 // x - the new column value 1429 // Throws: 1430 // TSQLException - if a database access error occurs 1431 1432 } 1433 1434 //___________________________________________________________________ 1435 void TSQLResultSet::UpdateShort( Int_t columnIndex,Short_t x ) 1436 { 1437 // Updates a column with a Short_t value. The UpdateXXX methods 1438 // are used to update column values in the current row, 1439 // or the insert row. The UpdateXXX methods do not update the 1440 // underlying database; instead the UpdateRow() or InsertRow() 1441 // methods are called to update the database. 1442 // 1443 // Parameters: 1444 // columnIndex - the first column is 1, the second is 2, ... 1445 // x - the new column value 1446 // Throws: 1447 // TSQLException - if a database access error occurs 1448 1449 } 1450 1451 //___________________________________________________________________ 1452 void TSQLResultSet::UpdateInt( Int_t columnIndex,Int_t x ) 1453 { 1454 // Updates a column with an integer value. The UpdateXXX 1455 // methods are used to update column values in the current row, 1456 // or the insert row. The UpdateXXX methods do not update the 1457 // underlying database; instead the UpdateRow() or InsertRow() 1458 // methods are called to update the database. 1459 // 1460 // Parameters: 1461 // columnIndex - the first column is 1, the second is 2, ... 1462 // x - the new column value 1463 // Throws: 1464 // TSQLException - if a database access error occurs 1465 1466 } 1467 1468 //___________________________________________________________________ 1469 void TSQLResultSet::UpdateLong( Int_t columnIndex,Long_t x ) 1470 { 1471 // Updates a column with a Long_t value. The UpdateXXX methods 1472 // are used to update column values in the current row, 1473 // or the insert row. The UpdateXXX methods do not update the 1474 // underlying database; instead the UpdateRow() or InsertRow() 1475 // methods are called to update the database. 1476 // 1477 // Parameters: 1478 // columnIndex - the first column is 1, the second is 2, ... 1479 // x - the new column value 1480 // Throws: 1481 // TSQLException - if a database access error occurs 1482 1483 } 1484 1485 //___________________________________________________________________ 1486 void TSQLResultSet::UpdateFloat( Int_t columnIndex,Float_t x ) 1487 { 1488 // Updates a column with a Float_t value. The UpdateXXX methods 1489 // are used to update column values in the current row, 1490 // or the insert row. The UpdateXXX methods do not update the 1491 // underlying database; instead the UpdateRow() or InsertRow() 1492 // methods are called to update the database. 1493 // 1494 // Parameters: 1495 // columnIndex - the first column is 1, the second is 2, ... 1496 // x - the new column value 1497 // Throws: 1498 // TSQLException - if a database access error occurs 1499 1500 } 1501 1502 //___________________________________________________________________ 1503 void TSQLResultSet::UpdateDouble( Int_t columnIndex, 1504 Double_t x ) 1505 { 1506 // Updates a column with a Double value. The UpdateXXX 1507 // methods are used to update column values in the current row, 1508 // or the insert row. The UpdateXXX methods do not update the 1509 // underlying database; instead the UpdateRow() or InsertRow() 1510 // methods are called to update the database. 1511 // 1512 // Parameters: 1513 // columnIndex - the first column is 1, the second is 2, ... 1514 // x - the new column value 1515 // Throws: 1516 // TSQLException - if a database access error occurs 1517 1518 } 1519 1520 //___________________________________________________________________ 1521 void TSQLResultSet::UpdateString( Int_t columnIndex, 1522 const TString& x ) 1523 { 1524 // Updates a column with a TString value. The UpdateXXX 1525 // methods are used to update column values in the current row, 1526 // or the insert row. The UpdateXXX methods do not update the 1527 // underlying database; instead the UpdateRow() or InsertRow() 1528 // methods are called to update the database. 1529 // 1530 // Parameters: 1531 // columnIndex - the first column is 1, the second is 2, ... 1532 // x - the new column value 1533 // Throws: 1534 // TSQLException - if a database access error occurs 1535 1536 } 1537 1538 //___________________________________________________________________ 1539 void TSQLResultSet::UpdateBytes( Int_t columnIndex, 1540 const TArrayC& x ) 1541 { 1542 // Updates a column with a Char_t array value. The UpdateXXX 1543 // methods are used to update column values in the current row, 1544 // or the insert row. The UpdateXXX methods do not update the 1545 // underlying database; instead the UpdateRow() or InsertRow() 1546 // methods are called to update the database. 1547 // 1548 // Parameters: 1549 // columnIndex - the first column is 1, the second is 2, ... 1550 // x - the new column value 1551 // Throws: 1552 // TSQLException - if a database access error occurs 1553 1554 } 1555 1556 //___________________________________________________________________ 1557 void TSQLResultSet::UpdateDate( Int_t columnIndex, 1558 const TSQLDate& x ) 1559 { 1560 // Updates a column with a TSQLDate value. The UpdateXXX methods 1561 // are used to update column values in the current row, 1562 // or the insert row. The UpdateXXX methods do not update the 1563 // underlying database; instead the UpdateRow() or InsertRow() 1564 // methods are called to update the database. 1565 // 1566 // Parameters: 1567 // columnIndex - the first column is 1, the second is 2, ... 1568 // x - the new column value 1569 // Throws: 1570 // TSQLException - if a database access error occurs 1571 1572 } 1573 1574 //___________________________________________________________________ 1575 void TSQLResultSet::UpdateTime( Int_t columnIndex, 1576 const TSQLTime& x ) 1577 { 1578 // Updates a column with a TSQLTime value. The UpdateXXX methods 1579 // are used to update column values in the current row, 1580 // or the insert row. The UpdateXXX methods do not update the 1581 // underlying database; instead the UpdateRow() or InsertRow() 1582 // methods are called to update the database. 1583 // 1584 // Parameters: 1585 // columnIndex - the first column is 1, the second is 2, ... 1586 // x - the new column value 1587 // Throws: 1588 // TSQLException - if a database access error occurs 1589 1590 } 1591 1592 //___________________________________________________________________ 1593 void TSQLResultSet::UpdateTimestamp( Int_t columnIndex, 1594 const TSQLTimestamp& x ) 1595 { 1596 // Updates a column with a TSQLTimestamp value. The UpdateXXX 1597 // methods are used to update column values in the current row, 1598 // or the insert row. The UpdateXXX methods do not update the 1599 // underlying database; instead the UpdateRow() or InsertRow() 1600 // methods are called to update the database. 1601 // 1602 // Parameters: 1603 // columnIndex - the first column is 1, the second is 2, ... 1604 // x - the new column value 1605 // Throws: 1606 // TSQLException - if a database access error occurs 1607 1608 } 1609 1610 //___________________________________________________________________ 1611 void TSQLResultSet::UpdateAsciiStream( Int_t columnIndex, 1612 TBuffer* x, 1613 Int_t length ) 1614 { 1615 // Updates a column with an ascii stream value. The UpdateXXX 1616 // methods are used to update column values in the current row, 1617 // or the insert row. The UpdateXXX methods do not update the 1618 // underlying database; instead the UpdateRow() or InsertRow() 1619 // methods are called to update the database. 1620 // 1621 // Parameters: 1622 // columnIndex - the first column is 1, the second is 2, ... 1623 // x - the new column value 1624 // length - length of stream 1625 // Throws: 1626 // TSQLException - if a database access error occurs 1627 1628 } 1629 1630 //___________________________________________________________________ 1631 void TSQLResultSet::UpdateBinaryStream( Int_t columnIndex, 1632 TBuffer* x, 1633 Int_t length ) 1634 { 1635 // Updates a column with a binary stream value. The UpdateXXX 1636 // methods are used to update column values in the current row, 1637 // or the insert row. The UpdateXXX methods do not update the 1638 // underlying database; instead the UpdateRow() or InsertRow() 1639 // methods are called to update the database. 1640 // 1641 // Parameters: 1642 // columnIndex - the first column is 1, the second is 2, ... 1643 // x - the new column value 1644 // length - length of stream 1645 // Throws: 1646 // TSQLException - if a database access error occurs 1647 1648 } 1649 1650 //___________________________________________________________________ 1651 void TSQLResultSet::UpdateObject( Int_t columnIndex,TObject* x ) 1652 { 1653 // Updates a column with a ROOT object. The UpdateXXX 1654 // methods are used to update column values in the current row, 1655 // or the insert row. The UpdateXXX methods do not update the 1656 // underlying database; instead the UpdateRow() or InsertRow() 1657 // methods are called to update the database. 1658 // 1659 // Parameters: 1660 // columnIndex - the first column is 1, the second is 2, ... 1661 // x - the new column value 1662 // length - length of stream 1663 // Throws: 1664 // TSQLException - if a database access error occurs 1665 1666 TBuffer *b = new TBuffer(TBuffer::kWrite); 1667 b->WriteObject(x); 1668 UpdateBinaryStream(columnIndex,b,b->BufferSize()); 1669 b->DetachBuffer(); 1670 delete b; 1671 } 1672 1673 //___________________________________________________________________ 1674 void TSQLResultSet::UpdateNull( const TString& columnName ) 1675 { 1676 // Updates a column with a null value. The UpdateXXX methods 1677 // are used to update column values in the current row, 1678 // or the insert row. The UpdateXXX methods do not update the 1679 // underlying database; instead the UpdateRow() or InsertRow() 1680 // methods are called to update the database. 1681 // 1682 // Parameters: 1683 // columnIndex - the first column is 1, the second is 2, ... 1684 // x - the new column value 1685 // Throws: 1686 // TSQLException - if a database access error occurs 1687 1688 UpdateNull(FindColumn(columnName)); 1689 } 1690 1691 //___________________________________________________________________ 1692 void TSQLResultSet::UpdateBoolean( const TString& columnName,Bool_t x ) 1693 { 1694 // Updates a column with a boolean value. The UpdateXXX methods 1695 // are used to update column values in the current row, 1696 // or the insert row. The UpdateXXX methods do not update the 1697 // underlying database; instead the UpdateRow() or InsertRow() 1698 // methods are called to update the database. 1699 // 1700 // Parameters: 1701 // columnIndex - the first column is 1, the second is 2, ... 1702 // x - the new column value 1703 // Throws: 1704 // TSQLException - if a database access error occurs 1705 1706 UpdateBoolean(FindColumn(columnName),x); 1707 } 1708 1709 //___________________________________________________________________ 1710 void TSQLResultSet::UpdateByte( const TString& columnName,Char_t x ) 1711 { 1712 // Updates a column with a Char_t value. The UpdateXXX methods 1713 // are used to update column values in the current row, 1714 // or the insert row. The UpdateXXX methods do not update the 1715 // underlying database; instead the UpdateRow() or InsertRow() 1716 // methods are called to update the database. 1717 // 1718 // Parameters: 1719 // columnIndex - the first column is 1, the second is 2, ... 1720 // x - the new column value 1721 // Throws: 1722 // TSQLException - if a database access error occurs 1723 1724 UpdateByte(FindColumn(columnName),x); 1725 } 1726 1727 //___________________________________________________________________ 1728 void TSQLResultSet::UpdateShort( const TString& columnName,Short_t x ) 1729 { 1730 // Updates a column with a short value. The UpdateXXX methods 1731 // are used to update column values in the current row, 1732 // or the insert row. The UpdateXXX methods do not update the 1733 // underlying database; instead the UpdateRow() or InsertRow() 1734 // methods are called to update the database. 1735 // 1736 // Parameters: 1737 // columnIndex - the first column is 1, the second is 2, ... 1738 // x - the new column value 1739 // Throws: 1740 // TSQLException - if a database access error occurs 1741 1742 UpdateShort(FindColumn(columnName),x); 1743 } 1744 1745 //___________________________________________________________________ 1746 void TSQLResultSet::UpdateInt( const TString& columnName,Int_t x ) 1747 { 1748 // Updates a column with an integer value. The UpdateXXX methods 1749 // are used to update column values in the current row, 1750 // or the insert row. The UpdateXXX methods do not update the 1751 // underlying database; instead the UpdateRow() or InsertRow() 1752 // methods are called to update the database. 1753 // 1754 // Parameters: 1755 // columnIndex - the first column is 1, the second is 2, ... 1756 // x - the new column value 1757 // Throws: 1758 // TSQLException - if a database access error occurs 1759 1760 UpdateInt(FindColumn(columnName),x); 1761 } 1762 1763 //___________________________________________________________________ 1764 void TSQLResultSet::UpdateLong( const TString& columnName,Long_t x ) 1765 { 1766 // Updates a column with a long value. The UpdateXXX methods 1767 // are used to update column values in the current row, 1768 // or the insert row. The UpdateXXX methods do not update the 1769 // underlying database; instead the UpdateRow() or InsertRow() 1770 // methods are called to update the database. 1771 // 1772 // Parameters: 1773 // columnIndex - the first column is 1, the second is 2, ... 1774 // x - the new column value 1775 // Throws: 1776 // TSQLException - if a database access error occurs 1777 1778 UpdateLong(FindColumn(columnName),x); 1779 } 1780 1781 //___________________________________________________________________ 1782 void TSQLResultSet::UpdateFloat( const TString& columnName,Float_t x ) 1783 { 1784 // Updates a column with a float value. The UpdateXXX methods 1785 // are used to update column values in the current row, 1786 // or the insert row. The UpdateXXX methods do not update the 1787 // underlying database; instead the UpdateRow() or InsertRow() 1788 // methods are called to update the database. 1789 // 1790 // Parameters: 1791 // columnIndex - the first column is 1, the second is 2, ... 1792 // x - the new column value 1793 // Throws: 1794 // TSQLException - if a database access error occurs 1795 1796 UpdateFloat(FindColumn(columnName),x); 1797 } 1798 1799 //___________________________________________________________________ 1800 void TSQLResultSet::UpdateDouble( const TString& columnName,Double_t x ) 1801 { 1802 // Updates a column with a double value. The UpdateXXX methods 1803 // are used to update column values in the current row, 1804 // or the insert row. The UpdateXXX methods do not update the 1805 // underlying database; instead the UpdateRow() or InsertRow() 1806 // methods are called to update the database. 1807 // 1808 // Parameters: 1809 // columnIndex - the first column is 1, the second is 2, ... 1810 // x - the new column value 1811 // Throws: 1812 // TSQLException - if a database access error occurs 1813 1814 UpdateDouble(FindColumn(columnName),x); 1815 } 1816 1817 //___________________________________________________________________ 1818 void TSQLResultSet::UpdateString( const TString& columnName, 1819 const TString& x ) 1820 { 1821 // Updates a column with a TString value. The UpdateXXX methods 1822 // are used to update column values in the current row, 1823 // or the insert row. The UpdateXXX methods do not update the 1824 // underlying database; instead the UpdateRow() or InsertRow() 1825 // methods are called to update the database. 1826 // 1827 // Parameters: 1828 // columnIndex - the first column is 1, the second is 2, ... 1829 // x - the new column value 1830 // Throws: 1831 // TSQLException - if a database access error occurs 1832 1833 UpdateString(FindColumn(columnName),x); 1834 } 1835 1836 //___________________________________________________________________ 1837 void TSQLResultSet::UpdateBytes( const TString& columnName, 1838 const TArrayC& x ) 1839 { 1840 // Updates a column with a bytes array value. The update methods 1841 // are used to update column values in the current row, 1842 // or the insert row. The UpdateXXX methods do not update the 1843 // underlying database; instead the UpdateRow() or InsertRow() 1844 // methods are called to update the database. 1845 // 1846 // Parameters: 1847 // columnIndex - the first column is 1, the second is 2, ... 1848 // x - the new column value 1849 // Throws: 1850 // TSQLException - if a database access error occurs 1851 1852 UpdateBytes(FindColumn(columnName),x); 1853 } 1854 1855 //___________________________________________________________________ 1856 void TSQLResultSet::UpdateDate( const TString& columnName, 1857 const TSQLDate& x ) 1858 { 1859 // Updates a column with a TSQLDate value. The UpdateXXX methods 1860 // are used to update column values in the current row, 1861 // or the insert row. The UpdateXXX methods do not update the 1862 // underlying database; instead the UpdateRow() or InsertRow() 1863 // methods are called to update the database. 1864 // 1865 // Parameters: 1866 // columnIndex - the first column is 1, the second is 2, ... 1867 // x - the new column value 1868 // Throws: 1869 // TSQLException - if a database access error occurs 1870 1871 UpdateDate(FindColumn(columnName),x); 1872 } 1873 1874 //___________________________________________________________________ 1875 void TSQLResultSet::UpdateTime( const TString& columnName, 1876 const TSQLTime& x ) 1877 { 1878 // Updates a column with a TSQLTime value. The UpdateXXX methods 1879 // are used to update column values in the current row, 1880 // or the insert row. The UpdateXXX methods do not update the 1881 // underlying database; instead the UpdateRow() or InsertRow() 1882 // methods are called to update the database. 1883 // 1884 // Parameters: 1885 // columnIndex - the first column is 1, the second is 2, ... 1886 // x - the new column value 1887 // Throws: 1888 // TSQLException - if a database access error occurs 1889 1890 UpdateTime(FindColumn(columnName),x); 1891 } 1892 1893 //___________________________________________________________________ 1894 void TSQLResultSet::UpdateTimestamp( const TString& columnName, 1895 const TSQLTimestamp& x ) 1896 { 1897 // Updates a column with a TSQLTimestamp value. The update methods 1898 // are used to update column values in the current row, 1899 // or the insert row. The UpdateXXX methods do not update the 1900 // underlying database; instead the UpdateRow() or InsertRow() 1901 // methods are called to update the database. 1902 // 1903 // Parameters: 1904 // columnIndex - the first column is 1, the second is 2, ... 1905 // x - the new column value 1906 // Throws: 1907 // TSQLException - if a database access error occurs 1908 1909 UpdateTimestamp(FindColumn(columnName),x); 1910 } 1911 1912 //___________________________________________________________________ 1913 void TSQLResultSet::UpdateAsciiStream( const TString& columnName, 1914 TBuffer* x, 1915 Int_t length ) 1916 { 1917 // Updates a column with an ascii stream value. The update methods 1918 // are used to update column values in the current row, 1919 // or the insert row. The UpdateXXX methods do not update the 1920 // underlying database; instead the UpdateRow() or InsertRow() 1921 // methods are called to update the database. 1922 // 1923 // Parameters: 1924 // columnIndex - the first column is 1, the second is 2, ... 1925 // x - the new column value 1926 // length - length of stream 1927 // Throws: 1928 // TSQLException - if a database access error occurs 1929 1930 UpdateAsciiStream(FindColumn(columnName),x,length); 1931 } 1932 1933 //___________________________________________________________________ 1934 void TSQLResultSet::UpdateBinaryStream( const TString& columnName, 1935 TBuffer* x, 1936 Int_t length ) 1937 { 1938 // Updates a column with a binary stream value. The update methods 1939 // are used to update column values in the current row, 1940 // or the insert row. The UpdateXXX methods do not update the 1941 // underlying database; instead the UpdateRow() or InsertRow() 1942 // methods are called to update the database. 1943 // 1944 // Parameters: 1945 // columnIndex - the first column is 1, the second is 2, ... 1946 // x - the new column value 1947 // length - length of stream 1948 // Throws: 1949 // TSQLException - if a database access error occurs 1950 1951 UpdateBinaryStream(FindColumn(columnName),x,length); 1952 } 1953 1954 //___________________________________________________________________ 1955 void TSQLResultSet::UpdateObject(const TString& columnName,TObject* x) 1956 { 1957 // Updates a column with a ROOT object. The update methods 1958 // are used to update column values in the current row, 1959 // or the insert row. The UpdateXXX methods do not update the 1960 // underlying database; instead the UpdateRow() or InsertRow() 1961 // methods are called to update the database. 1962 // 1963 // Parameters: 1964 // columnIndex - the first column is 1, the second is 2, ... 1965 // x - the new column value 1966 // length - length of stream 1967 // Throws: 1968 // TSQLException - if a database access error occurs 1969 1970 UpdateObject(FindColumn(columnName),x); 1971 } 1972 1973 //___________________________________________________________________ 1974 void TSQLResultSet::InsertRow() 1975 { 1976 // Inserts the contents of the insert row into the result set 1977 // and the database. Must be on the insert row when this method 1978 // is called. 1979 // 1980 // Throws: 1981 // TSQLException - if a database access error occurs, if 1982 // called when not on the insert row, or if not all of 1983 // non-nullable columns in the insert row have been given 1984 // a value. 1985 1986 1987 } 1988 1989 //___________________________________________________________________ 1990 void TSQLResultSet::UpdateRow() 1991 { 1992 // Updates the underlying database with the new contents of 1993 // the current row. Cannot be called when on the insert row. 1994 // 1995 // Throws: 1996 // TSQLException - if a database access error occurs or if 1997 // called when on the insert row 1998 1999 } 2000 2001 //___________________________________________________________________ 2002 void TSQLResultSet::DeleteRow() 2003 { 2004 // Deletes the current row from the result set and the underlying 2005 // database. Cannot be called when on the insert row. 2006 // 2007 // Throws: 2008 // TSQLException - if a database access error occurs or 2009 // if called when on the insert row. 2010 2011 } 2012 2013 //___________________________________________________________________ 2014 void TSQLResultSet::RefreshRow() 2015 { 2016 // Refreshes the current row with its most recent value in 2017 // the database. Cannot be called when on the insert row. 2018 // The RefreshRow() method provides a way for an application to 2019 // explicitly tell the driver to refetch a row(s) from the 2020 // database. An application may want to call RefreshRow() when 2021 // caching or prefetching is being done by the driver to 2022 // fetch the latest value of a row from the database. The 2023 // driver may actually refresh multiple rows at once if the 2024 // fetch size is greater than one. All values are refetched 2025 // subject to the transaction isolation level and cursor 2026 // sensitivity. If RefreshRow() is called after calling UpdateXXX, 2027 // but before calling UpdateRow(), then the updates made to the 2028 // row are lost. Calling the method RefreshRow() frequently will 2029 // likely slow performance. 2030 // 2031 // Throws: 2032 // TSQLException - if a database access error occurs or 2033 // if called when on the insert row 2034 2035 2036 } 2037 2038 //___________________________________________________________________ 2039 void TSQLResultSet::CancelRowUpdates() 2040 { 2041 // Cancels the updates made to a row. This method may be 2042 // called after calling an UpdateXXX method(s) and before 2043 // calling UpdateRow() to rollback the updates made to a row. 2044 // If no updates have been made or UpdateRow() has already been 2045 // called then this method has no effect. 2046 // 2047 // Throws: 2048 // TSQLException - if a database access error occurs or if 2049 // called when on the insert row 2050 2051 } 2052 2053 //___________________________________________________________________ 2054 void TSQLResultSet::MoveToInsertRow() 2055 { 2056 // Moves the cursor to the insert row. The current cursor 2057 // position is remembered while the cursor is positioned on 2058 // the insert row. The insert row is a special row associated 2059 // with an updatable result set. It is essentially a buffer 2060 // where a new row may be constructed by calling the UpdateXXX 2061 // methods prior to inserting the row into the result set. 2062 // Only the UpdateXXX, GetXXX, and InsertRow() methods may be 2063 // called when the cursor is on the insert row. 2064 // All of the columns in a result set must be given a value 2065 // each time this method is called before calling InsertRow(). 2066 // The method UpdateXXX must be called before a GetXXX method 2067 // can be called on a column value. 2068 // 2069 // Throws: 2070 // TSQLException - if a database access error occurs 2071 // or the result set is not updatable 2072 2073 } 2074 2075 //___________________________________________________________________ 2076 void TSQLResultSet::MoveToCurrentRow() 2077 { 2078 // Moves the cursor to the remembered cursor position, 2079 // usually the current row. This method has no effect if the 2080 // cursor is not on the insert row. 2081 // 2082 // Throws: 2083 // TSQLException - if a database access error occurs or 2084 // the result set is not updatable 2085 2086 2087 } 2088 2089 //___________________________________________________________________ 2090 TSQLStatement* TSQLResultSet::GetStatement() const 2091 { 2092 // Returns the TSQLStatement that produced this TSQLResultSet 2093 // object. If the result set was generated some other way, such 2094 // as by a TSQLDatabaseMetaData method,this method returns null. 2095 // 2096 // Returns: 2097 // the TSQLStatment that produced the result set or null 2098 // if the result set was produced some other way 2099 // Throws: 2100 // TSQLException - if a database access error occurs 2101 2102 return fStatement; 2103 } 2104 2105 //___________________________________________________________________ 2106 TSQLRow* TSQLResultSet::Next() 2107 { 2108 // Moves the cursor down one row from its current position. A 2109 // TSQLResultSet cursor is initially positioned before the first 2110 // row; the first call to next makes the first row the current 2111 // row; the second call makes the second row the current row, 2112 // and so on. 2113 // 2114 // If an input stream is open for the current row, a call to the 2115 // method next will implicitly close it. The TSQLResultSet's 2116 // warning chain is cleared when a new row is read. 2117 // 2118 // Returns: 2119 // pointer to TSQLRow(kTRUE) if the new current row is valid; 2120 // null(kFALSE) if there are no more rows 2121 // Throws: 2122 // TSQLException - if a database access error occurs 2123 2124 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 2125 2126 if( imp->fOnInsertRow ) imp->fOnInsertRow = kFALSE; 2127 if( imp->fDoingUpdates ) imp->fDoingUpdates = kFALSE; 2128 2129 if( !imp->fMYSQL_RES->row_count ) return; 2130 2131 return return_value ? fRow->Set(this) : 0; 2132 } 2133 2134 //___________________________________________________________________ 2135 TSQLRow* TSQLResultSet::First() 2136 { 2137 // Moves the cursor to the first row in the result set. 2138 // 2139 // Returns: 2140 // pointer to TSQLRow(kTRUE) if the cursor is on a valid row; 2141 // null(kFALSE) if there are no rows in the result set 2142 // Throws: 2143 // TSQLException - if a database access error occurs or 2144 // the result set type is kTYPE_FORWARD_ONLY 2145 2146 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 2147 MySQLStatementPrivate* stmt = (MySQLStatementPrivate*)fStatement->fImp; 2148 MySQLConnectionPrivate* con = (MySQLConnectionPrivate*)fStatement->fConnection->fImp; 2149 2150 if( imp->fCurrentRow || imp->fCursorType != kTYPE_FORWARD_ONLY ) { 2151 Throw(); 2152 return 0; 2153 } 2154 2155 if( imp->fOnInsertRow ) imp->fOnInsertRow = kFALSE; 2156 2157 if( !imp->fMYSQL_RES->row_count || con->fMYSQL->status==MYSQL_STATUS_USE_RESULT ) return 0; 2158 else { 2159 if( imp->fDoingUpdates ) imp->fDoingUpdates = kFALSE; 2160 imp->fCurrentRow = 0; 2161 mysql_data_seek(imp->fMYSQL_RES,0L); 2162 2163 return fRow->Set(imp->fMYSQL_RES); 2164 } 2165 } 2166 2167 //___________________________________________________________________ 2168 TSQLRow* TSQLResultSet::Absolute( Int_t row ) 2169 { 2170 // Moves the cursor to the given row number in the result set. 2171 // If the row number is positive, the cursor moves to the 2172 // given row number with respect to the beginning of the 2173 // result set. The first row is row 1, the second is row 2, 2174 // and so on. 2175 // 2176 // If the given row number is negative, the cursor moves to an 2177 // absolute row position with respect to the end of the result 2178 // set. For example, calling Absolute(-1) positions the cursor 2179 // on the last row, Absolute(-2) indicates the next-to-last row, 2180 // and so on. 2181 // 2182 // An attempt to position the cursor beyond the first/last row 2183 // in the result set leaves the cursor before/after the first/last 2184 // row, respectively. 2185 // 2186 // Note: calling Absolute(1) is the same as calling First(). 2187 // calling Absolute(-1) is the same as calling Last(). 2188 // 2189 // Returns: 2190 // pointer to TSQLRow(kTRUE) if the cursor is on the result set; 2191 // null(kFALSE) otherwise 2192 // Throws: 2193 // TSQLException - if a database access error occurs or 2194 // row is 0, or result set type is kTYPE_FORWARD_ONLY 2195 2196 if (row == 0) { 2197 throw new SQLException("Cannot absolute position to row 0", "S1009"); 2198 } 2199 2200 if (_on_insert_row) { 2201 _on_insert_row = false; 2202 } 2203 2204 if (_doing_updates) { 2205 _doing_updates = false; 2206 } 2207 2208 if (row == 1) { 2209 return first(); 2210 } 2211 else if (row == -1) { 2212 return last(); 2213 } 2214 2215 if (row > Rows.size()) { 2216 afterLast(); 2217 2218 return false; 2219 } 2220 else if (row < 0) { 2221 2222 // adjust to reflect after end of result set 2223 int new_row_position = Rows.size() + row + 1; 2224 2225 if (new_row_position <= 0) { 2226 beforeFirst(); 2227 2228 return false; 2229 } 2230 else { 2231 return absolute(new_row_position); 2232 } 2233 } 2234 else { 2235 row--; // adjust for index difference 2236 currentRow = row; 2237 This_Row = (byte[][])Rows.elementAt(currentRow); 2238 2239 return true; 2240 } 2241 } 2242 2243 //___________________________________________________________________ 2244 TSQLRow* TSQLResultSet::Relative(Int_t rows) 2245 { 2246 // Moves the cursor a relative number of rows, either positive or 2247 // negative. Attempting to move beyond the first/last row in 2248 // the result set positions the cursor before/after the the 2249 // first/last row. Calling Relative(0) is valid, but does not 2250 // change the cursor position. 2251 // 2252 // Note: Calling Relative(1) is different from calling Next() 2253 // because is makes sense to call Next() when there is 2254 // no current row, for example, when the cursor is 2255 // positioned before the first row or after the last row 2256 // of the result set. 2257 // Returns: 2258 // pointer to TSQLRow(kTRUE) if the cursor is on a row; 2259 // null(kFALSE) otherwise 2260 // Throws: 2261 // TSQLException - if a database access error occurs, 2262 // there is no current row, or the result set type 2263 // is kTYPE_FORWARD_ONLY 2264 2265 int new_row_position = currentRow + rows + 1; 2266 } 2267 2268 //___________________________________________________________________ 2269 TSQLRow* TSQLResultSet::Previous() 2270 { 2271 // Moves the cursor to the previous row in the result set. 2272 // 2273 // Note: Previous() is not the same as Relative(-1) 2274 // because it makes sense to call Previous() 2275 // when there is no current row. 2276 // 2277 // Returns: 2278 // pointer to TSQLRow(kTRUE) if the cursor is on a valid row; 2279 // null(kFALSE) if it is off the result set 2280 // Throws: 2281 // TSQLException - if a database access error occurs or 2282 // the result set type is kTYPE_FORWARD_ONLY 2283 2284 Bool_t return_value = kFALSE; 2285 2286 return return_value ? fRow->Set(this) : 0; 2287 } 2288 2289 //___________________________________________________________________ 2290 TSQLRow* TSQLResultSet::Last() 2291 { 2292 // Moves the cursor to the last row in the result set. 2293 // 2294 // Returns: 2295 // pointer to TSQLRow(kTRUE) if the cursor is on a valid row; 2296 // null(kFALSE) if there are norows in the result set 2297 // 2298 // Throws: 2299 // TSQLException - if a database access error occurs or 2300 // the result set type is kTYPE_FORWARD_ONLY 2301 2302 Bool_t return_value = kFALSE; 2303 return return_value ? fRow->Set(this) : 0; 2304 } 2305 2306 //___________________________________________________________________ 2307 Int_t TSQLResultSet::GetFieldCount() 2308 { 2309 // Get number of fields(aka columns) in result. 2310 2311 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 2312 return imp->fMYSQL_RES->field_count; 2313 } 2314 2315 //___________________________________________________________________ 2316 const char* TSQLResultSet::GetFieldName(Int_t field) 2317 { 2318 // Get name of specified field( aka column ). 2319 2320 MySQLResultSetPrivate* imp = (MySQLResultSetPrivate*)fImp; 2321 2322 if( (column > imp->fMYSQL_RES->field_count) || (column < 1) ) { 2323 return (set_stmt_error(stmt,"S1002","Invalid column number",0)); 2324 return ""; 2325 } 2326 2327 return imp->MYSQL_RES->fields[column-1].name; 2328 } 2329 2330 //___________________________________________________________________ 2331 void TSQLResultSet::Close(Option_t *option) 2332 { 2333 // Releases this TSQLResultSet object's database and resources 2334 // immediately instead of waiting for this to happen when it is 2335 // automatically closed. 2336 // 2337 // Note: A TSQLResultSet is automatically closed by the 2338 // statement that generated it when that statement 2339 // is closed, re-executed, or is used to retrieve the next 2340 // result from a sequence of multiple results. A TSQLResultSet 2341 // is also automatically closed when it is garbage collected. 2342 // 2343 // Throws: 2344 // TSQLException - if a database access error occurs 2345 2346 2347 fMetaData = 0; 2348 fRow = 0; 2349 fImp = 0; 2350 Destroyed(); 2351 } 2352 2353 //////////////////////// Print utility ////////////////////////////// 2354 //___________________________________________________________________ 2355 Int_t GetValueFromOption(const TString& pattern,const TString& option) 2356 { 2357 // internal use func. 2358 2359 Ssiz_t t1,t2; 2360 const char* tmp; 2361 2362 TString stropt = option; 2363 stropt.ReplaceAll(" ",""); // strip blanks 2364 stropt.ToLower(); 2365 2366 t1 = stropt.Index(pattern.Data()); 2367 t1 = t2 = stropt.Index("=",t1) + 1; 2368 TString str = stropt(t1,1024); // 2369 tmp = str.Data(); 2370 2371 for(int i=0;isdigit(tmp[i])!=0;i++) t2=i+1; 2372 str = stropt(t1,t2); 2373 return atoi(str.Data()); 2374 } 2375 2376 //___________________________________________________________________ 2377 void TSQLResultSet::Print(Option_t *option) 2378 { 2379 // Print a resultset contents 2380 // 2381 // The following options are valid: 2382 // 2383 // begin=nnn - start print from #nnn'th row, for example Print("begin=100") 2384 // end=nnn - end print at #nnn'th row, for example Print("begin=100 end=1000") 2385 // nrows=nnn - print #nnn rows, for example Print("begin=100 nrows=1000") 2386 2387 if(!fImp) { 2388 Warning("Print()","TSQLResultSet is destroyed\n"); 2389 Throw(new TSQLException("TSQLResultSet is destroyed")); 2390 Destroyed(); 2391 return; 2392 } 2393 2394 TString colname; 2395 Int_t ds; 2396 Int_t dl; 2397 Int_t* nn; 2398 Int_t* pd1; 2399 Int_t pd2; 2400 TString str; 2401 Int_t save_row = GetRow(); 2402 Int_t cur_row; 2403 Int_t nr = 0; 2404 2405 Int_t srow = save_row; // start from srow, default is current 2406 Int_t nrows = -1; // -1 - stand for "all rows" 2407 Int_t erow = -1; // -1 - stand for "to the last row" 2408 2409 TString stropt = option; 2410 stropt.ToLower(); 2411 2412 if(stropt.Contains("begin")) { 2413 srow = GetValueFromOption("begin",stropt); 2414 } 2415 2416 if (stropt.Contains("end")) { 2417 erow = GetValueFromOption("end",stropt); 2418 } 2419 2420 if (stropt.Contains("nrows")) { 2421 nrows = GetValueFromOption("nrows",stropt); 2422 } 2423 2424 Int_t ncols = fMetaData->GetColumnCount(); 2425 2426 nn = new Int_t[ncols+1]; 2427 pd1 = new Int_t[ncols+1]; 2428 2429 for(int i=1; i<ncols+1; i++) { 2430 colname = fMetaData->GetColumnName(i); 2431 ds = fMetaData->GetColumnDisplaySize(i)+2; 2432 dl = colname.Length() + 2; 2433 nn[i] = TMath::Max(dl,ds); 2434 pd1[i] = nn[i]-dl; 2435 } 2436 2437 // 2438 for(int i=1; i<ncols+1; i++) { 2439 cout << "+"; cout.fill('-'); cout.width(nn[i]+1); cout << "+"; 2440 } cout << endl; 2441 2442 for(int i=1; i<ncols+1; i++) { 2443 colname = fMetaData->GetColumnName(i); 2444 cout << "| " << colname << " "; 2445 cout.fill(' '); cout.width(pd1[i]+1); cout << "|"; 2446 } cout << endl; 2447 2448 // 2449 for(int i=1; i<ncols+1; i++) { 2450 cout << "+"; cout.fill('-'); cout.width(nn[i]+1); cout << "+"; 2451 } cout << endl; 2452 2453 cur_row = GetRow(); 2454 2455 if(fStatement) { 2456 if(fStatement->GetResultSetType() != kTYPE_FORWARD_ONLY ) { 2457 Absolute(srow-1); 2458 } else { 2459 if(srow>cur_row) { 2460 while ( Next() && cur_row+2 < srow) cur_row = GetRow(); 2461 } 2462 } 2463 } 2464 2465 static TStopwatch timer; 2466 timer.Start(kTRUE); 2467 2468 nr = 0; 2469 cur_row = GetRow(); 2470 2471 while ( Next() ) { 2472 2473 if(nrows > 0 && nr >= nrows) break; 2474 if(erow > 0 && cur_row >= erow ) break; 2475 nr++; 2476 cur_row = GetRow(); 2477 2478 for(int i=1; i<ncols+1; i++) { 2479 str = GetString(i); 2480 cout << "| " << str; 2481 pd2 = nn[i] - str.Length(); 2482 cout.fill(' '); cout.width(pd2); cout << "|"; 2483 } cout << endl; 2484 } 2485 2486 for(int i=1; i<ncols+1; i++) { 2487 cout << "+"; cout.fill('-'); cout.width(nn[i]+1); cout << "+"; 2488 } cout << endl; 2489 2490 timer.Stop(); 2491 Double_t rtime = timer.RealTime(); 2492 // Double_t ctime = timer.CpuTime(); 2493 cout << nr << " rows in set. ( Real time: " << rtime << " seconds )" << endl; 2494 2495 if(fStatement) { 2496 if(fStatement->GetResultSetType() != kTYPE_FORWARD_ONLY ) { 2497 Absolute(save_row); 2498 } else { 2499 Warning("Print","To set cursor to initial position -> re-execute Query."); 2500 } 2501 } 2502 delete [] nn; 2503 delete [] pd1; 2504 } 2505 2506 //___________________________________________________________________ 2507 TTree* TSQLResultSet::Tree(Int_t begin,Int_t end) 2508 { 2509 // Writes resultset content to ROOT tree 2510 // 2511 // This method creates "new TTree". 2512 // To avoid memory leakage it should be deleted if not used. 2513 // 2514 // See also TTree 2515 // 2516 // Comment: this method is experimental nad buggy 2517 2518 TString leafList; // leaf description string 2519 TString clmname; // column name 2520 2521 Int_t siz; 2522 Int_t ncollumns; 2523 char* buf; 2524 Int_t type,offset,prec; 2525 TString str; 2526 char tmpstr[40]; 2527 2528 Int_t intg; 2529 Short_t shrt; 2530 Float_t flt; 2531 Double_t dbl; 2532 Int_t yy, mm, dd, hh, mi, ss; 2533 UInt_t t; 2534 struct tm tp; 2535 Int_t save_row = GetRow(); 2536 Int_t cur_row; 2537 2538 Int_t srow = begin > 0 ? begin : save_row; 2539 Int_t erow = end > 0 ? end : -1; 2540 Int_t tmp; 2541 2542 if(srow>erow) { 2543 tmp = erow; 2544 erow = srow; 2545 srow = tmp; 2546 } 2547 2548 // calculate "leaf buffer" size 2549 // 2550 ncollumns = fMetaData->GetColumnCount(); 2551 2552 for( int i=1; i <= ncollumns; ++i ) { 2553 type = fMetaData->GetColumnType(i); 2554 2555 switch( type ) { 2556 case kCHAR: 2557 case kVARCHAR: 2558 siz += fMetaData->GetPrecision(i)+1; // length + zero 2559 break; 2560 case kINTEGER: 2561 siz += sizeof(Int_t); 2562 break; 2563 case kDATE: 2564 case kTIME: 2565 case kTIMESTAMP: 2566 siz += sizeof(UInt_t); 2567 break; 2568 case kBIT: 2569 case kTINYINT: 2570 case kSMALLINT: 2571 siz += sizeof(Short_t); 2572 break; 2573 case kREAL: 2574 siz += sizeof(Float_t); 2575 break; 2576 case kLONGVARCHAR: // not resolved yet how to handle 2577 case kLONGVARBINARY: 2578 case kVARBINARY: 2579 break; 2580 case kBIGINT: // convert all these types to Double_t 2581 case kDECIMAL: 2582 case kNUMERIC: 2583 case kDOUBLE: 2584 case kFLOAT: 2585 default: 2586 siz += sizeof(Double_t); 2587 break; 2588 } 2589 } 2590 2591 // determine leaf description string 2592 // 2593 for( int i=1; i <= ncollumns; ++i ) { 2594 type = fMetaData->GetColumnType(i); 2595 clmname = fMetaData->GetColumnName(i); 2596 2597 switch( type ) { 2598 case kCHAR: 2599 case kVARCHAR: 2600 prec = fMetaData->GetPrecision(i)+1; 2601 sprintf(tmpstr,"[%d]",prec); 2602 leafList += clmname + tmpstr + "/C:"; // 2603 break; 2604 case kINTEGER: 2605 leafList += clmname + "/I:"; // signed integer 2606 break; 2607 case kDATE: 2608 case kTIME: 2609 case kTIMESTAMP: 2610 leafList += clmname + "/i:"; // unsigned integer ( time_t format ) 2611 break; 2612 case kBIT: 2613 case kTINYINT: 2614 case kSMALLINT: 2615 leafList += clmname + "/S:"; // signed short 2616 break; 2617 case kREAL: 2618 leafList += clmname + "/F:"; // floating point 2619 break; 2620 case kLONGVARCHAR: // not resolved yet how to handle 2621 case kLONGVARBINARY: 2622 case kVARBINARY: 2623 break; 2624 case kBIGINT: // convert all these types to Double_t 2625 case kDECIMAL: 2626 case kNUMERIC: 2627 case kDOUBLE: 2628 case kFLOAT: 2629 default: 2630 leafList += clmname + "/D:"; // double 2631 break; 2632 } 2633 } 2634 if(!leafList.IsNull()) leafList.Resize(leafList.Length()-1); // cut off last ":" 2635 2636 // Dinamically allocate "leaf buffer" 2637 // 2638 buf = new char[siz]; // buffer 2639 2640 TString tblname = fMetaData->GetTableName(1); 2641 2642 if(tblname.IsNull()) { // if table name unknown => generate "random name" 2643 tblname = "table"; 2644 sprintf(tmpstr,"%d",gRandom->Integer(1000)); 2645 tblname += tmpstr; 2646 } 2647 2648 // Create a ROOT Tree 2649 // 2650 TTree* tree = new TTree(tblname.Data(),"Created by TSQLResultSet:Tree() method"); 2651 2652 tree->Branch(tblname.Data(),(void*)buf,leafList.Data()); 2653 2654 // skip to start 2655 cur_row = GetRow(); 2656 2657 if(fStatement) { 2658 if(fStatement->GetResultSetType() != kTYPE_FORWARD_ONLY ) { 2659 Absolute(srow-1); 2660 } else { 2661 if(srow>cur_row) { 2662 while ( Next() && cur_row+2 < srow) cur_row = GetRow(); 2663 } 2664 } 2665 } 2666 // tree filling 2667 // 2668 while( Next() ) { // iterate rows 2669 offset = 0; 2670 2671 if(erow>0 && cur_row >= erow) break; 2672 cur_row = GetRow(); 2673 2674 for( int i=1; i <= ncollumns; ++i ) { 2675 type = fMetaData->GetColumnType(i); 2676 2677 switch( type ) { 2678 case kCHAR: 2679 case kVARCHAR: 2680 siz = fMetaData->GetPrecision(i)+1; 2681 str = GetString(i); 2682 memcpy(&buf[offset],str.Data(),siz); 2683 break; 2684 case kINTEGER: 2685 siz = sizeof(Int_t); 2686 intg = GetInt(i); 2687 memcpy(&buf[offset],&intg,siz); 2688 break; 2689 case kBIT: 2690 case kTINYINT: 2691 case kSMALLINT: 2692 siz = sizeof(Short_t); 2693 shrt = GetShort(i); 2694 memcpy(&buf[offset],&shrt,siz); 2695 break; 2696 case kREAL: 2697 siz = sizeof(Float_t); 2698 dbl = GetFloat(i); 2699 memcpy(&buf[offset],&flt,siz); 2700 break; 2701 case kDATE: // convert all date-times into time_t 2702 case kTIME: // probably not working for kTIME 2703 case kTIMESTAMP: 2704 siz = sizeof(UInt_t); 2705 str = GetString(i); 2706 sscanf(str.Data(), "%d-%d-%d %d:%d:%d", 2707 &yy, &mm, &dd, &hh, &mi, &ss); 2708 tp.tm_year = yy-1900; 2709 tp.tm_mon = mm; 2710 tp.tm_mday = dd; 2711 tp.tm_hour = hh; 2712 tp.tm_min = mi; 2713 tp.tm_sec = ss; 2714 tp.tm_isdst = -1; 2715 t = (UInt_t)mktime(&tp); 2716 memcpy(&buf[offset],&t,siz); 2717 break; 2718 case kLONGVARCHAR: // not resolved how to handle 2719 case kLONGVARBINARY: 2720 case kVARBINARY: 2721 break; 2722 case kBIGINT: // convert all these types to Double_t 2723 case kDECIMAL: 2724 case kNUMERIC: 2725 case kDOUBLE: 2726 case kFLOAT: 2727 default: 2728 siz = sizeof(Double_t); 2729 dbl = GetDouble(i); 2730 memcpy(&buf[offset],&dbl,siz); 2731 break; 2732 } 2733 offset += siz; 2734 } 2735 tree->Fill(); 2736 } 2737 delete buf; 2738 2739 if(fStatement) { 2740 if(fStatement->GetResultSetType() != kTYPE_FORWARD_ONLY ) { 2741 Absolute(save_row); 2742 } else { 2743 Warning("Print","To set cursor to initial position -> re-execute Query."); 2744 } 2745 } 2746 return tree; 2747 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |