TDbiInRowStream.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include <sstream>
00007
00008 #include "TDbiFieldType.hxx"
00009 #include "TDbiInRowStream.hxx"
00010 #include "TDbiString.hxx"
00011 #include "TDbiStatement.hxx"
00012 #include "TDbiTableMetaData.hxx"
00013 #include <TSK_DBI_Log.hxx>
00014 #include <MsgFormat.h>
00015 using std::endl;
00016 #include "UtilString.hxx"
00017 #include "TVldTimeStamp.hxx"
00018
00019 ClassImp(TDbiInRowStream)
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 TDbiInRowStream::TDbiInRowStream(TDbiStatement* stmtDb,
00055 const TDbiString& sql,
00056 const TDbiTableMetaData* metaData,
00057 const TDbiTableProxy* tableProxy,
00058 UInt_t dbNo,
00059 const string& fillOpts) :
00060 TDbiRowStream(metaData),
00061 fCurRow(0),
00062 fDbNo(dbNo),
00063 fStatement(stmtDb),
00064 fTSQLStatement(0),
00065 fExhausted(true),
00066 fTableProxy(tableProxy),
00067 fFillOpts(fillOpts)
00068 {
00069
00070
00071
00072
00073
00074
00075
00076
00077 SK_DBI_Trace( "Creating TDbiInRowStream" << " ");
00078
00079 if ( stmtDb ) {
00080 fTSQLStatement = stmtDb->ExecuteQuery(sql.c_str());
00081 if ( fTSQLStatement && fTSQLStatement->NextResultRow() ) fExhausted = false;
00082 }
00083
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 TDbiInRowStream::~TDbiInRowStream() {
00106
00107
00108
00109
00110
00111
00112
00113 SK_DBI_Trace( "Destroying TDbiInRowStream" << " ");
00114 delete fTSQLStatement;
00115 fTSQLStatement = 0;
00116 delete fStatement;
00117 fStatement = 0;
00118
00119 }
00120
00121
00122
00123
00124 #define IN(t) istringstream in(AsString(t)); in
00125
00126
00127
00128
00129 #define IN2(t,m) \
00130 int col = CurColNum()-1; \
00131 if ( CurRowNum() == 0 ) { \
00132 istringstream in(AsString(t)); \
00133 in >> dest; \
00134 } \
00135 else { \
00136 dest = fTSQLStatement->m(col); \
00137 IncrementCurCol(); \
00138 } \
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 #define IN3(t) \
00150 int col = this->CurColNum()-1; \
00151 const TDbiFieldType& fType = this->ColFieldType(col+1); \
00152 if ( fType.GetSize() == 8 ) { \
00153 dest=fTSQLStatement->GetUInt(col); \
00154 } \
00155 else { \
00156 t dest_signed; \
00157 *this >> dest_signed; \
00158 dest = dest_signed; \
00159 if ( fType.GetSize() == 1 ) dest &= 0xff; \
00160 if ( fType.GetSize() == 2 ) dest &= 0xffff; \
00161 if ( fType.GetSize() == 4 ) dest &= 0xffffffff; \
00162 }\
00163
00164 TDbiInRowStream& TDbiInRowStream::operator>>(Bool_t& dest) {
00165 IN(TDbi::kBool) >> dest; return *this;}
00166 TDbiInRowStream& TDbiInRowStream::operator>>(Char_t& dest) {
00167 IN(TDbi::kChar) >> dest; return *this;}
00168 TDbiInRowStream& TDbiInRowStream::operator>>(Short_t& dest) {
00169 IN2(TDbi::kInt,GetInt); return *this;}
00170 TDbiInRowStream& TDbiInRowStream::operator>>(UShort_t& dest) {
00171 IN3(Short_t); return *this;}
00172 TDbiInRowStream& TDbiInRowStream::operator>>(Int_t& dest) {
00173 IN2(TDbi::kInt,GetInt); return *this;}
00174 TDbiInRowStream& TDbiInRowStream::operator>>(UInt_t& dest) {
00175 IN3(Int_t); return *this;}
00176 TDbiInRowStream& TDbiInRowStream::operator>>(Long_t& dest) {
00177 IN2(TDbi::kLong, GetLong); return *this;}
00178 TDbiInRowStream& TDbiInRowStream::operator>>(ULong_t& dest) {
00179 IN3(Long_t); return *this;}
00180 TDbiInRowStream& TDbiInRowStream::operator>>(Float_t& dest) {
00181 IN2(TDbi::kFloat,GetDouble); return *this;}
00182 TDbiInRowStream& TDbiInRowStream::operator>>(Double_t& dest) {
00183 IN2(TDbi::kDouble,GetDouble);return *this;}
00184
00185
00186
00187 TDbiInRowStream& TDbiInRowStream::operator>>(string& dest) {
00188 dest = AsString(TDbi::kString); return *this;}
00189 TDbiInRowStream& TDbiInRowStream::operator>>(TVldTimeStamp& dest){
00190 dest=TDbi::MakeTimeStamp(AsString(TDbi::kDate)); return *this;}
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 string& TDbiInRowStream::AsString(TDbi::DataTypes type) {
00217
00218
00219
00220
00221
00222
00223
00224 TDbiFieldType reqdt(type);
00225
00226
00227
00228 Bool_t fail = ! LoadCurValue();
00229
00230 UInt_t col = CurColNum();
00231 IncrementCurCol();
00232
00233 if ( fail ) {
00234 string udef = reqdt.UndefinedValue();
00235 SK_DBI_Severe( "... value \"" << udef
00236 << "\" will be substitued." << " ");
00237 fValString = udef;
00238 return fValString;
00239 }
00240
00241
00242
00243 const TDbiFieldType& actdt = MetaData()->ColFieldType(col);
00244
00245 if ( reqdt.IsCompatible(actdt) ) {
00246 Bool_t smaller = reqdt.IsSmaller(actdt);
00247
00248 if ( reqdt.GetConcept() == TDbi::kChar && fValString.size() == 1
00249 ) smaller = kFALSE;
00250 if ( smaller ) {
00251 SK_DBI_Warn( "In table " << TableNameTc()
00252 << " row " << fCurRow
00253 << " column "<< col
00254 << " (" << MetaData()->ColName(col) << ")"
00255 << " value \"" << fValString
00256 << "\" of type " << actdt.AsString()
00257 << " may be truncated before storing in " << reqdt.AsString()
00258 << " ");
00259 }
00260 }
00261 else {
00262 string udef = reqdt.UndefinedValue();
00263 SK_DBI_Severe( "In table " << TableNameTc()
00264 << " row " << fCurRow
00265 << " column "<< col
00266 << " (" << MetaData()->ColName(col) << ")"
00267 << " value \"" << fValString
00268 << "\" of type " << actdt.AsString()
00269 << " is incompatible with user type " << reqdt.AsString()
00270 << ", value \"" << udef
00271 << "\" will be substituted." << " ");
00272 fValString = udef;
00273 }
00274
00275 return fValString;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 Bool_t TDbiInRowStream::CurColExists() const {
00296
00297
00298
00299
00300
00301
00302 Int_t col = CurColNum();
00303
00304 if ( IsExhausted() ) {
00305 SK_DBI_Severe( "In table " << TableNameTc()
00306 << " attempting to access row " << fCurRow
00307 << " column " << col
00308 << " but only " << fCurRow << " rows in table." << " ");
00309 return kFALSE;
00310 }
00311
00312 int numCols = NumCols();
00313 if ( col > numCols ) {
00314 SK_DBI_Severe( "In table " << TableNameTc()
00315 << " row " << fCurRow
00316 << " attempting to access column "<< col
00317 << " but only " << NumCols() << " in table ." << " ");
00318 return kFALSE;
00319 }
00320
00321 return kTRUE;
00322
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 string TDbiInRowStream::CurColString() const {
00341
00342
00343
00344
00345
00346
00347 if ( ! CurColExists() ) return "";
00348
00349 TString valStr = this->GetStringFromTSQL(CurColNum());
00350 return valStr.Data();
00351
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 Bool_t TDbiInRowStream::FetchRow() {
00371
00372
00373
00374
00375
00376
00377
00378 ClearCurCol();
00379 if ( IsExhausted() ) return kFALSE;
00380 ++fCurRow;
00381 if ( ! fTSQLStatement->NextResultRow() ) fExhausted = true;
00382 return ! fExhausted;
00383
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 TString TDbiInRowStream::GetStringFromTSQL(Int_t col) const {
00399
00400
00401 TString valStr = fTSQLStatement->GetString(col-1);
00402 return valStr;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 Bool_t TDbiInRowStream::LoadCurValue() const{
00423
00424
00425 fValString.clear();
00426
00427 if ( ! CurColExists() ) return kFALSE;
00428
00429 Int_t col = CurColNum();
00430 TString valStr = this->GetStringFromTSQL(col);
00431
00432
00433
00434 if ( CurColFieldType().GetConcept() == TDbi::kFloat ) {
00435 ostringstream out;
00436 out << setprecision(8);
00437 if ( CurColFieldType().GetType() == TDbi::kDouble ) out << setprecision(16);
00438
00439 out << fTSQLStatement->GetDouble(col-1);
00440 valStr = out.str().c_str();
00441 }
00442 int len = valStr.Length();
00443
00444
00445
00446 const char* pVal = valStr.Data();
00447
00448 if ( len >= 2
00449 && ( *pVal == *(pVal+len-1) )
00450 && ( *pVal == '\'' || *pVal == '"' ) ) {
00451 ++pVal;
00452 len -= 2;
00453 }
00454 fValString.assign(pVal,len);
00455
00456 return kTRUE;
00457
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 void TDbiInRowStream::RowAsCsv(string& row) const {
00469
00470 const TDbiTableMetaData* md = this->MetaData();
00471
00472 Int_t maxCol = this->NumCols();
00473 for (Int_t col = 1; col <= maxCol; ++col) {
00474
00475 if ( fTSQLStatement->IsNull(col-1) ) {
00476 row += "NULL";
00477 if ( col < maxCol ) row += ',';
00478 continue;
00479 }
00480 Bool_t mustDelimit = md->ColMustDelimit(col);
00481 UInt_t concept = md->ColFieldConcept(col);
00482 if ( mustDelimit ) row += '\'';
00483 TString str = this->GetStringFromTSQL(col);
00484 const char* value = str.Data();
00485
00486
00487 if ( concept == TDbi::kString ) UtilString::MakePrintable(value,row);
00488
00489
00490
00491 else if ( concept == TDbi::kFloat ) {
00492 ostringstream out;
00493 out << setprecision(8);
00494 if ( md->ColFieldType(col).GetType() == TDbi::kDouble ) out << setprecision(16);
00495 out << fTSQLStatement->GetDouble(col-1);
00496 row += out.str();
00497 }
00498
00499
00500 else row += value;
00501
00502 if ( mustDelimit ) row += '\'';
00503 if ( col < maxCol ) row += ',';
00504 }
00505 }
00506
00507
00508