Back to home page

sPhenix code displayed by LXR

 
 

    


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 }