TDbiFieldType.cxx

Go to the documentation of this file.
00001 // $Id: TDbiFieldType.cxx,v 1.1 2011/01/18 05:49:20 finch Exp $
00002 
00003 
00004 
00005 //////////////////////////////////////////////////////////////////////////
00006 ////////////////////////////     ROOT API     ////////////////////////////
00007 //////////////////////////////////////////////////////////////////////////
00008 
00009 
00010 
00011 #include <iostream>
00012 
00013 #include <sstream>
00014 
00015 #include "TSQLServer.h"
00016 #include "TString.h"
00017 
00018 #include "TDbiFieldType.hxx"
00019 #include <TSK_DBI_Log.hxx>
00020 #include <MsgFormat.h>
00021 using std::endl;
00022 
00023 ClassImp(TDbiFieldType)
00024 
00025 //   Definition of static data members
00026 //   *********************************
00027 
00028 
00029 //    Definition of all member functions (static or otherwise)
00030 //    *******************************************************
00031 //
00032 //    -  ordered: ctors, dtor, operators then in alphabetical order.
00033 
00034 //.....................................................................
00035 
00036 TDbiFieldType::TDbiFieldType(Int_t type /* = TDbi::kInt */)
00037 {
00038 //
00039 //
00040 //  Purpose:  Default constructor
00041 //
00042 //  Arguments:
00043 //    type     in    Data type  (default TDbi::kInt).
00044 
00045 
00046 
00047   this->Init(type);
00048 
00049 }
00050 //.....................................................................
00051 
00052 TDbiFieldType::TDbiFieldType(Int_t type,
00053                            Int_t size,
00054                            const char* typeName) {
00055 
00056 
00057 //
00058 //
00059 //  Purpose:  Constructor for TSQL meta-data.
00060 //
00061 //  Arguments:
00062 //    type      in    value from TSQLColumnInfo::GetSQLType()
00063 //    size      in    value from TSQLColumnInfo::GetLength()
00064 //    typeName  in    value from TSQLColumnInfo::GetTypeName()
00065 
00066 
00067   TString name(typeName);
00068   name.ToUpper();
00069 
00070   // Handle integer types.
00071 
00072   if ( type == TSQLServer::kSQL_INTEGER || type == TSQLServer::kSQL_NUMERIC ) {
00073 
00074     // TSQLServer reports e.g. int(32) as size 32, (even though maximum display is 11)
00075     // so treat any type starting int or INT as size kMaxInt (i.e. standard 4 byte int)
00076     if ( name.BeginsWith("INT") ) size = kMaxInt;
00077     if      ( size <= kMaxTinyInt  ) { this->Init(TDbi::kTiny);  return; }
00078     else if ( size <= kMaxSmallInt ) { this->Init(TDbi::kShort); return; }
00079     else if ( size <= kMaxInt      ) { this->Init(TDbi::kInt);   return; }
00080     else                             { this->Init(TDbi::kLong);  return; }
00081 
00082   }
00083 
00084   // Handle floating point types
00085 
00086   if ( type == TSQLServer::kSQL_FLOAT  ) { this->Init(TDbi::kFloat);  return; }
00087   if ( type == TSQLServer::kSQL_DOUBLE ) { this->Init(TDbi::kDouble);  return; }
00088 
00089   // Handle cases where type is determined uniquely by type name.
00090 
00091   if ( name == "BINARY_FLOAT" )  { this->Init(TDbi::kFloat);  return; }
00092   if ( name == "BINARY_DOUBLE" ) { this->Init(TDbi::kDouble); return; }
00093   if ( name == "TINYTEXT" )      { this->Init(TDbi::kString,kMaxMySQLVarchar);   return; }
00094   if ( name == "TEXT" )          { this->Init(TDbi::kString,kMaxMySQLText);   return; }
00095   if ( name == "DATE" )          { this->Init(TDbi::kDate);   return; }
00096   if ( name == "DATETIME" )      { this->Init(TDbi::kDate);   return; }
00097 
00098   // Handle character types
00099 
00100   if ( type == TSQLServer::kSQL_CHAR && size <= kMaxChar ) {
00101     this->Init(TDbi::kChar,size);
00102     return;
00103   }
00104   if ( type == TSQLServer::kSQL_CHAR || type == TSQLServer::kSQL_VARCHAR ) {
00105     if ( size < kMaxMySQLVarchar ) Init(TDbi::kString,size);
00106     else                           Init(TDbi::kString,kMaxMySQLText);
00107     return;
00108   }
00109 
00110   // Anything else is bad news!
00111 
00112      SK_DBI_Severe(  "Unable to form SQL TDbiFieldType from: " << type << "  ");
00113   this->Init(TDbi::kUnknown);
00114 
00115 }
00116 
00117 //.....................................................................
00118 
00119 TDbiFieldType::TDbiFieldType(const TDbiFieldType& from)
00120 {
00121 //
00122 //
00123 //  Purpose:  Copy constructor
00124 
00125 //  Program Notes:-
00126 //  =============
00127 
00128 //  Make explicit for leak checking.
00129 
00130 
00131   *this = from;
00132 }
00133 
00134 //.....................................................................
00135 
00136 TDbiFieldType::TDbiFieldType(const string& sql,
00137                            Int_t size )
00138 {
00139 //
00140 //
00141 //  Purpose:  Constructor from a MySQL type string
00142 
00143 
00144 
00145 
00146   if (         sql == "TINYINT" )   this->Init(TDbi::kTiny);
00147 
00148   else if (    sql == "SMALLINT" )  this->Init(TDbi::kShort);
00149 
00150   else if (    sql == "INT"
00151             || sql == "INTEGER"
00152             || sql == "NUMERIC" )   this->Init(TDbi::kInt);
00153 
00154   else if (     sql == "BIGINT" )   this->Init(TDbi::kLong);
00155 
00156   else if (    sql == "FLOAT"
00157             || sql == "REAL")       this->Init(TDbi::kFloat);
00158 
00159   else if (    sql == "DOUBLE" )    this->Init(TDbi::kDouble);
00160 
00161   else if (    sql == "CHAR"
00162             || sql == "VARCHAR"
00163             || sql == "TEXT"
00164             || sql == "TINYTEXT" ) {
00165 
00166     if      ( sql == "TINYTEXT" ) size = kMaxMySQLVarchar;
00167     else if ( sql == "TEXT"     ) size = kMaxMySQLText;
00168     else {
00169       if ( size < 0 ) {
00170         if ( sql == "CHAR" ) size = 1;
00171         else                 size = kMaxMySQLVarchar -1;
00172       }
00173     }
00174     if ( fSize <= kMaxChar ) this->Init(TDbi::kChar,size);
00175     else                     this->Init(TDbi::kString,size);
00176 
00177   }
00178 
00179   else if ( sql == "DATETIME" )     this->Init(TDbi::kDate);
00180 
00181   else {
00182        SK_DBI_Severe(  "Unable to type from SQL: " << sql << "  ");
00183                                     this->Init(TDbi::kUnknown);
00184   }
00185 
00186 }
00187 
00188 
00189 //.....................................................................
00190 
00191 TDbiFieldType::~TDbiFieldType() {
00192 //
00193 //
00194 //  Purpose: Destructor
00195 //
00196 //  Arguments:
00197 //    None.
00198 //
00199 //  Return:    n/a
00200 //
00201 //  Contact:   N. West
00202 //
00203 //  Specification:-
00204 //  =============
00205 //
00206 //  o  Destroy FieldType.
00207 
00208 
00209 //  Program Notes:-
00210 //  =============
00211 
00212 //  None.
00213 
00214 
00215 
00216 }
00217 
00218 //.....................................................................
00219 
00220 string TDbiFieldType::AsString() const {
00221 //
00222 //
00223 //  Purpose:  Return field type as a string.
00224 //
00225 //  Arguments: None.
00226 //
00227 //  Return:    Field type as a string e.g. "Int"
00228 //
00229 //  Contact:   N. West
00230 //
00231 //  Specification:-
00232 //  =============
00233 //
00234 //  o Return field type as a string.
00235 
00236 //  Program Notes:-
00237 //  =============
00238 
00239 //  None.
00240 
00241   switch ( fType ) {
00242 
00243   case  TDbi::kBool    : return "Bool";
00244   case  TDbi::kChar    : return "Char";
00245   case  TDbi::kUChar   : return "UChar";
00246   case  TDbi::kTiny    : return "Tiny";
00247   case  TDbi::kUTiny   : return "UTiny";
00248   case  TDbi::kShort   : return "Short";
00249   case  TDbi::kUShort  : return "UShort";
00250   case  TDbi::kInt     : return "Int";
00251   case  TDbi::kUInt    : return "UInt";
00252   case  TDbi::kLong    : return "Long";
00253   case  TDbi::kULong   : return "ULong";
00254   case  TDbi::kFloat   : return "Float";
00255   case  TDbi::kDouble  : return "Double";
00256   case  TDbi::kString  : return "String";
00257   case  TDbi::kTString : return "TString";
00258   case  TDbi::kDate    : return "Date";
00259   }
00260   return "Unknown";
00261 }
00262 //.....................................................................
00263 
00264 string TDbiFieldType::AsSQLString() const {
00265 //
00266 //
00267 //  Purpose:  Return field type as a string suitable for MySQL column.
00268 
00269   ostringstream os;
00270 
00271   switch ( fType ) {
00272 
00273   case  TDbi::kBool    :   os << "CHAR";          break;
00274 
00275   case  TDbi::kUTiny   :
00276   case  TDbi::kTiny    :   os << "TINYINT";       break;
00277 
00278   case  TDbi::kShort   :
00279   case  TDbi::kUShort  :   os << "SMALLINT";      break;
00280 
00281   case  TDbi::kInt     :
00282   case  TDbi::kUInt    :   os << "INT";           break;
00283 
00284   case  TDbi::kLong    :
00285   case  TDbi::kULong   :   os << "BIGINT";        break;
00286 
00287   case  TDbi::kFloat   :   os << "FLOAT";         break;
00288 
00289   case  TDbi::kDouble  :   os << "DOUBLE";        break;
00290 
00291   case  TDbi::kChar    :
00292   case  TDbi::kUChar   :
00293   case  TDbi::kString  :
00294   case  TDbi::kTString :
00295     if      ( fSize == 1)                os << "CHAR";
00296     else if ( fSize <= kMaxChar)         os << "CHAR("    << fSize << ')';
00297     else if ( fSize <  kMaxMySQLVarchar) os << "VARCHAR(" << fSize << ')';
00298     else if ( fSize == kMaxMySQLVarchar) os << "TINYTEXT";
00299     else                                 os << "TEXT";
00300     break;
00301 
00302   case  TDbi::kDate    :   os << "DATETIME";      break;
00303 
00304   default :               os << "Unknown";
00305 
00306   }
00307 
00308   return os.str();
00309 
00310 }
00311 
00312 
00313 //.....................................................................
00314 
00315 
00316 void TDbiFieldType::Init(Int_t type  /* Type as defined by TDbi::DataTypes */,
00317                         Int_t size  /* Size in bytes (default: -1 - take size from type)*/ ) {
00318 //
00319 //
00320 //  Purpose:  Initialise object.
00321 //
00322 
00323   switch ( type ) {
00324 
00325   case TDbi::kBool :
00326       fType      = TDbi::kBool;
00327       fConcept   = TDbi::kBool;
00328       fSize      = 1;
00329       break;
00330 
00331     case TDbi::kChar :
00332       fType      = TDbi::kChar;
00333       fConcept   = TDbi::kChar;
00334       fSize      = 1;
00335       break;
00336 
00337     case TDbi::kUChar :
00338       fType      = TDbi::kUChar;
00339       fConcept   = TDbi::kUChar;
00340       fSize      = 1;
00341       break;
00342 
00343     case TDbi::kTiny :
00344       fType      = TDbi::kTiny;
00345       fConcept   = TDbi::kInt;
00346       fSize      = 1;
00347       break;
00348 
00349     case TDbi::kUTiny :
00350       fType      = TDbi::kUTiny;
00351       fConcept   = TDbi::kUInt;
00352       fSize      = 1;
00353       break;
00354 
00355     case TDbi::kShort :
00356       fType      = TDbi::kShort;
00357       fConcept   = TDbi::kInt;
00358       fSize      = 2;
00359       break;
00360 
00361     case TDbi::kUShort :
00362       fType      = TDbi::kUShort;
00363       fConcept   = TDbi::kUInt;
00364       fSize      = 2;
00365       break;
00366 
00367     case TDbi::kInt :
00368       fType      = TDbi::kInt;
00369       fConcept   = TDbi::kInt;
00370       fSize      = 4;
00371       break;
00372 
00373     case TDbi::kUInt :
00374       fType      = TDbi::kUInt;
00375       fConcept   = TDbi::kUInt;
00376       fSize      = 4;
00377       break;
00378 
00379     case TDbi::kLong :
00380       fType    = TDbi::kLong;
00381       fConcept = TDbi::kInt;
00382       fSize    = 8;
00383       break;
00384 
00385     case TDbi::kULong :
00386       fType    = TDbi::kULong;
00387       fConcept = TDbi::kUInt;
00388       fSize    = 8;
00389       break;
00390 
00391     case TDbi::kFloat :
00392       fType      = TDbi::kFloat;
00393       fConcept   = TDbi::kFloat;
00394       fSize      = 4;
00395       break;
00396 
00397     case TDbi::kDouble :
00398       fType      = TDbi::kDouble;
00399       fConcept   = TDbi::kFloat;
00400       fSize      = 8;
00401       break;
00402 
00403     case TDbi::kString :
00404       fType      = TDbi::kString;
00405       fConcept   = TDbi::kString;
00406       fSize      = 65535;
00407       break;
00408 
00409     case TDbi::kTString :
00410       fType      = TDbi::kTString;
00411       fConcept   = TDbi::kString;
00412       fSize      = 65535;
00413       break;
00414 
00415     case TDbi::kDate :
00416       fType      = TDbi::kDate;
00417       fConcept   = TDbi::kDate;
00418       fSize      = 4;
00419       break;
00420 
00421     case TDbi::kUnknown :
00422       fType      = TDbi::kUnknown;
00423       fConcept   = TDbi::kUnknown;
00424       break;
00425 
00426     default :
00427          SK_DBI_Severe(  "Unable to form Root TDbiFieldType from: " << type << "  ");
00428       fType      = TDbi::kUnknown;
00429       fConcept   = TDbi::kUnknown;
00430       fSize      = 0;
00431   }
00432 
00433   // Override fSize if necessary.
00434 
00435   if ( size      >= 0  ) fSize      = size;
00436 
00437 }
00438 
00439 //.....................................................................
00440 
00441 Bool_t TDbiFieldType::IsCompatible(const TDbiFieldType& other) const {
00442 //
00443 //
00444 //  Purpose: Return kTRUE if this is compatible with or can accept
00445 //           the other type.
00446 //
00447 //  Arguments:
00448 //    other        in    The TDbiFieldType to be compared
00449 //
00450 //  Return: kTRUE if the this type can accept other type.
00451 //
00452 //  Contact:   N. West
00453 //
00454 //  Specification:-
00455 //  =============
00456 //
00457 //  o If the two types have the same concept or have compatible
00458 //    concepts return kTRUE.
00459 //
00460 //  o Also return true if the other type can be be used as input.
00461 //
00462 
00463 //  Program Notes:-
00464 //  =============
00465 
00466 //  None.
00467 
00468 #define MATCHES(x,y)  \
00469     ( (fConcept == x) && (concept == y) )\
00470   || ((fConcept == y) && (concept == x) )
00471   UInt_t concept = other.GetConcept();
00472   if ( fConcept == concept ) return kTRUE;
00473   if ( MATCHES(TDbi::kBool,  TDbi::kChar)  ) return kTRUE;
00474   if ( MATCHES(TDbi::kBool,  TDbi::kUChar) ) return kTRUE;
00475   if ( MATCHES(TDbi::kInt,   TDbi::kChar)  ) return kTRUE;
00476   if ( MATCHES(TDbi::kUInt,  TDbi::kUChar) ) return kTRUE;
00477 //  Allow unsigned to match signed because the TSQLResultSetL interface
00478 //  does not support unsigned types but its GetShort and GetInt
00479 //  methods will return unsigned data intact so we must trust
00480 //  that the user knows what they are doing!
00481   if ( MATCHES(TDbi::kUInt,  TDbi::kInt)   ) return kTRUE;
00482 //  Allow char to be input to string.
00483   if ( concept == TDbi::kChar && fConcept == TDbi::kString ) return kTRUE;
00484 
00485 return kFALSE;
00486 
00487 }
00488 
00489 //.....................................................................
00490 
00491 string TDbiFieldType::UndefinedValue() const {
00492 //
00493 //
00494 //  Purpose:  Return value to be used when unknown.
00495 //
00496 //  Arguments: None
00497 //
00498 //  Return:   Value as a string to be used when unknown.
00499 //
00500 //  Contact:   N. West
00501 //
00502 //  Specification:-
00503 //  =============
00504 //
00505 //  o Return value to be used when unknown.
00506 
00507 //  Program Notes:-
00508 //  =============
00509 
00510 //  For each conceptual data type there is an associated
00511 //  data type to be used when attemping to get value from outside
00512 //  the table or when table type incompatible with data.
00513 
00514 
00515   switch ( fConcept ) {
00516     case TDbi::kBool   : return "0";
00517     case TDbi::kChar   : return "";
00518     case TDbi::kUChar  : return "";
00519     case TDbi::kInt    : return "-999";
00520     case TDbi::kUInt   : return " 999";
00521     case TDbi::kFloat  : return "-999.";
00522     case TDbi::kString : return "";
00523     case TDbi::kDate   : return "1980-00-00 00:00:00";
00524 
00525     default :
00526          SK_DBI_Severe( "Unable to define undefined type for: "
00527             << fConcept << "  ");
00528       return "";
00529   }
00530 }
00531 
00532 

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1