Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DbiRecord.cxx

Go to the documentation of this file.
00001 // $Id: DbiRecord.cxx,v 1.4 2004/08/03 21:37:33 rhatcher Exp $
00002 
00003 #include <iostream>
00004 #include <list>
00005 
00006 #include "DatabaseInterface/DbiResultKey.h"
00007 #include "DatabaseInterface/DbiRecord.h"
00008 #include "LeakChecker/Lea.h"
00009 #include "MessageService/MsgService.h"
00010 
00011 ClassImp(DbiRecord)
00012 
00013 
00014 //   Definition of static data members
00015 //   *********************************
00016 
00017 CVSID("$Id: DbiRecord.cxx,v 1.4 2004/08/03 21:37:33 rhatcher Exp $");
00018 
00019 //   Global Functions
00020 //   ****************
00021 
00022 std::ostream& operator<<(std::ostream& os, const DbiRecord& rec) {
00023 
00024   int numKeys = rec.fKeys.GetSize();
00025 
00026   if ( numKeys == 0 ) {
00027     os << "DbiRecord is empty." << endl;
00028     return os;
00029   }
00030 
00031   os << "DbiRecord contains the following " << numKeys << " DbiResultKeys:- \n\n";
00032   TIter itr(&rec.fKeys);
00033   while ( const DbiResultKey* key = dynamic_cast<const DbiResultKey*>(itr.Next() ) )
00034     os << "  " << *key;
00035   return os;
00036 
00037 }
00038 
00039 // Definition of member functions (alphabetical order)
00040 // ***************************************************
00041 
00042 //.....................................................................
00043 
00044 DbiRecord::DbiRecord()
00045 {
00046 //
00047 //
00048 //  Purpose:  Default constructor
00049 //
00050 //  Contact:   N. West
00051 //
00052 //  Specification:-
00053 //  =============
00054 //
00055 //  o  Create DbiRecord.
00056 
00057   LEA_CTOR    //Leak Checker
00058 
00059   MSG("Dbi", Msg::kVerbose) << "Creating DbiRecord" << endl;
00060 
00061 }
00062 
00063 //.....................................................................
00064 
00065 DbiRecord::~DbiRecord() {
00066 //
00067 //
00068 //  Purpose: Destructor
00069 //
00070 //  Contact:   N. West
00071 //
00072 //  Specification:-
00073 //  =============
00074 //
00075 //  o  Destroy DbiRecord
00076 
00077   LEA_DTOR    //Leak Checker
00078 
00079   MSG("Dbi", Msg::kVerbose) << "Destroying DbiRecord" << endl;
00080 
00081 }
00082 
00083 //.....................................................................
00084 
00085 void DbiRecord::AddTableRowNames( std::set<std::string>& names) const {
00086 //
00087 //
00088 //  Purpose: Add TableRow names to supplied set. 
00089 //
00090 
00091   TIter itr(&fKeys);
00092   while ( const DbiResultKey* key = dynamic_cast<const DbiResultKey*>(itr.Next() ) )
00093     names.insert(key->GetTableRowName());
00094 
00095 }
00096 //.....................................................................
00097 
00098 void DbiRecord::AdoptKey(DbiResultKey* key) {
00099 //
00100 //
00101 //  Purpose:  Adopt (take control of) a Dbikey.
00102 //
00103 //  Arguments: 
00104 //    key          in    DbiResultKey to be adopted 
00105 //
00106 
00107   if ( ! key ) {
00108     MSG("Dbi",Msg::kWarning) << "Attempting to adopt a null DbiResultKey!" << endl;
00109     return;
00110   }
00111   if ( fKeys.FindObject(key) ) {
00112     MSG("Dbi",Msg::kWarning) << "Attempting to adopt DbiResultKey at " << (void*) key 
00113                              << " which is already adopted." << endl; 
00114   }
00115   else {
00116     MSG("Dbi",Msg::kDebug) << "Adopting key: " << key->AsString() << endl;
00117     fKeys.Add(key);
00118   }
00119 
00120 }
00121 //.....................................................................
00122 
00123 Bool_t DbiRecord::CompareTableRowKeys(const DbiRecord* that,
00124                                       const std::string& tableRow,
00125                                       std::ostream* os) const  {
00126 //
00127 //
00128 //  Purpose: Compare all keys for a specific table::row with supplied DbiRecord
00129 //
00130 //  Arguments: 
00131 //    that         in    The DbiRecord to be compared
00132 //    tableRow     in    The table::row name used to select DbiesultKeys
00133 //    os           in    stream on which to report results if not null.
00134 //
00135 //  Return:    =false  One or more keys don't exactly match
00136 //             =true   All selected keys match (by maybe none were selected).
00137 
00138   typedef std::list<const DbiResultKey*> list_t;
00139   typedef std::list<const DbiResultKey*>::iterator list_itr_t;
00140   
00141   bool allMatch = true;
00142 
00143   //  Collect list of selected keys from both records.
00144 
00145   list_t list1, list2;
00146   TIter itr1(&fKeys);
00147   while ( const DbiResultKey* key = dynamic_cast<const DbiResultKey*>(itr1.Next() ) )
00148     if ( key->GetTableRowName() == tableRow ) list1.push_back(key);
00149   TIter itr2(&that->fKeys);
00150   while ( const DbiResultKey* key = dynamic_cast<const DbiResultKey*>(itr2.Next() ) )
00151     if ( key->GetTableRowName() == tableRow ) list2.push_back(key);
00152 
00153   //  Repeatedly find the best match between the 2 lists and remove it until
00154   //  no good matches remain.
00155 
00156   float bestMatch = 1.;
00157   list_itr_t bestItr1 = list1.begin();
00158   list_itr_t bestItr2 = list2.begin();
00159 
00160   while ( bestMatch > 0. ) {
00161     bestMatch = 0.;
00162     for ( list_itr_t itr1 = list1.begin(); itr1 != list1.end(); ++itr1 ) {
00163       for ( list_itr_t itr2 = list2.begin(); itr2 != list2.end(); ++itr2 ) {
00164         float match = (*itr1)->Compare(*itr2);
00165         if ( match > bestMatch ) {
00166           bestMatch = match;
00167           bestItr1 = itr1;
00168           bestItr2 = itr2;
00169         }
00170       }
00171     }
00172     if ( bestMatch > 0. ) {
00173       if ( os ) {
00174         if ( bestMatch == 1.) *os << "Found in both records. Exact match " << **bestItr1;
00175         else {
00176           *os << "Found in both records. Match " << bestMatch 
00177              << "  " <<  **bestItr1 << " " << **bestItr2;
00178           allMatch = false;
00179         }
00180       }
00181       list1.erase(bestItr1);
00182       list2.erase(bestItr2);
00183     }
00184   }
00185 
00186   // Deal with the leftovers.
00187 
00188   if ( list1.size() > 0 || list2.size() > 0 ) allMatch = false;
00189   if ( os ) {
00190     for ( list_itr_t itr1 = list1.begin(); itr1 != list1.end(); ++itr1 ) 
00191       *os << "Found in first record: " << **itr1;
00192     for ( list_itr_t itr2 = list2.begin(); itr2 != list2.end(); ++itr2 ) 
00193       *os << "Found in second record: " << **itr2;
00194   }
00195 
00196   return allMatch;
00197 }
00198 
00199 //.....................................................................
00200 
00201 const DbiResultKey* DbiRecord::DeleteKey(const DbiResultKey* key) {
00202 //
00203 //
00204 //  Purpose:  Delete key.
00205 //
00206 //  Arguments: 
00207 //    key          in    DbiResultKey to be deleted
00208 //
00209 //  Return:    = 0 If DbiRecord owned the key and has deleted it.
00210 //             key (unchanged) if DbiRecord did not own it. 
00211 
00212 // Remove takes a non-const pointer (don't ask me) so cast so that key
00213 // can be a const (the caller doesn't own the DbiResultKey, this object does)
00214   DbiResultKey* myKey = const_cast<DbiResultKey*>(key);
00215   TObject* keyFound = fKeys.Remove(myKey);
00216 
00217   if ( keyFound ) {
00218     MSG("Dbi",Msg::kDebug) << "Deleting key: " << key->AsString() << endl;
00219     delete key;
00220     return 0;
00221   }
00222   else {
00223     MSG("Dbi",Msg::kWarning) << "Attempting to delete DbiResultKey at " << (void*) key 
00224                              << " which has not been adopted." << endl; 
00225     return key;
00226   }
00227 
00228 }
00229 
00230 /*    Template for New Member Function
00231 
00232 //.....................................................................
00233 
00234 DbiRecord:: {
00235 //
00236 //
00237 //  Purpose:  
00238 //
00239 //  Arguments: 
00240 //    xxxxxxxxx    in    yyyyyy
00241 //
00242 //  Return:    
00243 //
00244 //  Contact:   N. West
00245 //
00246 //  Specification:-
00247 //  =============
00248 //
00249 //  o 
00250 
00251 //  Program Notes:-
00252 //  =============
00253 
00254 //  None.
00255 
00256 
00257 }
00258 
00259 */
00260 

Generated on Mon Feb 15 11:06:34 2010 for loon by  doxygen 1.3.9.1