00001 #ifndef DBITABLEPROXY_H 00002 #define DBITABLEPROXY_H 00003 00004 /** 00005 * 00006 * 00007 * \class TDbiTableProxy 00008 * 00009 * 00010 * \brief 00011 * <b>Concept</b> Object to query a specific database table. 00012 * 00013 * \brief 00014 * <b>Purpose</b> A TDbiTableProxy is an object that knows how to send 00015 * queries to a specific database table. Internally it uses a cache 00016 * to minimise I/O. 00017 * 00018 * Contact: A.Finch@lancaster.ac.uk 00019 * 00020 * 00021 */ 00022 00023 #include <string> 00024 #include <sstream> 00025 using std::string; 00026 00027 #include "TDbi.hxx" 00028 #include "TDbiDBProxy.hxx" 00029 #include "TDbiTableMetaData.hxx" 00030 #include "TDbiValidityRec.hxx" 00031 #include "TVldContext.hxx" 00032 #include "TVldTimeStamp.hxx" 00033 00034 00035 class TDbiCache; 00036 class TDbiCascader; 00037 class TDbiResultSet; 00038 class TDbiDatabaseManager; 00039 class TDbiTableRow; 00040 class TDbiValidityRec; 00041 class TDbiValidityRecBuilder; 00042 00043 class TDbiTableProxy 00044 { 00045 00046 friend class TDbiDatabaseManager; //Allow Resistry access to ctor/dtor. 00047 00048 public: 00049 00050 // State testing member functions 00051 const TDbiDBProxy& GetDBProxy() const { return fDBProxy; } 00052 TDbiCascader& GetCascader() { return *fCascader; } 00053 const TDbiTableMetaData& GetMetaData() const { return fMetaData; } 00054 const TDbiTableMetaData& GetMetaValid() const { return fMetaValid; } 00055 string GetRowName() const { 00056 return fTableRow ? fTableRow->ClassName() : "Unknown";} 00057 string GetTableName() const { return fTableName;} 00058 // State changing member functions 00059 TDbiCache* GetCache() { return fCache;} 00060 // 00061 ///\verbatim 00062 /// Purpose: Apply context specific query to database table and return result. 00063 /// 00064 /// Arguments: 00065 /// vc in The Validity Context for the query. 00066 /// task in The task of the query. 00067 /// findFullTimeWindow 00068 /// in Attempt to find full validity of query 00069 /// i.e. beyond TDbi::GetTimeGate 00070 /// 00071 /// Return: Query result (never zero even if query fails). 00072 /// 00073 /// Contact: N. West 00074 /// 00075 /// Specification:- 00076 /// ============= 00077 /// 00078 /// o Apply query to database table and return result. 00079 /// 00080 /// Program Notes:- 00081 /// ============= 00082 /// 00083 /// None. 00084 /// 00085 /// See if there is one already in the cache for universal aggregate no. 00086 /// \endverbatim 00087 const TDbiResultSet* Query(const TVldContext& vc, 00088 const TDbi::Task& task, 00089 Bool_t findFullTimeWindow = true); 00090 /// 00091 ///\verbatim 00092 /// Purpose: Apply extended context query to database table and return result. 00093 /// 00094 /// Arguments: 00095 /// context in The Validity Context (see TDbiSqlContext) 00096 /// task in The task of the query. 00097 /// data in Optional SQL extension to secondary query. 00098 /// fillOpts in Optional fill options (available to TDbiTableRow) 00099 /// 00100 /// Return: Query result (never zero even if query fails). 00101 /// 00102 /// Contact: N. West 00103 /// 00104 /// Specification:- 00105 /// ============= 00106 /// 00107 /// o Apply extended context query to database table and return result. 00108 /// 00109 /// o Don't save/restore to L2 cache: encoding the query name as a file name 00110 /// would be cumbersome and in any case extended queries are abnormal 00111 /// so optimisation is unwarranted. 00112 /// 00113 /// 00114 /// Construct the query's "SQL Qualifiers" by forming the 3 strings 00115 /// (which task encoded into the context) into a single semi-colon 00116 /// separated string. 00117 /// \endverbatim 00118 const TDbiResultSet* Query(const string& context, 00119 const TDbi::Task& task, 00120 const string& data, 00121 const string& fillOpts); 00122 ///\verbatim 00123 /// 00124 /// Purpose: Apply non-agregate query to database table and return result. 00125 /// 00126 /// Arguments: 00127 /// seqNo in The sequence number of validity record that satisfies the query. 00128 /// dbNo in Database number in the cascade. 00129 /// 00130 /// Return: Query result (never zero even if query fails). 00131 ///\endverbatim 00132 const TDbiResultSet* Query(UInt_t seqNo,UInt_t dbNo); 00133 ///\verbatim 00134 /// 00135 /// Purpose: Apply non-agregate query to database table and return result. 00136 /// 00137 /// Arguments: 00138 /// vrec in The validity record that satisfies the query. 00139 /// canReuse in True if result is to be cached. 00140 /// 00141 /// Return: Query result (never zero even if query fails). 00142 /// 00143 /// Contact: N. West 00144 /// 00145 /// Specification:- 00146 /// ============= 00147 /// 00148 /// o Apply non-aggregated query to main database table. Cache if required, 00149 /// and return result. 00150 ///\endverbatim 00151 const TDbiResultSet* Query(const TDbiValidityRec& vrec, 00152 Bool_t canReuse = kTRUE); 00153 ///\verbatim 00154 /// 00155 /// Purpose: Determine a suitable Creation Date so that this validity 00156 /// record, if written to the selected DB, will overlay 00157 /// correctly. 00158 /// 00159 /// Specification:- 00160 /// ============= 00161 /// 00162 /// o Determine optimal Creation Date to overlay new data. See Program Notes. 00163 /// 00164 /// Program Notes:- 00165 /// ============= 00166 /// 00167 /// 00168 /// It is normal practice, particularly for calibration data, to have 00169 /// overlapping the validity records. Each time a new set of runs are 00170 /// processed the start time of the validity is set to the start time of 00171 /// the first run and the end time is set beyond the start time by an 00172 /// interval that characterises the stability of the constants. So long 00173 /// as a new set of constants is created before the end time is reached 00174 /// there will be no gap. Where there is an overlap the Creation Date is 00175 /// used to select the later constants on the basis that later is better. 00176 /// However, if reprocessing old data it is also normal practice to 00177 /// process recent data first and in this case the constants for earlier 00178 /// data get later creation dates and overlay works the wrong way. To 00179 /// solve this, the creation date is faked as follows:- 00180 /// 00181 /// 00182 /// 1. For new data i.e. data that does not overlay any existing data, 00183 /// the creation date is set to the validity start time. 00184 /// 00185 /// 2. For replacement data i.e. data that does overlay existing data, 00186 /// the creation date is set to be one minute greater than the Creation 00187 /// Date on the current best data. 00188 /// 00189 /// This scheme ensures that new data will overlay existing data at the 00190 /// start of its validity but will be itself overlaid by data that has 00191 /// a later start time (assuming validity record start times are more 00192 /// than a few minutes apart) 00193 /// 00194 ///\endverbatim 00195 00196 TVldTimeStamp QueryOverlayCreationDate(const TDbiValidityRec& vrec, 00197 UInt_t dbNo); 00198 /// 00199 /// 00200 /// Purpose: Refresh meta data for table. 00201 /// 00202 void RefreshMetaData(); 00203 ///\verbatim 00204 /// 00205 /// Purpose: Apply Sql condition to its TDbiDBProxy. 00206 /// 00207 /// Arguments: 00208 /// sql in SQL condition string (excluding where). 00209 /// 00210 /// Return: n/a 00211 /// 00212 /// Contact: N. West 00213 /// 00214 /// Specification:- 00215 /// ============= 00216 /// 00217 /// o Apply Sql condition to its TDbiDBProxy. 00218 /// 00219 /// Program Notes:- 00220 /// ============= 00221 /// 00222 /// None. 00223 ///\endverbatim 00224 void SetSqlCondition(const string& sql); 00225 Bool_t TableExists() const { return fExists; } 00226 00227 protected: 00228 00229 ///Constructors (protected because created and owned by TDbiDatabaseManager). 00230 ///\verbatim 00231 /// 00232 /// Purpose: Constructor 00233 /// 00234 /// Arguments: 00235 /// in cascader Reference to one and only cascader 00236 /// in tableName Table name. 00237 /// in tableRow Example table row object. 00238 /// 00239 /// Return: n/a 00240 /// 00241 /// Contact: N. West 00242 /// 00243 /// Specification:- 00244 /// ============= 00245 /// 00246 /// o Create table proxy for supplied table name. 00247 ///\endverbatim 00248 TDbiTableProxy(TDbiCascader* cascader, 00249 const string& tableName, 00250 const TDbiTableRow* tableRow); 00251 virtual ~TDbiTableProxy(); 00252 00253 // State testing member functions 00254 00255 // State changing member functions 00256 00257 private: 00258 00259 // Disabled (not implemented) copy constructor and asignment. 00260 00261 TDbiTableProxy(const TDbiTableProxy&); 00262 TDbiTableProxy& operator=(const TDbiTableProxy&); 00263 00264 00265 /// Level 2 (disk) cache management. 00266 Bool_t CanReadL2Cache() const; 00267 Bool_t CanWriteL2Cache() const; 00268 ///\verbatim 00269 /// 00270 /// Purpose: Restore results from named level 2 disk cache into memory cache. 00271 /// Returns true if anything restored 00272 /// 00273 /// Specification:- 00274 /// ============= 00275 /// 00276 /// o Restore to cache but only if enabled and exists. 00277 ///\endverbatim 00278 Bool_t RestoreFromL2Cache(const TDbiValidityRecBuilder& builder); 00279 ///\verbatim 00280 /// 00281 /// Purpose: Save result to named level 2 cache. Returns true if saved. 00282 /// 00283 /// Specification:- 00284 /// ============= 00285 /// 00286 /// o Save to cache but only if enabled and suitable. 00287 ///\endverbatim 00288 Bool_t SaveToL2Cache(const string& name, TDbiResultSet& res); 00289 00290 // Data members (fMeta* must precede fDBProxy, it has to be created 00291 // first - see initialiser list) 00292 00293 00294 /// Pointer to one and only cascader 00295 TDbiCascader* fCascader; 00296 00297 /// Meta data for main(data) table. 00298 TDbiTableMetaData fMetaData; 00299 00300 /// Meta data for aux. (validity)table. 00301 TDbiTableMetaData fMetaValid; 00302 00303 /// True if row supports L2 cache. 00304 Bool_t fCanL2Cache; 00305 00306 /// Associated cache for result. 00307 TDbiCache* fCache; 00308 00309 /// Proxy to database 00310 TDbiDBProxy fDBProxy; 00311 00312 /// true if table exists; 00313 Bool_t fExists; 00314 00315 /// Table Name 00316 string fTableName; 00317 00318 /// Pet object used to create new rows. 00319 TDbiTableRow* fTableRow; 00320 00321 ClassDef(TDbiTableProxy,0) // Object to query a specific table. 00322 00323 }; 00324 00325 #endif // DBITABLEPROXY_H 00326