EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FairDbTableProxy.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FairDbTableProxy.cxx
1 
2 #include "Detector.h"
3 #include "SimFlag.h"
4 #include "FairDbBinaryFile.h"
5 #include "FairDbCache.h"
7 #include "FairDbResult.h"
8 #include "FairDbTableProxy.h"
9 #include "FairDbTableRow.h"
10 #include "FairDbTimerManager.h"
11 #include "FairDbValidityRec.h"
13 #include "FairDbExceptionLog.h"
14 
16 
17 
19  const string& tableName,
20  const string& vldSuffix,
21  const FairDbTableRow* tableRow) :
22  fMultConnector(cascader),
23  fMetaData(tableName),
24  fMetaValid(tableName+vldSuffix),
25  fCanL2Cache(kFALSE),
26  fCache(0),
27  fDBProxy(*cascader,tableName,&fMetaData,&fMetaValid,this),
28  fExists(0),
29  fTableName(tableName),
30  fTableRow(tableRow->CreateTableRow())
31 {
32 
33  fCache = new FairDbCache(*this,fTableName);
34  this->RefreshMetaData();
35  fExists = fDBProxy.TableExists();
36  fCanL2Cache = tableRow->CanL2Cache();
37  if ( fCanL2Cache ) {
38  cout << "FairDbTableProxy: Can L2 cache " << this->GetRowName() << endl;
39  }
40  cout << "Creating FairDbTableProxy "
41  << fTableName.c_str() << " at " << this
42  << ( fExists ? " (table exists)"
43  : " (table missing)" )
44  << endl;
45 }
46 
47 
49 {
50  delete fCache;
51  delete fTableRow;
52 
53 }
54 
56 {
58 
59 }
61 {
63 
64 }
66  const FairDb::Task& task,
67  Bool_t findFullTimeWindow)
68 {
69 
70  if ( const FairDbResult* result = fCache->Search(vc,task)
71  ) { return result; }
72 
73  FairDbConnectionMaintainer cm(fMultConnector); //Stack object to hold connections
74 
75 // Make Global Exception Log bookmark
76  UInt_t startGEL = FairDbExceptionLog::GetGELog().Size()+1;
77 
78 // Build a complete set of effective validity record from the database.
79  FairDbValidityRecBuilder builder(fDBProxy,vc,task,-1,findFullTimeWindow);
80 
81 // Deal with non-aggregated data.
82 
83  if ( builder.NonAggregated() ) {
84 
85  FairDbValidityRec effVRec = builder.GetValidityRec(0);
86 // Force off const - we haven't finished with FairDbResult yet!
87  FairDbResult* result = const_cast<FairDbResult*>(Query(effVRec));
88 // Record latest entries from Global Exception Log.
89  result->CaptureExceptionLog(startGEL);
90  return result;
91  }
92 
93 // Deal with aggregated data.
94 
95 
96  if ( this->CanReadL2Cache() ) {
97  UInt_t numPresent = 0;
98  UInt_t numRequired = 0;
99  Int_t maxRow = builder.GetNumValidityRec() - 1;
100  for ( Int_t rowNo = 1; rowNo <= maxRow; ++rowNo ) {
101  const FairDbValidityRec& vrec = builder.GetValidityRec(rowNo);
102  if ( fCache->Search(vrec) ) { ++numPresent; }
103  else if ( ! vrec.IsGap() ) { ++numRequired; }
104  }
105  if ( numRequired < numPresent )
106  cout << "Skipping search of L2 cache; already have "
107  << numPresent << " aggregates, and only require a further "
108  << numRequired << endl;
109  else { this->RestoreFromL2Cache(builder); }
110  }
111 
113  fTableRow,
114  fCache,
115  &builder,
116  &fDBProxy);
117 // Record latest entries from Global Exception Log.
118  result->CaptureExceptionLog(startGEL);
119 
120  fCache->Adopt(result);
121  this->SaveToL2Cache(builder.GetL2CacheName(),*result);
122  return result;
123 
124 }
125 //.....................................................................
126 
127 const FairDbResult* FairDbTableProxy::Query(const string& context,
128  const FairDb::Task& task,
129  const string& data,
130  const string& fillOpts)
131 {
132 
133  std::ostringstream os;
134  os << context;
135  if ( task != FairDb::kAnyTask
136  ) { os << " and Task = " << task; }
137  os << ';' << data << ';' << fillOpts;
138  string sqlQualifiers = os.str();
139 
140 
141  cout << "Extended query: sqlQualifiers: " << sqlQualifiers << endl;
142 
143 // See if there is one already in the cache.
144 
145  if ( const FairDbResult* result = fCache->Search(sqlQualifiers)
146  ) { return result; }
147 
148  FairDbConnectionMaintainer cm(fMultConnector); //Stack object to hold connections
149 
150 // Make Global Exception Log bookmark
151  UInt_t startGEL = FairDbExceptionLog::GetGELog().Size()+1;
152 
153 // Build a complete set of effective validity records from the database.
154  FairDbValidityRecBuilder builder(fDBProxy,context,task);
155 
156 // For extended context queries, FairDbValidityRecBuilder will always
157 // assemble a result that has to be represented by a FairDbResultAgg
158 
160  fTableRow,
161  fCache,
162  &builder,
163  &fDBProxy,
164  sqlQualifiers);
165 // Record latest entries from Global Exception Log.
166  result->CaptureExceptionLog(startGEL);
167 
168  fCache->Adopt(result);
169  return result;
170 
171 }
172 
173 const FairDbResult* FairDbTableProxy::Query(UInt_t seqNo,UInt_t dbNo)
174 {
175 
176  FairDbConnectionMaintainer cm(fMultConnector); //Stack object to hold connections
177 
178 // Make Global Exception Log bookmark
179  UInt_t startGEL = FairDbExceptionLog::GetGELog().Size()+1;
180 
181  // Apply SEQNO query to cascade member.
182  FairDbResultSet* rs = fDBProxy.QueryValidity(seqNo,dbNo);
184  FairDbResultNonAgg result(rs,&tr,0,kFALSE);
185  delete rs;
186 
187  // If query failed, return an empty result.
188  if ( result.GetNumRows() == 0 ) {
189  FairDbResultNonAgg* empty = new FairDbResultNonAgg();
190 // Record latest entries from Global Exception Log.
191  empty->CaptureExceptionLog(startGEL);
192  fCache->Adopt(empty);
193  return empty;
194  }
195 
196 // Otherwise perform a validity rec query, but don't
197 // allow result to be used; it's validity has not been trimmed
198 // by neighbouring records.
199 
200  const FairDbValidityRec* vrec
201  = dynamic_cast<const FairDbValidityRec*>(result.GetTableRow(0));
202 // Force off const - we haven't finished with FairDbResult yet!
203  FairDbResult* res = const_cast<FairDbResult*>(Query(*vrec,kFALSE));
204 // Record latest entries from Global Exception Log.
205  res->CaptureExceptionLog(startGEL);
206  return res;
207 
208 }
209 
211  Bool_t canReuse )
212 {
213 
214  FairDbConnectionMaintainer cm(fMultConnector); //Stack object to hold connections
215 
216 // Make Global Exception Log bookmark
217  UInt_t startGEL = FairDbExceptionLog::GetGELog().Size()+1;
218 
219  if ( canReuse ) {
220  FairDbValidityRecBuilder builder(vrec,this->GetTableName());
221  if ( this->RestoreFromL2Cache(builder) ) {
222  const FairDbResult* res = fCache->Search(vrec);
223  if ( res ) { return res; }
224  }
225  }
226 
227  unsigned int seqNo = vrec.GetSeqNo();
228  FairDbResult* result = 0;
229 
230 // If no records, create an empty FairDbResult.
231  if ( ! seqNo ) {
232  result = new FairDbResultNonAgg(0,0,&vrec);
233  }
234 
235 // If query does not apply to this table, report error and
236 // produce an empty FairDbResult.
237 
238  else if (vrec.GetTableProxy()->GetTableName() != GetTableName() ) {
239 
240  cout << "Unable to satisfy FairDbValidityRec keyed query:" << endl
241  << vrec
242  << " was filled by " << vrec.GetTableProxy()->GetTableName()
243  << " not by this FairDbTableProxy ("
244  << GetTableName() << ")" << endl;
245  result = new FairDbResultNonAgg(0,0,&vrec);
246  }
247 
248  else {
249 
250 
251 // Apply query, and build DiResult from its FairDbResultSet.
252 
253  FairDbResultSet* rs = fDBProxy.QuerySeqNo(seqNo,vrec.GetDbNo());
254  result = new FairDbResultNonAgg(rs,fTableRow,&vrec);
255  delete rs;
256  }
257 
258 // Record latest entries from Global Exception Log.
259  result->CaptureExceptionLog(startGEL);
260 
261 // Cache in memory and on disk if required and return the results.
262 
263  fCache->Adopt(result);
264  if ( canReuse ) { this->SaveToL2Cache(vrec.GetL2CacheName(),*result); }
265  else { result->SetCanReuse(kFALSE); }
266 
267  return result;
268 
269 }
270 
271 //.....................................................................
272 
274 {
275 //
276 //
277 // Purpose: Refresh meta data for table.
278 //
279 
282 
283 }
284 //.....................................................................
285 
287  UInt_t dbNo)
288 {
289  // Practice for claibrated data
290 
291  const ValRange& vr(vrec.GetValRange());
292  ValContext vc((Detector::Detector_t) vr.GetDetectorMask(),
293  (SimFlag::SimFlag_t) vr.GetSimMask(),
294  vr.GetTimeStart());
295 
296  FairDbConnectionMaintainer cm(fMultConnector); //Stack object to hold connections
297 
298  // Build a complete set of effective validity records from the
299  // selected database.
300  FairDbValidityRecBuilder builder(fDBProxy,vc,vrec.GetTask(),dbNo);
301 
302  // Pick up the validity record for the current aggregate.
303  const FairDbValidityRec& vrecOvlay(builder.GetValidityRecFromAggNo(vrec.GetAggregateNo()));
304 
305  // If its a gap i.e. nothing is overlayed, return the start time, otherwise
306  // return its Creation Date plus one minute.
307  ValTimeStamp ovlayTS(vr.GetTimeStart());
308  if ( ! vrecOvlay.IsGap() ) {
309  time_t overlaySecs = vrecOvlay.GetCreationDate().GetSec();
310  ovlayTS = ValTimeStamp(overlaySecs + 60,0);
311  }
312 
313  cout << "Looking for overlay creation date for: "
314  << vrec << "found it would overlap: "
315  << vrecOvlay << " so overlay creation date set to "
316  << ovlayTS.AsString("s") << endl;
317  return ovlayTS;
318 
319 }
320 
322 {
323 
324  const string name(builder.GetL2CacheName());
325  cout << "Request to restore query result " << name
326  << endl;
327  if ( ! this->CanReadL2Cache() ) { return kFALSE; }
328  string cacheFileName;
329  if ( name != ""
330  ) cacheFileName = this->GetTableName() + "_"
331  + this->GetRowName() + "_"
332  + name + ".dbi_cache";
333  FairDbBinaryFile bf(cacheFileName.c_str());
334  if ( ! bf.IsOK() ) {
335  cout << "Caching disabled or cannot open "
336  << bf.GetFileName() << endl;
337  return kFALSE;
338  }
339 
340  static bool warnOnce = true;
341  if ( warnOnce ) {
342  cout << "\n\n\n"
343  << " WARNING: Reading from the Level 2 cache has been activated.\n"
344  << " ******* This should only be used for development and never for production !!!\n\n\n";
345  warnOnce = false;
346  }
347 
348  cout << "Restoring query result from " << bf.GetFileName() << endl;
350 
351  FairDbResult* result = 0;
352  unsigned numRowsRest = 0;
353  unsigned numRowsIgn = 0;
354  UInt_t numNonAgg = 0;
355  bf >> numNonAgg;
356 
357  while ( numNonAgg-- ) {
358  if ( ! bf.IsOK() ) { break; }
359  if ( ! result ) { result = new FairDbResultNonAgg; }
360  bf >> *result;
361 
362 // The original query may have had a validity range truncated by
363 // the time window, so replace its FairDbValidityRec with the one
364 // just obtained from the database.
365  const FairDbValidityRec& vrec = result->GetValidityRec();
366  UInt_t seqNo = vrec.GetSeqNo();
367  cout << "Fix up L2 cache FairDbValidityRec, by replacing: " << vrec
368  << " with: " << builder.GetValidityRecFromSeqNo(seqNo) << endl;
369 // Sneaky end-run round const to fix-up FairDbValidityRec.
370  (const_cast<FairDbValidityRec&>(vrec)) = builder.GetValidityRecFromSeqNo(seqNo);
371 
372 // Adopt only if not already in memory cache.
373  if ( ! fCache->Search(vrec) ) {
374  numRowsRest += result->GetNumRows();
375  fCache->Adopt(result);
376  result = 0;
377  } else { numRowsIgn += result->GetNumRows(); }
378  }
379  cout << " a total of " << numRowsRest << " were restored ("
380  << numRowsIgn << " ignored - already in memory)" << endl;
381 
382  delete result;
383  result = 0;
384 
385  return numRowsRest > 0;
386 
387 }
388 
390 {
391 
392  cout << "Request to save query result as " << name
393  << " data from DB? " << res.ResultsFromDb()
394  << " can be saved? " << res.CanSave() << endl;
395  if ( ! this->CanWriteL2Cache() || ! res.ResultsFromDb() || ! res.CanSave() ) { return kFALSE; }
396 
397  string cacheFileName;
398  if ( name != ""
399  ) cacheFileName = this->GetTableName() + "_"
400  + this->GetRowName() + "_"
401  + name + ".dbi_cache";
402  FairDbBinaryFile bf(cacheFileName.c_str(),kFALSE);
403  if ( bf.IsOK() ) {
404  cout << "Saving query result (" << res.GetNumRows()
405  << " rows) to " << bf.GetFileName() << endl;
407 
408  // if writing a FairDbResultNonAgg, add leading count of 1. (if writing
409  // a FairDbResultAgg it will writes its one leading count.
410  if ( dynamic_cast<FairDbResultNonAgg*>(&res) ) {
411  UInt_t numNonAgg = 1;
412  bf << numNonAgg;
413  }
414  bf << res;
415  return kTRUE;
416  }
417  cout << "Caching disabled or cannot open "
418  << bf.GetFileName() << endl;
419  return kFALSE;
420 
421 }
422 
423 void FairDbTableProxy::SetSqlCondition(const string& sql)
424 {
425 
427 
428 }