Go to top,
Notes and Further References
The DatabaseInterface is fully described in the
User Manual
In order to read any Database table supported by the DatabaseInterface../../../UgliGeometry
package, you need to have a context. This concept was introduced
in the Validity slide and the
associated notes explained how to get a VldContext for a RawRecord:-
const VldContext* vc = raw->GetVldContext();
Once there you can create a pointer to any supported database table.
For example UgliGeometry
has the table UgliDbiSteelPln, so at minimum, all you need to do
to get the table of UgliDbiSteelPln rows that are currently valid is:-
DbiResultPtr rptr(vc);
Note that DbiResultPtr is a
templated
class. The compiler takes the real class UgliDbiSteelPln and
generates the associated DbiResultPtr class. We will come
back to the UgliDbiSteelPln when we get to
UgliGeometry,
however if you take a quick peek at
UgliDbiSteelPln.h
which includes:-
Float_t GetZBack() const;
you will have a message to send an UgliDbiSteelPln once
DbiResultPtr has given you one from the table:-
UInt_t numRows = rptr.GetNumRows();
const UgliDbiSteelPln* firstPln = rptr.GetRow(0);
const UgliDbiSteelPln* lastPln = rptr.GetRow(numRows-1);
cout << "There are " << numRows << " steel planes"
<< " Z limits: " << firstPln->GetZBack()
<< " .. " << lastPln->GetZBack() << endl;
Pulling data from that database can be expensive so the DatabaseInterface
caches data in case its reused.
time_dbi.C is a complete ROOT macro to demonstrate this.
time_dbi()
The controlling main program is very similar to ones we have seen before.
See the Writing_ROOT_macros
if you need help.
void myAnaTimeDbi(const MomNavigator* mom)
Has the code that does the timing.
void myAnaTimeDbi(const MomNavigator* mom)
{
RawRecord* raw = dynamic_cast<RawRecord*>(mom->GetFragment("RawRecord"));
const VldContext* vc = raw->GetVldContext();
TStopwatch t;
t.Start();
DbiResultPtr<PlexPixelSpotToStripEnd> rptr(*vc);
t.Stop();
UInt_t numRows = rptr.GetNumRows();
cout << "There are " << numRows << " rows"
<< " cpu " << t.CpuTime() << " elapse " << t.RealTime() << endl;
}
TStopwatch is a little ROOT class that you can send Start() and Stop()
messages to and ask it for CpuTime() and RealTime().
Its used to time the creation of a DbiResultPtr to a PlexPixelSpotToStripEnd
table:-
DbiResultPtr rptr(*vc);
As you have probably noticed, this time we are reading a
Plex table.
When I run:-
loon -q time_dbi.C $ROOT_DATA/fardet_data/2002_06/F00005963_0000.mdaq.root
I get:-
Successfully opened connection to: mysql:odbc://localhost/offline
DbiCascader Status:-
Status URL
Open mysql:odbc://localhost/offline
DbiTimer:PLEXPIXELSPOTTOSTRIPEND: Query done. 190464rows, 6.1Mb Cpu 143.4 , elapse 154.8
SubWatch Query database : Cpu 1.8 , elapse 10.8 , Starts 2
SubWatch Create row objects : Cpu 24.0 , elapse 24.4 , Starts 190466
SubWatch Retrieve TSQL rows : Cpu 8.2 , elapse 8.2 , Starts 190465
SubWatch Fill row objects : Cpu 108.9 , elapse 110.8 , Starts 190465
There are 190464 rows cpu 144.090000 elapse 158.880000
There are 190464 rows cpu 0.000000 elapse 0.000000
There are 190464 rows cpu 0.000000 elapse 0.000000
There are 190464 rows cpu -0.000000 elapse 0.000000
There are 190464 rows cpu 0.000000 elapse 0.000000
There are 190464 rows cpu 0.000000 elapse -0.000000
There are 190464 rows cpu -0.000000 elapse 0.000000
There are 190464 rows cpu 0.000000 elapse 0.000000
There are 190464 rows cpu -0.000000 elapse 0.000000
There are 190464 rows cpu 0.010000 elapse 0.010000
The important point to note is that there is significant cpu and
elapse time for the first call, but after that, and even though
the local DbiResultPtr has been destroyed and recreated, the times are below
the resolution of the timer because the data is coming from the cache.
Exercises
Here is a list of some of the Plex and UgilGeometry
table row classes we have:-
By adapting the above macro try
to create DbiResultPtrs to look at some of the tables and
access the individual table row objects.