TDbiTableMetaData.cxx

Go to the documentation of this file.
00001 
00002 //////////////////////////////////////////////////////////////////////////
00003 ////////////////////////////     ROOT API     ////////////////////////////
00004 //////////////////////////////////////////////////////////////////////////
00005 
00006 
00007 #include <cassert>
00008 #include <cctype>
00009 #include <sstream>
00010 
00011 #include "TString.h"
00012 
00013 #include "TDbi.hxx"
00014 #include "TDbiString.hxx"
00015 #include "TDbiTableMetaData.hxx"
00016 #include <TSK_DBI_Log.hxx>
00017 #include <MsgFormat.h>
00018 using std::endl;
00019 
00020 ClassImp(TDbiTableMetaData)
00021 
00022 //   Definition of static data members
00023 //   *********************************
00024 
00025 
00026 TDbiTableMetaData::ColumnAttributes TDbiTableMetaData::fgDummy;
00027 
00028 //    Definition of all member functions (static or otherwise)
00029 //    *******************************************************
00030 //
00031 //    -  ordered: ctors, dtor, operators then in alphabetical order.
00032 
00033 //.....................................................................
00034 
00035 TDbiTableMetaData::TDbiTableMetaData(const string& tableName) :
00036 fNumCols(0),
00037 fTableName(tableName)
00038 {
00039 //
00040 //
00041 //  Purpose:  Default constructor
00042 
00043 //  Program Notes:-
00044 //  =============
00045 
00046 //  This is filled by the owning TDbiTableProxy, as it is too low level to
00047 //  use the cascade to fill itself, hence the friend status granted to TDbiDBProxy.
00048 
00049 
00050   SK_DBI_Trace( "Creating TDbiTableMetaData" << "  ");
00051 
00052 }
00053 
00054 //.....................................................................
00055 
00056 TDbiTableMetaData::~TDbiTableMetaData() {
00057 //
00058 //
00059 //  Purpose: Destructor
00060 
00061 
00062   SK_DBI_Trace( "Destroying TDbiTableMetaData" << "  ");
00063 
00064 }
00065 
00066 ///.....................................................................
00067 
00068 void TDbiTableMetaData::Clear() {
00069 //
00070 //
00071 //  Purpose: Clear out existing data (apart from table name)
00072 //
00073 //  Contact:   N. West
00074 
00075   fColAttr.clear();
00076   fNumCols = 0;
00077 
00078 }
00079 
00080 //.....................................................................
00081 
00082 void TDbiTableMetaData::ExpandTo(UInt_t colNum) {
00083 //
00084 //
00085 //  Purpose: Expand table if required to specied colNum
00086 //
00087 //  Arguments:
00088 //    colNum       in    Column number to expand to (1,2...).
00089 //
00090 //  Return:
00091 //
00092 //  Contact:   N. West
00093 //
00094 //  Specification:-
00095 //  =============
00096 //
00097 //  o
00098 
00099 //  Program Notes:-
00100 //  =============
00101 
00102 //  None.
00103 
00104   assert ( colNum < MAXCOL );
00105   while ( fNumCols < colNum ) {
00106     fColAttr.push_back(ColumnAttributes());
00107     ++fNumCols;
00108   }
00109 }
00110 
00111 //.....................................................................
00112 
00113 const  TDbiTableMetaData::ColumnAttributes&  TDbiTableMetaData::GetAttributes(Int_t colNum) const {
00114 
00115 // Return a column attributes (will be dummy entry if requesting invalid column)
00116 
00117   if ( colNum > 0 && colNum <= (signed) fNumCols ) return fColAttr[colNum-1];
00118   fgDummy.SetDefault();
00119   return fgDummy;
00120 
00121 }
00122 
00123 //.....................................................................
00124 
00125 string TDbiTableMetaData::GetToken(const char*& strPtr) {
00126 //
00127 //
00128 //  Purpose:  Skip spaces and return next token from string and move pointer on.
00129 
00130   string token;
00131 
00132 // Skip white space and quit if at EOS.
00133   while ( isspace(*strPtr) ) ++strPtr;
00134   if ( *strPtr == 0 ) return token;
00135 
00136 // Collect the first character whatever it is.
00137   char firstChar = *strPtr++;
00138   token = firstChar;
00139   if ( ! isalnum(firstChar) && firstChar != '_' ) return token;
00140 
00141 // Collect more if collecting alphanumeric + underscore string
00142   while ( isalnum(*strPtr) || *strPtr == '_' ) token += *strPtr++;
00143   return token;
00144 
00145 }
00146 
00147 //.....................................................................
00148 
00149  TDbiTableMetaData::ColumnAttributes& TDbiTableMetaData::SetAttributes(Int_t colNum) {
00150 
00151 // Return a column attributes (will be dummy entry if requesting invalid column)
00152 
00153   this->ExpandTo(colNum);
00154   // Using const metho so must cast away constness.
00155   return const_cast<TDbiTableMetaData::ColumnAttributes&>(this->GetAttributes(colNum));
00156 
00157 }
00158 
00159 
00160 //.....................................................................
00161 
00162 void TDbiTableMetaData::SetColFieldType(const TDbiFieldType& fieldType,
00163                                        Int_t colNum) {
00164 //
00165 //
00166 //  Purpose:  Define field type for specified column.
00167 //
00168 //  Arguments:
00169 //    fieldType    in    Column field type.
00170 //    colNum       in    Column number (1,2...)
00171 //
00172 
00173   ColumnAttributes&  attrib(this->SetAttributes(colNum));
00174   UInt_t concept     = fieldType.GetConcept();
00175   attrib.Type        = fieldType;
00176   attrib.MustDelimit = concept == TDbi::kString || concept == TDbi::kDate || concept == TDbi::kChar;
00177   attrib.Concept     = concept;
00178 
00179 }
00180 
00181 //.....................................................................
00182 
00183 void TDbiTableMetaData::SetFromSql(const string& sql) {
00184 //
00185 //
00186 //  Purpose:  Reconstruct this object using SQL to create table.
00187 
00188 
00189   TString SqlUpper(sql);
00190   SqlUpper.ToUpper();
00191 
00192   const char* strPtr = SqlUpper.Data();
00193 
00194   string token1(TDbiTableMetaData::GetToken(strPtr));
00195   string token2(TDbiTableMetaData::GetToken(strPtr));
00196   string token3(TDbiTableMetaData::GetToken(strPtr));
00197   string token4(TDbiTableMetaData::GetToken(strPtr));
00198 
00199   if ( token1 != "CREATE" || token2 != "TABLE" || token4 != "(" ) {
00200     SK_DBI_Severe( "Cannot recreate: SQL " << SqlUpper
00201                            << " does not start CREATE TABLE ... (" << "  ");
00202     return;
00203   }
00204 
00205   this->Clear();
00206   fTableName = token3;
00207   SK_DBI_Log( "Recreating  TDbiTableMetaData for table " << fTableName << "  ");
00208 
00209 // Loop processing column specifications.
00210   Int_t col = 0;
00211 
00212   string delim;
00213   while ( delim != ")" ) {
00214     string name = TDbiTableMetaData::GetToken(strPtr);
00215 
00216 //  Deal with INDEX and PRIMARY KEY
00217     if ( name == "INDEX" ||  name == "KEY" || name == "PRIMARY" ) {
00218       if ( name == "PRIMARY" || name == "KEY" )delim = TDbiTableMetaData::GetToken(strPtr);
00219       delim = TDbiTableMetaData::GetToken(strPtr);
00220       if ( delim == "(" ) while ( delim != ")" ) delim = TDbiTableMetaData::GetToken(strPtr);
00221       delim = TDbiTableMetaData::GetToken(strPtr);
00222       continue;
00223     }
00224 
00225 //  Collect name and type.
00226     ++col;
00227     this->SetColName(name,col);
00228     this->SetColIsNullable(col);
00229 
00230     string type = TDbiTableMetaData::GetToken(strPtr);
00231     int precision = 0;
00232     delim = TDbiTableMetaData::GetToken(strPtr);
00233     if ( delim == "(" ) {
00234       delim = TDbiTableMetaData::GetToken(strPtr);
00235       istringstream is(delim);
00236       is >> precision;
00237       delim = TDbiTableMetaData::GetToken(strPtr);
00238       delim = TDbiTableMetaData::GetToken(strPtr);
00239     }
00240     TDbiFieldType ft(type,precision);
00241     this->SetColFieldType(ft,col);
00242     SK_DBI_Log( "  Column: " << col << " name " << this->ColName(col)
00243                           << " type " << this->ColFieldType(col).AsString()
00244                           << " precision " << precision << "  ");
00245 
00246 //  Collect optional qualifiers.
00247 
00248     while ( delim != ","  &&  delim != ")" ) {
00249       string opt2 = TDbiTableMetaData::GetToken(strPtr);
00250       if ( delim == "NOT" && opt2 == "NULL") {
00251         this->SetColIsNullable(col,false);
00252         delim = TDbiTableMetaData::GetToken(strPtr);
00253       }
00254       else if ( delim == "PRIMARY" && opt2 == "KEY") {
00255         delim = TDbiTableMetaData::GetToken(strPtr);
00256       }
00257       else if ( delim == "AUTO_INCREMENT") {
00258         delim = opt2;
00259       }
00260       else if ( delim == "UNSIGNED") {
00261         delim = opt2;
00262       }
00263       else {
00264         SK_DBI_Warn( "Column: " << col << " name " << name << " type " << ft.AsString()
00265                               << " ignoring unknown option: " << delim << "  ");
00266         delim = opt2;
00267       }
00268     }
00269   }
00270 
00271 }
00272 
00273 
00274 //.....................................................................
00275 
00276 string TDbiTableMetaData::Sql() const {
00277 //
00278 //
00279 //  Purpose:  Return SQL string to create table.
00280 //
00281 //  Return:    SQL command to create required table.
00282 
00283   Bool_t mainTable = fTableName.substr(fTableName.size()-3,3) != "VLD";
00284 
00285   string tableName = fTableName;
00286   TDbiString sql;
00287   sql.GetString() = "";
00288   sql << "create table " << tableName << "(";
00289 
00290 
00291 //  Assemble columns.
00292 
00293   int numCols = this->NumCols();
00294   for(int i=1; i<= numCols; i++) {
00295 
00296     sql << this->ColName(i) << " " ;
00297     sql << this->ColFieldType(i).AsSQLString();
00298 
00299     if(    this->ColName(i) == "SEQNO"
00300         && ! mainTable )          sql << " not null primary key" ;
00301 
00302     else if( ! this->ColIsNullable(i)
00303             || this->ColName(i) == "SEQNO"
00304             || this->ColName(i) == "ROW_COUNTER"
00305            ) sql << " not null" ;
00306 
00307     if (i < numCols)              sql << ", ";
00308 
00309   }
00310 
00311 // Deal with key/index/constraint.
00312 
00313 // Nothing to do for the special xxxSEQNO tables.
00314   if ( fTableName == "GLOBALSEQNO" ||  fTableName == "LOCALSEQNO" ) {
00315     sql << ")";
00316   }
00317 
00318   else {
00319    if ( mainTable ) {
00320       sql << ", primary key (SEQNO,ROW_COUNTER)";
00321     }
00322     else {
00323       sql << ", key TIMESTART (TIMESTART), key TIMEEND (TIMEEND)";
00324     }
00325     sql << ")";
00326   }
00327 
00328   return sql.GetString();
00329 
00330 }
00331 
00332 

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1