00001
00002
00003 #include <sstream>
00004
00005 #include "DatabaseInterface/DbiBinaryFile.h"
00006 #include "DatabaseInterface/DbiResultKey.h"
00007 #include "DatabaseInterface/DbiRecord.h"
00008 #include "DatabaseInterface/DbiResult.h"
00009 #include "DatabaseInterface/DbiResultSet.h"
00010 #include "DatabaseInterface/DbiServices.h"
00011 #include "DatabaseInterface/DbiTableRow.h"
00012 #include "LeakChecker/Lea.h"
00013 #include "MessageService/MsgService.h"
00014
00015 ClassImp(DbiResult)
00016
00017
00018
00019
00020 Int_t DbiResult::fgLastID(0);
00021
00022 CVSID("$Id: DbiResult.cxx,v 1.24 2011/10/31 18:59:42 rhatcher Exp $");
00023
00024
00025
00026
00027
00028 DbiBinaryFile& operator<<(DbiBinaryFile& bf, const DbiResult& res) {
00029
00030
00031
00032 DbiResult& res_tmp = const_cast< DbiResult&>(res);
00033 res_tmp.Streamer(bf);
00034 return bf;
00035 }
00036
00037
00038
00039 DbiBinaryFile& operator>>(DbiBinaryFile& bf, DbiResult& res) {
00040
00041 res.Streamer(bf);
00042 return bf;
00043 }
00044
00045
00046
00047
00048
00049
00050
00051 DbiResult::DbiResult(DbiResultSet* resultSet,
00052 const DbiValidityRec* vrec,
00053 const string& sqlQualifiers) :
00054 fID(++fgLastID),
00055 fCanReuse(kTRUE),
00056 fEffVRec(0),
00057 fKey(0),
00058 fResultsFromDb(kFALSE),
00059 fNumClients(0),
00060 fTableName("Unknown"),
00061 fSqlQualifiers(sqlQualifiers)
00062 {
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 LEA_CTOR
00089
00090 MSG("Dbi", Msg::kVerbose) << "Creating DbiResult" << endl;
00091
00092 if ( vrec ) fEffVRec = *vrec;
00093 if ( resultSet ) fTableName = resultSet->TableNameTc();
00094
00095 }
00096
00097
00098
00099 DbiResult::~DbiResult() {
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 LEA_DTOR
00123
00124 MSG("Dbi", Msg::kVerbose) << "Destroying DbiResult." << endl;
00125
00126 if ( fNumClients ) {
00127 MSG("Dbi", Msg::kWarning)
00128 << "Warning: Destroying DbiResult with " << fNumClients
00129 << " clients " << endl;
00130 }
00131
00132 this->DeRegisterKey();
00133
00134 }
00135
00136
00137 void DbiResult::BuildLookUpTable() const {
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 Bool_t duplicatesOK = this->IsExtendedContext();
00153
00154 MSG("Dbi", Msg::kVerbose) << "Building look-uptable. Allow duplicates: "
00155 << duplicatesOK << endl;
00156
00157 for ( Int_t rowNo = this->GetNumRows()-1;
00158 rowNo >= 0;
00159 --rowNo ) {
00160 const DbiTableRow* row = this->GetTableRow(rowNo);
00161 UInt_t index = row->GetIndex(rowNo);
00162
00163
00164
00165
00166 const DbiTableRow* row2 = this->DbiResult::GetTableRowByIndex(index);
00167
00168 MSG("Dbi", Msg::kVerbose)
00169 << "Look-up. Row no " << rowNo
00170 << " index " << index
00171 << " row,row2 " << (void*) row << "," << (void*) row2 << endl;
00172
00173 if ( row2 != 0 && row2 != row && ! duplicatesOK ) {
00174 std::ostringstream msg;
00175 msg << "Duplicated row natural index: " << index
00176 << " Found at row " << rowNo
00177 << " of table " << this->TableName()
00178 << ":-\n index of agg " << row->GetAggregateNo();
00179 if ( row->GetOwner() ) msg << "(SEQNO " << row->GetOwner()->GetValidityRec(row).GetSeqNo() << ")";
00180 msg << " matches agg " << row2->GetAggregateNo();
00181 if ( row2->GetOwner() ) msg << "(SEQNO " << row2->GetOwner()->GetValidityRec(row2).GetSeqNo() << ")";
00182 MAXMSG("Dbi",Msg::kError,20) << msg.str() << endl;
00183 }
00184
00185 else fIndexKeys[index] = row;
00186 }
00187
00188 }
00189
00190
00191
00192 Bool_t DbiResult::CanDelete(const DbiResult* res) {
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 if ( res
00206 && this->CanReuse()
00207 && this->GetValidityRec().HasExpired(res->GetValidityRec())
00208 ) this->SetCanReuse(kFALSE);
00209
00210 return ! this->GetNumClients() && ! this->CanReuse();
00211 }
00212
00213
00214
00215 void DbiResult::CaptureExceptionLog(UInt_t startFrom) {
00216
00217
00218
00219
00220 fExceptionLog.Clear();
00221 DbiExceptionLog::GetGELog().Copy(fExceptionLog,startFrom);
00222
00223 }
00224
00225
00226
00227 void DbiResult::DeRegisterKey() {
00228
00229
00230
00231
00232 if ( ! fKey ) return;
00233
00234 DbiRecord* record = DbiServices::GetRecord();
00235 if ( ! record ) {
00236 MSG("Dbi",Msg::kWarning) << "Attempting to deregister DbiResultKey at " << (void*) fKey
00237 << " but owning DbiRecord cannot be found." << endl;
00238 }
00239 else {
00240 record->DeleteKey(fKey);
00241 fKey = 0;
00242 }
00243
00244 }
00245
00246
00247 const DbiResultKey* DbiResult::GetKey() const {
00248
00249
00250
00251 return fKey ? fKey : DbiResultKey::GetEmptyKey();
00252
00253 }
00254
00255
00256
00257 const DbiTableRow* DbiResult::GetTableRowByIndex(UInt_t index) const {
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 IndexToRow_t::const_iterator idx = fIndexKeys.find(index);
00268 return ( idx == fIndexKeys.end() ) ? 0 : (*idx).second;
00269
00270 }
00271
00272
00273
00274 void DbiResult::RegisterKey() {
00275
00276
00277
00278
00279 if ( fKey || this->GetNumRows() == 0) return;
00280
00281 DbiRecord* record = DbiServices::GetRecord();
00282 if ( ! record ) {
00283 MSG("Dbi",Msg::kWarning) << "cannot create and register key"
00284 << ", owning DbiRecord cannot be found." << endl;
00285 }
00286 else {
00287 DbiResultKey* key = this->CreateKey();
00288 record->AdoptKey(key);
00289 fKey = key;
00290 }
00291
00292 }
00293
00294
00295 Bool_t DbiResult::Satisfies(const VldContext& vc,
00296 const Dbi::Task& task) {
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 Bool_t isExtendedContext = this->IsExtendedContext();
00320 Bool_t canReuse = this->CanReuse();
00321 Bool_t isCompatible = this->GetValidityRec().IsCompatible(vc,task);
00322 Bool_t hasExpired = this->GetValidityRec().HasExpired(vc,task);
00323 UInt_t numClients = this->GetNumClients();
00324 MSG("Dbi",Msg::kDebug)
00325 << " Checking result with DbiValidityRec:- \n " << this->GetValidityRec()
00326 << " With extended context: " << isExtendedContext
00327 << " CanReuse: " << canReuse
00328 << " Is Compatible: " << isCompatible
00329 << " HasExpired: " << hasExpired
00330 << " number of clients: " << numClients
00331 << endl;
00332
00333 if ( isExtendedContext ) return kFALSE;
00334
00335 if ( canReuse && isCompatible ) return kTRUE;
00336
00337
00338
00339
00340
00341 if ( canReuse && hasExpired && numClients == 0 ) {
00342 MSG("Dbi",Msg::kDebug) << " Marking result as not reusable" << endl;
00343 this-> SetCanReuse(kFALSE);
00344 }
00345
00346 return kFALSE;
00347
00348 }
00349
00350
00351 void DbiResult::Streamer(DbiBinaryFile& file) {
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 if ( file.IsReading() ) {
00362 MSG("Dbi", Msg::kDebug) << " Restoring DbiResult ..." << endl;
00363 file >> fCanReuse;
00364 fEffVRec.Streamer(file);
00365 MSG("Dbi", Msg::kVerbose) << " Restored " << fEffVRec << endl;
00366 fResultsFromDb = kFALSE;
00367 fNumClients = 0;
00368 file >> fTableName;
00369 MSG("Dbi", Msg::kVerbose) << " Restored string " << fTableName << endl;
00370 }
00371 else if ( file.IsWriting() ) {
00372 MSG("Dbi", Msg::kDebug) << " Saving DbiResult ..." << endl;
00373 file << fCanReuse;
00374 MSG("Dbi", Msg::kVerbose) << " Saving " << fEffVRec << endl;
00375 fEffVRec.Streamer(file);
00376 MSG("Dbi", Msg::kVerbose) << " Saving string " << fTableName << endl;
00377 file << fTableName;
00378 }
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411